diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 1b42ca7..d30a70f 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -916,6 +916,7 @@ impl<'src> Parser<'src> { fn parse(&mut self, precedence: Precedence) -> Result<(), ParseError> { let allow_assignment = precedence < Precedence::Assignment; let allow_return = precedence == Precedence::None; + let mut parsed = false; if let Some(prefix_parser) = ParseRule::from(&self.current_token.kind()).prefix { log::debug!( @@ -924,6 +925,7 @@ impl<'src> Parser<'src> { ); prefix_parser(self, allow_assignment, allow_return)?; + parsed = true; } let mut infix_rule = ParseRule::from(&self.current_token.kind()); @@ -948,9 +950,38 @@ impl<'src> Parser<'src> { } infix_rule = ParseRule::from(&self.current_token.kind()); + parsed = true; } - Ok(()) + if parsed { + Ok(()) + } else { + Err(ParseError::ExpectedTokenMultiple { + expected: &[ + // This should list all infix operators and the semicolon token + TokenKind::BangEqual, + TokenKind::DoubleAmpersand, + TokenKind::DoublePipe, + TokenKind::DoubleEqual, + TokenKind::Greater, + TokenKind::GreaterEqual, + TokenKind::Less, + TokenKind::LessEqual, + TokenKind::Minus, + TokenKind::MinusEqual, + TokenKind::Percent, + TokenKind::Plus, + TokenKind::PlusEqual, + TokenKind::Star, + TokenKind::StarEqual, + TokenKind::Semicolon, + TokenKind::Slash, + TokenKind::SlashEqual, + ], + found: self.current_token.to_owned(), + position: self.current_position, + }) + } } } diff --git a/dust-lang/tests/parse_errors.rs b/dust-lang/tests/parse_errors.rs index 7b6c5ae..2c942e8 100644 --- a/dust-lang/tests/parse_errors.rs +++ b/dust-lang/tests/parse_errors.rs @@ -63,3 +63,20 @@ fn subtract_assign_expects_variable() { }) ); } + +#[test] +fn let_statement_expects_identifier() { + let source = "let 1 = 2"; + + assert_eq!( + parse(source), + Err(DustError::Parse { + error: ParseError::ExpectedToken { + expected: TokenKind::Identifier, + found: Token::Integer("1").to_owned(), + position: Span(4, 5) + }, + source + }) + ); +}