fix: fix assignment parser

This commit is contained in:
Araozu 2024-10-19 21:20:25 -05:00
parent aede32a068
commit b4e5caa0f0
4 changed files with 35 additions and 12 deletions

View File

@ -24,7 +24,6 @@ pub const COMPILER_TODO: u32 = 20;
pub const SEMANTIC_MISMATCHED_TYPES: u32 = 21; pub const SEMANTIC_MISMATCHED_TYPES: u32 = 21;
pub const SEMANTIC_DUPLICATED_REFERENCE: u32 = 22; pub const SEMANTIC_DUPLICATED_REFERENCE: u32 = 22;
pub const SEMANTIC_MISMATCHED_ARGUMENT_COUNT: u32 = 23; pub const SEMANTIC_MISMATCHED_ARGUMENT_COUNT: u32 = 23;
pub const SYNTAX_INVALID_ASSIGNMENT: u32 = 24;
/// Reads the error codes from the error code list /// Reads the error codes from the error code list
pub fn error_code_to_string() -> String { pub fn error_code_to_string() -> String {

View File

@ -1,10 +1,10 @@
use crate::{ use crate::{
error_handling::{error_messages::SYNTAX_INVALID_ASSIGNMENT, ErrorContainer, ErrorLabel}, error_handling::{error_messages::SYNTAX_INCOMPLETE_STATEMENT, ErrorContainer, ErrorLabel},
lexic::token::{self, TokenType}, lexic::token::{self, TokenType},
syntax::{ syntax::{
ast::{Assignment, Expression}, ast::{Assignment, Expression},
parseable::{self, Parseable, ParsingError}, 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 // 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), Ok((t, next)) => (t, next),
Err(ParsingError::Mismatch(t)) => { Err(ParsingError::Mismatch(t)) => {
// The parser found a token, but it's not the `=` operator // 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(), end: t.get_end_position(),
}; };
let econtainer = ErrorContainer { let econtainer = ErrorContainer {
error_code: SYNTAX_INVALID_ASSIGNMENT, error_code: SYNTAX_INCOMPLETE_STATEMENT,
error_offset: t.position, error_offset: t.position,
labels: vec![label], labels: vec![label],
note: None, note: None,
@ -50,7 +59,7 @@ impl<'a> Parseable<'a> for Assignment<'a> {
end: identifier.get_end_position(), end: identifier.get_end_position(),
}; };
let econtainer = ErrorContainer { let econtainer = ErrorContainer {
error_code: SYNTAX_INVALID_ASSIGNMENT, error_code: SYNTAX_INCOMPLETE_STATEMENT,
error_offset: identifier.position, error_offset: identifier.position,
labels: vec![label], labels: vec![label],
note: None, note: None,
@ -70,7 +79,7 @@ impl<'a> Parseable<'a> for Assignment<'a> {
end: equal_operator.get_end_position(), end: equal_operator.get_end_position(),
}; };
let econtainer = ErrorContainer { let econtainer = ErrorContainer {
error_code: SYNTAX_INVALID_ASSIGNMENT, error_code: SYNTAX_INCOMPLETE_STATEMENT,
error_offset: equal_operator.position, error_offset: equal_operator.position,
labels: vec![label], labels: vec![label],
note: None, note: None,

View File

@ -60,14 +60,12 @@ impl<'a> Parseable<'a> for Statement<'a> {
} }
// Try to parse an assignment // 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) { match Assignment::try_parse(tokens, current_pos) {
Ok((prod, next)) => return Ok((Statement::Assignment(prod), next)), 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)
} }
} }

View File

@ -69,6 +69,23 @@ pub fn try_operator(tokens: &Vec<Token>, 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<Token>,
pos: usize,
operators: Vec<String>,
) -> 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. /// 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. /// Ignores all whitespace, newlines and comments.