Block expression parsing

This commit is contained in:
bad 2022-05-05 19:29:50 +02:00
parent 2171bebc08
commit 07d4ba5706
5 changed files with 76 additions and 9 deletions

View file

@ -0,0 +1,45 @@
use itertools::PeekingNext;
use std::fmt::Debug;
use super::{ExpressionNode, Parser, Result};
use crate::{ast::statement::Statement, lexer::token};
#[derive(Default)]
pub struct BlockExpr {
pub statements: Vec<Statement>,
}
impl Debug for BlockExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "(")?;
for statement in self.statements.iter() {
writeln!(f, "{:?}", statement)?;
}
writeln!(f, ")")?;
Ok(())
}
}
impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> {
pub(super) fn block_expr(&mut self) -> Result<ExpressionNode> {
if self
.token_iter
.peeking_next(|t| matches!(t.token_type, token::TokenType::LeftBrace))
.is_some()
{
let mut block_expr = BlockExpr::default();
while self
.token_iter
.peeking_next(|t| matches!(t.token_type, token::TokenType::RightBrace))
.is_none()
{
block_expr.statements.push(self.statement()?)
}
Ok(block_expr.into())
} else {
self.equality()
}
}
}

View file

@ -1,20 +1,23 @@
mod binary_expr;
pub mod expression_node; pub mod expression_node;
pub mod operator;
mod binary_expr;
mod block_expr;
mod grouping_expr; mod grouping_expr;
mod literal_expr; mod literal_expr;
pub mod operator;
mod unary_expr; mod unary_expr;
mod variable_expr; mod variable_expr;
pub use binary_expr::BinaryExpr; pub use binary_expr::BinaryExpr;
pub use block_expr::BlockExpr;
pub use grouping_expr::GroupingExpr; pub use grouping_expr::GroupingExpr;
use itertools::PeekingNext;
pub use literal_expr::Literal; pub use literal_expr::Literal;
pub use unary_expr::UnaryExpr; pub use unary_expr::UnaryExpr;
pub use variable_expr::VariableExpr; pub use variable_expr::VariableExpr;
use super::parser::{InnerASTParsingError, Parser, Result}; use super::parser::{InnerASTParsingError, Parser, Result};
use crate::lexer::token::{self, TokenType}; use crate::lexer::token::{self, TokenType};
use itertools::PeekingNext;
use from_variants::FromVariants; use from_variants::FromVariants;
use match_any::match_any; use match_any::match_any;
@ -27,6 +30,7 @@ pub enum ExpressionNode {
Literal(Literal), Literal(Literal),
Variable(VariableExpr), Variable(VariableExpr),
UnaryExpr(UnaryExpr), UnaryExpr(UnaryExpr),
BlockExpr(BlockExpr),
} }
macro_rules! all_variants { macro_rules! all_variants {
@ -39,6 +43,7 @@ macro_rules! all_variants {
ExpressionNode::GroupingExpr($val_name) | ExpressionNode::GroupingExpr($val_name) |
ExpressionNode::Literal($val_name) | ExpressionNode::Literal($val_name) |
ExpressionNode::Variable($val_name) | ExpressionNode::Variable($val_name) |
ExpressionNode::BlockExpr($val_name) |
ExpressionNode::UnaryExpr($val_name) => $expr_arm) ExpressionNode::UnaryExpr($val_name) => $expr_arm)
} }
}; };
@ -53,7 +58,7 @@ impl Debug for ExpressionNode {
impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> { impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> {
pub fn expression(&mut self) -> Result<ExpressionNode> { pub fn expression(&mut self) -> Result<ExpressionNode> {
self.equality() self.block_expr()
} }
pub(super) fn primary(&mut self) -> Result<ExpressionNode> { pub(super) fn primary(&mut self) -> Result<ExpressionNode> {
let token = self.token_iter.next(); let token = self.token_iter.next();

View file

@ -33,8 +33,9 @@ impl Display for UnaryOperator {
} }
pub enum Operator { pub enum Operator {
Minus,
Plus,
BangEqual, BangEqual,
Equal,
EqualEqual, EqualEqual,
Greater, Greater,
GreaterEqual, GreaterEqual,
@ -57,8 +58,9 @@ impl TryFrom<token::TokenType> for Operator {
fn try_from(value: token::TokenType) -> Result<Self, Self::Error> { fn try_from(value: token::TokenType) -> Result<Self, Self::Error> {
Ok(match value { Ok(match value {
token::TokenType::Plus => Self::Plus,
token::TokenType::Minus => Self::Minus,
token::TokenType::BangEqual => Self::BangEqual, token::TokenType::BangEqual => Self::BangEqual,
token::TokenType::Equal => Self::Equal,
token::TokenType::EqualEqual => Self::EqualEqual, token::TokenType::EqualEqual => Self::EqualEqual,
token::TokenType::Greater => Self::Greater, token::TokenType::Greater => Self::Greater,
token::TokenType::GreaterEqual => Self::GreaterEqual, token::TokenType::GreaterEqual => Self::GreaterEqual,
@ -76,8 +78,9 @@ impl Display for Operator {
f, f,
"{}", "{}",
match *self { match *self {
Operator::Plus => "+",
Operator::Minus => "-",
Operator::Less => "<", Operator::Less => "<",
Operator::Equal => "=",
Operator::Greater => ">", Operator::Greater => ">",
Operator::BangEqual => "!=", Operator::BangEqual => "!=",
Operator::LessEqual => "<=", Operator::LessEqual => "<=",

View file

@ -23,13 +23,14 @@ impl Interpret for expression::BinaryExpr {
let left_val = self.left.interpret(w).expect("expected lval"); let left_val = self.left.interpret(w).expect("expected lval");
let right_val = self.right.interpret(w).expect("expected rval"); let right_val = self.right.interpret(w).expect("expected rval");
match self.operator { match self.operator {
Operator::Plus => todo!(),
Operator::Minus => todo!(),
Operator::BangEqual => Ok((left_val != right_val).into()), Operator::BangEqual => Ok((left_val != right_val).into()),
Operator::Less => Ok((left_val < right_val).into()), Operator::Less => Ok((left_val < right_val).into()),
Operator::LessEqual => Ok((left_val <= right_val).into()), Operator::LessEqual => Ok((left_val <= right_val).into()),
Operator::Greater => Ok((left_val > right_val).into()), Operator::Greater => Ok((left_val > right_val).into()),
Operator::GreaterEqual => Ok((left_val >= right_val).into()), Operator::GreaterEqual => Ok((left_val >= right_val).into()),
Operator::EqualEqual => Ok((left_val == right_val).into()), Operator::EqualEqual => Ok((left_val == right_val).into()),
Operator::Equal => todo!(),
} }
} }
} }
@ -62,3 +63,12 @@ impl Interpret for expression::VariableExpr {
} }
} }
} }
impl Interpret for expression::BlockExpr {
fn interpret(&self, world: &mut World) -> Result<Value, RuntimeError> {
for stmnt in self.statements.iter() {
stmnt.interpret(world)?;
}
Ok(Value::Nil)
}
}

View file

@ -1,2 +1,6 @@
asdf = 1; asdf = 1;
print asdf; asdf2 = 1;
{
print "asdf "+asdf;
print "asdf2"+asdf2;
};