2012-01-11 3 views
2

Как написано в другом посте, я пишу компилятор Shen в Clojure. Для этого мне нужен макрос/функция, которая получает символ как параметр, и если функция Shen привязана к ней, она возвращает функцию, и если символ определен как макрос Clojure, он должен вернуть макрос, поэтому ((function or) true false) должен дать тот же результат как (or true false).Возврат макроса из макроса в Clojure

Мой макрос в настоящее время выглядит следующим образом:

(defmacro kl/function [x] 
(cl/let [fn (symbol (cl/str (name x) "__fnPoF__"))] 
    (if (function? fn) `(eval ~fn) `(quote ~x)))) 

Постфиксное «__fnPoF__» есть из-за двойное пространство имен в Shen. (Значение и функции могут быть назначены одному и тому же символу.)

Моя проблема сейчас в том, что ((function or) true false) оценивается как ложное, так как он оценивает, как ('or true false), но если я оставить из «цитата» (x вместо `(quote ~x) я получаю следующее исключение:

kl=> (function *) 
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'kl/*, compiling:(NO_SOURCE_PATH:8) 

ли кто-то есть идея, как решить эту проблему

ответ

3

вы не можете «вернуться» макрос, поскольку макросы не имеют значения, но вы можете сделать (функция или) расширения?. к символу или, тогда обычные механизмы макроэкспозиции/оценки Clojure w плохо делай то, что хочешь. Таким образом, в то время как я не знаю, как работает Shen, похоже, простое изменение будет:

(defmacro kl/function [x] 
    (cl/let [fn (symbol (cl/str (name x) "__fnPoF__"))] 
    (if (function? fn) 
     `(eval ~fn) 
     x))) 

Как и в сторону, что eval ударяет меня как бедствия ожидания произойдет. Я сильно сомневаюсь, что для ваших целей необходимо eval.

+0

Как я писал выше, если я заменю '' (quote x) 'на' x', я получаю 'CompilerException java.lang.RuntimeException: не могу взять значение макроса: # 'kl/*, compiling :(NO_SOURCE_PATH: 8) ' –

+0

@NameLess Вау, это довольно интересно. Похоже, макроэкрандер видит, что '((function when) ...)' не имеет макроса в качестве своей первой подформы, поэтому он отказывается от макрорасширения. Затем, когда внутренняя вещь расширяется до 'когда', она не возвращается. Я не уверен, как вы с этим справитесь. – amalloy

Смежные вопросы