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 std::error::Error;
pub trait Node {
fn token_literal(&self) -> &'static str;
fn validate(&self) -> Result<(), Box<dyn Error>>;
pub enum Node {
Statement(StatementType),
Expression,
}
pub(crate) trait Statement: Node {
fn parse(&mut Parser) -> Result<Self, Box<dyn Error>>
#[derive(PartialEq, Debug)]
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
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<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(())
#[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<LetStatement, Box<dyn Error>> {
pub fn parse(parser: &mut Parser) -> Result<LetStatement, Box<dyn Error>> {
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<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;
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<Lexer<'a>>,
current_token: Option<Token>,
}
@ -19,15 +19,13 @@ impl<'a> Parser<'a> {
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 {
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);

View File

@ -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<Box<dyn Statement>>,
statements: Vec<StatementType>,
}
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);
}
}
}