eval-when-compile permits compile-time definitions that can be used from macros

This commit is contained in:
Konrad Hinsen 2013-06-02 17:21:03 +02:00
parent 12abef5ed5
commit 80105d9731
2 changed files with 32 additions and 2 deletions

View File

@ -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),

View File

@ -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))))