diff --git a/src/parser/ast/mod.rs b/src/parser/ast/mod.rs index 7221377..360e5b0 100644 --- a/src/parser/ast/mod.rs +++ b/src/parser/ast/mod.rs @@ -3,47 +3,39 @@ use crate::lexer::Token; use crate::parser::Parser; use std::error::Error; -pub trait Node { - fn token_literal(&self) -> &'static str; - fn validate(&self) -> Result<(), Box>; +pub enum Node { + Statement(StatementType), + Expression, } -pub(crate) trait Statement: Node { - fn parse(&mut Parser) -> Result> +#[derive(PartialEq, Debug)] +pub enum StatementType { + Let(LetStatement), + Ident(Identifier), +} + +pub trait Statement { + fn parse(&mut Parser) -> Result> + where + Self: Sized; + fn new() -> StatementType where Self: Sized; } -pub trait Expression: Node {} - -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct LetStatement { name: Identifier, // value: dyn Expression, } impl LetStatement { - pub fn new(identifier: Identifier) -> LetStatement { - LetStatement { name: identifier } - } -} -impl Node for LetStatement { - fn validate(&self) -> Result<(), Box> { - if self.token_literal() != "let" { - return Err(Box::new(ParseError::new( - &("self.token_literal is not set, got=".to_owned() + self.token_literal()), - ))); - } - Ok(()) + #[allow(dead_code)] + pub fn new(identifier: Identifier) -> StatementType { + StatementType::Let(LetStatement { name: identifier }) } - fn token_literal(&self) -> &'static str { - "let" - } -} - -impl Statement for LetStatement { - fn parse(parser: &mut Parser) -> Result> { + pub fn parse(parser: &mut Parser) -> Result> { let name; //TODO: Add expression parser match parser.lexer.next() { @@ -67,35 +59,25 @@ impl Statement for LetStatement { return Err(Box::new(ParseError::new("expected =, Could not find it"))); } + // TODO: Replace this with code to parse expressions correctly while !parser.current_token_is(Token::Semicolon) { - println!("prev_token={:?}", parser.current_token); parser.current_token = parser.lexer.next(); - println!("current_token={:?}", parser.current_token); } Ok(LetStatement { name }) } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct Identifier { name: String, } impl Identifier { + #[allow(dead_code)] pub fn new(name: &str) -> Identifier { Identifier { name: name.to_owned(), } } } -impl Node for Identifier { - fn validate(&self) -> Result<(), Box> { - Ok(()) - } - fn token_literal(&self) -> &'static str { - "IDENT" - } -} - -impl Expression for Identifier {} diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 4836c7c..a0b465c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3,11 +3,11 @@ mod program; pub use self::program::Program; -use self::ast::{LetStatement, Statement}; +use self::ast::{LetStatement, Statement, StatementType}; use crate::lexer::{Lexer, Token}; use std::iter::Peekable; -pub(crate) struct Parser<'a> { +pub struct Parser<'a> { lexer: Peekable>, current_token: Option, } @@ -19,15 +19,13 @@ impl<'a> Parser<'a> { current_token: None, } } - fn parse_statement(&mut self, token: Token) -> Option> { + fn parse_statement(&mut self, token: Token) -> Option { match token { Token::Let => { - let stmt = match LetStatement::parse(self) { - Ok(v) => v, - Err(_) => return None, //TODO: Return appropriate error - }; - - Some(Box::new(stmt)) + match LetStatement::parse(self) { + Ok(v) => Some(StatementType::Let(v)), + Err(_) => None, //TODO: Return appropriate error + } } n @ _ => { println!("{:?}", n); diff --git a/src/parser/program.rs b/src/parser/program.rs index 9896c03..87ce3bb 100644 --- a/src/parser/program.rs +++ b/src/parser/program.rs @@ -1,9 +1,10 @@ use crate::lexer::{Lexer, Token}; -use crate::parser::ast::Statement; +use crate::parser::ast::{Statement, StatementType}; use crate::parser::Parser; +#[derive(Debug)] pub struct Program { - statements: Vec>, + statements: Vec, } impl Program { @@ -25,7 +26,7 @@ impl Program { break; } } - + println!("statements={:?}", statements); Program { statements } } } @@ -44,19 +45,22 @@ mod tests { "; let out = Program { statements: vec![ - Box::new(LetStatement::new(Identifier::new("yr"))), - Box::new(LetStatement::new(Identifier::new("qq"))), - Box::new(LetStatement::new(Identifier::new("foobar"))), + LetStatement::new(Identifier::new("yr")), + LetStatement::new(Identifier::new("qq")), + LetStatement::new(Identifier::new("foobar")), ], }; let lexer = Lexer::new(ip); let ast_tree = Program::parse(lexer); + println!("{:?}", ast_tree); if ast_tree.statements.len() != 3 { assert_eq!(ast_tree.statements.len(), 3); } + for (out, expected_out) in ast_tree.statements.iter().zip(out.statements.iter()) { - // assert!(out, expected_out); + assert_eq!(out, expected_out); + println!("out={:?}, expected_out={:?}", out, expected_out); } } }