From 9cda9643a99ef737e83a5cb554d85f33fce92d84 Mon Sep 17 00:00:00 2001 From: bad Date: Sat, 23 Apr 2022 19:43:42 +0200 Subject: [PATCH] Add expressions --- src/ast/expression/expression_node.rs | 1 + src/ast/expression/expression_parser.rs | 1 + src/ast/statement/statement_node.rs | 15 +++++++++-- src/interpreter/ast_walker/mod.rs | 1 + .../ast_walker/statement_interpreter.rs | 26 +++++++++++++++++++ src/interpreter/environment.rs | 3 +++ src/interpreter/mod.rs | 1 + src/interpreter/types.rs | 7 ++--- src/lib.rs | 7 +++-- test.lox | 4 +++ 10 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 src/interpreter/ast_walker/statement_interpreter.rs create mode 100644 src/interpreter/environment.rs diff --git a/src/ast/expression/expression_node.rs b/src/ast/expression/expression_node.rs index d33596b..99aedae 100644 --- a/src/ast/expression/expression_node.rs +++ b/src/ast/expression/expression_node.rs @@ -120,6 +120,7 @@ pub enum Literal { Int(i32), Float(f32), Bool(bool), + Nil } pub struct BinaryExpr { diff --git a/src/ast/expression/expression_parser.rs b/src/ast/expression/expression_parser.rs index c102fea..754af3a 100644 --- a/src/ast/expression/expression_parser.rs +++ b/src/ast/expression/expression_parser.rs @@ -102,6 +102,7 @@ impl<'a, T: Iterator>> Parser<'a, T> { 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)); diff --git a/src/ast/statement/statement_node.rs b/src/ast/statement/statement_node.rs index 41b9450..2ae168f 100644 --- a/src/ast/statement/statement_node.rs +++ b/src/ast/statement/statement_node.rs @@ -7,8 +7,19 @@ pub enum Statement { Print(PrintStatement), } +macro_rules! all_variants { + ($expr:expr, $val_name:ident => $expr_arm:expr) => { + { + use match_any::match_any; + use $crate::ast::statement::statement_node::*; + match_any!($expr, Statement::Expression($val_name) | Statement::Print($val_name) => $expr_arm) + } + }; +} +pub(crate) use all_variants; + #[derive(Debug)] -pub struct ExpressionStatement(ExpressionNode); +pub struct ExpressionStatement(pub ExpressionNode); impl ExpressionStatement { pub fn new(expr: ExpressionNode) -> Self { Self(expr) @@ -16,7 +27,7 @@ impl ExpressionStatement { } #[derive(Debug)] -pub struct PrintStatement(ExpressionNode); +pub struct PrintStatement(pub ExpressionNode); impl PrintStatement { pub fn new(expr: ExpressionNode) -> Self { Self(expr) diff --git a/src/interpreter/ast_walker/mod.rs b/src/interpreter/ast_walker/mod.rs index d3e147d..cca6bb4 100644 --- a/src/interpreter/ast_walker/mod.rs +++ b/src/interpreter/ast_walker/mod.rs @@ -1,4 +1,5 @@ mod expression_interpreter; +mod statement_interpreter; pub use super::{error::RuntimeError, types}; use super::types::Value; diff --git a/src/interpreter/ast_walker/statement_interpreter.rs b/src/interpreter/ast_walker/statement_interpreter.rs new file mode 100644 index 0000000..f0c3a6a --- /dev/null +++ b/src/interpreter/ast_walker/statement_interpreter.rs @@ -0,0 +1,26 @@ +use super::{RuntimeError, types::Value}; +use super::Interpret; +use crate::ast::statement::statement_node; + + + +impl Interpret for statement_node::Statement { + fn interpret(&self) -> Result { + statement_node::all_variants!(self, n => n.interpret()) + } +} + + +impl Interpret for statement_node::PrintStatement { + fn interpret(&self) -> Result { + let res = self.0.interpret()?; + println!("{:?}", res); + Ok(res) + } +} + +impl Interpret for statement_node::ExpressionStatement { + fn interpret(&self) -> Result { + self.0.interpret() + } +} diff --git a/src/interpreter/environment.rs b/src/interpreter/environment.rs new file mode 100644 index 0000000..f5a191a --- /dev/null +++ b/src/interpreter/environment.rs @@ -0,0 +1,3 @@ +struct Environment { + +} diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 8764f40..f33f8b5 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -1,3 +1,4 @@ pub mod ast_walker; pub mod types; pub mod error; +mod environment; diff --git a/src/interpreter/types.rs b/src/interpreter/types.rs index a5cd514..60d5861 100644 --- a/src/interpreter/types.rs +++ b/src/interpreter/types.rs @@ -6,7 +6,7 @@ pub enum Value { Int(i32), Float(f32), Bool(bool), - Null, + Nil, // TODO: create a cow(not rust cow) string instead of cloning a normal string String(String), } @@ -14,14 +14,15 @@ pub enum Value { impl From for Value { fn from(l: expression_node::Literal) -> Self { match_any::match_any!(l, - expression_node::Literal::Int(v) | expression_node::Literal::Bool(v) | expression_node::Literal::Float(v) | expression_node::Literal::String(v) => v.into() + expression_node::Literal::Int(v) | expression_node::Literal::Bool(v) | expression_node::Literal::Float(v) | expression_node::Literal::String(v) => v.into(), + expression_node::Literal::Nil => Self::Nil ) } } impl Default for Value { fn default() -> Self { - Self::Null + Self::Nil } } diff --git a/src/lib.rs b/src/lib.rs index f917a99..275d2b4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,12 +23,11 @@ pub fn parse(tokens: Vec) -> ParseAllResult { } pub fn exec(nodes: Vec) -> Result { - todo!(); - /* + let mut last_res = Value::Nil; for statement in nodes { - //statement.interpret()?; + last_res = statement.interpret()?; } - */ + Ok(last_res) } pub fn run(code: &str) -> Result { diff --git a/test.lox b/test.lox index 0a3ffe1..e62683e 100644 --- a/test.lox +++ b/test.lox @@ -1 +1,5 @@ 1 == 1; +1 == 2; +print 1; +print 2; +nil;