Fix metadata on functions.
[jackhill/mal.git] / python / step5_tco.py
index ffde863..d9d34bc 100644 (file)
@@ -1,41 +1,41 @@
 import sys, traceback
 import mal_readline
-from mal_types import (pr_str, sequential_Q, symbol_Q, coll_Q, list_Q,
-                       vector_Q, hash_map_Q, new_symbol, new_function,
-                       new_list, new_vector, new_hash_map, Env, types_ns)
-from reader import (read_str, Blank)
+import mal_types as types
+import reader, printer
+from env import Env
+import core
 
 # read
 def READ(str):
-    return read_str(str)
+    return reader.read_str(str)
 
 # eval
 def eval_ast(ast, env):
-    if symbol_Q(ast):
+    if types._symbol_Q(ast):
         return env.get(ast)
-    elif list_Q(ast):
-        return new_list(*map(lambda a: EVAL(a, env), ast))
-    elif vector_Q(ast):
-        return new_vector(*map(lambda a: EVAL(a, env), ast))
-    elif hash_map_Q(ast):
+    elif types._list_Q(ast):
+        return types._list(*map(lambda a: EVAL(a, env), ast))
+    elif types._vector_Q(ast):
+        return types._vector(*map(lambda a: EVAL(a, env), ast))
+    elif types._hash_map_Q(ast):
         keyvals = []
         for k in ast.keys():
             keyvals.append(EVAL(k, env))
             keyvals.append(EVAL(ast[k], env))
-        return new_hash_map(*keyvals)
+        return types._hash_map(*keyvals)
     else:
         return ast  # primitive value, return unchanged
 
 def EVAL(ast, env):
     while True:
         #print("EVAL %s" % ast)
-        if not list_Q(ast):
+        if not types._list_Q(ast):
             return eval_ast(ast, env)
-    
+
         # apply list
         if len(ast) == 0: return ast
-        a0 = ast[0] 
-    
+        a0 = ast[0]
+
         if "def!" == a0:
             a1, a2 = ast[1], ast[2]
             res = EVAL(a2, env)
@@ -61,20 +61,19 @@ def EVAL(ast, env):
             # Continue loop (TCO)
         elif "fn*" == a0:
             a1, a2 = ast[1], ast[2]
-            return new_function(EVAL, a2, env, a1)
+            return types._function(EVAL, Env, a2, env, a1)
         else:
             el = eval_ast(ast, env)
             f = el[0]
-            if hasattr(f, '__meta__') and f.__meta__.has_key("exp"):
-                m = f.__meta__
-                ast = m['exp']
-                env = Env(m['env'], m['params'], el[1:])
+            if hasattr(f, '__ast__'):
+                ast = f.__ast__
+                env = f.__gen_env__(el[1:])
             else:
                 return f(*el[1:])
 
 # print
 def PRINT(exp):
-    return pr_str(exp)
+    return printer._pr_str(exp)
 
 # repl
 repl_env = Env()
@@ -83,7 +82,7 @@ def REP(str):
 def _ref(k,v): repl_env.set(k, v)
 
 # Import types functions
-for name, val in types_ns.items(): _ref(name, val)
+for name, val in core.ns.items(): _ref(name, val)
 
 # Defined using the language itself
 REP("(def! not (fn* (a) (if a false true)))")
@@ -94,6 +93,6 @@ while True:
         if line == None: break
         if line == "": continue
         print(REP(line))
-    except Blank: continue
+    except reader.Blank: continue
     except Exception as e:
         print "".join(traceback.format_exception(*sys.exc_info()))