crftng-intrprtrs/src/ast/expression/expression_parser.rs

124 lines
3.1 KiB
Rust

use itertools::PeekingNext;
use crate::lexer::token::{self, TokenType};
use super::super::parser::{InnerASTParsingError, Parser, Result};
use super::expression_node::*;
impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> {
pub fn expression(&mut self) -> Result<ExpressionNode> {
self.equality()
}
fn equality(&mut self) -> Result<ExpressionNode> {
let mut node = self.comparison()?;
while let Some(o) = self
.token_iter
.peeking_next(|t| matches!(t.token_type, TokenType::EqualEqual | TokenType::BangEqual))
{
node = BinaryExpr::new(
Box::new(node),
o.token_type.try_into().unwrap(),
Box::new(self.comparison()?),
)
.into();
}
Ok(node)
}
fn comparison(&mut self) -> Result<ExpressionNode> {
let mut node = self.term()?;
while let Some(o) = self.token_iter.peeking_next(|t| {
matches!(
t.token_type,
TokenType::Greater
| TokenType::GreaterEqual
| TokenType::Less | TokenType::LessEqual
)
}) {
node = BinaryExpr::new(
Box::new(node),
o.token_type.try_into().unwrap(),
Box::new(self.comparison()?),
)
.into();
}
Ok(node)
}
fn term(&mut self) -> Result<ExpressionNode> {
let mut node = self.factor()?;
while let Some(o) = self
.token_iter
.peeking_next(|t| matches!(t.token_type, TokenType::Minus | TokenType::Plus))
{
node = BinaryExpr::new(
Box::new(node),
o.token_type.try_into().unwrap(),
Box::new(self.comparison()?),
)
.into()
}
Ok(node)
}
fn factor(&mut self) -> Result<ExpressionNode> {
let mut node = self.unary()?;
while let Some(o) = self
.token_iter
.peeking_next(|t| matches!(t.token_type, TokenType::Star | TokenType::Slash))
{
node = BinaryExpr::new(
Box::new(node),
o.token_type.try_into().unwrap(),
Box::new(self.comparison()?),
)
.into();
}
Ok(node)
}
fn unary(&mut self) -> Result<ExpressionNode> {
if let Some(op) = self
.token_iter
.peeking_next(|t| matches!(t.token_type, TokenType::Bang | TokenType::Minus))
{
let right = Box::new(self.unary()?);
Ok(ExpressionNode::UnaryExpr(UnaryExpr::new(
op.token_type.try_into().unwrap(),
right,
)))
} else {
self.primary()
}
}
fn primary(&mut self) -> Result<ExpressionNode> {
let token = self.token_iter.next();
let node = match token.token_type {
TokenType::False => ExpressionNode::Literal(Literal::Bool(false)),
TokenType::True => ExpressionNode::Literal(Literal::Bool(true)),
TokenType::Int(i) => ExpressionNode::Literal(Literal::Int(i)),
TokenType::String(i) => ExpressionNode::Literal(Literal::String(i)),
TokenType::Float(f) => ExpressionNode::Literal(Literal::Float(f)),
TokenType::Nil => ExpressionNode::Literal(Literal::Nil),
TokenType::LeftParen => {
let expr = self.expression()?;
let group = GroupingExpr::new(Box::new(expr));
match self
.token_iter
.peeking_next(|v| matches!(v.token_type, TokenType::RightParen))
{
Some(_) => return Ok(group.into()),
None => return Err(token.location.wrap(InnerASTParsingError::UnmatchedBrace)),
}
}
a => return Err(token.location.wrap(InnerASTParsingError::IncorrectToken(a))),
};
Ok(node)
}
}