Refactored again, let statement parser, Except for the expression parser is complete
This commit is contained in:
parent
20a4907153
commit
5bd49acb67
|
@ -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 {}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user