diff --git a/src/term/parser/lexer.rs b/src/term/parser/lexer.rs index 625f98a1..7594b9ce 100644 --- a/src/term/parser/lexer.rs +++ b/src/term/parser/lexer.rs @@ -127,9 +127,6 @@ pub enum Token { #[token("/*", comment)] MultiLineComment, - #[token("data")] - Data, - Error(LexingError), } @@ -256,7 +253,6 @@ impl fmt::Display for Token { Self::Dollar => write!(f, "$"), Self::Let => write!(f, "let"), Self::Match => write!(f, "match"), - Self::Data => write!(f, "data"), Self::Equals => write!(f, "="), Self::Num(num) => write!(f, "{num}"), Self::Str(s) => write!(f, "\"{s}\""), diff --git a/src/term/parser/parser.rs b/src/term/parser/parser.rs index db9973a1..46cafd98 100644 --- a/src/term/parser/parser.rs +++ b/src/term/parser/parser.rs @@ -111,6 +111,13 @@ fn token_stream( // Parsers +fn soft_keyword<'a, I>(keyword: &'static str) -> impl Parser<'a, I, (), extra::Err>> +where + I: ValueInput<'a, Token = Token, Span = SimpleSpan>, +{ + any().filter(move |t| matches!(t, Token::Name(n) if n.as_str() == keyword)).to(()).labelled(keyword) +} + fn name<'a, I>() -> impl Parser<'a, I, Name, extra::Err>> where I: ValueInput<'a, Token = Token, Span = SimpleSpan>, @@ -124,7 +131,6 @@ where let Token::Name(name) = t else { unreachable!() }; Name::from(name) }) - .or(just(Token::Data).to(Name("data".into()))) .labelled("") } @@ -134,7 +140,7 @@ where I: ValueInput<'a, Token = Token, Span = SimpleSpan>, { any() - .filter(|t| matches!(t, Token::Name(_))) + .filter(|t| matches!(t, Token::Name(n) if n.as_str() != "data")) .map(|t| { let Token::Name(name) = t else { unreachable!() }; name @@ -408,9 +414,10 @@ where ) })); - let paren_lhs = lhs - .clone() - .delimited_by(just(Token::LParen), just(Token::RParen)) + let paren_lhs = + just(Token::LParen) + .ignore_then(lhs.clone().map_err(|err| map_unexpected_eof::(err, Token::Name("".into())))) + .then_ignore(just(Token::RParen)) .then_ignore(just(Token::Equals).map_err(|err| map_unexpected_eof::(err, Token::Equals))); choice((just_lhs, paren_lhs)) @@ -421,7 +428,7 @@ where I: ValueInput<'a, Token = Token, Span = SimpleSpan>, { let unclosed_terms = term() - .and_is(just(Token::Data).not().rewind()) + .and_is(soft_keyword("data").not().rewind()) .and_is(rule_pattern().not().rewind()) .repeated() .at_least(1) @@ -457,7 +464,7 @@ where let ctrs = arity_0.or(arity_n).separated_by(just(Token::Or)).at_least(1).collect(); let data_name = tl_name().map_with_span(|name, span| (name, span)); - just(Token::Data) + soft_keyword("data") .ignore_then(data_name.map_err(|err| map_unexpected_eof::(err, Token::Name("".to_string())))) .then_ignore(just(Token::Equals)) .then(ctrs.map_err(|err| map_unexpected_eof::(err, Token::Name("constructor".to_string())))) diff --git a/tests/snapshots/compile_file__just_paren.hvm.snap b/tests/snapshots/compile_file__just_paren.hvm.snap index bb3e80dd..ded9c634 100644 --- a/tests/snapshots/compile_file__just_paren.hvm.snap +++ b/tests/snapshots/compile_file__just_paren.hvm.snap @@ -2,5 +2,5 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file/just_paren.hvm --- -At tests/golden_tests/compile_file/just_paren.hvm:1:1: found '(' expected 'data', or +At tests/golden_tests/compile_file/just_paren.hvm:1:1: found end of input expected  1 | ( diff --git a/tests/snapshots/compile_file__unexpected_top_char.hvm.snap b/tests/snapshots/compile_file__unexpected_top_char.hvm.snap index da6d0560..0e25b6d0 100644 --- a/tests/snapshots/compile_file__unexpected_top_char.hvm.snap +++ b/tests/snapshots/compile_file__unexpected_top_char.hvm.snap @@ -2,5 +2,5 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file/unexpected_top_char.hvm --- -At tests/golden_tests/compile_file/unexpected_top_char.hvm:1:1: found '*' expected 'data', , or '(' +At tests/golden_tests/compile_file/unexpected_top_char.hvm:1:1: found end of input expected data, , or '('  1 | *