Made error! macro more programtic

TODO implement Display on Token so we're not just displaying the debug
name of the token enum variants
This commit is contained in:
greg 2016-01-17 00:59:31 -08:00
parent 4f96abd7d9
commit f53c14535b

View File

@ -94,10 +94,18 @@ impl Parser {
} }
macro_rules! expect { macro_rules! expect {
($self_:expr, $token:pat, $error:expr) => { ($self_:expr, $token:pat) => {
match $self_.peek() { match $self_.peek() {
Some($token) => {$self_.next();}, Some($token) => {$self_.next();},
_ => return ParseError::result_from_str($error) Some(x) => {
let err = format!("Expected `{:?}` but got `{:?}`", stringify!($token), x); //TODO implement Display for token
return ParseError::result_from_str(&err)
},
None => {
let err = format!("Expected `{:?}` but got end of input", stringify!($token));
return ParseError::result_from_str(&err) //TODO make this not require 2 stringifications
}
} }
} }
} }
@ -152,19 +160,19 @@ impl Parser {
fn declaration(&mut self) -> ParseResult<ASTNode> { fn declaration(&mut self) -> ParseResult<ASTNode> {
use tokenizer::Token::*; use tokenizer::Token::*;
expect!(self, Keyword(Kw::Fn), "Expected 'fn'"); expect!(self, Keyword(Kw::Fn));
let prototype = try!(self.prototype()); let prototype = try!(self.prototype());
let body: Vec<Expression> = try!(self.body()); let body: Vec<Expression> = try!(self.body());
expect!(self, Keyword(Kw::End), "Expected 'end'"); expect!(self, Keyword(Kw::End));
Ok(ASTNode::FuncNode(Function { prototype: prototype, body: body } )) Ok(ASTNode::FuncNode(Function { prototype: prototype, body: body } ))
} }
fn prototype(&mut self) -> ParseResult<Prototype> { fn prototype(&mut self) -> ParseResult<Prototype> {
use tokenizer::Token::*; use tokenizer::Token::*;
let name: String = expect_identifier!(self); let name: String = expect_identifier!(self);
expect!(self, LParen, "Expected '('"); expect!(self, LParen);
let args: Vec<String> = try!(self.identlist()); let args: Vec<String> = try!(self.identlist());
expect!(self, RParen, "Expected ')'"); expect!(self, RParen);
Ok(Prototype {name: name, args: args}) Ok(Prototype {name: name, args: args})
} }
@ -282,16 +290,16 @@ impl Parser {
fn call_expr(&mut self) -> ParseResult<Vec<Expression>> { fn call_expr(&mut self) -> ParseResult<Vec<Expression>> {
use tokenizer::Token::*; use tokenizer::Token::*;
expect!(self, LParen, "Expected '('"); expect!(self, LParen);
let args: Vec<Expression> = try!(self.exprlist()); let args: Vec<Expression> = try!(self.exprlist());
expect!(self, RParen, "Expected ')'"); expect!(self, RParen);
Ok(args) Ok(args)
} }
fn paren_expr(&mut self) -> ParseResult<Expression> { fn paren_expr(&mut self) -> ParseResult<Expression> {
expect!(self, Token::LParen, "Expected LParen"); expect!(self, Token::LParen);
let expr = try!(self.expression()); let expr = try!(self.expression());
expect!(self, Token::RParen, "Expected LParen"); expect!(self, Token::RParen);
Ok(expr) Ok(expr)
} }
} }