From bc4fbe4276aa92560c02c1d9e5a12191724794be Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 2 Jan 2016 23:21:47 -0800 Subject: [PATCH] Start implementing definition WIP, doesn't work --- src/evaluator.rs | 3 +++ src/parser.rs | 35 +++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/evaluator.rs b/src/evaluator.rs index e75ae6b..0f2aa35 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -42,6 +42,9 @@ fn reduce_full(ast: AST) -> EvaluatorResult { fn reduce_step(ast: AST) -> EvaluatorResult { use parser::AST::*; match ast { + Definition(name, value) => { + Ok(*value) + }, Block(mut block_nodes) => { match block_nodes.pop() { None => Err(EvaluatorError { err: format!("Block with no statements") }), diff --git a/src/parser.rs b/src/parser.rs index 3e95c9a..656b097 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -10,6 +10,7 @@ pub enum AST { Number(f64), Name(String), Block(Vec), + Definition(String, Box), } impl fmt::Display for AST { @@ -34,7 +35,8 @@ pub type ParseResult = Result; program : block EOF block : (statement sep)+ sep : NEWLINE | SEMICOLON - statement: expr + statement: expr | definition + definition: 'let' NAME '=' expr expr : term ((PLUS|MIMUS) term)* term : factor ((MUL | DIV) factor)* 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 { use tokenizer::Token::*; match self.next() { - Some(Identifier(ref s)) if s == identifier_str => Ok(()), + Some(Identifier(ref s)) => Ok(s.to_string()), Some(next) => { - return parse_error!("Expected identifier `{}` but got {:?}", identifier_str, next); + return parse_error!("Expected identifier but got {:?}", next); } 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 { - 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) } + fn definition(&mut self) -> ParseResult { + 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 { use tokenizer::Token::*; let mut lhs = try!(self.term());