priority expression
This commit is contained in:
@@ -164,12 +164,13 @@ impl Parser {
|
|||||||
TokenType::Symbol(Symbol::LBrace) => Expression::BlockExpression(self.block()?),
|
TokenType::Symbol(Symbol::LBrace) => Expression::BlockExpression(self.block()?),
|
||||||
|
|
||||||
// match literal expressions with a semi-colon afterwards
|
// match literal expressions with a semi-colon afterwards
|
||||||
TokenType::Number(_) | TokenType::String(_)
|
TokenType::Number(_) | TokenType::String(_) if !self_matches_peek!(self, TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical()) => {
|
||||||
if !self_matches_peek!(self, TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical()) =>
|
|
||||||
{
|
|
||||||
Expression::Literal(self.literal()?)
|
Expression::Literal(self.literal()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// match priority expressions with a left parenthesis
|
||||||
|
TokenType::Symbol(Symbol::LParen) => Expression::PriorityExpression(self.priority()?),
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ParseError::UnexpectedToken {
|
return Err(ParseError::UnexpectedToken {
|
||||||
token: current_token.clone(),
|
token: current_token.clone(),
|
||||||
@@ -180,8 +181,25 @@ impl Parser {
|
|||||||
Ok(to_return)
|
Ok(to_return)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binary(&mut self) -> Result<BinaryExpression, ParseError> {
|
fn priority(&mut self) -> Result<Box<Expression>, ParseError> {
|
||||||
todo!()
|
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> {
|
fn invocation(&mut self) -> Result<InvocationExpression, ParseError> {
|
||||||
@@ -470,6 +488,23 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!("add()", expression.to_string());
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ pub enum Expression {
|
|||||||
FunctionExpression(FunctionExpression),
|
FunctionExpression(FunctionExpression),
|
||||||
BlockExpression(BlockExpression),
|
BlockExpression(BlockExpression),
|
||||||
InvocationExpression(InvocationExpression),
|
InvocationExpression(InvocationExpression),
|
||||||
|
PriorityExpression(Box<Expression>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Expression {
|
impl std::fmt::Display for Expression {
|
||||||
@@ -165,6 +166,7 @@ impl std::fmt::Display for Expression {
|
|||||||
Expression::BlockExpression(e) => write!(f, "{}", e),
|
Expression::BlockExpression(e) => write!(f, "{}", e),
|
||||||
Expression::InvocationExpression(e) => write!(f, "{}", e),
|
Expression::InvocationExpression(e) => write!(f, "{}", e),
|
||||||
Expression::Variable(id) => write!(f, "{}", id),
|
Expression::Variable(id) => write!(f, "{}", id),
|
||||||
|
Expression::PriorityExpression(e) => write!(f, "({})", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,13 +148,6 @@ impl Symbol {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_assignment(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Symbol::Assign => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Hash, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Hash, Eq, Clone, Copy)]
|
||||||
|
|||||||
Reference in New Issue
Block a user