13
13
14
14
from hy .lex import mangle , unmangle
15
15
16
- import hy .macros
17
- from hy ._compat import (
18
- str_type , bytes_type , long_type , PY3 , PY35 , raise_empty )
19
- from hy .macros import require , macroexpand , tag_macroexpand
16
+ from hy ._compat import (str_type , string_types , bytes_type , long_type , PY3 ,
17
+ PY35 , raise_empty )
18
+ from hy .macros import require , load_macros , macroexpand , tag_macroexpand
20
19
import hy .importer
21
20
22
21
import traceback
23
22
import importlib
23
+ import inspect
24
+ import pkgutil
25
+ import types
24
26
import ast
25
27
import sys
26
28
import copy
@@ -279,32 +281,48 @@ def is_unpack(kind, x):
279
281
and x [0 ] == "unpack-" + kind )
280
282
281
283
282
- _stdlib = {}
283
-
284
-
285
284
class HyASTCompiler (object ):
285
+ """A Hy-to-Python AST compiler"""
286
286
287
- def __init__ (self , module_name ):
287
+ def __init__ (self , module ):
288
+ """
289
+ Parameters
290
+ ----------
291
+ module: str or types.ModuleType
292
+ Module in which the Hy tree is evaluated.
293
+ """
288
294
self .anon_var_count = 0
289
295
self .imports = defaultdict (set )
290
- self .module_name = module_name
291
296
self .temp_if = None
297
+
298
+ if not inspect .ismodule (module ):
299
+ module = importlib .import_module (module )
300
+
301
+ self .module = module
302
+ self .module_name = module .__name__
303
+
292
304
self .can_use_stdlib = (
293
- not module_name .startswith ("hy.core" )
294
- or module_name == "hy.core.macros" )
305
+ not self .module_name .startswith ("hy.core" )
306
+ or self .module_name == "hy.core.macros" )
307
+
308
+ # Load stdlib macros into the module namespace.
309
+ load_macros (self .module )
310
+
311
+ self ._stdlib = {}
312
+
295
313
# Everything in core needs to be explicit (except for
296
314
# the core macros, which are built with the core functions).
297
- if self .can_use_stdlib and not _stdlib :
315
+ if self .can_use_stdlib :
298
316
# Populate _stdlib.
299
317
import hy .core
300
- for module in hy .core .STDLIB :
301
- mod = importlib .import_module (module )
302
- for e in map (ast_str , mod . EXPORTS ):
318
+ for stdlib_module in hy .core .STDLIB :
319
+ mod = importlib .import_module (stdlib_module )
320
+ for e in map (ast_str , getattr ( mod , ' EXPORTS' , []) ):
303
321
if getattr (mod , e ) is not getattr (builtins , e , '' ):
304
322
# Don't bother putting a name in _stdlib if it
305
323
# points to a builtin with the same name. This
306
324
# prevents pointless imports.
307
- _stdlib [e ] = module
325
+ self . _stdlib [e ] = stdlib_module
308
326
309
327
def get_anon_var (self ):
310
328
self .anon_var_count += 1
@@ -1098,11 +1116,6 @@ def compile_unary_operator(self, expr, root, arg):
1098
1116
brackets (SYM , sym (":as" ), _symn ) |
1099
1117
brackets (SYM , brackets (many (_symn + maybe (sym (":as" ) + _symn )))))])
1100
1118
def compile_import_or_require (self , expr , root , entries ):
1101
- """
1102
- TODO for `require`: keep track of what we've imported in this run and
1103
- then "unimport" it after we've completed `thing' so that we don't
1104
- pollute other envs.
1105
- """
1106
1119
ret = Result ()
1107
1120
1108
1121
for entry in entries :
@@ -1128,8 +1141,9 @@ def compile_import_or_require(self, expr, root, entries):
1128
1141
else :
1129
1142
assignments = [(k , v or k ) for k , v in kids ]
1130
1143
1144
+ ast_module = ast_str (module , piecewise = True )
1145
+
1131
1146
if root == "import" :
1132
- ast_module = ast_str (module , piecewise = True )
1133
1147
module = ast_module .lstrip ("." )
1134
1148
level = len (ast_module ) - len (module )
1135
1149
if assignments == "ALL" and prefix == "" :
@@ -1150,10 +1164,23 @@ def compile_import_or_require(self, expr, root, entries):
1150
1164
for k , v in assignments ]
1151
1165
ret += node (
1152
1166
expr , module = module or None , names = names , level = level )
1153
- else : # root == "require"
1154
- importlib .import_module (module )
1155
- require (module , self .module_name ,
1156
- assignments = assignments , prefix = prefix )
1167
+
1168
+ elif require (ast_module , self .module , assignments = assignments ,
1169
+ prefix = prefix ):
1170
+ # Actually calling `require` is necessary for macro expansions
1171
+ # occurring during compilation.
1172
+ self .imports ['hy.macros' ].update ([None ])
1173
+ # The `require` we're creating in AST is the same as above, but used at
1174
+ # run-time (e.g. when modules are loaded via bytecode).
1175
+ ret += self .compile (HyExpression ([
1176
+ HySymbol ('hy.macros.require' ),
1177
+ HyString (ast_module ),
1178
+ HySymbol ('None' ),
1179
+ HyKeyword ('assignments' ),
1180
+ (HyString ("ALL" ) if assignments == "ALL" else
1181
+ [[HyString (k ), HyString (v )] for k , v in assignments ]),
1182
+ HyKeyword ('prefix' ),
1183
+ HyString (prefix )]).replace (expr ))
1157
1184
1158
1185
return ret
1159
1186
@@ -1484,7 +1511,8 @@ def compile_class_expression(self, expr, root, name, rest):
1484
1511
[x for pair in attrs [0 ] for x in pair ]).replace (attrs )))
1485
1512
1486
1513
for e in body :
1487
- e = self .compile (self ._rewire_init (macroexpand (e , self )))
1514
+ e = self .compile (self ._rewire_init (
1515
+ macroexpand (e , self .module , self )))
1488
1516
bodyr += e + e .expr_as_stmt ()
1489
1517
1490
1518
return bases + asty .ClassDef (
@@ -1520,28 +1548,24 @@ def compile_dispatch_tag_macro(self, expr, root, tag, arg):
1520
1548
return self .compile (tag_macroexpand (
1521
1549
HyString (mangle (tag )).replace (tag ),
1522
1550
arg ,
1523
- self ))
1524
-
1525
- _namespaces = {}
1551
+ self .module ))
1526
1552
1527
1553
@special (["eval-and-compile" , "eval-when-compile" ], [many (FORM )])
1528
1554
def compile_eval_and_compile (self , expr , root , body ):
1529
1555
new_expr = HyExpression ([HySymbol ("do" ).replace (expr [0 ])]).replace (expr )
1530
- if self .module_name not in self ._namespaces :
1531
- # Initialize a compile-time namespace for this module.
1532
- self ._namespaces [self .module_name ] = {
1533
- 'hy' : hy , '__name__' : self .module_name }
1556
+
1534
1557
hy .importer .hy_eval (new_expr + body ,
1535
- self ._namespaces [self .module_name ],
1536
- self .module_name )
1558
+ self .module .__dict__ ,
1559
+ self .module )
1560
+
1537
1561
return (self ._compile_branch (body )
1538
1562
if ast_str (root ) == "eval_and_compile"
1539
1563
else Result ())
1540
1564
1541
1565
@builds_model (HyExpression )
1542
1566
def compile_expression (self , expr ):
1543
1567
# Perform macro expansions
1544
- expr = macroexpand (expr , self )
1568
+ expr = macroexpand (expr , self . module , self )
1545
1569
if not isinstance (expr , HyExpression ):
1546
1570
# Go through compile again if the type changed.
1547
1571
return self .compile (expr )
@@ -1665,8 +1689,8 @@ def compile_symbol(self, symbol):
1665
1689
attr = ast_str (local ),
1666
1690
ctx = ast .Load ())
1667
1691
1668
- if self .can_use_stdlib and ast_str (symbol ) in _stdlib :
1669
- self .imports [_stdlib [ast_str (symbol )]].add (ast_str (symbol ))
1692
+ if self .can_use_stdlib and ast_str (symbol ) in self . _stdlib :
1693
+ self .imports [self . _stdlib [ast_str (symbol )]].add (ast_str (symbol ))
1670
1694
1671
1695
return asty .Name (symbol , id = ast_str (symbol ), ctx = ast .Load ())
1672
1696
@@ -1699,20 +1723,41 @@ def compile_dict(self, m):
1699
1723
return ret + asty .Dict (m , keys = keyvalues [::2 ], values = keyvalues [1 ::2 ])
1700
1724
1701
1725
1702
- def hy_compile (tree , module_name , root = ast .Module , get_expr = False ):
1726
+ def hy_compile (tree , module , root = ast .Module , get_expr = False ):
1703
1727
"""
1704
- Compile a HyObject tree into a Python AST Module.
1728
+ Compile a Hy tree into a Python AST tree.
1729
+
1730
+ Parameters
1731
+ ----------
1732
+ module: str or types.ModuleType
1733
+ Module, or name of the module, in which the Hy tree is evaluated.
1705
1734
1706
- If `get_expr` is True, return a tuple (module, last_expression), where
1707
- `last_expression` is the.
1735
+ root: ast object, optional (ast.Module)
1736
+ Root object for the Python AST tree.
1737
+
1738
+ get_expr: bool, optional (False)
1739
+ If true, return a tuple with `(root_obj, last_expression)`.
1740
+
1741
+ Returns
1742
+ -------
1743
+ out : A Python AST tree
1708
1744
"""
1709
1745
1746
+ if isinstance (module , string_types ):
1747
+ if module .startswith ('<' ) and module .endswith ('>' ):
1748
+ module = types .ModuleType (module )
1749
+ else :
1750
+ module = importlib .import_module (ast_str (module , piecewise = True ))
1751
+ if not inspect .ismodule (module ):
1752
+ raise TypeError ('Invalid module type: {}' .format (type (module )))
1753
+
1754
+
1710
1755
tree = wrap_value (tree )
1711
1756
if not isinstance (tree , HyObject ):
1712
1757
raise HyCompileError ("`tree` must be a HyObject or capable of "
1713
1758
"being promoted to one" )
1714
1759
1715
- compiler = HyASTCompiler (module_name )
1760
+ compiler = HyASTCompiler (module )
1716
1761
result = compiler .compile (tree )
1717
1762
expr = result .force_expr
1718
1763
0 commit comments