Skip to content

Commit 2b1936c

Browse files
authored
Add namespace functions to basilisp.core (#176)
* Add namespace functions to basilisp.core * Rename Namespace.mappings to Namespace.interns * Use refer_all method for CLI bootstrapping of REPL * Loads of new Namespace tests * Many more Var tests * Fix a bug with ns-publics * Non-functional refer function * Realize lazy seq to check if the sequence is empty * First pass on a require function * Generated Python vars are private to each namespace * Resolve macro symbols with more sophisticated heuristic * Rearrange some code * Add small import macro * Add ns preamble macro * Fix import mechanism using global keyword hackery * Fix the gated import test * Plz fix everything * Fix linting error * Refactor require code slightly
1 parent 77b1871 commit 2b1936c

File tree

7 files changed

+722
-133
lines changed

7 files changed

+722
-133
lines changed

basilisp/cli.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import basilisp.lang.symbol as sym
1212
import basilisp.main as basilisp
1313
import basilisp.reader as reader
14-
from basilisp.util import Maybe
1514

1615

1716
@click.group()
@@ -44,11 +43,7 @@ def bootstrap_repl(which_ns: str) -> types.ModuleType:
4443
ns = runtime.Namespace.get_or_create(sym.symbol(which_ns))
4544
repl_module = importlib.import_module('basilisp.repl')
4645
ns.add_alias(sym.symbol('basilisp.repl'), repl_ns)
47-
for name in ['*1', '*2', '*3', '*e', 'doc', 'pydoc', 'source']:
48-
ns.intern(sym.symbol(name),
49-
Maybe(runtime.Var.find(sym.symbol(name, ns='basilisp.repl'))).or_else_raise(
50-
lambda: runtime.RuntimeException(
51-
f"Var basilisp.repl/{name} not found!"))) # pylint: disable=cell-var-from-loop
46+
ns.refer_all(repl_ns)
5247
return repl_module
5348

5449

basilisp/compiler.py

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import collections
33
import contextlib
44
import functools
5+
import importlib
56
import itertools
67
import sys
78
import types
@@ -181,11 +182,11 @@ def quoted(self):
181182
yield
182183
self._is_quoted.pop()
183184

184-
def add_import(self, imp: sym.Symbol):
185-
self.current_ns.add_import(imp)
185+
def add_import(self, imp: sym.Symbol, mod: types.ModuleType):
186+
self.current_ns.add_import(imp, mod)
186187

187188
@property
188-
def imports(self):
189+
def imports(self) -> lmap.Map:
189190
return self.current_ns.imports
190191

191192
@property
@@ -225,15 +226,6 @@ def attr_node(node, idx):
225226
return attr_node(ast.Name(id=attrs[0], ctx=ast.Load()), 1)
226227

227228

228-
def _is_py_module(name: str) -> bool:
229-
"""Determine if a namespace is Python module."""
230-
try:
231-
__import__(name)
232-
return True
233-
except ModuleNotFoundError:
234-
return False
235-
236-
237229
class ASTNodeType(Enum):
238230
DEPENDENCY = 1
239231
NODE = 2
@@ -943,22 +935,32 @@ def _if_ast(ctx: CompilerContext, form: llist.List) -> ASTStream:
943935

944936
def _import_ast(ctx: CompilerContext, form: llist.List) -> ASTStream:
945937
"""Append Import statements into the compiler context nodes."""
946-
assert form[0] == _IMPORT
938+
assert form.first == _IMPORT
947939
assert all([isinstance(f, sym.Symbol) for f in form.rest])
948940

949-
import_names = []
941+
last = None
950942
for s in form.rest:
951-
if not _is_py_module(s.name):
943+
try:
944+
module = importlib.import_module(s.name)
945+
ctx.add_import(s, module)
946+
except ModuleNotFoundError:
952947
raise ImportError(f"Module '{s.name}' not found")
953-
ctx.add_import(s)
948+
954949
with ctx.quoted():
950+
module_name = s.name.split(".", maxsplit=1)[0]
951+
yield _dependency(ast.Global(names=[module_name]))
952+
yield _dependency(ast.Assign(targets=[ast.Name(id=module_name, ctx=ast.Store())],
953+
value=ast.Call(func=_load_attr("builtins.__import__"),
954+
args=[ast.Str(s.name)],
955+
keywords=[])))
956+
last = ast.Name(id=module_name, ctx=ast.Load())
955957
yield _dependency(ast.Call(
956958
func=_load_attr(f'{_NS_VAR_VALUE}.add_import'),
957-
args=_unwrap_nodes(_to_ast(ctx, s)),
959+
args=list(chain(_unwrap_nodes(_to_ast(ctx, s)), [last])),
958960
keywords=[]))
959-
import_names.append(ast.alias(name=s.name, asname=None))
960-
yield _dependency(ast.Import(names=import_names))
961-
yield _node(ast.NameConstant(None))
961+
962+
assert last is not None
963+
yield _node(last)
962964

963965

964966
def _interop_call_ast(ctx: CompilerContext, form: llist.List) -> ASTStream:
@@ -1780,7 +1782,7 @@ def _module_imports(ctx: CompilerContext) -> Iterable[ast.Import]:
17801782
'basilisp.lang.vector': _VEC_ALIAS,
17811783
'basilisp.lang.util': _UTIL_ALIAS}
17821784
return seq(ctx.imports) \
1783-
.map(lambda s: s.name) \
1785+
.map(lambda entry: entry.key.name) \
17841786
.map(lambda name: (name, aliases.get(name, None))) \
17851787
.map(lambda t: ast.Import(names=[ast.alias(name=t[0], asname=t[1])])) \
17861788
.to_list()

0 commit comments

Comments
 (0)