Commits

Lucian Brănescu-Mihăilă committed 790eecd

Refactor the macros namespace to be part of the env. Tests pass.

  • Participants
  • Parent commits 330736a

Comments (0)

Files changed (2)

 
 
 class List(list, Collection):
+    start = '('
+    end = ')'
+
     def __repr__(self):
         return '(' + ' '.join(map(str, self)) + ')'
 
 
 class Vector(list, Collection):
+    start = '['
+    end = ']'
+
     def __repr__(self):
         return '[' + ' '.join(map(str, self)) + ']'
 
 
 
 class Env(dict):
-    def __init__(self, ns, parent=None):
+    def __init__(self, ns, parent=None, macros=None):
         super(Env, self).__init__(ns)
+
+        if parent is not None:
+            macros = parent.macros
+        elif macros is None:
+            macros = {}
+
         self.parent = parent
+        self.macros = macros
 
     def __getitem__(self, key):
         try:
         self.args = body[1]
         self.body = body[2]
 
-        macros[name] = self
+        env.macros[name] = self
 
     def __call__(self, args, env):
         if len(args) != len(self.args):
     'println': println,
     'input': input,
     'exit': sys.exit,
-})
+}, macros=macros)
 loc = env
 
 
         if len(sexp) == 0:
             raise ValueError("Missing function expression")
 
-        if isinstance(sexp[0], Symbol) and sexp[0] in macros:
-            m = macros[sexp[0]]
+        if isinstance(sexp[0], Symbol) and sexp[0] in env.macros:
+            m = env.macros[sexp[0]]
             return m(sexp[1:], env)
 
         else:
 def lsp(source, env=env):
     return eval(parse(lex('(do {0})'.format(source))), env=env)
 
-# load prelude
-with open(join(dirname(__file__), 'prelude.lsp')) as f:
-    lsp(f.read())
+
+def init():
+    # load prelude
+    with open(join(dirname(__file__), 'prelude.lsp')) as f:
+        lsp(f.read())
+init()
 
 
 def target(*args):
     assert read("(= '(1 2) '3)") == read("(= (quote (1 2)) (quote 3))")
 
 
+def test_env():
+    glob = Env({'x': 1})
+    loc = Env({'y': 2}, parent=glob)
+
+    assert glob['x'] == 1
+    assert loc['y'] == 2
+    assert loc['x'] == 1
+
+
 def test_eval_atom():
     assert eval(1) == 1
 
     assert lsp('a') == 1
 
 
-def test_env():
-    glob = Env({'x': 1})
-    loc = Env({'y': 2}, parent=glob)
-
-    assert glob['x'] == 1
-    assert loc['y'] == 2
-    assert loc['x'] == 1
-
-
 def test_fn():
     assert lsp('((fn () 1))') == 1
     assert lsp('((fn (x) x) 1)') == 1