Binary expressions are buggy. Priorities are good, but the l and r are flipped _sometimes_

This commit is contained in:
2024-11-22 02:29:27 -07:00
parent 5ec0a79e6c
commit e9675cd5d2

View File

@@ -4,6 +4,7 @@ use crate::tokenizer::{
token::{Keyword, Symbol, Token, TokenType},
Tokenizer, TokenizerBuffer, TokenizerError,
};
use std::io::SeekFrom;
use thiserror::Error;
use tree_node::*;
@@ -250,7 +251,6 @@ impl Parser {
};
}
// We cannot use recursion here, as we need to handle the precedence of the operators
// We need to use a loop to parse the binary expressions.
@@ -280,11 +280,6 @@ impl Parser {
// build the expressions and operators vectors
while token_matches!(current_token, TokenType::Symbol(s) if s.is_operator()) {
println!(
"Looped: expressions len: {}, operators len: {}",
expressions.len(),
operators.len()
);
// We are guaranteed to have an operator symbol here as we checked in the while loop
let operator = extract_token_data!(current_token, TokenType::Symbol(ref s), s.clone());
operators.push(operator);
@@ -352,7 +347,7 @@ impl Parser {
// Loop through operators, and build the binary expressions for addition and subtraction operators
for (i, operator) in operators.iter().enumerate() {
if operator == &Symbol::Plus || operator == &Symbol::Minus {
let left = expressions.remove(i);
let left = expressions.remove(min!(i, expressions.len() - 1));
let right = expressions.remove(min!(i, expressions.len() - 1));
match operator {
@@ -387,6 +382,11 @@ impl Parser {
});
}
// Edge case. If the current token is a semi-colon, we need to set current token to the previous token
if token_matches!(current_token, TokenType::Symbol(Symbol::Semicolon)) {
self.tokenizer.seek(SeekFrom::Current(-1))?;
}
// Ensure the last expression is a binary expression
match expressions.pop().unwrap() {
Expression::BinaryExpression(binary) => Ok(binary),
@@ -751,6 +751,11 @@ mod tests {
let expr = parser!("1 + 3 ^ 5").parse()?.unwrap();
assert_eq!("(1 + (3 ^ 5))", expr.to_string());
let input = "4 ^ 2 + 3 ^ 2";
let expr = parser!(input).parse()?.unwrap();
println!("Original: {}\nTranscribed: {}", input, expr.to_string());
let expr = parser!("12 - 1 + 3 * 5").parse()?.unwrap();
assert_eq!("((12 - 1) + (3 * 5))", expr.to_string());