Skip to content

Commit 28be02b

Browse files
authored
Store generated Python code in *generated-python* in current ns (#108)
1 parent c7f01ea commit 28be02b

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

basilisp/compiler.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,13 @@ def _resolve_sym(ctx: CompilerContext, form: sym.Symbol) -> Optional[str]:
13901390
return _resolve_sym_var(ctx, v)
13911391
ns_sym = sym.symbol(form.ns)
13921392
if ns_sym in ctx.current_ns.imports:
1393+
# We still import Basilisp code, so we'll want to make sure
1394+
# that the symbol isn't referring to a Basilisp Var first
1395+
v = Var.find(form)
1396+
if v is not None:
1397+
return _resolve_sym_var(ctx, v)
1398+
1399+
# Otherwise, try to direct-link it like a Python variable
13931400
safe_ns = munge(form.ns)
13941401
safe_name = munge(form.name)
13951402
return f"{safe_ns}.{safe_name}"
@@ -1689,6 +1696,8 @@ def compile_and_exec_form(form: LispForm,
16891696

16901697
if runtime.print_generated_python():
16911698
print(to_py_str(ast_module))
1699+
else:
1700+
runtime.add_generated_python(to_py_str(ast_module))
16921701

16931702
bytecode = compile(ast_module, source_filename, 'exec')
16941703
exec(bytecode, module.__dict__)
@@ -1711,6 +1720,8 @@ def _incremental_compile_module(nodes: MixedNodeStream,
17111720

17121721
if runtime.print_generated_python():
17131722
print(to_py_str(module))
1723+
else:
1724+
runtime.add_generated_python(to_py_str(module))
17141725

17151726
bytecode = compile(module, source_filename, 'exec')
17161727
exec(bytecode, mod.__dict__)

basilisp/lang/runtime.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
_NS_VAR_NAME = '*ns*'
2121
_NS_VAR_NS = _CORE_NS
2222
_PYTHON_PACKAGE_NAME = 'basilisp'
23+
_GENERATED_PYTHON_VAR_NAME = '*generated-python*'
2324
_PRINT_GENERATED_PY_VAR_NAME = '*print-generated-python*'
2425

2526

@@ -186,6 +187,9 @@ class Namespace:
186187
'basilisp.lang.util'])
187188
.map(sym.symbol)))
188189
GATED_IMPORTS = pset(['basilisp.core'])
190+
191+
_IGNORED_CORE_MAPPINGS = pset([_GENERATED_PYTHON_VAR_NAME])
192+
189193
_NAMESPACES = atom.Atom(pmap())
190194

191195
__slots__ = ('_name', '_module', '_mappings', '_refers', '_aliases', '_imports')
@@ -293,7 +297,8 @@ def __import_core_mappings(ns_cache: PMap,
293297
if core_ns is None:
294298
raise KeyError(f"Namespace {core_ns_name} not found")
295299
for s, var in core_ns.mappings.items():
296-
new_ns.intern(s, var)
300+
if s.name not in Namespace._IGNORED_CORE_MAPPINGS:
301+
new_ns.intern(s, var)
297302

298303
@staticmethod
299304
def __get_or_create(ns_cache: PMap,
@@ -577,6 +582,21 @@ def resolve_alias(s: sym.Symbol) -> sym.Symbol:
577582
return sym.symbol(s.name, ns=ns.name)
578583

579584

585+
def add_generated_python(generated_python: str,
586+
var_name: str = _GENERATED_PYTHON_VAR_NAME,
587+
which_ns: Optional[str] = None) -> None:
588+
"""Add generated Python code to a dynamic variable in which_ns."""
589+
if which_ns is None:
590+
which_ns = get_current_ns().name
591+
ns_sym = sym.Symbol(var_name, ns=which_ns)
592+
v = Maybe(Var.find(ns_sym)) \
593+
.or_else(lambda: Var.intern(sym.symbol(which_ns), # type: ignore
594+
sym.symbol(var_name),
595+
"",
596+
dynamic=True))
597+
v.value = v.value + generated_python
598+
599+
580600
def print_generated_python(var_name: str = _PRINT_GENERATED_PY_VAR_NAME,
581601
core_ns_name: str = _CORE_NS) -> bool:
582602
"""Return the value of the `*print-generated-python*` dynamic variable."""
@@ -616,5 +636,10 @@ def in_ns(s: sym.Symbol):
616636
Var.intern(
617637
core_ns_sym,
618638
sym.symbol(_PRINT_GENERATED_PY_VAR_NAME),
619-
True,
639+
False,
640+
dynamic=True)
641+
Var.intern(
642+
core_ns_sym,
643+
sym.symbol(_GENERATED_PYTHON_VAR_NAME),
644+
"",
620645
dynamic=True)

0 commit comments

Comments
 (0)