diff --git a/src/error_handling/error_messages.rs b/src/error_handling/error_messages.rs index 5440793..ea01446 100644 --- a/src/error_handling/error_messages.rs +++ b/src/error_handling/error_messages.rs @@ -24,7 +24,6 @@ pub const COMPILER_TODO: u32 = 20; pub const SEMANTIC_MISMATCHED_TYPES: u32 = 21; pub const SEMANTIC_DUPLICATED_REFERENCE: u32 = 22; pub const SEMANTIC_MISMATCHED_ARGUMENT_COUNT: u32 = 23; -pub const SYNTAX_INVALID_ASSIGNMENT: u32 = 24; /// Reads the error codes from the error code list pub fn error_code_to_string() -> String { diff --git a/src/syntax/parsers/assignment.rs b/src/syntax/parsers/assignment.rs index 2e76f93..78e5153 100644 --- a/src/syntax/parsers/assignment.rs +++ b/src/syntax/parsers/assignment.rs @@ -1,10 +1,10 @@ use crate::{ - error_handling::{error_messages::SYNTAX_INVALID_ASSIGNMENT, ErrorContainer, ErrorLabel}, + error_handling::{error_messages::SYNTAX_INCOMPLETE_STATEMENT, ErrorContainer, ErrorLabel}, lexic::token::{self, TokenType}, syntax::{ ast::{Assignment, Expression}, parseable::{self, Parseable, ParsingError}, - utils::{parse_token_type, try_operator}, + utils::{parse_token_type, try_many_operator}, }, }; @@ -24,7 +24,16 @@ impl<'a> Parseable<'a> for Assignment<'a> { }; // parse the equal sign - let (equal_operator, next) = match try_operator(tokens, next, String::from("=")) { + let assignment_operators = vec![ + String::from("="), + String::from("+="), + String::from("-="), + String::from("*="), + String::from("/="), + String::from("%="), + ]; + + let (equal_operator, next) = match try_many_operator(tokens, next, assignment_operators) { Ok((t, next)) => (t, next), Err(ParsingError::Mismatch(t)) => { // The parser found a token, but it's not the `=` operator @@ -34,7 +43,7 @@ impl<'a> Parseable<'a> for Assignment<'a> { end: t.get_end_position(), }; let econtainer = ErrorContainer { - error_code: SYNTAX_INVALID_ASSIGNMENT, + error_code: SYNTAX_INCOMPLETE_STATEMENT, error_offset: t.position, labels: vec![label], note: None, @@ -50,7 +59,7 @@ impl<'a> Parseable<'a> for Assignment<'a> { end: identifier.get_end_position(), }; let econtainer = ErrorContainer { - error_code: SYNTAX_INVALID_ASSIGNMENT, + error_code: SYNTAX_INCOMPLETE_STATEMENT, error_offset: identifier.position, labels: vec![label], note: None, @@ -70,7 +79,7 @@ impl<'a> Parseable<'a> for Assignment<'a> { end: equal_operator.get_end_position(), }; let econtainer = ErrorContainer { - error_code: SYNTAX_INVALID_ASSIGNMENT, + error_code: SYNTAX_INCOMPLETE_STATEMENT, error_offset: equal_operator.position, labels: vec![label], note: None, diff --git a/src/syntax/parsers/statement.rs b/src/syntax/parsers/statement.rs index f9f0ac7..66f2f1a 100644 --- a/src/syntax/parsers/statement.rs +++ b/src/syntax/parsers/statement.rs @@ -60,14 +60,12 @@ impl<'a> Parseable<'a> for Statement<'a> { } // Try to parse an assignment + // If this fails, return unmatched because there is still the + // possibility that an expression will be parsed later match Assignment::try_parse(tokens, current_pos) { Ok((prod, next)) => return Ok((Statement::Assignment(prod), next)), - Err(ParsingError::Err(e)) => return Err(ParsingError::Err(e)), - _ => {} + _ => Err(ParsingError::Unmatched), } - - // Here nothing was parsed. - Err(ParsingError::Unmatched) } } diff --git a/src/syntax/utils.rs b/src/syntax/utils.rs index 9681b4b..6b553fc 100644 --- a/src/syntax/utils.rs +++ b/src/syntax/utils.rs @@ -69,6 +69,23 @@ pub fn try_operator(tokens: &Vec, pos: usize, operator: String) -> Parsin } } +/// Expects the token at `pos` to be any of the passed operators. Doesn't ignore whitespace or newlines +pub fn try_many_operator( + tokens: &Vec, + pos: usize, + operators: Vec, +) -> ParsingResult<&Token> { + // + for op in operators { + match try_operator(tokens, pos, op) { + Ok(v) => return Ok(v), + _ => {} + } + } + + return Err(ParsingError::Unmatched); +} + /// Expects the token at `pos` to be of type `token_type`, and returns the token and the next position. /// /// Ignores all whitespace, newlines and comments.