有可能将sweet.js宏`m`扩展为符号`m`吗?

时间:2014-10-30 14:32:26

标签: sweet.js

假设有一个名为m的函数,就像这样调用

//foo.js
m("foo")

我有一个sweet.js宏,它定义了一个名为m的宏,它用于获取foo.js并展开m(基本上是为了在编译时运行该函数)

在某些情况下,我想不扩展m,因为与宏不同,函数可以作为一等公民传播

doSomething(m) //don't want to expand this as a macro

如果我没有在宏中覆盖这种情况的情况,sweet.js会抱怨,所以我需要一个只能扩展到相同符号的全能规则。

macro m {
  //simplification to demonstrate a case that recursively expand macro
  case { _ ( $foo, $bar) } => { return #{m($foo)} }
  //does syntax unwrapping in real case
  case { _ ( $foo ) } => { return #{$foo} }

  //**this tries to recursively expand `m`, which is not what I want**
  case { _ } => { return #{m} } 
}

如果宏的其他情况需要递归地扩展m作为宏,如何将m宏扩展为m函数?

1 个答案:

答案 0 :(得分:1)

您需要let绑定宏:

let m = macro {
  case { _ ( $foo, $bar) } => { return #{$foo} }
  case { _ ( $foo ) } => { return #{$foo} }

  // `m` is bound to the surrounding scope, not the macro
  case { _ } => { return #{m} }
}

修改

抱歉,第一次没有完全阅读你的问题:)

这是一个更好的解决方案,您只需将其拆分为两个不同的宏,一个可以执行实际的递归工作,另一个可以处理非递归基本情况:

function m() {}
macro m_impl {
  case { _ ( $foo, $bar) } => { return #{m_impl($foo)} }
  case { _ ( $foo ) } => { return #{$foo} }
}

let m = macro {
  case { _ ($foo, $bar) } => { return #{m_impl($foo, $bar)} } 
  case { _ } => { return #{m} } 
}

m (100, 200);
doSomething(m)