Refactored again, let statement parser, Except for the expression parser is complete

This commit is contained in:
Ishan Jain 2019-09-07 20:30:31 +05:30
parent 20a4907153
commit 5bd49acb67
3 changed files with 40 additions and 56 deletions

View File

@ -3,47 +3,39 @@ use crate::lexer::Token;
use crate::parser::Parser; use crate::parser::Parser;
use std::error::Error; use std::error::Error;
pub trait Node { pub enum Node {
fn token_literal(&self) -> &'static str; Statement(StatementType),
fn validate(&self) -> Result<(), Box<dyn Error>>; Expression,
} }
pub(crate) trait Statement: Node { #[derive(PartialEq, Debug)]
fn parse(&mut Parser) -> Result<Self, Box<dyn Error>> pub enum StatementType {
Let(LetStatement),
Ident(Identifier),
}
pub trait Statement {
fn parse(&mut Parser) -> Result<StatementType, Box<dyn Error>>
where
Self: Sized;
fn new() -> StatementType
where where
Self: Sized; Self: Sized;
} }
pub trait Expression: Node {} #[derive(Debug, PartialEq)]
#[derive(Debug)]
pub struct LetStatement { pub struct LetStatement {
name: Identifier, name: Identifier,
// value: dyn Expression, // value: dyn Expression,
} }
impl LetStatement { impl LetStatement {
pub fn new(identifier: Identifier) -> LetStatement { #[allow(dead_code)]
LetStatement { name: identifier } pub fn new(identifier: Identifier) -> StatementType {
} StatementType::Let(LetStatement { name: identifier })
}
impl Node for LetStatement {
fn validate(&self) -> Result<(), Box<dyn Error>> {
if self.token_literal() != "let" {
return Err(Box::new(ParseError::new(
&("self.token_literal is not set, got=".to_owned() + self.token_literal()),
)));
}
Ok(())
} }
fn token_literal(&self) -> &'static str { pub fn parse(parser: &mut Parser) -> Result<LetStatement, Box<dyn Error>> {
"let"
}
}
impl Statement for LetStatement {
fn parse(parser: &mut Parser) -> Result<LetStatement, Box<dyn Error>> {
let name; let name;
//TODO: Add expression parser //TODO: Add expression parser
match parser.lexer.next() { match parser.lexer.next() {
@ -67,35 +59,25 @@ impl Statement for LetStatement {
return Err(Box::new(ParseError::new("expected =, Could not find it"))); 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) { while !parser.current_token_is(Token::Semicolon) {
println!("prev_token={:?}", parser.current_token);
parser.current_token = parser.lexer.next(); parser.current_token = parser.lexer.next();
println!("current_token={:?}", parser.current_token);
} }
Ok(LetStatement { name }) Ok(LetStatement { name })
} }
} }
#[derive(Debug)] #[derive(Debug, PartialEq)]
pub struct Identifier { pub struct Identifier {
name: String, name: String,
} }
impl Identifier { impl Identifier {
#[allow(dead_code)]
pub fn new(name: &str) -> Identifier { pub fn new(name: &str) -> Identifier {
Identifier { Identifier {
name: name.to_owned(), name: name.to_owned(),
} }
} }
} }
impl Node for Identifier {
fn validate(&self) -> Result<(), Box<dyn Error>> {
Ok(())
}
fn token_literal(&self) -> &'static str {
"IDENT"
}
}
impl Expression for Identifier {}

View File

@ -3,11 +3,11 @@ mod program;
pub use self::program::Program; pub use self::program::Program;
use self::ast::{LetStatement, Statement}; use self::ast::{LetStatement, Statement, StatementType};
use crate::lexer::{Lexer, Token}; use crate::lexer::{Lexer, Token};
use std::iter::Peekable; use std::iter::Peekable;
pub(crate) struct Parser<'a> { pub struct Parser<'a> {
lexer: Peekable<Lexer<'a>>, lexer: Peekable<Lexer<'a>>,
current_token: Option<Token>, current_token: Option<Token>,
} }
@ -19,15 +19,13 @@ impl<'a> Parser<'a> {
current_token: None, current_token: None,
} }
} }
fn parse_statement(&mut self, token: Token) -> Option<Box<dyn ast::Statement>> { fn parse_statement(&mut self, token: Token) -> Option<ast::StatementType> {
match token { match token {
Token::Let => { Token::Let => {
let stmt = match LetStatement::parse(self) { match LetStatement::parse(self) {
Ok(v) => v, Ok(v) => Some(StatementType::Let(v)),
Err(_) => return None, //TODO: Return appropriate error Err(_) => None, //TODO: Return appropriate error
}; }
Some(Box::new(stmt))
} }
n @ _ => { n @ _ => {
println!("{:?}", n); println!("{:?}", n);

View File

@ -1,9 +1,10 @@
use crate::lexer::{Lexer, Token}; use crate::lexer::{Lexer, Token};
use crate::parser::ast::Statement; use crate::parser::ast::{Statement, StatementType};
use crate::parser::Parser; use crate::parser::Parser;
#[derive(Debug)]
pub struct Program { pub struct Program {
statements: Vec<Box<dyn Statement>>, statements: Vec<StatementType>,
} }
impl Program { impl Program {
@ -25,7 +26,7 @@ impl Program {
break; break;
} }
} }
println!("statements={:?}", statements);
Program { statements } Program { statements }
} }
} }
@ -44,19 +45,22 @@ mod tests {
"; ";
let out = Program { let out = Program {
statements: vec![ statements: vec![
Box::new(LetStatement::new(Identifier::new("yr"))), LetStatement::new(Identifier::new("yr")),
Box::new(LetStatement::new(Identifier::new("qq"))), LetStatement::new(Identifier::new("qq")),
Box::new(LetStatement::new(Identifier::new("foobar"))), LetStatement::new(Identifier::new("foobar")),
], ],
}; };
let lexer = Lexer::new(ip); let lexer = Lexer::new(ip);
let ast_tree = Program::parse(lexer); let ast_tree = Program::parse(lexer);
println!("{:?}", ast_tree);
if ast_tree.statements.len() != 3 { if ast_tree.statements.len() != 3 {
assert_eq!(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()) { 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);
} }
} }
} }