diff --git a/src/ast/expression/block_expr.rs b/src/ast/expression/block_expr.rs new file mode 100644 index 0000000..5e00bf3 --- /dev/null +++ b/src/ast/expression/block_expr.rs @@ -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, +} + +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>> Parser<'a, T> { + pub(super) fn block_expr(&mut self) -> Result { + 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() + } + } +} diff --git a/src/ast/expression/mod.rs b/src/ast/expression/mod.rs index 5601795..eddec05 100644 --- a/src/ast/expression/mod.rs +++ b/src/ast/expression/mod.rs @@ -1,20 +1,23 @@ -mod binary_expr; pub mod expression_node; +pub mod operator; + +mod binary_expr; +mod block_expr; mod grouping_expr; mod literal_expr; -pub mod operator; mod unary_expr; mod variable_expr; pub use binary_expr::BinaryExpr; +pub use block_expr::BlockExpr; pub use grouping_expr::GroupingExpr; -use itertools::PeekingNext; pub use literal_expr::Literal; pub use unary_expr::UnaryExpr; pub use variable_expr::VariableExpr; use super::parser::{InnerASTParsingError, Parser, Result}; use crate::lexer::token::{self, TokenType}; +use itertools::PeekingNext; use from_variants::FromVariants; use match_any::match_any; @@ -27,6 +30,7 @@ pub enum ExpressionNode { Literal(Literal), Variable(VariableExpr), UnaryExpr(UnaryExpr), + BlockExpr(BlockExpr), } macro_rules! all_variants { @@ -39,6 +43,7 @@ macro_rules! all_variants { ExpressionNode::GroupingExpr($val_name) | ExpressionNode::Literal($val_name) | ExpressionNode::Variable($val_name) | + ExpressionNode::BlockExpr($val_name) | ExpressionNode::UnaryExpr($val_name) => $expr_arm) } }; @@ -53,7 +58,7 @@ impl Debug for ExpressionNode { impl<'a, T: Iterator>> Parser<'a, T> { pub fn expression(&mut self) -> Result { - self.equality() + self.block_expr() } pub(super) fn primary(&mut self) -> Result { let token = self.token_iter.next(); diff --git a/src/ast/expression/operator.rs b/src/ast/expression/operator.rs index 69dbb74..aa17f0b 100644 --- a/src/ast/expression/operator.rs +++ b/src/ast/expression/operator.rs @@ -33,8 +33,9 @@ impl Display for UnaryOperator { } pub enum Operator { + Minus, + Plus, BangEqual, - Equal, EqualEqual, Greater, GreaterEqual, @@ -57,8 +58,9 @@ impl TryFrom for Operator { fn try_from(value: token::TokenType) -> Result { Ok(match value { + token::TokenType::Plus => Self::Plus, + token::TokenType::Minus => Self::Minus, token::TokenType::BangEqual => Self::BangEqual, - token::TokenType::Equal => Self::Equal, token::TokenType::EqualEqual => Self::EqualEqual, token::TokenType::Greater => Self::Greater, token::TokenType::GreaterEqual => Self::GreaterEqual, @@ -76,8 +78,9 @@ impl Display for Operator { f, "{}", match *self { + Operator::Plus => "+", + Operator::Minus => "-", Operator::Less => "<", - Operator::Equal => "=", Operator::Greater => ">", Operator::BangEqual => "!=", Operator::LessEqual => "<=", diff --git a/src/interpreter/ast_walker/expression_interpreter.rs b/src/interpreter/ast_walker/expression_interpreter.rs index e93c394..bc7def2 100644 --- a/src/interpreter/ast_walker/expression_interpreter.rs +++ b/src/interpreter/ast_walker/expression_interpreter.rs @@ -23,13 +23,14 @@ impl Interpret for expression::BinaryExpr { let left_val = self.left.interpret(w).expect("expected lval"); let right_val = self.right.interpret(w).expect("expected rval"); match self.operator { + Operator::Plus => todo!(), + Operator::Minus => todo!(), Operator::BangEqual => Ok((left_val != right_val).into()), Operator::Less => Ok((left_val < right_val).into()), Operator::LessEqual => Ok((left_val <= right_val).into()), Operator::Greater => Ok((left_val > right_val).into()), Operator::GreaterEqual => 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 { + for stmnt in self.statements.iter() { + stmnt.interpret(world)?; + } + Ok(Value::Nil) + } +} diff --git a/test.lox b/test.lox index 0093aa0..38037d7 100644 --- a/test.lox +++ b/test.lox @@ -1,2 +1,6 @@ asdf = 1; -print asdf; +asdf2 = 1; +{ + print "asdf "+asdf; + print "asdf2"+asdf2; +};