diff --git a/src/ast.rs b/src/ast.rs index 875d60e..a0348a2 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -39,12 +39,15 @@ pub struct BlockStatement { #[derive(Debug, Eq, Clone, PartialEq)] pub enum Statement { ReturnStatement(Box), - LetStatement { name: Box, value: Box }, + LetStatement { + name: Box, + value: Box, + }, } #[derive(Debug, Eq, Clone, PartialEq)] pub enum AstNode { - Statement(Statement), - Expression(Expression), + Statement(Box), + Expression(Box), Program { statements: Vec }, } diff --git a/src/evaluator.rs b/src/evaluator.rs index b7a952a..c899142 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -35,8 +35,8 @@ impl Evaluator { pub fn eval(&mut self, node: AstNode) -> Object { match node { AstNode::Program { statements } => self.eval_program(statements), - AstNode::Statement(statement) => self.eval_statement(statement), - AstNode::Expression(expression) => self.eval_expression(expression), + AstNode::Statement(statement) => self.eval_statement(*statement), + AstNode::Expression(expression) => self.eval_expression(*expression), } } @@ -50,7 +50,7 @@ impl Evaluator { Expression::Boolean(value) => Object::Boolean(value), Expression::String(value) => Object::String(value), Expression::Prefix { operator, right } => { - let right = self.eval(AstNode::Expression(*right)); + let right = self.eval(AstNode::Expression(right)); self.eval_prefix_expression(operator, right) } Expression::Infix { @@ -58,8 +58,8 @@ impl Evaluator { left, right, } => { - let left = self.eval(AstNode::Expression(*left)); - let right = self.eval(AstNode::Expression(*right)); + let left = self.eval(AstNode::Expression(left)); + let right = self.eval(AstNode::Expression(right)); self.eval_infix_expression(left, right, operator) } Expression::IfExpression { @@ -68,7 +68,7 @@ impl Evaluator { alternative, .. } => { - let condition = self.eval(AstNode::Expression(*condition)); + let condition = self.eval(AstNode::Expression(condition)); if condition.is_truthy() { return self.eval_block_statement(consequence.statements); @@ -93,7 +93,7 @@ impl Evaluator { arguments, .. } => { - let function = self.eval(AstNode::Expression(*function)); + let function = self.eval(AstNode::Expression(function)); match function { Object::Builtin(builtin_fn) => { @@ -153,7 +153,7 @@ impl Evaluator { fn eval_statement(&mut self, statement: Statement) -> Object { match statement { Statement::ReturnStatement(value) => { - let result_object = self.eval(AstNode::Expression(*value)); + let result_object = self.eval(AstNode::Expression(value)); Object::Return(Box::new(result_object)) } Statement::LetStatement { name, value } => { @@ -162,7 +162,7 @@ impl Evaluator { _ => panic!(), }; - let result_object = self.eval(AstNode::Expression(*value)); + let result_object = self.eval(AstNode::Expression(value)); self.context.insert(let_name.clone(), result_object.clone()); result_object } @@ -172,7 +172,7 @@ impl Evaluator { fn eval_expressions(&mut self, expressions: Vec) -> Vec { expressions .iter() - .map(|expression| self.eval(AstNode::Expression(expression.clone()))) + .map(|expression| self.eval(AstNode::Expression(Box::new(expression.clone())))) .collect() } @@ -261,7 +261,7 @@ impl Object { Object::Null => "null".to_string(), Object::Array(elems) => { let elements_str = elems - .into_iter() + .iter() .map(|e| e.inspect()) .collect::>() .join(", "); diff --git a/src/parser.rs b/src/parser.rs index e98008b..56684a4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -100,11 +100,14 @@ impl Parser { return None; } - Some(AstNode::Statement(Statement::LetStatement { name, value })) + Some(AstNode::Statement(Box::new(Statement::LetStatement { + name, + value, + }))) } fn parse_expression_statement(&mut self) -> Option { - let expression = self.parse_expression(Precedence::Lowest)?; + let expression = Box::new(self.parse_expression(Precedence::Lowest)?); if self.current_token == Token::Semicolon { self.advance_tokens(); @@ -126,7 +129,9 @@ impl Parser { let expression = Box::new(self.parse_expression(Precedence::Lowest)?); - Some(AstNode::Statement(Statement::ReturnStatement(expression))) + Some(AstNode::Statement(Box::new(Statement::ReturnStatement( + expression, + )))) } fn parse_expression(&mut self, precedence: Precedence) -> Option { diff --git a/tests/parser.rs b/tests/parser.rs index 95f971c..0420e92 100644 --- a/tests/parser.rs +++ b/tests/parser.rs @@ -30,10 +30,10 @@ fn given_let_statements_with_single_integers_shold_parse_correctly() { let expected_identifier = expected_identifiers.get(idx).unwrap(); let expected_int = expected_ints.get(idx).unwrap(); - let expected_statement = AstNode::Statement(Statement::LetStatement { + let expected_statement = AstNode::Statement(Box::new(Statement::LetStatement { name: Box::new(Expression::Identifier(expected_identifier.to_string())), value: Box::new(Expression::Int(expected_int.to_string().parse().unwrap())), - }); + })); assert_eq!(*statement, expected_statement); }) @@ -67,8 +67,9 @@ fn given_return_statements_with_single_integers_shold_parse_correctly() { let expected_expression = Expression::Int(expected_int.to_string().parse().unwrap()); - let expected_statement = - AstNode::Statement(Statement::ReturnStatement(Box::new(expected_expression))); + let expected_statement = AstNode::Statement(Box::new(Statement::ReturnStatement( + Box::new(expected_expression), + ))); assert_eq!(*statement, expected_statement); }) @@ -94,7 +95,7 @@ fn given_a_variable_name_it_should_parse_correctly() { match statements.first().unwrap() { AstNode::Expression(expression) => { - assert_eq!(*expression, Expression::Identifier("foo".to_string())); + assert_eq!(**expression, Expression::Identifier("foo".to_string())); } _ => panic!("wrong statement!"), } @@ -122,7 +123,7 @@ fn given_a_number_expression_it_should_parse_correctly() { match statement { AstNode::Expression(expression) => { assert_eq!( - *expression, + **expression, Expression::Int("5".to_string().parse().unwrap()) ); } @@ -163,7 +164,7 @@ fn given_a_prefix_expression_it_should_parse_correctly() { let expected_right_expression = Expression::Int(expected_values.get(idx).unwrap().parse().unwrap()); - match expression { + match &**expression { Expression::Prefix { operator, right } => { assert_eq!(operator, expected_operator); assert_eq!(*right, Box::new(expected_right_expression)); @@ -291,7 +292,9 @@ fn given_an_if_expression_it_should_parse_correctly() { right: Box::new(Expression::Identifier("y".to_string())), }), consequence: Box::new(BlockStatement { - statements: vec![AstNode::Expression(Expression::Identifier("x".to_string()))], + statements: vec![AstNode::Expression(Box::new(Expression::Identifier( + "x".to_string(), + )))], }), alternative: None, }; @@ -305,7 +308,7 @@ fn given_an_if_expression_it_should_parse_correctly() { let statement = statements.first().unwrap(); match statement { - AstNode::Expression(expression) => assert_eq!(*expression, expected_expression), + AstNode::Expression(expression) => assert_eq!(**expression, expected_expression), _ => panic!("Unexpected statement!"), } } @@ -326,10 +329,14 @@ fn given_an_if_else_expression_it_should_parse_correctly() { right: Box::new(Expression::Identifier("y".to_string())), }), consequence: Box::new(BlockStatement { - statements: vec![AstNode::Expression(Expression::Identifier("x".to_string()))], + statements: vec![AstNode::Expression(Box::new(Expression::Identifier( + "x".to_string(), + )))], }), alternative: Some(BlockStatement { - statements: vec![AstNode::Expression(Expression::Identifier("y".to_string()))], + statements: vec![AstNode::Expression(Box::new(Expression::Identifier( + "y".to_string(), + )))], }), }; @@ -343,7 +350,7 @@ fn given_an_if_else_expression_it_should_parse_correctly() { let statement = statements.first().unwrap(); match statement { - AstNode::Expression(expression) => assert_eq!(*expression, expected_expression), + AstNode::Expression(expression) => assert_eq!(**expression, expected_expression), _ => panic!("Unexpected statement!"), } } @@ -360,11 +367,11 @@ fn given_a_function_expression_it_should_parse_correctly() { Token::Identifier("b".to_string()), ], body: Box::new(BlockStatement { - statements: vec![AstNode::Expression(Expression::Infix { + statements: vec![AstNode::Expression(Box::new(Expression::Infix { operator: Token::Plus, left: Box::new(Expression::Identifier("a".to_string())), right: Box::new(Expression::Identifier("b".to_string())), - })], + }))], }), }; @@ -381,7 +388,7 @@ fn given_a_function_expression_it_should_parse_correctly() { let statement = statements.first().unwrap(); match statement { - AstNode::Expression(expression) => assert_eq!(*expression, expected_expression), + AstNode::Expression(expression) => assert_eq!(**expression, expected_expression), _ => panic!("Unexpected expression!"), } } @@ -422,7 +429,7 @@ fn given_a_call_expression_it_should_parse_correctly() { let statement = statements.first().unwrap(); match statement { - AstNode::Expression(expression) => assert_eq!(*expression, expected_expression), + AstNode::Expression(expression) => assert_eq!(**expression, expected_expression), _ => panic!("Unexpected statement!"), } } @@ -448,7 +455,7 @@ fn given_a_string_expression_it_should_parse_correctly() { let statement = statements.first().unwrap(); match statement { - AstNode::Expression(expression) => assert_eq!(*expression, expected_expression), + AstNode::Expression(expression) => assert_eq!(**expression, expected_expression), _ => panic!("Unexpected expression!"), } } @@ -482,7 +489,7 @@ fn given_an_array_expression_it_should_parse_correctly() { let statement = statements.first().unwrap(); match statement { - AstNode::Expression(expression) => assert_eq!(*expression, expected_expression), + AstNode::Expression(expression) => assert_eq!(**expression, expected_expression), _ => panic!("Unexpected expression!"), } } @@ -505,7 +512,7 @@ fn assert_boolean_expression(code: &str, expected_expression: &Expression) { let statement = statements.first().unwrap(); match statement { - AstNode::Expression(expression) => assert_eq!(expression, expected_expression), + AstNode::Expression(expression) => assert_eq!(&**expression, expected_expression), _ => panic!("Unexpected statement!"), } } @@ -539,7 +546,7 @@ fn assert_infix_expression(code: &str, expected_operator: Token, expected_litera right: Box::new(expected_right_exp), }; - assert_eq!(*expression, expected_expression); + assert_eq!(&**expression, &expected_expression); } _ => panic!(), }