priority expression

This commit is contained in:
2024-11-21 22:23:31 -07:00
parent c9fc59a034
commit febb4e9d55
3 changed files with 42 additions and 12 deletions

View File

@@ -164,12 +164,13 @@ impl Parser {
TokenType::Symbol(Symbol::LBrace) => Expression::BlockExpression(self.block()?),
// match literal expressions with a semi-colon afterwards
TokenType::Number(_) | TokenType::String(_)
if !self_matches_peek!(self, TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical()) =>
{
TokenType::Number(_) | TokenType::String(_) if !self_matches_peek!(self, TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical()) => {
Expression::Literal(self.literal()?)
}
// match priority expressions with a left parenthesis
TokenType::Symbol(Symbol::LParen) => Expression::PriorityExpression(self.priority()?),
_ => {
return Err(ParseError::UnexpectedToken {
token: current_token.clone(),
@@ -180,8 +181,25 @@ impl Parser {
Ok(to_return)
}
fn binary(&mut self) -> Result<BinaryExpression, ParseError> {
todo!()
fn priority(&mut self) -> Result<Box<Expression>, ParseError> {
let current_token = token_from_option!(self.current_token);
if !token_matches!(current_token, TokenType::Symbol(Symbol::LParen)) {
return Err(ParseError::UnexpectedToken {
token: current_token.clone(),
});
}
let expression = self.parse()?.ok_or(ParseError::UnexpectedEOF)?;
// make sure the next token is a right parenthesis
let current_token = token_from_option!(self.get_next()?);
if !token_matches!(current_token, TokenType::Symbol(Symbol::RParen)) {
return Err(ParseError::UnexpectedToken {
token: current_token.clone(),
});
}
Ok(Box::new(expression))
}
fn invocation(&mut self) -> Result<InvocationExpression, ParseError> {
@@ -470,6 +488,23 @@ mod tests {
assert_eq!("add()", expression.to_string());
Ok(())
}
#[test]
fn test_priority_expression() -> Result<()> {
let input = r#"
let x = (4);
"#;
let tokenizer = Tokenizer::from(input.to_owned());
let mut parser = Parser::new(tokenizer);
let expression = parser.parse()?.unwrap();
assert_eq!("(let x = (4))", expression.to_string());
Ok(())
}
}

View File

@@ -150,6 +150,7 @@ pub enum Expression {
FunctionExpression(FunctionExpression),
BlockExpression(BlockExpression),
InvocationExpression(InvocationExpression),
PriorityExpression(Box<Expression>),
}
impl std::fmt::Display for Expression {
@@ -165,6 +166,7 @@ impl std::fmt::Display for Expression {
Expression::BlockExpression(e) => write!(f, "{}", e),
Expression::InvocationExpression(e) => write!(f, "{}", e),
Expression::Variable(id) => write!(f, "{}", id),
Expression::PriorityExpression(e) => write!(f, "({})", e),
}
}
}

View File

@@ -148,13 +148,6 @@ impl Symbol {
_ => false,
}
}
pub fn is_assignment(&self) -> bool {
match self {
Symbol::Assign => true,
_ => false,
}
}
}
#[derive(Debug, PartialEq, Hash, Eq, Clone, Copy)]