From 80bc7ec089ef4f858e841fa9ece3a451ad2115c2 Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 16 Jan 2016 20:23:43 -0800 Subject: [PATCH] Proper call expression parsing --- src/parser.rs | 67 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 95954fe..381bce1 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -10,9 +10,10 @@ use tokenizer::{Token, Kw, Op}; exprlist := Expression (Comma Expression)* | e expression := primary_expression (op primary_expression)* - primary_expression := Variable | Number | String | call_expr | paren_expr + primary_expression := Number | String | identifier_expr | paren_expr + identifier_expr := call_expression | Variable paren_expr := LParen expression RParen - call_expr := identifier LParen exprlist RParen + call_expr := Identifier LParen exprlist RParen op := '+', '-', etc. */ @@ -101,6 +102,16 @@ macro_rules! expect { } } +macro_rules! expect_identifier { + ($self_:expr) => { + match $self_.peek() { + Some(Identifier(s)) => {$self_.next(); s}, + _ => return ParseError::result_from_str("Expected Identifier") + } + } +} + + fn is_delimiter(token: &Token) -> bool { use tokenizer::Token::*; match *token { @@ -155,10 +166,7 @@ impl Parser { fn prototype(&mut self) -> ParseResult { use tokenizer::Token::*; - let name: String = match self.peek() { - Some(Identifier(name)) => {self.next(); name}, - _ => return ParseError::result_from_str("Expected identifier") - }; + let name: String = expect_identifier!(self); expect!(self, LParen, "Expected '('"); let mut args: Vec = try!(self.identlist()); expect!(self, RParen, "Expected ')'"); @@ -187,6 +195,24 @@ impl Parser { Ok(args) } + fn exprlist(&mut self) -> ParseResult> { + use tokenizer::Token::*; + let mut args: Vec = Vec::new(); + loop { + if let Some(RParen) = self.peek() { + break; + } + let exp = try!(self.expression()); + args.push(exp); + if let Some(Comma) = self.peek() { + self.next(); + } else { + break; + } + } + Ok(args) + } + fn body(&mut self) -> ParseResult> { use tokenizer::Token::*; let mut exprs = Vec::new(); @@ -239,13 +265,7 @@ impl Parser { let expr = match self.peek() { Some(NumLiteral(n)) => { self.next(); Expression::Number(n) }, Some(StrLiteral(s)) => { self.next(); Expression::StringLiteral(s) }, - Some(Identifier(var)) => { - self.next(); - match self.peek() { - Some(Token::LParen) => try!(self.call_expr()), - _ => Expression::Variable(var) - } - }, + Some(Identifier(var)) => { try!(self.identifier_expr()) }, Some(Token::LParen) => { try!(self.paren_expr()) } Some(x) => return ParseError::result_from_str("Expected primary expression"), None => return ParseError::result_from_str("Expected primary expression received EoI") @@ -254,9 +274,26 @@ impl Parser { Ok(expr) } - fn call_expr(&mut self) -> ParseResult { + fn identifier_expr(&mut self) -> ParseResult { use tokenizer::Token::*; - unimplemented!() + let name = expect_identifier!(self); + let expr = match self.peek() { + Some(LParen) => { + let args = try!(self.call_expr()); + Expression::Call(name, args) + }, + __ => Expression::Variable(name) + }; + + Ok(expr) + } + + fn call_expr(&mut self) -> ParseResult> { + use tokenizer::Token::*; + expect!(self, LParen, "Expected '('"); + let mut args: Vec = try!(self.exprlist()); + expect!(self, RParen, "Expected ')'"); + Ok(args) } fn paren_expr(&mut self) -> ParseResult {