def test_step6_standard_string(self): self.assertEqual( '"foo"', step6_file.EVAL(MalString('"foo"'), Env(None)).native()) self.assertEqual('"foo"', step6_file.rep('"foo"').__str__()) self.assertEqual('"foo"', MalString('"foo"').native()) self.assertEqual('"\\"foo\\""', MalString('"foo"').__str__())
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 readline(arg: MalExpression) -> Union[MalString, MalNil]: try: assert isinstance(arg, MalString) line = input(arg.native()) except EOFError: return MalNil() return MalString(line)
def visit_mString(self, node, children) -> MalString: # node.value will have quotes, escape sequences assert type(node.value) is str if node.value[0] != '"': raise Exception( "internal error: parsed a string with no start quote") val: str = node.value if len(val) < 2 or val[-1] != '"': raise MalSyntaxException("unbalanced string") val = val[1:-1] # remove outer quotes # handle escaped characters i = 0 result = "" while i < len(val): if val[i] == "\\": if (i + 1) < len(val): if val[i + 1] == "n": result += "\n" elif val[i + 1] == "\\": result += "\\" elif val[i + 1] == '"': result += '"' i += 2 else: raise MalSyntaxException( "unbalanced string or invalid escape sequence") else: result += val[i] i += 1 return MalString(result)
def keys(args: List[MalExpression]) -> MalExpression: if len(args) != 1: raise MalInvalidArgumentException( MalNil(), "keys requires exactly one argument") if not isinstance(args[0], MalHash_map): raise MalInvalidArgumentException(args[0], "not a hash map") return MalList( [MalString(x, is_already_encoded=True) for x in args[0].native()])
def PRINT(x: MalExpression) -> str: return str(x) def rep(x: str) -> str: return PRINT(EVAL(READ(x), repl_env)) if __name__ == "__main__": # repl loop eof: bool = False rep('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) "\nnil)")))))' ) mal_argv = MalList([MalString(x) for x in sys.argv[2:]]) repl_env.set("*ARGV*", mal_argv) if len(sys.argv) >= 2: file_str = sys.argv[1] rep('(load-file "' + file_str + '")') exit(0) while not eof: try: line = input("user> ") readline.add_history(line) try: print(rep(line)) except MalUnknownSymbolException as e: print("'" + e.func + "' not found")
def pr_str(args: List[MalExpression]) -> MalString: result_string = " ".join(map(lambda x: x.readable_str(), args)) return MalString(result_string)
def keyword(arg: MalExpression) -> MalExpression: assert isinstance(arg, MalString) if arg.is_keyword(): return arg else: return MalString(arg.unreadable_str(), keyword=True)
def core_str(args: List[MalExpression]) -> MalString: result = "" for a in args: result += a.unreadable_str() return MalString(result)
def slurp(filename: MalExpression) -> MalString: assert isinstance(filename, MalString) with open(filename.native(), "r") as the_file: contents = the_file.read() return MalString(contents)
def visit_mKeyword(self, node, children) -> MalString: assert type(node.value) is str assert len(node.value) > 1 return MalString(node.value[1:], keyword=True)
def find(self, key): if key in self.data: return self if self.outer is not None: return self.outer.find(key) raise MalException(MalString("'{}' not found".format(key)))