Start implementing definition

WIP, doesn't work
This commit is contained in:
greg 2016-01-02 23:21:47 -08:00
parent fc11ee753d
commit bc4fbe4276
2 changed files with 32 additions and 6 deletions

View File

@ -42,6 +42,9 @@ fn reduce_full(ast: AST) -> EvaluatorResult<AST> {
fn reduce_step(ast: AST) -> EvaluatorResult<AST> { fn reduce_step(ast: AST) -> EvaluatorResult<AST> {
use parser::AST::*; use parser::AST::*;
match ast { match ast {
Definition(name, value) => {
Ok(*value)
},
Block(mut block_nodes) => { Block(mut block_nodes) => {
match block_nodes.pop() { match block_nodes.pop() {
None => Err(EvaluatorError { err: format!("Block with no statements") }), None => Err(EvaluatorError { err: format!("Block with no statements") }),

View File

@ -10,6 +10,7 @@ pub enum AST {
Number(f64), Number(f64),
Name(String), Name(String),
Block(Vec<AST>), Block(Vec<AST>),
Definition(String, Box<AST>),
} }
impl fmt::Display for AST { impl fmt::Display for AST {
@ -34,7 +35,8 @@ pub type ParseResult<T> = Result<T, ParseError>;
program : block EOF program : block EOF
block : (statement sep)+ block : (statement sep)+
sep : NEWLINE | SEMICOLON sep : NEWLINE | SEMICOLON
statement: expr statement: expr | definition
definition: 'let' NAME '=' expr
expr : term ((PLUS|MIMUS) term)* expr : term ((PLUS|MIMUS) term)*
term : factor ((MUL | DIV) factor)* term : factor ((MUL | DIV) factor)*
factor : NUM | LPAREN expr RPAREN factor : NUM | LPAREN expr RPAREN
@ -76,15 +78,16 @@ impl Parser {
} }
} }
fn expect_identifier(&mut self, identifier_str: &str) -> ParseResult<()> {
fn expect_identifier(&mut self) -> ParseResult<String> {
use tokenizer::Token::*; use tokenizer::Token::*;
match self.next() { match self.next() {
Some(Identifier(ref s)) if s == identifier_str => Ok(()), Some(Identifier(ref s)) => Ok(s.to_string()),
Some(next) => { Some(next) => {
return parse_error!("Expected identifier `{}` but got {:?}", identifier_str, next); return parse_error!("Expected identifier but got {:?}", next);
} }
None => { None => {
return parse_error!("Expected identifier `{}` but got end of input", identifier_str); return parse_error!("Expected identifier but got end of input");
} }
} }
} }
@ -129,10 +132,30 @@ impl Parser {
} }
fn statement(&mut self) -> ParseResult<AST> { fn statement(&mut self) -> ParseResult<AST> {
let r = try!(self.expr()); use tokenizer::Token::*;
use tokenizer::Kw;
let r = match self.lookahead() {
Some(Keyword(Kw::Let)) => try!(self.definition()),
_ => try!(self.expr())
};
Ok(r) Ok(r)
} }
fn definition(&mut self) -> ParseResult<AST> {
use tokenizer::Token::*;
use tokenizer::Kw;
try!(self.expect(Keyword(Kw::Let)));
let name = try!(self.expect_identifier());
match self.lookahead() {
Some(Identifier(ref s)) if s == "=" => { self.next(); },
_ => return parse_error!("Expected `=`"),
}
let expr = try!(self.expr());
Ok(AST::Definition(name, Box::new(expr)))
}
fn expr(&mut self) -> ParseResult<AST> { fn expr(&mut self) -> ParseResult<AST> {
use tokenizer::Token::*; use tokenizer::Token::*;
let mut lhs = try!(self.term()); let mut lhs = try!(self.term());