Block expression parsing
This commit is contained in:
parent
2171bebc08
commit
07d4ba5706
5 changed files with 76 additions and 9 deletions
45
src/ast/expression/block_expr.rs
Normal file
45
src/ast/expression/block_expr.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Item = token::Token<'a>>> Parser<'a, T> {
|
||||
pub fn expression(&mut self) -> Result<ExpressionNode> {
|
||||
self.equality()
|
||||
self.block_expr()
|
||||
}
|
||||
pub(super) fn primary(&mut self) -> Result<ExpressionNode> {
|
||||
let token = self.token_iter.next();
|
||||
|
|
|
@ -33,8 +33,9 @@ impl Display for UnaryOperator {
|
|||
}
|
||||
|
||||
pub enum Operator {
|
||||
Minus,
|
||||
Plus,
|
||||
BangEqual,
|
||||
Equal,
|
||||
EqualEqual,
|
||||
Greater,
|
||||
GreaterEqual,
|
||||
|
@ -57,8 +58,9 @@ impl TryFrom<token::TokenType> for Operator {
|
|||
|
||||
fn try_from(value: token::TokenType) -> Result<Self, Self::Error> {
|
||||
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 => "<=",
|
||||
|
|
|
@ -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<Value, RuntimeError> {
|
||||
for stmnt in self.statements.iter() {
|
||||
stmnt.interpret(world)?;
|
||||
}
|
||||
Ok(Value::Nil)
|
||||
}
|
||||
}
|
||||
|
|
6
test.lox
6
test.lox
|
@ -1,2 +1,6 @@
|
|||
asdf = 1;
|
||||
print asdf;
|
||||
asdf2 = 1;
|
||||
{
|
||||
print "asdf "+asdf;
|
||||
print "asdf2"+asdf2;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue