Binary wip
This commit is contained in:
@@ -4,7 +4,6 @@ use crate::tokenizer::{
|
|||||||
token::{Keyword, Symbol, Token, TokenType},
|
token::{Keyword, Symbol, Token, TokenType},
|
||||||
Tokenizer, TokenizerBuffer, TokenizerError,
|
Tokenizer, TokenizerBuffer, TokenizerError,
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tree_node::*;
|
use tree_node::*;
|
||||||
|
|
||||||
@@ -20,8 +19,6 @@ pub enum ParseError {
|
|||||||
InvalidSyntax { token: Token, reason: String },
|
InvalidSyntax { token: Token, reason: String },
|
||||||
#[error("Unexpected EOF")]
|
#[error("Unexpected EOF")]
|
||||||
UnexpectedEOF,
|
UnexpectedEOF,
|
||||||
#[error("An unknown error has occurred")]
|
|
||||||
UnknownError,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! self_matches_peek {
|
macro_rules! self_matches_peek {
|
||||||
@@ -143,7 +140,7 @@ impl Parser {
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let to_return = Some(match current_token.token_type {
|
let expr = Some(match current_token.token_type {
|
||||||
// match declarations with a `let` keyword
|
// match declarations with a `let` keyword
|
||||||
TokenType::Keyword(Keyword::Let) => self.declaration()?,
|
TokenType::Keyword(Keyword::Let) => self.declaration()?,
|
||||||
|
|
||||||
@@ -178,7 +175,66 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(to_return)
|
let Some(expr) = expr else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
if self_matches_peek!(self, TokenType::Symbol(s) if s.is_operator()) {
|
||||||
|
return Ok(Some(self.binary(expr)?));
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2: check if the next token is an operator and if we should parse a binary expression with the previous expression
|
||||||
|
|
||||||
|
Ok(Some(expr))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binary(&mut self, previous: Expression) -> Result<tree_node::Expression, ParseError> {
|
||||||
|
let current_token = token_from_option!(self.get_next()?).clone();
|
||||||
|
|
||||||
|
// first, make sure the previous expression supports binary expressions
|
||||||
|
match previous {
|
||||||
|
Expression::BinaryExpression(_) // 1 + 2 + 3
|
||||||
|
| Expression::InvocationExpression(_) // add() + 3
|
||||||
|
| Expression::PriorityExpression(_) // (1 + 2) + 3
|
||||||
|
| Expression::Literal(_) // 1 + 2
|
||||||
|
| Expression::Variable(_) // x + 2
|
||||||
|
| Expression::Negation(_) // -1 + 2
|
||||||
|
=> {}
|
||||||
|
_ => {
|
||||||
|
return Err(ParseError::InvalidSyntax {
|
||||||
|
token: current_token.clone(),
|
||||||
|
reason: "Invalid expression for binary operation".to_owned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check the operator. If we have certain operators, we need to wrap in a priority expression
|
||||||
|
// Example: subtraction and division. Order of operations is important
|
||||||
|
|
||||||
|
let operator = extract_token_data!(
|
||||||
|
current_token,
|
||||||
|
TokenType::Symbol(ref s),
|
||||||
|
s.clone()
|
||||||
|
);
|
||||||
|
|
||||||
|
let expr = match operator {
|
||||||
|
Symbol::Plus => {
|
||||||
|
let right = self.expression()?.ok_or(ParseError::UnexpectedEOF)?;
|
||||||
|
Expression::BinaryExpression(BinaryExpression::Add(Box::new(previous), Box::new(right)))
|
||||||
|
},
|
||||||
|
Symbol::Minus => {
|
||||||
|
let right = self.expression()?.ok_or(ParseError::UnexpectedEOF)?;
|
||||||
|
Expression::PriorityExpression(Box::new(Expression::BinaryExpression(BinaryExpression::Subtract(Box::new(previous), Box::new(right)))))
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return Err(ParseError::InvalidSyntax {
|
||||||
|
token: current_token.clone(),
|
||||||
|
reason: "Invalid operator for binary operation".to_owned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn priority(&mut self) -> Result<Box<Expression>, ParseError> {
|
fn priority(&mut self) -> Result<Box<Expression>, ParseError> {
|
||||||
@@ -504,7 +560,6 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!("(let x = (4))", expression.to_string());
|
assert_eq!("(let x = (4))", expression.to_string());
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
use crate::tokenizer::token::Number;
|
use crate::tokenizer::token::Number;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
|||||||
Reference in New Issue
Block a user