2014-09-30 110 views
1

我试图限定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... 
})... 
} 
} 
+0

要回答标题问题:是的。有关示例,请参阅https://gist.github.com/natefaubion/f4be4c8531ef45de87b4。 – Havvy 2014-10-25 19:40:59

回答

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")