diff --git a/hy/compiler.py b/hy/compiler.py index 89debd9..9fba8cc 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -50,6 +50,16 @@ import sys from collections import defaultdict +_compile_time_ns = {} + +def compile_time_ns(module_name): + ns = _compile_time_ns.get(module_name) + if ns is None: + ns = {'hy': hy, '__name__': module_name} + _compile_time_ns[module_name] = ns + return ns + + class HyCompileError(HyError): def __init__(self, exception, traceback=None): self.exception = exception @@ -1645,7 +1655,7 @@ class HyASTCompiler(object): # We must provide __name__ in the namespace to make the Python # compiler set the __module__ attribute of the macro function. hy.importer.hy_eval(new_expression, - {'hy': hy, '__name__': self.module_name}, + compile_time_ns(self.module_name), self.module_name) # We really want to have a `hy` import to get hy.macro in @@ -1654,6 +1664,15 @@ class HyASTCompiler(object): return ret + @builds("eval_when_compile") + def compile_eval_when_compile(self, expression): + expression[0] = HySymbol("progn") + hy.importer.hy_eval(expression, + compile_time_ns(self.module_name), + self.module_name) + expression.pop(0) + return self._compile_branch(expression) + @builds(HyInteger) def compile_integer(self, number): return ast.Num(n=int(number), diff --git a/tests/native_tests/native_macros.hy b/tests/native_tests/native_macros.hy index 276685f..01b301b 100644 --- a/tests/native_tests/native_macros.hy +++ b/tests/native_tests/native_macros.hy @@ -9,7 +9,6 @@ (rev (.append x 1) (.append x 2) (.append x 3)) (assert (= x [3 2 1]))) - ; Macros returning constants (defmacro an-int [] 42) @@ -34,3 +33,15 @@ (defmacro a-dict [] {1 2}) (assert (= (a-dict) {1 2})) + +; A macro calling a previously defined function +(eval-when-compile + (defn foo [x y] + (quasiquote (+ (unquote x) (unquote y))))) + +(defmacro bar [x y] + (foo x y)) + +(defn test-fn-calling-macro [] + "NATIVE: test macro calling a plain function" + (assert (= 3 (bar 1 2))))