def init_repl_env() -> Env: def eval_func(args: List[MalExpression], env: Env) -> MalExpression: a0 = args[0] assert isinstance(a0, MalExpression) return EVAL(a0, env) def swap(args: List[MalExpression], env: Env) -> MalExpression: atom = args[0] assert isinstance(atom, MalAtom) func = args[1] atom.reset(EVAL(MalList([func, atom.native()] + args[2:]), env)) return atom.native() repl_env = Env(None) for key in core.ns: repl_env.set(key, core.ns[key]) repl_env.set("eval", MalFunctionCompiled(lambda args: eval_func(args, repl_env))) rep( '(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) "\nnil)")))))', repl_env, ) mal_argv = MalList([MalString(x) for x in sys.argv[2:]]) repl_env.set("*ARGV*", mal_argv) rep( "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))", repl_env, ) return repl_env
def init_repl_env() -> Env: def eval_func(args: List[MalExpression], env: Env) -> MalExpression: a0 = args[0] assert isinstance(a0, MalExpression) return EVAL(a0, env) env = Env(None) for key in core.ns: env.set(key, core.ns[key]) env.set("eval", MalFunctionCompiled(lambda args: eval_func(args, env))) rep('(def! *host-language* "python.2")', env) rep( '(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) "\nnil)")))))', env, ) mal_argv = MalList([MalString(x) for x in sys.argv[2:]]) env.set("*ARGV*", mal_argv) rep( "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))", env, ) return env
def EVAL(ast: MalExpression, env: Env) -> MalExpression: # print("EVAL: " + str(ast)) if not isinstance(ast, MalList): return eval_ast(ast, env) if len(ast.native()) == 0: return ast first = str(ast.native()[0]) rest = ast.native()[1:] if first == "def!": key = str(ast.native()[1]) value = EVAL(ast.native()[2], env) return env.set(key, value) if first == "let*": assert len(rest) == 2 let_env = Env(env) bindings = rest[0] assert isinstance(bindings, MalList) or isinstance(bindings, MalVector) bindings_list = bindings.native() assert len(bindings_list) % 2 == 0 for i in range(0, len(bindings_list), 2): assert isinstance(bindings_list[i], MalSymbol) assert isinstance(bindings_list[i + 1], MalExpression) let_env.set(str(bindings_list[i]), EVAL(bindings_list[i + 1], let_env)) expr = rest[1] return EVAL(expr, let_env) if first == "do": for x in range(0, len(rest) - 1): EVAL(rest[x], env) return EVAL(rest[len(rest) - 1], env) if first == "if": condition = EVAL(rest[0], env) if isinstance(condition, MalNil) or ( isinstance(condition, MalBoolean) and condition.native() is False ): if len(rest) >= 3: return EVAL(rest[2], env) else: return MalNil() else: return EVAL(rest[1], env) if first == "fn*": def func_body(x): func_env = Env(outer=env, binds=rest[0].native(), exprs=x) return EVAL(rest[1], func_env) return MalFunctionCompiled(func_body) evaled_ast = eval_ast(ast, env) f = evaled_ast.native()[0] args = evaled_ast.native()[1:] try: return f.call(args) except AttributeError: raise MalInvalidArgumentException(f, "attribute error")
MalInvalidArgumentException, MalString, ) repl_env = Env(None) for key in core.ns: repl_env.set(key, core.ns[key]) def eval_func(args: List[MalExpression]) -> MalExpression: a0 = args[0] assert isinstance(a0, MalExpression) return EVAL(a0, repl_env) repl_env.set("eval", MalFunctionCompiled(lambda args: eval_func(args))) def swap(args: List[MalExpression]) -> MalExpression: atom = args[0] assert isinstance(atom, MalAtom) func = args[1] atom.reset(EVAL(MalList([func, atom.native()] + args[2:]), repl_env)) return atom.native() def READ(x: str) -> MalExpression: return reader.read(x) def qq_loop(acc: MalList, elt: MalExpression) -> MalList:
import readline from typing import Dict import reader from env import Env from mal_types import ( MalExpression, MalBoolean, MalNil, MalSymbol, MalInvalidArgumentException, MalUnknownSymbolException, MalSyntaxException, ) from mal_types import MalInt, MalList, MalFunctionCompiled, MalVector, MalHash_map repl_env = Env(None) repl_env.set("+", MalFunctionCompiled(lambda a: MalInt(a[0].native() + a[1].native()))) repl_env.set("-", MalFunctionCompiled(lambda a: MalInt(a[0].native() - a[1].native()))) repl_env.set("*", MalFunctionCompiled(lambda a: MalInt(a[0].native() * a[1].native()))) repl_env.set( "/", MalFunctionCompiled(lambda a: MalInt(int(a[0].native() / a[1].native()))) ) def READ(x: str) -> MalExpression: return reader.read(x) def EVAL(ast: MalExpression, env: Env) -> MalExpression: dbgeval = env.get("DEBUG-EVAL") if (dbgeval is not None and not isinstance(dbgeval, MalNil)
return MalHash_map(dict_a_copy) def swap(args: List[MalExpression]) -> MalExpression: atom = args[0] assert isinstance(atom, MalAtom) func = args[1] assert isinstance(func, MalFunctionCompiled) or isinstance( func, MalFunctionRaw) atom.reset(func.call([atom.native()] + args[2:])) return atom.native() ns = { "+": MalFunctionCompiled( lambda args: MalInt(args[0].native() + args[1].native())), "-": MalFunctionCompiled( lambda args: MalInt(args[0].native() - args[1].native())), "*": MalFunctionCompiled( lambda args: MalInt(args[0].native() * args[1].native())), "/": MalFunctionCompiled( lambda args: MalInt(int(args[0].native() / args[1].native()))), "prn": MalFunctionCompiled(lambda args: prn(args)), "pr-str": MalFunctionCompiled(lambda args: pr_str(args)), "println": MalFunctionCompiled(lambda args: println(args)),
def EVAL(ast: MalExpression, env: Env) -> MalExpression: dbgeval = env.get("DEBUG-EVAL") if (dbgeval is not None and not isinstance(dbgeval, MalNil) and (not isinstance(dbgeval, MalBoolean) or dbgeval.native())): print("EVAL: " + str(ast)) if isinstance(ast, MalSymbol): key = str(ast) val = env.get(key) if val is None: raise MalUnknownSymbolException(key) return val if isinstance(ast, MalVector): return MalVector([EVAL(x, env) for x in ast.native()]) if isinstance(ast, MalHash_map): new_dict = {} # type: Dict[str, MalExpression] for key in ast.native(): new_dict[key] = EVAL(ast.native()[key], env) return MalHash_map(new_dict) if not isinstance(ast, MalList): return ast if len(ast.native()) == 0: return ast first = str(ast.native()[0]) rest = ast.native()[1:] if first == "def!": key = str(ast.native()[1]) value = EVAL(ast.native()[2], env) return env.set(key, value) if first == "let*": assert len(rest) == 2 let_env = Env(env) bindings = rest[0] assert isinstance(bindings, MalList) or isinstance(bindings, MalVector) bindings_list = bindings.native() assert len(bindings_list) % 2 == 0 for i in range(0, len(bindings_list), 2): assert isinstance(bindings_list[i], MalSymbol) assert isinstance(bindings_list[i + 1], MalExpression) let_env.set(str(bindings_list[i]), EVAL(bindings_list[i + 1], let_env)) expr = rest[1] return EVAL(expr, let_env) if first == "do": for x in range(0, len(rest) - 1): EVAL(rest[x], env) return EVAL(rest[len(rest) - 1], env) if first == "if": condition = EVAL(rest[0], env) if isinstance(condition, MalNil) or (isinstance(condition, MalBoolean) and condition.native() is False): if len(rest) >= 3: return EVAL(rest[2], env) else: return MalNil() else: return EVAL(rest[1], env) if first == "fn*": def func_body(x): func_env = Env(outer=env, binds=rest[0].native(), exprs=x) return EVAL(rest[1], func_env) return MalFunctionCompiled(func_body) f, *args = (EVAL(form, env) for form in ast.native()) try: return f.call(args) except AttributeError: raise MalInvalidArgumentException(f, "attribute error")
import readline from typing import Dict import reader from mal_types import MalExpression, MalSymbol from mal_types import MalFunctionCompiled, MalInt from mal_types import MalList, MalVector, MalHash_map from mal_types import MalUnknownSymbolException, MalSyntaxException repl_env = { "+": MalFunctionCompiled(lambda a: MalInt(a[0].native() + a[1].native())), "-": MalFunctionCompiled(lambda a: MalInt(a[0].native() - a[1].native())), "*": MalFunctionCompiled(lambda a: MalInt(a[0].native() * a[1].native())), "/": MalFunctionCompiled(lambda a: MalInt(int(a[0].native() / a[1].native()))), } def READ(x: str) -> MalExpression: return reader.read(x) def EVAL(ast: MalExpression, env: Dict[str, MalFunctionCompiled]) -> MalExpression: # print("EVAL: " + str(ast)) if isinstance(ast, MalSymbol): try: return env[str(ast)] except KeyError: raise MalUnknownSymbolException(str(ast)) if isinstance(ast, MalVector):
def test_step8_is_macro(self): self.assertEqual(False, MalFunctionCompiled(lambda a: MalInt(1)).is_macro()) self.assertEqual( False, MalFunctionRaw(core.ns["+"], MalInt(1), MalList([]), Env(None)).is_macro(), )
def test_print_function(self): self.assertEqual("#<function>", str(MalFunctionCompiled(lambda x: MalInt(0))))
from typing import Dict import reader from env import Env from mal_types import ( MalExpression, MalSymbol, MalInvalidArgumentException, MalUnknownSymbolException, MalSyntaxException, ) from mal_types import MalInt, MalList, MalFunctionCompiled, MalVector, MalHash_map repl_env = Env(None) repl_env.set( "+", MalFunctionCompiled(lambda a: MalInt(a[0].native() + a[1].native()))) repl_env.set( "-", MalFunctionCompiled(lambda a: MalInt(a[0].native() - a[1].native()))) repl_env.set( "*", MalFunctionCompiled(lambda a: MalInt(a[0].native() * a[1].native()))) repl_env.set( "/", MalFunctionCompiled(lambda a: MalInt(int(a[0].native() / a[1].native())))) def READ(x: str) -> MalExpression: return reader.read(x) def eval_ast(ast: MalExpression, env: Env) -> MalExpression: if isinstance(ast, MalSymbol):