Add block parsing
Right now evaluating a block reduces it to just the last AST in it, will fix later with environments
This commit is contained in:
parent
dd2b4893a4
commit
fc11ee753d
@ -42,6 +42,12 @@ fn reduce_full(ast: AST) -> EvaluatorResult<AST> {
|
||||
fn reduce_step(ast: AST) -> EvaluatorResult<AST> {
|
||||
use parser::AST::*;
|
||||
match ast {
|
||||
Block(mut block_nodes) => {
|
||||
match block_nodes.pop() {
|
||||
None => Err(EvaluatorError { err: format!("Block with no statements") }),
|
||||
Some(node) => reduce_full(node),
|
||||
}
|
||||
},
|
||||
BinOp(left, op, right) => {
|
||||
let left = try!(reduce_full(*left));
|
||||
let op = try!(reduce_full(*op));
|
||||
|
@ -9,6 +9,7 @@ pub enum AST {
|
||||
BinOp(Box<AST>, Box<AST>, Box<AST>),
|
||||
Number(f64),
|
||||
Name(String),
|
||||
Block(Vec<AST>),
|
||||
}
|
||||
|
||||
impl fmt::Display for AST {
|
||||
@ -30,6 +31,10 @@ pub type ParseResult<T> = Result<T, ParseError>;
|
||||
|
||||
/* grammar
|
||||
|
||||
program : block EOF
|
||||
block : (statement sep)+
|
||||
sep : NEWLINE | SEMICOLON
|
||||
statement: expr
|
||||
expr : term ((PLUS|MIMUS) term)*
|
||||
term : factor ((MUL | DIV) factor)*
|
||||
factor : NUM | LPAREN expr RPAREN
|
||||
@ -98,12 +103,36 @@ impl Parser {
|
||||
}
|
||||
|
||||
fn parse(&mut self) -> ParseResult<AST> {
|
||||
let r = self.expr();
|
||||
try!(self.expect(Token::Newline));
|
||||
let r = self.block();
|
||||
try!(self.expect(Token::EOF));
|
||||
r
|
||||
}
|
||||
|
||||
fn block(&mut self) -> ParseResult<AST> {
|
||||
use tokenizer::Token::*;
|
||||
let mut block_nodes: Vec<AST> = Vec::new();
|
||||
loop {
|
||||
let s: AST = try!(self.statement());
|
||||
block_nodes.push(s);
|
||||
match self.lookahead() {
|
||||
Some(Semicolon) | Some(Newline) => {
|
||||
self.next();
|
||||
if let Some(EOF) = self.lookahead() {
|
||||
break
|
||||
}
|
||||
},
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
|
||||
Ok(AST::Block(block_nodes))
|
||||
}
|
||||
|
||||
fn statement(&mut self) -> ParseResult<AST> {
|
||||
let r = try!(self.expr());
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
fn expr(&mut self) -> ParseResult<AST> {
|
||||
use tokenizer::Token::*;
|
||||
let mut lhs = try!(self.term());
|
||||
@ -157,7 +186,7 @@ impl Parser {
|
||||
self.next();
|
||||
Ok(AST::Number(n))
|
||||
},
|
||||
_ => parse_error!("Expected LParen or NumLiteral")
|
||||
x => parse_error!("Expected LParen or NumLiteral, got {:?}", x )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user