2014-10-30 2 views
0

Пусть есть функция где-то называется m, которая вызывается как этотМожно ли сделать макрос sweet.js `m` расширением символа` 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 жалуется, поэтому мне нужно иметь правило catch-all, которое просто расширяется до того же символа.

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

Вы хотите 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} } 
} 

Edit:

К сожалению, не читал Ваш вопрос полностью в первый раз :)

Вот лучше решение, вам просто нужно разделить его на два разных макроса: один, который может выполнять фактическую рекурсивную работу, а другой - для обработки нерекурсивного базового футляра:

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) 
+0

Это не работает, когда некоторым правилам case необходимо развернуть m в качестве макроса (как в первом случае) – LeoHorie

+0

А, извините, слишком быстро прочитайте ваш вопрос. Отредактировано в том, что, надеюсь, лучшее решение для вас. – timdisney

+0

Aha, идеальное решение! Благодаря! – LeoHorie