Reputation: 1320
Suppose there's a function somewhere called m
, which is invoked like this
//foo.js
m("foo")
I have a sweet.js macro that defines a macro called m
which is meant to take foo.js and expand m
(basically to run the function at compile time)
In some cases I want to not expand m
, because unlike macros, functions can be passed around as first class citizens
doSomething(m) //don't want to expand this as a macro
If I don't have a case that covers this scenario in the macro, sweet.js complains, so I need to have a catch-all rule that just expands to the same symbol.
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} }
}
How do I make the m
macro expand to the m
function, given that other cases of the macro do need to recursively expand m
as a macro?
Upvotes: 0
Views: 99
Reputation: 5337
You'll want to let
bind the macro:
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} }
}
Edit:
Sorry, didn't read your question fully the first time :)
Here's a better solution, you just need to split it out into two different macros, one that can do the actual recursive work and another to handle the non-recursive base case:
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)
Upvotes: 1