Refactor statement module tree

This commit is contained in:
bad 2022-05-02 11:38:20 +02:00
parent fc5a50227f
commit e4e0eb322e
10 changed files with 151 additions and 130 deletions

View file

@ -1,5 +1,5 @@
use super::ast_parser_iter::ParserIter; use super::ast_parser_iter::ParserIter;
use super::statement::statement_node; use super::statement;
use crate::error::ErrorLocationWrapper; use crate::error::ErrorLocationWrapper;
use crate::lexer::{token, token::TokenType}; use crate::lexer::{token, token::TokenType};
use std::result::Result as StdResult; use std::result::Result as StdResult;
@ -29,7 +29,7 @@ pub struct Parser<'a, T: Iterator<Item = token::Token<'a>>> {
pub(super) token_iter: super::ast_parser_iter::ParserIter<T>, pub(super) token_iter: super::ast_parser_iter::ParserIter<T>,
} }
pub type ParseAllResult = StdResult<Vec<statement_node::Statement>, Vec<ASTParsingError>>; pub type ParseAllResult = StdResult<Vec<statement::Statement>, Vec<ASTParsingError>>;
impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> { impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> {
pub fn new(iter: T) -> Parser<'a, T> { pub fn new(iter: T) -> Parser<'a, T> {

View file

@ -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<Item = token::Token<'a>>> Parser<'a, T> {
pub fn expression_statement(&mut self) -> Result<Statement> {
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))
}
}
}

View file

@ -1,2 +1,37 @@
pub mod statement_node; use crate::lexer::token;
mod statement_parser;
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<Item = token::Token<'a>>> Parser<'a, T> {
pub fn statement(&mut self) -> Result<Statement> {
self.print_statement()
}
}

View file

@ -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<Item = token::Token<'a>>> Parser<'a, T> {
pub(super) fn print_statement(&mut self) -> Result<Statement> {
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()
}
}
}

View file

@ -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 }
}
}

View file

@ -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<Item = token::Token<'a>>> Parser<'a, T> {
pub fn statement(&mut self) -> Result<Statement> {
self.print_statement()
}
fn print_statement(&mut self) -> Result<Statement> {
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<Statement> {
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<Statement> {
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))
}
}
}

View file

@ -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<Item = token::Token<'a>>> Parser<'a, T> {
pub(super) fn variable_assignment_statement(&mut self) -> Result<Statement> {
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()
}
}
}

View file

@ -1,15 +1,15 @@
use super::Interpret; use super::Interpret;
use super::{types::Value, RuntimeError}; use super::{types::Value, RuntimeError};
use crate::ast::statement::statement_node; use crate::ast::statement;
use crate::interpreter::world::World; use crate::interpreter::world::World;
impl Interpret for statement_node::Statement { impl Interpret for statement::Statement {
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> { fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
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<Value, RuntimeError> { fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
let res = self.0.interpret(w)?; let res = self.0.interpret(w)?;
println!("{:?}", res); 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<Value, RuntimeError> { fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
self.0.interpret(w) self.0.interpret(w)
} }
} }
impl Interpret for statement_node::VariableAssignmentStatement { impl Interpret for statement::VariableAssignmentStatement {
fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> { fn interpret(&self, w: &mut World) -> Result<Value, RuntimeError> {
let expr_val = self.node.interpret(w)?; let expr_val = self.node.interpret(w)?;
// Clone for now, later this will use a GC and won't need to clone // Clone for now, later this will use a GC and won't need to clone

View file

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::ast::statement::statement_node::Statement; use crate::ast::statement::Statement;
use super::{ use super::{
ast_walker::{Interpret, RuntimeError}, ast_walker::{Interpret, RuntimeError},

View file

@ -5,7 +5,7 @@ pub mod interpreter;
pub mod lexer; pub mod lexer;
use ast::parser::ParseAllResult; use ast::parser::ParseAllResult;
use ast::statement::statement_node::Statement; use ast::statement::Statement;
use interpreter::ast_walker::{Interpret, RuntimeError}; use interpreter::ast_walker::{Interpret, RuntimeError};
use interpreter::types::Value; use interpreter::types::Value;
use interpreter::world::World; use interpreter::world::World;