Fix todo/error parser on when clauses.
This commit is contained in:
@@ -11,7 +11,7 @@ authors = ["Lucas Rosa <x@rvcas.dev>", "Kasey White <kwhitemsg@gmail.com>"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
chumsky = "0.8.0"
|
||||
chumsky = "0.9.0"
|
||||
hex = "0.4.3"
|
||||
indexmap = "1.9.1"
|
||||
indoc = "1.0.7"
|
||||
|
||||
@@ -446,6 +446,18 @@ impl UntypedExpr {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn error(location: Span, reason: Option<Self>) -> Self {
|
||||
UntypedExpr::Trace {
|
||||
location,
|
||||
kind: TraceKind::Error,
|
||||
then: Box::new(UntypedExpr::ErrorTerm { location }),
|
||||
text: Box::new(reason.unwrap_or_else(|| UntypedExpr::String {
|
||||
location,
|
||||
value: DEFAULT_ERROR_STR.to_string(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append_in_sequence(self, next: Self) -> Self {
|
||||
let location = Span {
|
||||
start: self.location().start,
|
||||
|
||||
@@ -591,8 +591,12 @@ pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseE
|
||||
then: Box::new(then_),
|
||||
text: Box::new(text),
|
||||
}),
|
||||
todo_parser(r.clone(), Token::ErrorTerm),
|
||||
todo_parser(r.clone(), Token::Todo),
|
||||
just(Token::ErrorTerm)
|
||||
.ignore_then(expr_parser(r.clone()).or_not())
|
||||
.map_with_span(|reason, span| expr::UntypedExpr::error(span, reason)),
|
||||
just(Token::Todo)
|
||||
.ignore_then(expr_parser(r.clone()).or_not())
|
||||
.map_with_span(|reason, span| expr::UntypedExpr::todo(span, reason)),
|
||||
expr_parser(r.clone())
|
||||
.then(r.repeated())
|
||||
.foldl(|current, next| current.append_in_sequence(next)),
|
||||
@@ -600,31 +604,6 @@ pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseE
|
||||
})
|
||||
}
|
||||
|
||||
pub fn todo_parser(
|
||||
r: Recursive<'_, Token, expr::UntypedExpr, ParseError>,
|
||||
keyword: Token,
|
||||
) -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> + '_ {
|
||||
just(keyword.clone())
|
||||
.ignore_then(expr_parser(r.clone()).or_not())
|
||||
.map_with_span(move |text, span| {
|
||||
let (kind, value) = match keyword {
|
||||
Token::ErrorTerm => (TraceKind::Error, expr::DEFAULT_ERROR_STR.to_string()),
|
||||
Token::Todo => (TraceKind::Todo, expr::DEFAULT_TODO_STR.to_string()),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
expr::UntypedExpr::Trace {
|
||||
kind,
|
||||
location: span,
|
||||
then: Box::new(expr::UntypedExpr::ErrorTerm { location: span }),
|
||||
text: Box::new(text.unwrap_or(expr::UntypedExpr::String {
|
||||
location: span,
|
||||
value,
|
||||
})),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expr_parser(
|
||||
seq_r: Recursive<'_, Token, expr::UntypedExpr, ParseError>,
|
||||
) -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> + '_ {
|
||||
@@ -934,8 +913,6 @@ pub fn expr_parser(
|
||||
choice((just(Token::LeftParen), just(Token::NewLineLeftParen))),
|
||||
just(Token::RightParen),
|
||||
),
|
||||
just(Token::ErrorTerm).rewind().ignore_then(seq_r.clone()),
|
||||
just(Token::Todo).rewind().ignore_then(seq_r.clone()),
|
||||
));
|
||||
|
||||
let anon_fn_parser = just(Token::Fn)
|
||||
@@ -983,7 +960,23 @@ pub fn expr_parser(
|
||||
}),
|
||||
)))
|
||||
// TODO: add hint "Did you mean to wrap a multi line clause in curly braces?"
|
||||
.then(r.clone())
|
||||
.then(choice((
|
||||
r.clone(),
|
||||
just(Token::Todo)
|
||||
.ignore_then(
|
||||
r.clone()
|
||||
.then_ignore(one_of(Token::RArrow).not().rewind())
|
||||
.or_not(),
|
||||
)
|
||||
.map_with_span(|reason, span| expr::UntypedExpr::todo(span, reason)),
|
||||
just(Token::ErrorTerm)
|
||||
.ignore_then(
|
||||
r.clone()
|
||||
.then_ignore(just(Token::RArrow).not().rewind())
|
||||
.or_not(),
|
||||
)
|
||||
.map_with_span(|reason, span| expr::UntypedExpr::error(span, reason)),
|
||||
)))
|
||||
.map_with_span(
|
||||
|(((patterns, alternative_patterns_opt), guard), then), span| ast::UntypedClause {
|
||||
location: span,
|
||||
|
||||
@@ -2830,8 +2830,9 @@ fn parse_keyword_todo() {
|
||||
|
||||
fn bar() {
|
||||
when x is {
|
||||
Something -> Void
|
||||
_ -> todo
|
||||
Foo -> todo
|
||||
Bar -> True
|
||||
_ -> False
|
||||
}
|
||||
}
|
||||
"#};
|
||||
@@ -2862,18 +2863,44 @@ fn parse_keyword_todo() {
|
||||
ast::Definition::Fn(Function {
|
||||
arguments: vec![],
|
||||
body: expr::UntypedExpr::When {
|
||||
location: Span::new((), 52..107),
|
||||
location: Span::new((), 52..120),
|
||||
subjects: vec![expr::UntypedExpr::Var {
|
||||
location: Span::new((), 57..58),
|
||||
name: "x".to_string(),
|
||||
}],
|
||||
clauses: vec![
|
||||
ast::Clause {
|
||||
location: Span::new((), 70..87),
|
||||
location: Span::new((), 70..81),
|
||||
pattern: vec![ast::Pattern::Constructor {
|
||||
is_record: false,
|
||||
location: Span::new((), 70..79),
|
||||
name: "Something".to_string(),
|
||||
location: Span::new((), 70..73),
|
||||
name: "Foo".to_string(),
|
||||
arguments: vec![],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
}],
|
||||
alternative_patterns: vec![],
|
||||
guard: None,
|
||||
then: expr::UntypedExpr::Trace {
|
||||
kind: ast::TraceKind::Todo,
|
||||
location: Span::new((), 77..81),
|
||||
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
||||
location: Span::new((), 77..81),
|
||||
}),
|
||||
text: Box::new(expr::UntypedExpr::String {
|
||||
location: Span::new((), 77..81),
|
||||
value: "aiken::todo".to_string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
ast::Clause {
|
||||
location: Span::new((), 88..99),
|
||||
pattern: vec![ast::Pattern::Constructor {
|
||||
is_record: false,
|
||||
location: Span::new((), 88..91),
|
||||
name: "Bar".to_string(),
|
||||
arguments: vec![],
|
||||
module: None,
|
||||
constructor: (),
|
||||
@@ -2883,28 +2910,21 @@ fn parse_keyword_todo() {
|
||||
alternative_patterns: vec![],
|
||||
guard: None,
|
||||
then: expr::UntypedExpr::Var {
|
||||
location: Span::new((), 83..87),
|
||||
name: "Void".to_string(),
|
||||
location: Span::new((), 95..99),
|
||||
name: "True".to_string(),
|
||||
},
|
||||
},
|
||||
ast::Clause {
|
||||
location: Span::new((), 94..103),
|
||||
location: Span::new((), 106..116),
|
||||
pattern: vec![ast::Pattern::Discard {
|
||||
name: "_".to_string(),
|
||||
location: Span::new((), 94..95),
|
||||
location: Span::new((), 106..107),
|
||||
}],
|
||||
alternative_patterns: vec![],
|
||||
guard: None,
|
||||
then: expr::UntypedExpr::Trace {
|
||||
kind: ast::TraceKind::Todo,
|
||||
location: Span::new((), 99..103),
|
||||
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
||||
location: Span::new((), 99..103),
|
||||
}),
|
||||
text: Box::new(expr::UntypedExpr::String {
|
||||
location: Span::new((), 99..103),
|
||||
value: "aiken::todo".to_string(),
|
||||
}),
|
||||
then: expr::UntypedExpr::Var {
|
||||
location: Span::new((), 111..116),
|
||||
name: "False".to_string(),
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -2915,7 +2935,7 @@ fn parse_keyword_todo() {
|
||||
public: false,
|
||||
return_annotation: None,
|
||||
return_type: (),
|
||||
end_position: 108,
|
||||
end_position: 121,
|
||||
}),
|
||||
],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user