diff --git a/src/lib/syntax/parser.rs b/src/lib/syntax/parser.rs index 756da329fd..207085b9fb 100644 --- a/src/lib/syntax/parser.rs +++ b/src/lib/syntax/parser.rs @@ -6,17 +6,6 @@ use crate::syntax::ast::punc::Punctuator; use crate::syntax::ast::token::{Token, TokenData}; use std::collections::btree_map::BTreeMap; -macro_rules! mk ( - ($this:expr, $def:expr) => { - { - Expr::new($def) - } - }; - ($this:expr, $def:expr, $first:expr) => { - Expr::new($def) - }; -); - /// `ParseError` is an enum which represents errors encounted during parsing an expression #[derive(Debug, Clone)] pub enum ParseError { @@ -54,8 +43,6 @@ impl Parser { exprs.push(result); } - // In the case of `Block` the Positions seem unnecessary - // TODO: refactor this or the `mk!` perhaps? Ok(Expr::new(ExprDef::Block(exprs))) } @@ -97,7 +84,7 @@ impl Parser { match keyword { Keyword::Throw => { let thrown = self.parse()?; - Ok(mk!(self, ExprDef::Throw(Box::new(thrown)))) + Ok(Expr::new(ExprDef::Throw(Box::new(thrown)))) } // vars, lets and consts are similar in parsing structure, we can group them together Keyword::Var | Keyword::Let => { @@ -202,52 +189,48 @@ impl Parser { Ok(Expr::new(ExprDef::ConstDecl(vars))) } - Keyword::Return => Ok(mk!( - self, - ExprDef::Return(Some(Box::new(self.parse()?.clone()))) - )), + Keyword::Return => Ok(Expr::new(ExprDef::Return(Some(Box::new( + self.parse()?.clone(), + ))))), Keyword::New => { let call = self.parse()?; match call.def { ExprDef::Call(ref func, ref args) => { - Ok(mk!(self, ExprDef::Construct(func.clone(), args.clone()))) + Ok(Expr::new(ExprDef::Construct(func.clone(), args.clone()))) } _ => Err(ParseError::ExpectedExpr("constructor", call)), } } - Keyword::TypeOf => Ok(mk!(self, ExprDef::TypeOf(Box::new(self.parse()?)))), + Keyword::TypeOf => Ok(Expr::new(ExprDef::TypeOf(Box::new(self.parse()?)))), Keyword::If => { self.expect_punc(Punctuator::OpenParen, "if block")?; let cond = self.parse()?; self.expect_punc(Punctuator::CloseParen, "if block")?; let expr = self.parse()?; let next = self.get_token(self.pos); - Ok(mk!( - self, - ExprDef::If( - Box::new(cond), - Box::new(expr), - if next.is_ok() - && next.expect("Could not get next value").data - == TokenData::Keyword(Keyword::Else) - { - self.pos += 1; - Some(Box::new(self.parse()?)) - } else { - None - } - ) - )) + Ok(Expr::new(ExprDef::If( + Box::new(cond), + Box::new(expr), + if next.is_ok() + && next.expect("Could not get next value").data + == TokenData::Keyword(Keyword::Else) + { + self.pos += 1; + Some(Box::new(self.parse()?)) + } else { + None + }, + ))) } Keyword::While => { self.expect_punc(Punctuator::OpenParen, "while condition")?; let cond = self.parse()?; self.expect_punc(Punctuator::CloseParen, "while condition")?; let expr = self.parse()?; - Ok(mk!( - self, - ExprDef::WhileLoop(Box::new(cond), Box::new(expr)) - )) + Ok(Expr::new(ExprDef::WhileLoop( + Box::new(cond), + Box::new(expr), + ))) } Keyword::Switch => { self.expect_punc(Punctuator::OpenParen, "switch value")?; @@ -285,7 +268,7 @@ impl Parser { _ => block.push(self.parse()?), } } - default = Some(mk!(self, ExprDef::Block(block))); + default = Some(Expr::new(ExprDef::Block(block))); } TokenData::Punctuator(Punctuator::CloseBlock) => break, _ => { @@ -302,17 +285,14 @@ impl Parser { } } self.expect_punc(Punctuator::CloseBlock, "switch block")?; - Ok(mk!( - self, - ExprDef::Switch( - Box::new(value.expect("Could not get value")), - cases, - match default { - Some(v) => Some(Box::new(v)), - None => None, - } - ) - )) + Ok(Expr::new(ExprDef::Switch( + Box::new(value.expect("Could not get value")), + cases, + match default { + Some(v) => Some(Box::new(v)), + None => None, + }, + ))) } Keyword::Function => { // function [identifier] () { etc } @@ -334,10 +314,11 @@ impl Parser { // Now we have the function identifier we should have an open paren for arguments ( ) let args = self.parse_function_parameters()?; let block = self.parse()?; - Ok(mk!( - self, - ExprDef::FunctionDecl(name, args, Box::new(block)) - )) + Ok(Expr::new(ExprDef::FunctionDecl( + name, + args, + Box::new(block), + ))) } _ => Err(ParseError::UnexpectedKeyword(keyword)), } @@ -357,16 +338,16 @@ impl Parser { self.parse()? } TokenData::Punctuator(Punctuator::Semicolon) | TokenData::Comment(_) => { - mk!(self, ExprDef::Const(Const::Undefined)) + Expr::new(ExprDef::Const(Const::Undefined)) } - TokenData::NumericLiteral(num) => mk!(self, ExprDef::Const(Const::Num(num))), - TokenData::NullLiteral => mk!(self, ExprDef::Const(Const::Null)), - TokenData::StringLiteral(text) => mk!(self, ExprDef::Const(Const::String(text))), - TokenData::BooleanLiteral(val) => mk!(self, ExprDef::Const(Const::Bool(val))), + TokenData::NumericLiteral(num) => Expr::new(ExprDef::Const(Const::Num(num))), + TokenData::NullLiteral => Expr::new(ExprDef::Const(Const::Null)), + TokenData::StringLiteral(text) => Expr::new(ExprDef::Const(Const::String(text))), + TokenData::BooleanLiteral(val) => Expr::new(ExprDef::Const(Const::Bool(val))), TokenData::Identifier(ref s) if s == "undefined" => { - mk!(self, ExprDef::Const(Const::Undefined)) + Expr::new(ExprDef::Const(Const::Undefined)) } - TokenData::Identifier(s) => mk!(self, ExprDef::Local(s)), + TokenData::Identifier(s) => Expr::new(ExprDef::Local(s)), TokenData::Keyword(keyword) => self.parse_struct(keyword)?, TokenData::RegularExpressionLiteral(body, flags) => Expr::new(ExprDef::Construct( Box::new(Expr::new(ExprDef::Local("RegExp".to_string()))), @@ -383,11 +364,7 @@ impl Parser { { self.pos += 2; let expr = self.parse()?; - mk!( - self, - ExprDef::ArrowFunctionDecl(Vec::new(), Box::new(expr)), - token - ) + Expr::new(ExprDef::ArrowFunctionDecl(Vec::new(), Box::new(expr))) } _ => { let next = self.parse()?; @@ -449,11 +426,7 @@ impl Parser { "arrow function", )?; let expr = self.parse()?; - mk!( - self, - ExprDef::ArrowFunctionDecl(args, Box::new(expr)), - token - ) + Expr::new(ExprDef::ArrowFunctionDecl(args, Box::new(expr))) } _ => { return Err(ParseError::Expected( @@ -479,7 +452,7 @@ impl Parser { TokenData::Punctuator(Punctuator::Comma) => { if !saw_expr_last { // An elision indicates that a space is saved in the array - array.push(mk!(self, ExprDef::Const(Const::Undefined))) + array.push(Expr::new(ExprDef::Const(Const::Undefined))) } saw_expr_last = false; self.pos += 1; @@ -502,14 +475,14 @@ impl Parser { } } } - mk!(self, ExprDef::ArrayDecl(array), token) + Expr::new(ExprDef::ArrayDecl(array)) } TokenData::Punctuator(Punctuator::OpenBlock) if self.get_token(self.pos)?.data == TokenData::Punctuator(Punctuator::CloseBlock) => { self.pos += 1; - mk!(self, ExprDef::ObjectDecl(Box::new(BTreeMap::new())), token) + Expr::new(ExprDef::ObjectDecl(Box::new(BTreeMap::new()))) } TokenData::Punctuator(Punctuator::OpenBlock) if self.get_token(self.pos.wrapping_add(1))?.data @@ -546,11 +519,7 @@ impl Parser { self.pos += 1; // { let expr = self.parse()?; self.pos += 1; - mk!( - self, - ExprDef::FunctionDecl(None, args, Box::new(expr)), - token - ) + Expr::new(ExprDef::FunctionDecl(None, args, Box::new(expr))) } _ => { return Err(ParseError::Expected( @@ -566,7 +535,7 @@ impl Parser { map.insert(name, value); self.pos += 1; } - mk!(self, ExprDef::ObjectDecl(map), token) + Expr::new(ExprDef::ObjectDecl(map)) } TokenData::Punctuator(Punctuator::OpenBlock) => { let mut exprs = Vec::new(); @@ -580,39 +549,35 @@ impl Parser { } } self.pos += 1; - mk!(self, ExprDef::Block(exprs), token) + Expr::new(ExprDef::Block(exprs)) } // Empty Block TokenData::Punctuator(Punctuator::CloseBlock) if self.get_token(self.pos.wrapping_sub(2))?.data == TokenData::Punctuator(Punctuator::OpenBlock) => { - mk!(self, ExprDef::Block(vec!()), token) - } - TokenData::Punctuator(Punctuator::Sub) => mk!( - self, - ExprDef::UnaryOp(UnaryOp::Minus, Box::new(self.parse()?)) - ), - TokenData::Punctuator(Punctuator::Add) => mk!( - self, - ExprDef::UnaryOp(UnaryOp::Plus, Box::new(self.parse()?)) - ), - TokenData::Punctuator(Punctuator::Not) => mk!( - self, - ExprDef::UnaryOp(UnaryOp::Not, Box::new(self.parse()?)) - ), - TokenData::Punctuator(Punctuator::Neg) => mk!( - self, - ExprDef::UnaryOp(UnaryOp::Tilde, Box::new(self.parse()?)) - ), - TokenData::Punctuator(Punctuator::Inc) => mk!( - self, - ExprDef::UnaryOp(UnaryOp::IncrementPre, Box::new(self.parse()?)) - ), - TokenData::Punctuator(Punctuator::Dec) => mk!( - self, - ExprDef::UnaryOp(UnaryOp::DecrementPre, Box::new(self.parse()?)) - ), + Expr::new(ExprDef::Block(vec![])) + } + TokenData::Punctuator(Punctuator::Sub) => { + Expr::new(ExprDef::UnaryOp(UnaryOp::Minus, Box::new(self.parse()?))) + } + TokenData::Punctuator(Punctuator::Add) => { + Expr::new(ExprDef::UnaryOp(UnaryOp::Plus, Box::new(self.parse()?))) + } + TokenData::Punctuator(Punctuator::Not) => { + Expr::new(ExprDef::UnaryOp(UnaryOp::Not, Box::new(self.parse()?))) + } + TokenData::Punctuator(Punctuator::Neg) => { + Expr::new(ExprDef::UnaryOp(UnaryOp::Tilde, Box::new(self.parse()?))) + } + TokenData::Punctuator(Punctuator::Inc) => Expr::new(ExprDef::UnaryOp( + UnaryOp::IncrementPre, + Box::new(self.parse()?), + )), + TokenData::Punctuator(Punctuator::Dec) => Expr::new(ExprDef::UnaryOp( + UnaryOp::DecrementPre, + Box::new(self.parse()?), + )), _ => return Err(ParseError::Expected(Vec::new(), token.clone(), "script")), }; if self.pos >= self.tokens.len() { @@ -632,7 +597,7 @@ impl Parser { let tk = self.get_token(self.pos)?; match tk.data { TokenData::Identifier(ref s) => { - result = mk!(self, ExprDef::GetConstField(Box::new(expr), s.to_string())) + result = Expr::new(ExprDef::GetConstField(Box::new(expr), s.to_string())) } _ => { return Err(ParseError::Expected( @@ -676,17 +641,18 @@ impl Parser { expect_comma_or_end = true; } } - result = mk!(self, ExprDef::Call(Box::new(expr), args)); + result = Expr::new(ExprDef::Call(Box::new(expr), args)); } TokenData::Punctuator(Punctuator::Question) => { self.pos += 1; let if_e = self.parse()?; self.expect(TokenData::Punctuator(Punctuator::Colon), "if expression")?; let else_e = self.parse()?; - result = mk!( - self, - ExprDef::If(Box::new(expr), Box::new(if_e), Some(Box::new(else_e))) - ); + result = Expr::new(ExprDef::If( + Box::new(expr), + Box::new(if_e), + Some(Box::new(else_e)), + )); } TokenData::Punctuator(Punctuator::OpenBracket) => { self.pos += 1; @@ -695,7 +661,7 @@ impl Parser { TokenData::Punctuator(Punctuator::CloseBracket), "array index", )?; - result = mk!(self, ExprDef::GetField(Box::new(expr), Box::new(index))); + result = Expr::new(ExprDef::GetField(Box::new(expr), Box::new(index))); } TokenData::Punctuator(Punctuator::Semicolon) | TokenData::Comment(_) => { self.pos += 1; @@ -703,7 +669,7 @@ impl Parser { TokenData::Punctuator(Punctuator::Assign) => { self.pos += 1; let next = self.parse()?; - result = mk!(self, ExprDef::Assign(Box::new(expr), Box::new(next))); + result = Expr::new(ExprDef::Assign(Box::new(expr), Box::new(next))); } TokenData::Punctuator(Punctuator::AssignAdd) => { result = self.binop(BinOp::Assign(AssignOp::Add), expr)? @@ -746,7 +712,7 @@ impl Parser { _ => return Err(ParseError::ExpectedExpr("identifier", result)), } let next = self.parse()?; - result = mk!(self, ExprDef::ArrowFunctionDecl(args, Box::new(next))); + result = Expr::new(ExprDef::ArrowFunctionDecl(args, Box::new(next))); } TokenData::Punctuator(Punctuator::Add) => { result = self.binop(BinOp::Num(NumOp::Add), expr)? @@ -812,16 +778,16 @@ impl Parser { result = self.binop(BinOp::Comp(CompOp::GreaterThanOrEqual), expr)? } TokenData::Punctuator(Punctuator::Inc) => { - result = mk!( - self, - ExprDef::UnaryOp(UnaryOp::IncrementPost, Box::new(self.parse()?)) - ) + result = Expr::new(ExprDef::UnaryOp( + UnaryOp::IncrementPost, + Box::new(self.parse()?), + )) } TokenData::Punctuator(Punctuator::Dec) => { - result = mk!( - self, - ExprDef::UnaryOp(UnaryOp::DecrementPost, Box::new(self.parse()?)) - ) + result = Expr::new(ExprDef::UnaryOp( + UnaryOp::DecrementPost, + Box::new(self.parse()?), + )) } _ => carry_on = false, }; @@ -840,25 +806,20 @@ impl Parser { ExprDef::BinOp(ref op2, ref a, ref b) => { let other_precedence = op2.get_precedence(); if precedence < other_precedence || (precedence == other_precedence && !assoc) { - mk!( - self, - ExprDef::BinOp( - op2.clone(), - b.clone(), - Box::new(mk!( - self, - ExprDef::BinOp(op.clone(), Box::new(orig), a.clone()) - )) - ) - ) + Expr::new(ExprDef::BinOp( + op2.clone(), + b.clone(), + Box::new(Expr::new(ExprDef::BinOp( + op.clone(), + Box::new(orig), + a.clone(), + ))), + )) } else { - mk!( - self, - ExprDef::BinOp(op, Box::new(orig), Box::new(next.clone())) - ) + Expr::new(ExprDef::BinOp(op, Box::new(orig), Box::new(next.clone()))) } } - _ => mk!(self, ExprDef::BinOp(op, Box::new(orig), Box::new(next))), + _ => Expr::new(ExprDef::BinOp(op, Box::new(orig), Box::new(next))), }) }