diff --git a/src/parser/ast/mod.rs b/src/parser/ast/mod.rs index 83915a9..7221377 100644 --- a/src/parser/ast/mod.rs +++ b/src/parser/ast/mod.rs @@ -1,5 +1,6 @@ -use super::ParserError; -use crate::lexer::Lexer; +use super::ParseError; +use crate::lexer::Token; +use crate::parser::Parser; use std::error::Error; pub trait Node { @@ -7,8 +8,8 @@ pub trait Node { fn validate(&self) -> Result<(), Box>; } -pub trait Statement: Node { - fn parse(&mut Lexer) -> Self +pub(crate) trait Statement: Node { + fn parse(&mut Parser) -> Result> where Self: Sized; } @@ -21,11 +22,16 @@ pub struct LetStatement { // 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(ParserError::new( - "self.token_literal is not set, got=".to_owned() + self.token_literal(), + return Err(Box::new(ParseError::new( + &("self.token_literal is not set, got=".to_owned() + self.token_literal()), ))); } Ok(()) @@ -37,19 +43,52 @@ impl Node for LetStatement { } impl Statement for LetStatement { - fn parse(lexer: &mut Lexer) -> LetStatement { - LetStatement { - name: Identifier { name: "potato" }, - // value: "", + fn parse(parser: &mut Parser) -> Result> { + let name; + //TODO: Add expression parser + match parser.lexer.next() { + Some(v) => match v { + Token::Ident(q) => name = Identifier { name: q }, + n @ _ => { + return Err(Box::new(ParseError::new(&format!( + "expected IDENT, Found {:?}", + n + )))) + } + }, + None => { + return Err(Box::new(ParseError::new( + "expected IDENT after let, Could not find it", + ))) + } + }; + + if !parser.expect_peek(Token::Assign) { + return Err(Box::new(ParseError::new("expected =, Could not find it"))); } + + 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)] pub struct Identifier { - name: &'static str, + name: String, } +impl Identifier { + pub fn new(name: &str) -> Identifier { + Identifier { + name: name.to_owned(), + } + } +} impl Node for Identifier { fn validate(&self) -> Result<(), Box> { Ok(()) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 684d59b..4836c7c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5,37 +5,76 @@ pub use self::program::Program; use self::ast::{LetStatement, Statement}; use crate::lexer::{Lexer, Token}; +use std::iter::Peekable; -struct Parser {} +pub(crate) struct Parser<'a> { + lexer: Peekable>, + current_token: Option, +} -impl Parser { - fn parse_statement(token: Token, lexer: &mut Lexer) -> Option> { - match token { - Token::Let => Some(Box::new(LetStatement::parse(lexer))), - _ => unimplemented!(), +impl<'a> Parser<'a> { + fn new(lexer: Lexer<'a>) -> Parser { + Parser { + lexer: lexer.peekable(), + current_token: None, } } + 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)) + } + n @ _ => { + println!("{:?}", n); + None + } + } + } + + fn expect_peek(&mut self, token: Token) -> bool { + if let Some(v) = self.lexer.peek() { + if v == &token { + self.lexer.next(); + true + } else { + false + } + } else { + false + } + } + + fn current_token_is(&self, token: Token) -> bool { + self.current_token == Some(token) + } } #[derive(Debug)] -struct ParserError { +struct ParseError { desc: String, } -impl std::fmt::Display for ParserError { +impl std::fmt::Display for ParseError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "ParserError: ") + write!(f, "ParseError: {}", self) } } -impl std::error::Error for ParserError { +impl std::error::Error for ParseError { fn description(&self) -> &str { &self.desc } } -impl ParserError { - fn new(desc: String) -> ParserError { - ParserError { desc } +impl ParseError { + fn new(desc: &str) -> ParseError { + ParseError { + desc: desc.to_owned(), + } } } diff --git a/src/parser/program.rs b/src/parser/program.rs index 6414612..9896c03 100644 --- a/src/parser/program.rs +++ b/src/parser/program.rs @@ -1,5 +1,5 @@ use crate::lexer::{Lexer, Token}; -use crate::parser::ast::{LetStatement, Statement}; +use crate::parser::ast::Statement; use crate::parser::Parser; pub struct Program { @@ -7,24 +7,16 @@ pub struct Program { } impl Program { - pub fn token_literal(&self) -> &'static str { - if self.statements.len() > 0 { - self.statements[0].token_literal() - } else { - "" - } - } - - pub fn parse(mut lexer: Lexer) -> Program { + pub fn parse(lexer: Lexer) -> Program { let mut statements = vec![]; - + let mut parser = Parser::new(lexer); loop { - if let Some(token) = lexer.next() { + if let Some(token) = parser.lexer.next() { if token == Token::EOF { break; } - if let Some(stmt) = Parser::parse_statement(token, &mut lexer) { + if let Some(stmt) = parser.parse_statement(token) { statements.push(stmt); } else { continue; @@ -41,8 +33,8 @@ impl Program { #[cfg(test)] mod tests { use crate::lexer::Lexer; + use crate::parser::ast::{Identifier, LetStatement}; use crate::parser::Program; - #[test] fn let_statements() { let ip = " @@ -50,12 +42,21 @@ mod tests { let qq = 10; let foobar = 8388383; "; - + 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"))), + ], + }; let lexer = Lexer::new(ip); let ast_tree = Program::parse(lexer); 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); + } } }