eval-when-compile permits compile-time definitions that can be used from macros
This commit is contained in:
parent
12abef5ed5
commit
80105d9731
@ -50,6 +50,16 @@ import sys
|
|||||||
from collections import defaultdict
|
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):
|
class HyCompileError(HyError):
|
||||||
def __init__(self, exception, traceback=None):
|
def __init__(self, exception, traceback=None):
|
||||||
self.exception = exception
|
self.exception = exception
|
||||||
@ -1645,7 +1655,7 @@ class HyASTCompiler(object):
|
|||||||
# We must provide __name__ in the namespace to make the Python
|
# We must provide __name__ in the namespace to make the Python
|
||||||
# compiler set the __module__ attribute of the macro function.
|
# compiler set the __module__ attribute of the macro function.
|
||||||
hy.importer.hy_eval(new_expression,
|
hy.importer.hy_eval(new_expression,
|
||||||
{'hy': hy, '__name__': self.module_name},
|
compile_time_ns(self.module_name),
|
||||||
self.module_name)
|
self.module_name)
|
||||||
|
|
||||||
# We really want to have a `hy` import to get hy.macro in
|
# We really want to have a `hy` import to get hy.macro in
|
||||||
@ -1654,6 +1664,15 @@ class HyASTCompiler(object):
|
|||||||
|
|
||||||
return ret
|
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)
|
@builds(HyInteger)
|
||||||
def compile_integer(self, number):
|
def compile_integer(self, number):
|
||||||
return ast.Num(n=int(number),
|
return ast.Num(n=int(number),
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
(rev (.append x 1) (.append x 2) (.append x 3))
|
(rev (.append x 1) (.append x 2) (.append x 3))
|
||||||
(assert (= x [3 2 1])))
|
(assert (= x [3 2 1])))
|
||||||
|
|
||||||
|
|
||||||
; Macros returning constants
|
; Macros returning constants
|
||||||
|
|
||||||
(defmacro an-int [] 42)
|
(defmacro an-int [] 42)
|
||||||
@ -34,3 +33,15 @@
|
|||||||
|
|
||||||
(defmacro a-dict [] {1 2})
|
(defmacro a-dict [] {1 2})
|
||||||
(assert (= (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))))
|
||||||
|
Loading…
Reference in New Issue
Block a user