def EVAL(ast, env): while True: #print("EVAL %s" % printer._pr_str(ast)) if not types._list_Q(ast): return eval_ast(ast, env) # apply list ast = macroexpand(ast, env) if not types._list_Q(ast): return eval_ast(ast, env) if len(ast) == 0: return ast a0 = ast[0] if "def!" == a0: a1, a2 = ast[1], ast[2] res = EVAL(a2, env) return env.set(a1, res) elif "let*" == a0: a1, a2 = ast[1], ast[2] let_env = Env(env) for i in range(0, len(a1), 2): let_env.set(a1[i], EVAL(a1[i+1], let_env)) ast = a2 env = let_env # Continue loop (TCO) elif "quote" == a0: return ast[1] elif "quasiquote" == a0: ast = quasiquote(ast[1]); # Continue loop (TCO) elif 'defmacro!' == a0: func = EVAL(ast[2], env) func._ismacro_ = True return env.set(ast[1], func) elif 'macroexpand' == a0: return macroexpand(ast[1], env) elif "do" == a0: eval_ast(ast[1:-1], env) ast = ast[-1] # Continue loop (TCO) elif "if" == a0: a1, a2 = ast[1], ast[2] cond = EVAL(a1, env) if cond is None or cond is False: if len(ast) > 3: ast = ast[3] else: ast = None else: ast = a2 # Continue loop (TCO) elif "fn*" == a0: a1, a2 = ast[1], ast[2] return types._function(EVAL, Env, a2, env, a1) else: el = eval_ast(ast, env) f = el[0] if hasattr(f, '__ast__'): ast = f.__ast__ env = f.__gen_env__(el[1:]) else: return f(*el[1:])
def EVAL(ast, env): # TCO loop through EVAL instead of recursing while True: if type(ast) is list: # return the input if it is an empty list if not ast: return ast else: # get the first element of the list arg0 = ast[0] # Examine all language special forms and their arguments # before applying to all remaining elements of the list if arg0 == "def!": result = EVAL(ast[2], env) return env.set(ast[1], result) elif arg0 == 'let*': let_env = Env(outer=env) for i in range(0, len(ast[1]), 2): key = ast[1][i] value = EVAL(ast[1][i + 1], let_env) let_env.set(key, value) env = let_env ast = ast[2] # Continue to loop (TCO) elif arg0 == 'do': eval_ast(ast[1:-1], env) ast = ast[-1] # Continue to loop (TCO) elif arg0 == 'if': result = EVAL(ast[1], env) if result: ast = ast[2] else: if len(ast) >= 4: ast = ast[3] else: ast = None # Continue to loop (TCO) elif arg0 == 'fn*': a1, a2 = ast[1], ast[2] return _function(EVAL, Env, a2, env, a1) elif arg0 == 'quote': return ast[1] elif arg0 == 'quasiquote': ast = quasiquote(ast[1]) else: evaled_list = eval_ast(ast, env) f = evaled_list[0] if hasattr(f, '__ast__'): ast = f.__ast__ env = f.__gen_env__(evaled_list[1:]) else: return f(*evaled_list[1:]) # If it is not a list just evaluate it else: return eval_ast(ast, env)
def EVAL(ast, env): while True: dbgeval = env.get_or_nil('DEBUG-EVAL') if dbgeval is not None and dbgeval is not False: print('EVAL: ' + printer._pr_str(ast)) if types._symbol_Q(ast): return env.get(ast) elif types._vector_Q(ast): return types._vector(*map(lambda a: EVAL(a, env), ast)) elif types._hash_map_Q(ast): return types.Hash_Map((k, EVAL(v, env)) for k, v in ast.items()) elif not types._list_Q(ast): return ast # primitive value, return unchanged else: # apply list if len(ast) == 0: return ast a0 = ast[0] if "def!" == a0: a1, a2 = ast[1], ast[2] res = EVAL(a2, env) return env.set(a1, res) elif "let*" == a0: a1, a2 = ast[1], ast[2] let_env = Env(env) for i in range(0, len(a1), 2): let_env.set(a1[i], EVAL(a1[i + 1], let_env)) ast = a2 env = let_env # Continue loop (TCO) elif "do" == a0: for i in range(1, len(ast) - 1): EVAL(ast[i], env) ast = ast[-1] # Continue loop (TCO) elif "if" == a0: a1, a2 = ast[1], ast[2] cond = EVAL(a1, env) if cond is None or cond is False: if len(ast) > 3: ast = ast[3] else: ast = None else: ast = a2 # Continue loop (TCO) elif "fn*" == a0: a1, a2 = ast[1], ast[2] return types._function(EVAL, Env, a2, env, a1) else: f = EVAL(a0, env) args = ast[1:] if hasattr(f, '__ast__'): ast = f.__ast__ env = f.__gen_env__(types.List(EVAL(a, env) for a in args)) else: return f(*(EVAL(a, env) for a in args))
def EVAL(ast, env): while True: #print("EVAL %s" % ast) if not types._list_Q(ast): return eval_ast(ast, env) # apply list if len(ast) == 0: return ast a0 = ast[0] if "def!" == a0: a1, a2 = ast[1], ast[2] res = EVAL(a2, env) return env.set(a1, res) elif "let*" == a0: a1, a2 = ast[1], ast[2] let_env = Env(env) for i in range(0, len(a1), 2): let_env.set(a1[i], EVAL(a1[i+1], let_env)) return EVAL(a2, let_env) elif "do" == a0: eval_ast(ast[1:-1], env) ast = ast[-1] # Continue loop (TCO) elif "if" == a0: a1, a2 = ast[1], ast[2] cond = EVAL(a1, env) if cond is None or cond is False: if len(ast) > 3: ast = ast[3] else: ast = None else: ast = a2 # Continue loop (TCO) elif "fn*" == a0: a1, a2 = ast[1], ast[2] return types._function(EVAL, Env, a2, env, a1) else: el = eval_ast(ast, env) f = el[0] if hasattr(f, '__ast__'): ast = f.__ast__ env = f.__gen_env__(el[1:]) else: return f(*el[1:])
def EVAL(ast, env): #print("EVAL %s" % ast) if not types._list_Q(ast): return eval_ast(ast, env) # apply list if len(ast) == 0: return ast a0 = ast[0] if "def!" == a0: a1, a2 = ast[1], ast[2] res = EVAL(a2, env) return env.set(a1, res) elif "let*" == a0: a1, a2 = ast[1], ast[2] let_env = Env(env) for i in range(0, len(a1), 2): let_env.set(a1[i], EVAL(a1[i+1], let_env)) return EVAL(a2, let_env) elif "do" == a0: el = eval_ast(ast[1:], env) return el[-1] elif "if" == a0: a1, a2 = ast[1], ast[2] cond = EVAL(a1, env) if cond is None or cond is False: if len(ast) > 3: return EVAL(ast[3], env) else: return None else: return EVAL(a2, env) elif "fn*" == a0: a1, a2 = ast[1], ast[2] return types._function(EVAL, Env, a2, env, a1) else: el = eval_ast(ast, env) f = el[0] return f(*el[1:])
def EVAL(ast, env): #print("EVAL %s" % printer._pr_str(ast)) if not types._list_Q(ast): return eval_ast(ast, env) # apply list if len(ast) == 0: return ast a0 = ast[0] if "def!" == a0: a1, a2 = ast[1], ast[2] res = EVAL(a2, env) return env.set(a1, res) elif "let*" == a0: a1, a2 = ast[1], ast[2] let_env = Env(env) for i in range(0, len(a1), 2): let_env.set(a1[i], EVAL(a1[i+1], let_env)) return EVAL(a2, let_env) elif "do" == a0: el = eval_ast(ast[1:], env) return el[-1] elif "if" == a0: a1, a2 = ast[1], ast[2] cond = EVAL(a1, env) if cond is None or cond is False: if len(ast) > 3: return EVAL(ast[3], env) else: return None else: return EVAL(a2, env) elif "fn*" == a0: a1, a2 = ast[1], ast[2] return types._function(EVAL, Env, a2, env, a1) else: el = eval_ast(ast, env) f = el[0] return f(*el[1:])
def EVAL(ast, env): while True: #print("EVAL %s" % printer._pr_str(ast)) if not types._list_Q(ast): return eval_ast(ast, env) # apply list ast = macroexpand(ast, env) if not types._list_Q(ast): return eval_ast(ast, env) if len(ast) == 0: return ast a0 = ast[0] if "def!" == a0: a1, a2 = ast[1], ast[2] res = EVAL(a2, env) return env.set(a1, res) elif "let*" == a0: a1, a2 = ast[1], ast[2] let_env = Env(env) for i in range(0, len(a1), 2): let_env.set(a1[i], EVAL(a1[i + 1], let_env)) ast = a2 env = let_env # Continue loop (TCO) elif "quote" == a0: return ast[1] elif "quasiquote" == a0: ast = quasiquote(ast[1]) # Continue loop (TCO) elif 'defmacro!' == a0: func = types._clone(EVAL(ast[2], env)) func._ismacro_ = True return env.set(ast[1], func) elif 'macroexpand' == a0: return macroexpand(ast[1], env) elif "py!*" == a0: exec(compile(ast[1], '', 'single'), globals()) return None elif "py*" == a0: return types.py_to_mal(eval(ast[1])) elif "." == a0: el = eval_ast(ast[2:], env) f = eval(ast[1]) return f(*el) elif "try*" == a0: if len(ast) < 3: return EVAL(ast[1], env) a1, a2 = ast[1], ast[2] if a2[0] == "catch*": err = None try: return EVAL(a1, env) except types.MalException as exc: err = exc.object except Exception as exc: err = exc.args[0] catch_env = Env(env, [a2[1]], [err]) return EVAL(a2[2], catch_env) else: return EVAL(a1, env) elif "do" == a0: eval_ast(ast[1:-1], env) ast = ast[-1] # Continue loop (TCO) elif "if" == a0: a1, a2 = ast[1], ast[2] cond = EVAL(a1, env) if cond is None or cond is False: if len(ast) > 3: ast = ast[3] else: ast = None else: ast = a2 # Continue loop (TCO) elif "fn*" == a0: a1, a2 = ast[1], ast[2] return types._function(EVAL, Env, a2, env, a1) else: el = eval_ast(ast, env) f = el[0] if hasattr(f, '__ast__'): ast = f.__ast__ env = f.__gen_env__(el[1:]) else: return f(*el[1:])
def EVAL(ast, env): while True: #print("EVAL %s" % printer._pr_str(ast)) if not types._list_Q(ast): return eval_ast(ast, env) # apply list ast = macroexpand(ast, env) if not types._list_Q(ast): return eval_ast(ast, env) if len(ast) == 0: return ast a0 = ast[0] if "def!" == a0: a1, a2 = ast[1], ast[2] res = EVAL(a2, env) return env.set(a1, res) elif "let*" == a0: a1, a2 = ast[1], ast[2] let_env = Env(env) for i in range(0, len(a1), 2): let_env.set(a1[i], EVAL(a1[i+1], let_env)) ast = a2 env = let_env # Continue loop (TCO) elif "quote" == a0: return ast[1] elif "quasiquote" == a0: ast = quasiquote(ast[1]); # Continue loop (TCO) elif 'defmacro!' == a0: func = EVAL(ast[2], env) func._ismacro_ = True return env.set(ast[1], func) elif 'macroexpand' == a0: return macroexpand(ast[1], env) elif "py!*" == a0: if sys.version_info[0] >= 3: exec(compile(ast[1], '', 'single'), globals()) else: exec(compile(ast[1], '', 'single') in globals()) return None elif "py*" == a0: return eval(ast[1]) elif "." == a0: el = eval_ast(ast[2:], env) f = eval(ast[1]) return f(*el) elif "try*" == a0: a1, a2 = ast[1], ast[2] if a2[0] == "catch*": try: return EVAL(a1, env); except Exception as exc: exc = exc.args[0] catch_env = Env(env, [a2[1]], [exc]) return EVAL(a2[2], catch_env) else: return EVAL(a1, env); elif "do" == a0: eval_ast(ast[1:-1], env) ast = ast[-1] # Continue loop (TCO) elif "if" == a0: a1, a2 = ast[1], ast[2] cond = EVAL(a1, env) if cond is None or cond is False: if len(ast) > 3: ast = ast[3] else: ast = None else: ast = a2 # Continue loop (TCO) elif "fn*" == a0: a1, a2 = ast[1], ast[2] return types._function(EVAL, Env, a2, env, a1) else: el = eval_ast(ast, env) f = el[0] if hasattr(f, '__ast__'): ast = f.__ast__ env = f.__gen_env__(el[1:]) else: return f(*el[1:])
def EVAL(ast, env): while True: dbgeval = env.get_or_nil('DEBUG-EVAL') if dbgeval is not None and dbgeval is not False: print('EVAL: ' + printer._pr_str(ast)) if types._symbol_Q(ast): return env.get(ast) elif types._vector_Q(ast): return types._vector(*map(lambda a: EVAL(a, env), ast)) elif types._hash_map_Q(ast): return types.Hash_Map((k, EVAL(v, env)) for k, v in ast.items()) elif not types._list_Q(ast): return ast # primitive value, return unchanged else: # apply list if len(ast) == 0: return ast a0 = ast[0] if "def!" == a0: a1, a2 = ast[1], ast[2] res = EVAL(a2, env) return env.set(a1, res) elif "let*" == a0: a1, a2 = ast[1], ast[2] let_env = Env(env) for i in range(0, len(a1), 2): let_env.set(a1[i], EVAL(a1[i+1], let_env)) ast = a2 env = let_env # Continue loop (TCO) elif "quote" == a0: return ast[1] elif "quasiquote" == a0: ast = quasiquote(ast[1]); # Continue loop (TCO) elif 'defmacro!' == a0: func = types._clone(EVAL(ast[2], env)) func._ismacro_ = True return env.set(ast[1], func) elif "py!*" == a0: exec(compile(ast[1], '', 'single'), globals()) return None elif "py*" == a0: return types.py_to_mal(eval(ast[1])) elif "." == a0: el = (EVAL(ast[i], env) for i in range(2, len(ast))) f = eval(ast[1]) return f(*el) elif "try*" == a0: if len(ast) < 3: return EVAL(ast[1], env) a1, a2 = ast[1], ast[2] if a2[0] == "catch*": err = None try: return EVAL(a1, env) except types.MalException as exc: err = exc.object except Exception as exc: err = exc.args[0] catch_env = Env(env, [a2[1]], [err]) return EVAL(a2[2], catch_env) else: return EVAL(a1, env); elif "do" == a0: for i in range(1, len(ast)-1): EVAL(ast[i], env) ast = ast[-1] # Continue loop (TCO) elif "if" == a0: a1, a2 = ast[1], ast[2] cond = EVAL(a1, env) if cond is None or cond is False: if len(ast) > 3: ast = ast[3] else: ast = None else: ast = a2 # Continue loop (TCO) elif "fn*" == a0: a1, a2 = ast[1], ast[2] return types._function(EVAL, Env, a2, env, a1) else: f = EVAL(a0, env) args = ast[1:] if hasattr(f, '_ismacro_'): ast = f(*args) continue # TCO if hasattr(f, '__ast__'): ast = f.__ast__ env = f.__gen_env__(types.List(EVAL(a, env) for a in args)) else: return f(*(EVAL(a, env) for a in args))