def read_atom(reader): token = reader.peek() try: val = int(token) return mal_types.MalNumber(val) except ValueError: pass if token in _quote_mapping: reader.next() return mal_types.MalList( [mal_types.MalSymbol(_quote_mapping[token]), read_form(reader)]) elif token == '^': reader.next() meta_data = read_form(reader) reader.next() lst = read_form(reader) return mal_types.MalList( [mal_types.MalSymbol("with-meta"), lst, meta_data]) elif token.startswith('"') and token.endswith('"'): return mal_types.MalString( bytes(token[1:-1], "utf-8").decode("unicode_escape")) elif token.startswith(":"): return mal_types.MalKeyword(token) elif token in ('true', 'false'): if token == 'true': return mal_types.MalBool(True) return mal_types.MalBool(False) elif token == 'nil': return mal_types.MalNil() return mal_types.MalSymbol(token) # symbol?
def seq(x): if not x.data: return mal_types.MalNil() elif isinstance(x, mal_types.MalList): return x elif isinstance(x, mal_types.MalVector): return mal_types.MalList(x.data) elif isinstance(x, mal_types.MalString): return mal_types.MalList([mal_types.MalString(i) for i in x.data])
def eval_ast(ast, env): if isinstance(ast, mal_types.MalSymbol): v = env.get(ast) if v is None: raise mal_types.MalException( mal_types.MalString("'{}' not found.".format(ast.data))) return v elif isinstance(ast, mal_types.list_types): class_type = ast.__class__ return class_type([EVAL(i, env) for i in ast]) elif isinstance(ast, mal_types.MalHashMap): return mal_types.MalHashMap( {EVAL(k, env): EVAL(v, env) for k, v in ast.items()}) return ast
def main(): rep("(def! not (fn* (a) (if a false true)))") rep('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))') 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)))))))""") rep("""(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))""") repl_env.set("*ARGV*", mal_types.MalList([mal_types.MalString(i) for i in sys.argv[2:]])) if sys.argv[1:]: rep('(load-file "{}")'.format(sys.argv[1])) exit() while True: try: print(rep(input("user> "))) except mal_types.MalException as e: # raise e print(e) except Exception as e: # raise e print(e)
def main(): rep("(def! not (fn* (a) (if a false true)))") rep('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))' ) repl_env.set( "*ARGV*", mal_types.MalList([mal_types.MalString(i) for i in sys.argv[2:]])) if sys.argv[1:]: rep('(load-file "{}")'.format(sys.argv[1])) exit() while True: try: print(rep(input("user> "))) except mal_types.MalException as e: # raise e print(e) except Exception as e: # raise e print(e)
def slurp(filename): if isinstance(filename, mal_types.MalString): filename = filename.data with open(filename, 'rt') as f: file_content = f.read() return mal_types.MalString(file_content)
def readline(string): try: return mal_types.MalString(input(string)) except EOFError: return mal_types.MalNil()
"empty?": is_empty, "count": lambda x: mal_types.MalNumber(len(x)), "=": equal, "<": lambda x, y: mal_types.MalBool(x.data < y.data), "<=": lambda x, y: mal_types.MalBool(x.data <= y.data), ">": lambda x, y: mal_types.MalBool(x.data > y.data), ">=": lambda x, y: mal_types.MalBool(x.data >= y.data), "pr-str": lambda *args: mal_types.MalString(" ".join( [pr_str(i, print_readably=True) for i in args])), "str": lambda *args: mal_types.MalString("".join( [pr_str(i, print_readably=False) for i in args])), "prn": prn, "println": println, "read-string": read_string, "slurp": slurp, "atom": atom, "atom?": is_atom,