From e4e0eb322ecca3e3f0c3a5086d686e8374b85894 Mon Sep 17 00:00:00 2001 From: bad Date: Mon, 2 May 2022 11:38:20 +0200 Subject: [PATCH] Refactor statement module tree --- src/ast/parser.rs | 4 +- src/ast/statement/expression_statement.rs | 28 ++++++++ src/ast/statement/mod.rs | 39 ++++++++++- src/ast/statement/print_statement.rs | 32 +++++++++ src/ast/statement/statement_node.rs | 48 ------------- src/ast/statement/statement_parser.rs | 70 ------------------- .../variable_assignment_statement.rs | 44 ++++++++++++ .../ast_walker/statement_interpreter.rs | 12 ++-- src/interpreter/world.rs | 2 +- src/lib.rs | 2 +- 10 files changed, 151 insertions(+), 130 deletions(-) create mode 100644 src/ast/statement/expression_statement.rs create mode 100644 src/ast/statement/print_statement.rs delete mode 100644 src/ast/statement/statement_node.rs create mode 100644 src/ast/statement/variable_assignment_statement.rs diff --git a/src/ast/parser.rs b/src/ast/parser.rs index 0d39e41..c808d38 100644 --- a/src/ast/parser.rs +++ b/src/ast/parser.rs @@ -1,5 +1,5 @@ use super::ast_parser_iter::ParserIter; -use super::statement::statement_node; +use super::statement; use crate::error::ErrorLocationWrapper; use crate::lexer::{token, token::TokenType}; use std::result::Result as StdResult; @@ -29,7 +29,7 @@ pub struct Parser<'a, T: Iterator>> { pub(super) token_iter: super::ast_parser_iter::ParserIter, } -pub type ParseAllResult = StdResult, Vec>; +pub type ParseAllResult = StdResult, Vec>; impl<'a, T: Iterator>> Parser<'a, T> { pub fn new(iter: T) -> Parser<'a, T> { diff --git a/src/ast/statement/expression_statement.rs b/src/ast/statement/expression_statement.rs new file mode 100644 index 0000000..1c7a859 --- /dev/null +++ b/src/ast/statement/expression_statement.rs @@ -0,0 +1,28 @@ +use crate::{ + ast::expression::expression_node::ExpressionNode, + ast::parser::{InnerASTParsingError, Parser, Result}, + lexer::token::{self, TokenType}, +}; + +use super::Statement; + +#[derive(Debug)] +pub struct ExpressionStatement(pub ExpressionNode); +impl ExpressionStatement { + pub fn new(expr: ExpressionNode) -> Self { + Self(expr) + } +} + +impl<'a, T: Iterator>> Parser<'a, T> { + pub fn expression_statement(&mut self) -> Result { + let expr = self.expression()?; + let token = self.token_iter.peek(); + if let TokenType::Semicolon = token.token_type { + self.token_iter.next(); + Ok(ExpressionStatement::new(expr).into()) + } else { + Err(token.location.wrap(InnerASTParsingError::ExpectedSemi)) + } + } +} diff --git a/src/ast/statement/mod.rs b/src/ast/statement/mod.rs index 0306a3d..015dd42 100644 --- a/src/ast/statement/mod.rs +++ b/src/ast/statement/mod.rs @@ -1,2 +1,37 @@ -pub mod statement_node; -mod statement_parser; +use crate::lexer::token; + +use super::parser::{InnerASTParsingError, Parser, Result}; + +mod expression_statement; +mod print_statement; +mod variable_assignment_statement; + +pub use expression_statement::ExpressionStatement; +pub use print_statement::PrintStatement; +pub use variable_assignment_statement::VariableAssignmentStatement; + +use from_variants::FromVariants; + +#[derive(FromVariants, Debug)] +pub enum Statement { + Expression(ExpressionStatement), + Print(PrintStatement), + VariableAssignment(VariableAssignmentStatement), +} + +macro_rules! all_variants { + ($expr:expr, $val_name:ident => $expr_arm:expr) => { + { + use match_any::match_any; + use $crate::ast::statement::*; + match_any!($expr, Statement::Expression($val_name) | Statement::Print($val_name) | Statement::VariableAssignment($val_name) => $expr_arm) + } + }; +} +pub(crate) use all_variants; + +impl<'a, T: Iterator>> Parser<'a, T> { + pub fn statement(&mut self) -> Result { + self.print_statement() + } +} diff --git a/src/ast/statement/print_statement.rs b/src/ast/statement/print_statement.rs new file mode 100644 index 0000000..3969a23 --- /dev/null +++ b/src/ast/statement/print_statement.rs @@ -0,0 +1,32 @@ +use itertools::PeekingNext; + +use super::{InnerASTParsingError, Parser, Result, Statement}; +use crate::ast::expression::expression_node::ExpressionNode; +use crate::lexer::token::{self, Token}; + +#[derive(Debug)] +pub struct PrintStatement(pub ExpressionNode); +impl PrintStatement { + pub fn new(expr: ExpressionNode) -> Self { + Self(expr) + } +} + +impl<'a, T: Iterator>> Parser<'a, T> { + pub(super) fn print_statement(&mut self) -> Result { + if let Some(Token { location: loc, .. }) = self + .token_iter + .peeking_next(|t| matches!(t.token_type, token::TokenType::Print)) + { + let expr = self.expression()?; + if let token::TokenType::Semicolon = self.token_iter.peek().token_type { + self.token_iter.next(); + Ok(PrintStatement::new(expr).into()) + } else { + Err(loc.wrap(InnerASTParsingError::ExpectedSemi)) + } + } else { + self.variable_assignment_statement() + } + } +} diff --git a/src/ast/statement/statement_node.rs b/src/ast/statement/statement_node.rs deleted file mode 100644 index c99127c..0000000 --- a/src/ast/statement/statement_node.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::ast::expression::expression_node::ExpressionNode; -use from_variants::FromVariants; - -#[derive(FromVariants, Debug)] -pub enum Statement { - Expression(ExpressionStatement), - Print(PrintStatement), - VariableAssignment(VariableAssignmentStatement), -} - -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) | Statement::VariableAssignment($val_name) => $expr_arm) - } - }; -} -pub(crate) use all_variants; - -#[derive(Debug)] -pub struct ExpressionStatement(pub ExpressionNode); -impl ExpressionStatement { - pub fn new(expr: ExpressionNode) -> Self { - Self(expr) - } -} - -#[derive(Debug)] -pub struct PrintStatement(pub ExpressionNode); -impl PrintStatement { - pub fn new(expr: ExpressionNode) -> Self { - Self(expr) - } -} - -#[derive(Debug)] -pub struct VariableAssignmentStatement { - pub var_name: String, - pub node: ExpressionNode, -} - -impl VariableAssignmentStatement { - pub fn new(var_name: String, node: ExpressionNode) -> Self { - Self { var_name, node } - } -} diff --git a/src/ast/statement/statement_parser.rs b/src/ast/statement/statement_parser.rs index 905a36e..e69de29 100644 --- a/src/ast/statement/statement_parser.rs +++ b/src/ast/statement/statement_parser.rs @@ -1,70 +0,0 @@ -use itertools::PeekingNext; - -use super::statement_node::{ExpressionStatement, PrintStatement, Statement}; -use crate::{ - ast::{ - parser::{InnerASTParsingError, Parser, Result}, - statement::statement_node::VariableAssignmentStatement, - }, - lexer::token::{self, Token, TokenType}, -}; - -impl<'a, T: Iterator>> Parser<'a, T> { - pub fn statement(&mut self) -> Result { - self.print_statement() - } - - fn print_statement(&mut self) -> Result { - if let Some(Token { location: loc, .. }) = self - .token_iter - .peeking_next(|t| matches!(t.token_type, token::TokenType::Print)) - { - let expr = self.expression()?; - if let token::TokenType::Semicolon = self.token_iter.peek().token_type { - self.token_iter.next(); - Ok(PrintStatement::new(expr).into()) - } else { - Err(loc.wrap(InnerASTParsingError::ExpectedSemi)) - } - } else { - self.variable_assignment_statement() - } - } - - fn variable_assignment_statement(&mut self) -> Result { - if matches!( - self.token_iter.peek_nth(0).token_type, - TokenType::Identifier(_) - ) && matches!(self.token_iter.peek_nth(1).token_type, TokenType::Equal) - { - let ident = if let TokenType::Identifier(ident) = self.token_iter.next().token_type { - ident - } else { - unreachable!() - }; - self.token_iter.next(); - let expr = self.expression()?; - - let token = self.token_iter.peek(); - if let token::TokenType::Semicolon = token.token_type { - self.token_iter.next(); - Ok(VariableAssignmentStatement::new(ident, expr).into()) - } else { - Err(token.location.wrap(InnerASTParsingError::ExpectedSemi)) - } - } else { - self.expression_statement() - } - } - - fn expression_statement(&mut self) -> Result { - let expr = self.expression()?; - let token = self.token_iter.peek(); - if let TokenType::Semicolon = token.token_type { - self.token_iter.next(); - Ok(ExpressionStatement::new(expr).into()) - } else { - Err(token.location.wrap(InnerASTParsingError::ExpectedSemi)) - } - } -} diff --git a/src/ast/statement/variable_assignment_statement.rs b/src/ast/statement/variable_assignment_statement.rs new file mode 100644 index 0000000..9f15292 --- /dev/null +++ b/src/ast/statement/variable_assignment_statement.rs @@ -0,0 +1,44 @@ +use super::Statement; +use super::{InnerASTParsingError, Parser, Result}; +use crate::ast::expression::expression_node::ExpressionNode; +use crate::lexer::token::{self, TokenType}; + +#[derive(Debug)] +pub struct VariableAssignmentStatement { + pub var_name: String, + pub node: ExpressionNode, +} + +impl VariableAssignmentStatement { + pub fn new(var_name: String, node: ExpressionNode) -> Self { + Self { var_name, node } + } +} + +impl<'a, T: Iterator>> Parser<'a, T> { + pub(super) fn variable_assignment_statement(&mut self) -> Result { + if matches!( + self.token_iter.peek_nth(0).token_type, + TokenType::Identifier(_) + ) && matches!(self.token_iter.peek_nth(1).token_type, TokenType::Equal) + { + let ident = if let TokenType::Identifier(ident) = self.token_iter.next().token_type { + ident + } else { + unreachable!() + }; + self.token_iter.next(); + let expr = self.expression()?; + + let token = self.token_iter.peek(); + if let token::TokenType::Semicolon = token.token_type { + self.token_iter.next(); + Ok(VariableAssignmentStatement::new(ident, expr).into()) + } else { + Err(token.location.wrap(InnerASTParsingError::ExpectedSemi)) + } + } else { + self.expression_statement() + } + } +} diff --git a/src/interpreter/ast_walker/statement_interpreter.rs b/src/interpreter/ast_walker/statement_interpreter.rs index a348ad3..5cf4a62 100644 --- a/src/interpreter/ast_walker/statement_interpreter.rs +++ b/src/interpreter/ast_walker/statement_interpreter.rs @@ -1,15 +1,15 @@ use super::Interpret; use super::{types::Value, RuntimeError}; -use crate::ast::statement::statement_node; +use crate::ast::statement; use crate::interpreter::world::World; -impl Interpret for statement_node::Statement { +impl Interpret for statement::Statement { fn interpret(&self, w: &mut World) -> Result { - statement_node::all_variants!(self, n => n.interpret(w)) + statement::all_variants!(self, n => n.interpret(w)) } } -impl Interpret for statement_node::PrintStatement { +impl Interpret for statement::PrintStatement { fn interpret(&self, w: &mut World) -> Result { let res = self.0.interpret(w)?; println!("{:?}", res); @@ -17,13 +17,13 @@ impl Interpret for statement_node::PrintStatement { } } -impl Interpret for statement_node::ExpressionStatement { +impl Interpret for statement::ExpressionStatement { fn interpret(&self, w: &mut World) -> Result { self.0.interpret(w) } } -impl Interpret for statement_node::VariableAssignmentStatement { +impl Interpret for statement::VariableAssignmentStatement { fn interpret(&self, w: &mut World) -> Result { let expr_val = self.node.interpret(w)?; // Clone for now, later this will use a GC and won't need to clone diff --git a/src/interpreter/world.rs b/src/interpreter/world.rs index a3ed8d7..b462603 100644 --- a/src/interpreter/world.rs +++ b/src/interpreter/world.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::ast::statement::statement_node::Statement; +use crate::ast::statement::Statement; use super::{ ast_walker::{Interpret, RuntimeError}, diff --git a/src/lib.rs b/src/lib.rs index fa41e31..3a6b0be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ pub mod interpreter; pub mod lexer; use ast::parser::ParseAllResult; -use ast::statement::statement_node::Statement; +use ast::statement::Statement; use interpreter::ast_walker::{Interpret, RuntimeError}; use interpreter::types::Value; use interpreter::world::World;