mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-21 20:34:08 +00:00
all is working again
This commit is contained in:
parent
022ed7b24c
commit
c26fd45d54
6 changed files with 191 additions and 113 deletions
|
@ -125,10 +125,11 @@ where
|
||||||
E: 'a,
|
E: 'a,
|
||||||
{
|
{
|
||||||
move |_, state: State<'a>| {
|
move |_, state: State<'a>| {
|
||||||
if state.column > state.indent_col {
|
if state.column > min_indent {
|
||||||
Ok((NoProgress, (), state))
|
Ok((NoProgress, (), state))
|
||||||
} else {
|
} else {
|
||||||
Err((NoProgress, indent_problem(state.line, state.column), state))
|
Err((NoProgress, indent_problem(state.line, state.column), state))
|
||||||
|
//Ok((NoProgress, (), state))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,6 +366,7 @@ fn parse_loc_term<'a>(
|
||||||
in_parens_region_fix(min_indent),
|
in_parens_region_fix(min_indent),
|
||||||
loc!(specialize(EExpr::Str, string_literal_help())),
|
loc!(specialize(EExpr::Str, string_literal_help())),
|
||||||
loc!(specialize(EExpr::Number, number_literal_help())),
|
loc!(specialize(EExpr::Number, number_literal_help())),
|
||||||
|
loc!(specialize(EExpr::Lambda, closure_help(min_indent))),
|
||||||
loc!(record_literal_help(min_indent)),
|
loc!(record_literal_help(min_indent)),
|
||||||
loc!(specialize(EExpr::List, list_literal_help(min_indent))),
|
loc!(specialize(EExpr::List, list_literal_help(min_indent))),
|
||||||
loc!(ident_etc_help(min_indent))
|
loc!(ident_etc_help(min_indent))
|
||||||
|
@ -382,6 +383,7 @@ fn parse_loc_term_better<'a>(
|
||||||
in_parens_region_fix(min_indent),
|
in_parens_region_fix(min_indent),
|
||||||
loc!(specialize(EExpr::Str, string_literal_help())),
|
loc!(specialize(EExpr::Str, string_literal_help())),
|
||||||
loc!(specialize(EExpr::Number, positive_number_literal_help())),
|
loc!(specialize(EExpr::Number, positive_number_literal_help())),
|
||||||
|
loc!(specialize(EExpr::Lambda, closure_help(min_indent))),
|
||||||
loc!(record_literal_help(min_indent)),
|
loc!(record_literal_help(min_indent)),
|
||||||
loc!(specialize(EExpr::List, list_literal_help(min_indent))),
|
loc!(specialize(EExpr::List, list_literal_help(min_indent))),
|
||||||
// loc!(ident_etc_help(min_indent))
|
// loc!(ident_etc_help(min_indent))
|
||||||
|
@ -579,7 +581,7 @@ fn foobar<'a>(
|
||||||
let initial = state;
|
let initial = state;
|
||||||
let end = state.get_position();
|
let end = state.get_position();
|
||||||
|
|
||||||
match dbg!(space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state)) {
|
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
||||||
Err((_, _, state)) => Ok((MadeProgress, expr.value, state)),
|
Err((_, _, state)) => Ok((MadeProgress, expr.value, state)),
|
||||||
Ok((_, spaces_before_op, state)) => {
|
Ok((_, spaces_before_op, state)) => {
|
||||||
let expr_state = ExprState {
|
let expr_state = ExprState {
|
||||||
|
@ -605,6 +607,43 @@ struct ExprState<'a> {
|
||||||
end: Position,
|
end: Position,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// expr_state.expr = if spaces.is_empty() {
|
||||||
|
// expr_state.expr
|
||||||
|
// } else {
|
||||||
|
// arena
|
||||||
|
// .alloc(expr_state.expr.value)
|
||||||
|
// .with_spaces_after(spaces, expr_state.expr.region)
|
||||||
|
// };
|
||||||
|
|
||||||
|
// fn attach_spaces<'a>(&'a Bump, expr: &mut Located<Expr<'a>>, spaces: &'a [CommentOrNewline<'a>] ) {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
impl<'a> ExprState<'a> {
|
||||||
|
fn consume_spaces(&mut self, arena: &'a Bump) {
|
||||||
|
if !self.spaces_after.is_empty() {
|
||||||
|
if let Some(last) = self.arguments.pop() {
|
||||||
|
let new = last.value.with_spaces_after(self.spaces_after, last.region);
|
||||||
|
|
||||||
|
self.arguments.push(arena.alloc(new));
|
||||||
|
} else {
|
||||||
|
let region = self.expr.region;
|
||||||
|
|
||||||
|
let mut value = Expr::Num("");
|
||||||
|
std::mem::swap(&mut self.expr.value, &mut value);
|
||||||
|
|
||||||
|
self.expr = arena
|
||||||
|
.alloc(value)
|
||||||
|
.with_spaces_after(self.spaces_after, region);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.spaces_after = &[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_expr_final<'a>(
|
fn parse_expr_final<'a>(
|
||||||
min_indent: u16,
|
min_indent: u16,
|
||||||
expr_state: ExprState<'a>,
|
expr_state: ExprState<'a>,
|
||||||
|
@ -631,7 +670,7 @@ fn to_call<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
arguments: Vec<'a, &'a Located<Expr<'a>>>,
|
arguments: Vec<'a, &'a Located<Expr<'a>>>,
|
||||||
loc_expr1: Located<Expr<'a>>,
|
loc_expr1: Located<Expr<'a>>,
|
||||||
_spaces_before: &'a [CommentOrNewline<'a>],
|
spaces_before: &'a [CommentOrNewline<'a>],
|
||||||
) -> Located<Expr<'a>> {
|
) -> Located<Expr<'a>> {
|
||||||
if arguments.is_empty() {
|
if arguments.is_empty() {
|
||||||
loc_expr1
|
loc_expr1
|
||||||
|
@ -712,20 +751,9 @@ fn parse_expr_operator<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
state: State<'a>,
|
state: State<'a>,
|
||||||
) -> ParseResult<'a, Expr<'a>, EExpr<'a>> {
|
) -> ParseResult<'a, Expr<'a>, EExpr<'a>> {
|
||||||
let (space_progress, mut spaces, state) =
|
let (_, spaces_after_operator, state) =
|
||||||
space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state)?;
|
space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state)?;
|
||||||
|
|
||||||
// add previous spaces to the expr
|
|
||||||
std::mem::swap(&mut spaces, &mut expr_state.spaces_after);
|
|
||||||
|
|
||||||
expr_state.expr = if spaces.is_empty() {
|
|
||||||
expr_state.expr
|
|
||||||
} else {
|
|
||||||
arena
|
|
||||||
.alloc(expr_state.expr.value)
|
|
||||||
.with_spaces_after(spaces, expr_state.expr.region)
|
|
||||||
};
|
|
||||||
|
|
||||||
// a `-` is unary if it is preceded by a space and not followed by a space
|
// a `-` is unary if it is preceded by a space and not followed by a space
|
||||||
|
|
||||||
let op = loc_op.value;
|
let op = loc_op.value;
|
||||||
|
@ -761,16 +789,39 @@ fn parse_expr_operator<'a>(
|
||||||
|
|
||||||
parse_expr_end2(min_indent, expr_state, arena, state)
|
parse_expr_end2(min_indent, expr_state, arena, state)
|
||||||
}
|
}
|
||||||
|
BinOp::Assignment => {
|
||||||
|
if !expr_state.operators.is_empty() {
|
||||||
|
// this `:` likely occured inline; treat it as an invalid operator
|
||||||
|
let fail = EExpr::BadOperator(
|
||||||
|
arena.alloc([b'=']),
|
||||||
|
loc_op.region.start_line,
|
||||||
|
loc_op.region.start_col,
|
||||||
|
);
|
||||||
|
|
||||||
|
Err((MadeProgress, fail, state))
|
||||||
|
} else if !expr_state.arguments.is_empty() {
|
||||||
|
let region = Region::across_all(expr_state.arguments.iter().map(|v| &v.region));
|
||||||
|
|
||||||
|
let fail = EExpr::ElmStyleFunction(
|
||||||
|
region,
|
||||||
|
loc_op.region.start_line,
|
||||||
|
loc_op.region.start_col,
|
||||||
|
);
|
||||||
|
|
||||||
|
Err((MadeProgress, fail, state))
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
BinOp::HasType => {
|
BinOp::HasType => {
|
||||||
debug_assert!(expr_state.operators.is_empty());
|
debug_assert!(expr_state.operators.is_empty());
|
||||||
dbg!(&expr_state.expr, &expr_state.arguments);
|
|
||||||
|
let expr_region = expr_state.expr.region;
|
||||||
|
|
||||||
match &expr_state.expr.value {
|
match &expr_state.expr.value {
|
||||||
Expr::GlobalTag(name) => {
|
Expr::GlobalTag(name) => {
|
||||||
let indented_more = min_indent + 1;
|
let indented_more = min_indent + 1;
|
||||||
|
|
||||||
let region = expr_state.expr.region;
|
|
||||||
|
|
||||||
let (_, ann_type, state) = specialize(
|
let (_, ann_type, state) = specialize(
|
||||||
EExpr::Type,
|
EExpr::Type,
|
||||||
space0_before_e(
|
space0_before_e(
|
||||||
|
@ -820,31 +871,86 @@ fn parse_expr_operator<'a>(
|
||||||
state,
|
state,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
_ => panic!(),
|
_ => {
|
||||||
|
expr_state.consume_spaces(arena);
|
||||||
|
let call = to_call(
|
||||||
|
arena,
|
||||||
|
expr_state.arguments,
|
||||||
|
expr_state.expr,
|
||||||
|
spaces_after_operator,
|
||||||
|
);
|
||||||
|
|
||||||
|
// let aligned_like_a_def = expr_state.expr.region.start_col == state.indent_col;
|
||||||
|
|
||||||
|
match expr_to_pattern_help(arena, &call.value) {
|
||||||
|
Ok(good) => {
|
||||||
|
let indented_more = min_indent + 1;
|
||||||
|
|
||||||
|
let (_, ann_type, state) = specialize(
|
||||||
|
EExpr::Type,
|
||||||
|
space0_before_e(
|
||||||
|
type_annotation::located_help(indented_more),
|
||||||
|
min_indent,
|
||||||
|
Type::TSpace,
|
||||||
|
Type::TIndentStart,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.parse(arena, state)?;
|
||||||
|
|
||||||
|
let alias_region = Region::span_across(&expr_region, &ann_type.region);
|
||||||
|
|
||||||
|
let alias = Def::Annotation(Located::at(expr_region, good), ann_type);
|
||||||
|
|
||||||
|
let loc_def = &*arena.alloc(Located::at(alias_region, alias));
|
||||||
|
|
||||||
|
let foo = space0_before_e(
|
||||||
|
move |a, s| parse_expr_help(min_indent, a, s),
|
||||||
|
min_indent,
|
||||||
|
EExpr::Space,
|
||||||
|
EExpr::IndentEnd,
|
||||||
|
);
|
||||||
|
|
||||||
|
let (_, loc_ret, state) = foo.parse(arena, state)?;
|
||||||
|
|
||||||
|
return Ok((
|
||||||
|
MadeProgress,
|
||||||
|
Expr::Defs(&*arena.alloc([loc_def]), arena.alloc(loc_ret)),
|
||||||
|
state,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
// this `:` likely occured inline; treat it as an invalid operator
|
||||||
|
let fail = EExpr::BadOperator(
|
||||||
|
arena.alloc([b':']),
|
||||||
|
loc_op.region.start_line,
|
||||||
|
loc_op.region.start_col,
|
||||||
|
);
|
||||||
|
|
||||||
|
Err((MadeProgress, fail, state))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => match loc_possibly_negative_or_negated_term(min_indent).parse(arena, state) {
|
_ => match loc_possibly_negative_or_negated_term(min_indent).parse(arena, state) {
|
||||||
Err((MadeProgress, f, s)) => Err((MadeProgress, f, s)),
|
Err((MadeProgress, f, s)) => Err((MadeProgress, f, s)),
|
||||||
Ok((_, new_expr, state)) => {
|
Ok((_, mut new_expr, state)) => {
|
||||||
let new_end = state.get_position();
|
let new_end = state.get_position();
|
||||||
|
|
||||||
expr_state.initial = state;
|
expr_state.initial = state;
|
||||||
|
|
||||||
|
// put the spaces from after the operator in front of the new_expr
|
||||||
|
if !spaces_after_operator.is_empty() {
|
||||||
|
new_expr = arena
|
||||||
|
.alloc(new_expr.value)
|
||||||
|
.with_spaces_before(spaces_after_operator, new_expr.region);
|
||||||
|
}
|
||||||
|
|
||||||
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
||||||
Err((_, _, state)) => {
|
Err((_, _, state)) => {
|
||||||
let spaces = expr_state.spaces_after;
|
|
||||||
|
|
||||||
let new_expr = if spaces.is_empty() {
|
|
||||||
new_expr
|
|
||||||
} else {
|
|
||||||
arena
|
|
||||||
.alloc(new_expr.value)
|
|
||||||
.with_spaces_before(spaces, new_expr.region)
|
|
||||||
};
|
|
||||||
|
|
||||||
let args = std::mem::replace(&mut expr_state.arguments, Vec::new_in(arena));
|
let args = std::mem::replace(&mut expr_state.arguments, Vec::new_in(arena));
|
||||||
|
|
||||||
let call = to_call(arena, args, expr_state.expr, spaces);
|
let call = to_call(arena, args, expr_state.expr, &[]);
|
||||||
|
|
||||||
expr_state.operators.push((call, loc_op));
|
expr_state.operators.push((call, loc_op));
|
||||||
expr_state.expr = new_expr;
|
expr_state.expr = new_expr;
|
||||||
|
@ -853,17 +959,7 @@ fn parse_expr_operator<'a>(
|
||||||
|
|
||||||
parse_expr_final(min_indent, expr_state, arena, state)
|
parse_expr_final(min_indent, expr_state, arena, state)
|
||||||
}
|
}
|
||||||
Ok((_, mut spaces, state)) => {
|
Ok((_, spaces, state)) => {
|
||||||
std::mem::swap(&mut spaces, &mut expr_state.spaces_after);
|
|
||||||
|
|
||||||
let new_expr = if spaces.is_empty() {
|
|
||||||
new_expr
|
|
||||||
} else {
|
|
||||||
arena
|
|
||||||
.alloc(new_expr.value)
|
|
||||||
.with_spaces_before(spaces, new_expr.region)
|
|
||||||
};
|
|
||||||
|
|
||||||
let args = std::mem::replace(&mut expr_state.arguments, Vec::new_in(arena));
|
let args = std::mem::replace(&mut expr_state.arguments, Vec::new_in(arena));
|
||||||
|
|
||||||
let call = to_call(arena, args, expr_state.expr, spaces);
|
let call = to_call(arena, args, expr_state.expr, spaces);
|
||||||
|
@ -871,6 +967,7 @@ fn parse_expr_operator<'a>(
|
||||||
expr_state.operators.push((call, loc_op));
|
expr_state.operators.push((call, loc_op));
|
||||||
expr_state.expr = new_expr;
|
expr_state.expr = new_expr;
|
||||||
expr_state.end = new_end;
|
expr_state.end = new_end;
|
||||||
|
expr_state.spaces_after = spaces;
|
||||||
|
|
||||||
parse_expr_end(min_indent, expr_state, arena, state)
|
parse_expr_end(min_indent, expr_state, arena, state)
|
||||||
}
|
}
|
||||||
|
@ -896,42 +993,31 @@ fn parse_expr_end2<'a>(
|
||||||
|
|
||||||
match parser.parse(arena, state) {
|
match parser.parse(arena, state) {
|
||||||
Err((MadeProgress, f, s)) => Err((MadeProgress, f, s)),
|
Err((MadeProgress, f, s)) => Err((MadeProgress, f, s)),
|
||||||
Ok((_, arg, state)) => {
|
Ok((_, mut arg, state)) => {
|
||||||
let new_end = state.get_position();
|
let new_end = state.get_position();
|
||||||
|
|
||||||
|
// now that we have `function arg1 ... <spaces> argn`, attach the spaces to the `argn`
|
||||||
|
if !expr_state.spaces_after.is_empty() {
|
||||||
|
arg = arena
|
||||||
|
.alloc(arg.value)
|
||||||
|
.with_spaces_before(expr_state.spaces_after, arg.region);
|
||||||
|
|
||||||
|
expr_state.spaces_after = &[];
|
||||||
|
}
|
||||||
expr_state.initial = state;
|
expr_state.initial = state;
|
||||||
|
|
||||||
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
match space0_e(min_indent, EExpr::Space, EExpr::IndentEnd).parse(arena, state) {
|
||||||
Err((_, _, state)) => {
|
Err((_, _, state)) => {
|
||||||
let spaces = expr_state.spaces_after;
|
|
||||||
|
|
||||||
let arg = if spaces.is_empty() {
|
|
||||||
arg
|
|
||||||
} else {
|
|
||||||
arena
|
|
||||||
.alloc(arg.value)
|
|
||||||
.with_spaces_before(spaces, arg.region)
|
|
||||||
};
|
|
||||||
|
|
||||||
expr_state.arguments.push(arena.alloc(arg));
|
expr_state.arguments.push(arena.alloc(arg));
|
||||||
expr_state.end = new_end;
|
expr_state.end = new_end;
|
||||||
expr_state.spaces_after = &[];
|
expr_state.spaces_after = &[];
|
||||||
|
|
||||||
parse_expr_final(min_indent, expr_state, arena, state)
|
parse_expr_final(min_indent, expr_state, arena, state)
|
||||||
}
|
}
|
||||||
Ok((_, mut spaces, state)) => {
|
Ok((_, new_spaces, state)) => {
|
||||||
std::mem::swap(&mut spaces, &mut expr_state.spaces_after);
|
|
||||||
|
|
||||||
let arg = if spaces.is_empty() {
|
|
||||||
arg
|
|
||||||
} else {
|
|
||||||
arena
|
|
||||||
.alloc(arg.value)
|
|
||||||
.with_spaces_before(spaces, arg.region)
|
|
||||||
};
|
|
||||||
|
|
||||||
expr_state.arguments.push(arena.alloc(arg));
|
expr_state.arguments.push(arena.alloc(arg));
|
||||||
expr_state.end = new_end;
|
expr_state.end = new_end;
|
||||||
|
expr_state.spaces_after = new_spaces;
|
||||||
|
|
||||||
parse_expr_end(min_indent, expr_state, arena, state)
|
parse_expr_end(min_indent, expr_state, arena, state)
|
||||||
}
|
}
|
||||||
|
@ -943,6 +1029,7 @@ fn parse_expr_end2<'a>(
|
||||||
match loc!(operator()).parse(arena, state) {
|
match loc!(operator()).parse(arena, state) {
|
||||||
Err((MadeProgress, f, s)) => Err((MadeProgress, f, s)),
|
Err((MadeProgress, f, s)) => Err((MadeProgress, f, s)),
|
||||||
Ok((_, loc_op, state)) => {
|
Ok((_, loc_op, state)) => {
|
||||||
|
expr_state.consume_spaces(arena);
|
||||||
expr_state.initial = before_op;
|
expr_state.initial = before_op;
|
||||||
parse_expr_operator(min_indent, expr_state, loc_op, arena, state)
|
parse_expr_operator(min_indent, expr_state, loc_op, arena, state)
|
||||||
}
|
}
|
||||||
|
@ -988,41 +1075,6 @@ fn parse_expr_end<'a>(
|
||||||
state: State<'a>,
|
state: State<'a>,
|
||||||
) -> ParseResult<'a, Expr<'a>, EExpr<'a>> {
|
) -> ParseResult<'a, Expr<'a>, EExpr<'a>> {
|
||||||
return parse_expr_end2(min_indent, expr_state, arena, state);
|
return parse_expr_end2(min_indent, expr_state, arena, state);
|
||||||
let parser = and!(
|
|
||||||
loc!(operator()),
|
|
||||||
// The spaces *after* the operator can be attached directly to
|
|
||||||
// the expression following the operator.
|
|
||||||
space0_before_e(
|
|
||||||
move |arena, state| parse_expr_help(min_indent, arena, state),
|
|
||||||
min_indent,
|
|
||||||
EExpr::Space,
|
|
||||||
EExpr::IndentEnd,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
match parser.parse(arena, state) {
|
|
||||||
Ok((_, (loc_op, loc_expr2), state)) => {
|
|
||||||
let ExprState {
|
|
||||||
expr: loc_expr1,
|
|
||||||
spaces_after: spaces_before,
|
|
||||||
..
|
|
||||||
} = expr_state;
|
|
||||||
|
|
||||||
let loc_expr1 = if spaces_before.is_empty() {
|
|
||||||
loc_expr1
|
|
||||||
} else {
|
|
||||||
// Attach the spaces retroactively to the expression preceding the operator.
|
|
||||||
arena
|
|
||||||
.alloc(loc_expr1.value)
|
|
||||||
.with_spaces_after(spaces_before, loc_expr1.region)
|
|
||||||
};
|
|
||||||
let tuple = arena.alloc((loc_expr1, loc_op, loc_expr2));
|
|
||||||
|
|
||||||
Ok((MadeProgress, Expr::BinOp(tuple), state))
|
|
||||||
}
|
|
||||||
Err((NoProgress, _, _)) => Ok((MadeProgress, expr_state.expr.value, expr_state.initial)),
|
|
||||||
Err((MadeProgress, fail, state)) => Err((MadeProgress, fail, state)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expr_help<'a>(
|
fn parse_expr_help<'a>(
|
||||||
|
|
|
@ -254,7 +254,12 @@ fn end_of_file<'a>() -> impl Parser<'a, (), SyntaxError<'a>> {
|
||||||
if state.has_reached_end() {
|
if state.has_reached_end() {
|
||||||
Ok((NoProgress, (), state))
|
Ok((NoProgress, (), state))
|
||||||
} else {
|
} else {
|
||||||
Err((NoProgress, SyntaxError::ConditionFailed, state))
|
dbg!(state);
|
||||||
|
Err((
|
||||||
|
NoProgress,
|
||||||
|
SyntaxError::NotEndOfFile(state.line, state.column),
|
||||||
|
state,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,7 @@ pub enum SyntaxError<'a> {
|
||||||
Expr(EExpr<'a>),
|
Expr(EExpr<'a>),
|
||||||
Header(EHeader<'a>),
|
Header(EHeader<'a>),
|
||||||
Space(BadInputError),
|
Space(BadInputError),
|
||||||
|
NotEndOfFile(Row, Col),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
|
|
@ -125,6 +125,22 @@ fn to_syntax_report<'a>(
|
||||||
|
|
||||||
report(doc)
|
report(doc)
|
||||||
}
|
}
|
||||||
|
NotEndOfFile(row, col) => {
|
||||||
|
let surroundings = Region::from_rows_cols(start_row, start_col, *row, *col);
|
||||||
|
let region = Region::from_row_col(*row, *col);
|
||||||
|
|
||||||
|
let doc = alloc.stack(vec![
|
||||||
|
alloc.reflow(r"I expected to reach the end of the file, but got stuck here:"),
|
||||||
|
alloc.region_with_subregion(surroundings, region),
|
||||||
|
alloc.concat(vec![alloc.reflow("no hints")]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Report {
|
||||||
|
filename,
|
||||||
|
doc,
|
||||||
|
title: "NOT END OF FILE".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
SyntaxError::Eof(region) => {
|
SyntaxError::Eof(region) => {
|
||||||
let doc = alloc.stack(vec![alloc.reflow("End of Field"), alloc.region(*region)]);
|
let doc = alloc.stack(vec![alloc.reflow("End of Field"), alloc.region(*region)]);
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ mod test_reporting {
|
||||||
problems: can_problems,
|
problems: can_problems,
|
||||||
..
|
..
|
||||||
} = can_expr(arena, expr_src)?;
|
} = can_expr(arena, expr_src)?;
|
||||||
|
dbg!(&loc_expr);
|
||||||
let mut subs = Subs::new(var_store.into());
|
let mut subs = Subs::new(var_store.into());
|
||||||
|
|
||||||
for (var, name) in output.introduced_variables.name_by_var {
|
for (var, name) in output.introduced_variables.name_by_var {
|
||||||
|
@ -4205,12 +4206,12 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── TOO MANY ARGS ───────────────────────────────────────────────────────────────
|
── TOO MANY ARGS ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
The `add` function expects 2 arguments, but it got 3 instead:
|
This value is not a function, but it was given 3 arguments:
|
||||||
|
|
||||||
4│ Num.add 1 2
|
3│ x == 5
|
||||||
^^^^^^^
|
^
|
||||||
|
|
||||||
Are there any missing commas? Or missing parentheses?
|
Are there any missing commas? Or missing parentheses?
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
@ -5727,22 +5728,24 @@ mod test_reporting {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
main =
|
main =
|
||||||
5 : I64
|
(\x -> x) : I64
|
||||||
|
|
||||||
|
3
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
── UNKNOWN OPERATOR ────────────────────────────────────────────────────────────
|
── UNKNOWN OPERATOR ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
This looks like an operator, but it's not one I recognize!
|
This looks like an operator, but it's not one I recognize!
|
||||||
|
|
||||||
1│ main =
|
1│ main =
|
||||||
2│ 5 : I64
|
2│ (\x -> x) : I64
|
||||||
^
|
^
|
||||||
|
|
||||||
The has-type operator : can only occur in a definition's type
|
The has-type operator : can only occur in a definition's type
|
||||||
signature, like
|
signature, like
|
||||||
|
|
||||||
increment : I64 -> I64
|
increment : I64 -> I64
|
||||||
increment = \x -> x + 1
|
increment = \x -> x + 1
|
||||||
"#
|
"#
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue