假设有一个名为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
函数?
答案 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)