sweet.js宏是否可以定义其他宏?

时间:2014-09-30 20:11:27

标签: sweet.js

我试图定义一个sweet.js宏,它允许更容易地定义其他重复宏,但我在这里发现了一个语法错误:

SyntaxError: [patterns] Ellipses level does not match in the template
11:                 { $($b...)... }

这是产生此语法错误的宏:

macro repeatingMacro{
    rule{
        $a {
            $b...
        } {
            $c...
        }
    } => {
        //the output of this macro should be another macro with repeating patterns
        macro $a {
            rule{
                { $($b...)... }
            } => {
                { $($c...)... }
            }
        }
    }
}

如果正确定义了这个宏,那么它将允许创建其他宏,如下所示:

repeatingMacro cond {
    $a... { $b... }
}
{
    if($a...){
        $b...
    }
}

var x = 1;
var y = 2;
cond {
(x > y) {
      alert(x);
}
(x < y) {
      alert(y)
}
}

This code can be edited online here.

换句话说,是否可以定义一个自动转换此宏的宏:

macro cond {
  rule {
    $x... { $y... }
} => {
  if($x...){
  $y...
}
}
}

...进入这个宏?

macro cond {
  rule {
    { $($x... { $y... })... }
} => {
  $(if($x...){
  $y...
})...
}
}

1 个答案:

答案 0 :(得分:3)

您遇到的直接问题是,如果您需要在宏的模板中发出文字省略号...,则需要通过执行$[...]来转义它。

但是在更高的层次上,您确定需要在这里进行宏定义宏的工作吗? Sweet.js实际上有一个很好的声明性功能,称为macroclass(记录为here),这使得这样的事情非常简单。事实上,cond就是我们使用的例子:

// define the cond_clause pattern class
macroclass cond_clause {
  pattern {
    rule { $check:expr => $body:expr }
  }
}

macro cond {
  rule { $first:cond_clause $rest:cond_clause ... } => {
    // sub-pattern variables in the custom class are 
    // referenced by concatenation
    if ($first$check) {
      $first$body
    } $(else if ($rest$check) {
      $rest$body
    }) ...
  }
}

cond
  x < 3  => console.log("less than 3")
  x == 3 => console.log("3")
  x > 3  => console.log("greater than 3")