add op! macro

This commit is contained in:
강동윤 2018-01-14 13:29:57 +09:00
parent 06d2be43c3
commit 15fde7b5ff
4 changed files with 73 additions and 18 deletions

View File

@ -25,6 +25,7 @@ use swc_atoms::JsWord;
use swc_common::{Span, Spanned};
use swc_macros::AstNode;
mod macros;
mod class;
mod decl;
mod expr;

View File

@ -0,0 +1,54 @@
/// Unary +,- is `op!(unary, "+")`, `op!(unary, "-")`.
/// Binary +,- is `op!(bin, "+")`, `op!(bin, "-")`.
#[macro_export]
macro_rules! op {
(unary, "-") => { $crate::UnaryOp::Minus };
(unary, "+") => { $crate::UnaryOp::Plus };
("!") => { $crate::UnaryOp::Bang };
("~") => { $crate::UnaryOp::Tilde };
("typeof") => { $crate::UnaryOp::TypeOf };
("void") => { $crate::UnaryOp::Void };
("delete") => { $crate::UnaryOp::Delete };
("++") => { $crate::UpdateOp::PlusPlus };
("--") => { $crate::UpdateOp::MinusMinus };
("==") => { $crate::BinaryOp::EqEq };
("!=") => { $crate::BinaryOp::NotEq };
("===") => { $crate::BinaryOp::EqEqEq };
("!==") => { $crate::BinaryOp::NotEqEq };
("<") => { $crate::BinaryOp::Lt };
("<=") => { $crate::BinaryOp::LtEq };
(">") => { $crate::BinaryOp::Gt };
(">=") => { $crate::BinaryOp::GtEq };
("<<") => { $crate::BinaryOp::LShift };
(">>") => { $crate::BinaryOp::RShift };
(">>>") => { $crate::BinaryOp::ZeroFillRShift };
(bin, "+") => { $crate::BinaryOp::Add };
(bin, "-") => { $crate::BinaryOp::Sub };
("*") => { $crate::BinaryOp::Mul };
("/") => { $crate::BinaryOp::Div };
("%") => { $crate::BinaryOp::Mod };
("|") => { $crate::BinaryOp::BitOr };
("^") => { $crate::BinaryOp::BitXor };
("&") => { $crate::BinaryOp::BitAnd };
("||") => { $crate::BinaryOp::LogicalOr };
("&&") => { $crate::BinaryOp::LogicalAnd };
("in") => { $crate::BinaryOp::In };
("instanceof") => { $crate::BinaryOp::InstanceOf };
("**") => { $crate::BinaryOp::Exp };
("=") => { $crate::AssignOp::Assign };
("+=") => { $crate::AssignOp::AddAssign };
("-=") => { $crate::AssignOp::SubAssign };
("*=") => { $crate::AssignOp::MulAssign };
("/=") => { $crate::AssignOp::DivAssign };
("%=") => { $crate::AssignOp::ModAssign };
("<<=") => { $crate::AssignOp::LShiftAssign };
(">>=") => { $crate::AssignOp::RShiftAssign };
(">>>=") => { $crate::AssignOp::ZeroFillRShiftAssign };
("|=") => { $crate::AssignOp::BitOrAssign };
("^=") => { $crate::AssignOp::BitXorAssign };
("&=") => { $crate::AssignOp::BitAndAssign };
("**=") => { $crate::AssignOp::ExpAssign };
}

View File

@ -25,8 +25,8 @@ impl<I: Input> Parser<I> {
None => return Ok(left),
}
} {
&Word(Keyword(In)) if self.ctx.include_in_expr => BinaryOp::In,
&Word(Keyword(InstanceOf)) => BinaryOp::InstanceOf,
&Word(Keyword(In)) if self.ctx.include_in_expr => op!("in"),
&Word(Keyword(InstanceOf)) => op!("instanceof"),
&BinOp(op) => op.into(),
_ => {
return Ok(left);
@ -56,7 +56,7 @@ impl<I: Input> Parser<I> {
match left.node {
// This is invalid syntax.
ExprKind::Unary { .. } if op == BinaryOp::Exp => {
ExprKind::Unary { .. } if op == op!("**") => {
// Correct implementation would be returning Ok(left) and
// returning "unexpected token '**'" on next.
// But it's not useful error message.
@ -70,7 +70,7 @@ impl<I: Input> Parser<I> {
let left_of_right = self.parse_unary_expr()?;
self.parse_bin_op_recursively(
left_of_right,
if op == BinaryOp::Exp {
if op == op!("**") {
// exponential operator is right associative
op.precedence() - 1
} else {
@ -97,9 +97,9 @@ impl<I: Input> Parser<I> {
// Parse update expression
if is!("++") || is!("--") {
let op = if bump!() == PlusPlus {
UpdateOp::PlusPlus
op!("++")
} else {
UpdateOp::MinusMinus
op!("--")
};
let arg = self.parse_unary_expr()?;
@ -116,13 +116,13 @@ impl<I: Input> Parser<I> {
// Parse unary expression
if is_one_of!("delete", "void", "typeof", '+', '-', '~', '!') {
let op = match bump!() {
Word(Keyword(Delete)) => UnaryOp::Delete,
Word(Keyword(Void)) => UnaryOp::Void,
Word(Keyword(TypeOf)) => UnaryOp::TypeOf,
BinOp(Add) => UnaryOp::Plus,
BinOp(Sub) => UnaryOp::Minus,
Tilde => UnaryOp::Tilde,
Bang => UnaryOp::Bang,
Word(Keyword(Delete)) => op!("delete"),
Word(Keyword(Void)) => op!("void"),
Word(Keyword(TypeOf)) => op!("typeof"),
BinOp(Add) => op!(unary, "+"),
BinOp(Sub) => op!(unary, "-"),
Tilde => op!("~"),
Bang => op!("!"),
_ => unreachable!(),
};
let arg = self.parse_unary_expr()?;
@ -152,9 +152,9 @@ impl<I: Input> Parser<I> {
if is_one_of!("++", "--") {
let start = cur_pos!();
let op = if bump!() == PlusPlus {
UpdateOp::PlusPlus
op!("++")
} else {
UpdateOp::MinusMinus
op!("--")
};
return Ok(box Expr {
@ -208,7 +208,7 @@ mod tests {
box Expr {
span: Default::default(),
node: ExprKind::Binary {
op: BinaryOp::Add,
op: op!(bin, "+"),
left: bin("5"),
right: bin("4 * 7"),
},
@ -223,7 +223,7 @@ mod tests {
box Expr {
span: Default::default(),
node: ExprKind::Binary {
op: BinaryOp::Add,
op: op!(bin, "+"),
left: bin("5 + 4"),
right: bin("7"),
},

View File

@ -82,7 +82,7 @@ impl Fold for MyFolder {
let span = get_joinned_span(&i.path);
match &*name {
"vec" | "unreachable" | "tok" | "js_word" => return i,
"vec" | "unreachable" | "tok" | "op" | "js_word" => return i,
"println" | "print" | "format" | "assert" | "assert_eq" | "assert_ne"
| "debug_assert" | "debug_assert_eq" | "debug_assert_ne" => {
let mut args: Punctuated<Expr, token::Comma> = parse_args(i.tts.into());