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 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();
|
||||||
|
|
|
@ -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 => "<=",
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
6
test.lox
6
test.lox
|
@ -1,2 +1,6 @@
|
||||||
asdf = 1;
|
asdf = 1;
|
||||||
print asdf;
|
asdf2 = 1;
|
||||||
|
{
|
||||||
|
print "asdf "+asdf;
|
||||||
|
print "asdf2"+asdf2;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue