Пример #1
0
Файл: core.py Проект: catb0t/mal
def conj(args):
    lst, args = args[0], args.rest()
    new_lst = None
    if types._list_Q(lst):
        vals = args.values[:]
        vals.reverse()
        new_lst = MalList(vals + lst.values)
    elif types._vector_Q(lst):
        new_lst = MalVector(lst.values + list(args.values))
    else:
        throw_str("conj on non-list/non-vector")
    new_lst.meta = lst.meta
    return new_lst
Пример #2
0
def eval_ast(ast: MalExpression, env: Env) -> MalExpression:
    if isinstance(ast, MalSymbol):
        return env.get(ast)
    if isinstance(ast, MalList):
        return MalList([EVAL(x, env) for x in ast.native()])
    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)
    return ast
Пример #3
0
def entry_point(argv):
    repl_env = Env()

    def REP(str, env):
        return PRINT(EVAL(READ(str), env))

    # core.py: defined using python
    for k, v in core.ns.items():
        repl_env.set(_symbol(unicode(k)), MalFunc(v))
    repl_env.set(types._symbol(u'eval'),
                 MalEval(None, env=repl_env, EvalFunc=EVAL))
    mal_args = []
    if len(argv) >= 3:
        for a in argv[2:]:
            mal_args.append(MalStr(unicode(a)))
    repl_env.set(_symbol(u'*ARGV*'), MalList(mal_args))

    # core.mal: defined using the language itself
    REP("(def! *host-language* \"rpython\")", repl_env)
    REP("(def! not (fn* (a) (if a false true)))", repl_env)
    REP(
        "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))",
        repl_env)
    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)

    if len(argv) >= 2:
        REP('(load-file "' + argv[1] + '")', repl_env)
        return 0

    REP("(println (str \"Mal [\" *host-language* \"]\"))", repl_env)
    while True:
        try:
            line = mal_readline.readline("user> ")
            if line == "": continue
            print(REP(line, repl_env))
        except EOFError as e:
            break
        except reader.Blank:
            continue
        except types.MalException as e:
            print(u"Error: %s" % printer._pr_str(e.object, False))
        except Exception as e:
            print("Error: %s" % e)
            if IS_RPYTHON:
                llop.debug_print_traceback(lltype.Void)
            else:
                print("".join(traceback.format_exception(*sys.exc_info())))
    return 0
Пример #4
0
 def test_let_multiple(self):
     env = Env(None)
     env.set(
         "+",
         mal_types.MalFunctionCompiled(
             lambda a: MalInt(a[0].native() + a[1].native())),
     )
     self.assertEqual(
         5,
         step3_env.EVAL(
             MalList([
                 MalSymbol("let*"),
                 MalList(
                     [MalSymbol("c"),
                      MalInt(2),
                      MalSymbol("d"),
                      MalInt(3)]),
                 MalList([MalSymbol("+"),
                          MalSymbol("c"),
                          MalSymbol("d")]),
             ]),
             env,
         ).native(),
     )
Пример #5
0
def main():
    rep("(def! not (fn* (a) (if a false true)))")
    rep("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\\nnil)\")))))")
    argv_lst = MalList("(")
    argv_lst += ['"' + reader.read_str(x) + '"' for x in sys.argv[2:]]
    repl_env.set_("*ARGV*", argv_lst)
    if len(sys.argv) > 1:
        rep("(load-file \"" + sys.argv[1] + '")')
        return
    while 1:
        try:
            read_str = input("user> ")
        except EOFError:
            break
        print(rep(read_str))
Пример #6
0
def apply(x, *y):
    assert type(y[-1] == MalList)
    tmp = MalList("(")
    for i in y[:-1]:
        tmp.append(i)
    tmp.extend(y[-1])
    if type(x) == dict:
        return x["fn"](*tmp)
    else:
        return x(*tmp)
Пример #7
0
def main():
    rep("(def! not (fn* (a) (if a false true)))")
    rep("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\\nnil)\")))))")
    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)))))))")
    argv_lst = MalList("(")
    argv_lst += ['"' + reader.read_str(x) + '"' for x in sys.argv[2:]]
    repl_env.set_("*ARGV*", argv_lst)
    if len(sys.argv) > 1:
        rep("(load-file \"" + sys.argv[1] + '")')
        return
    while 1:
        try:
            read_str = input("user> ")
        except EOFError:
            break
        print(rep(read_str))
Пример #8
0
 def __init__(
     self,
     outer: Optional["Env"],
     binds: Optional[List[MalExpression]] = None,
     exprs: Optional[List[MalExpression]] = None,
 ) -> None:
     self._outer = outer
     self._data: Dict[str, MalExpression] = {}
     if binds is not None and exprs is not None:
         for x in range(0, len(binds)):
             assert isinstance(binds[x], MalSymbol)
             if binds[x].native() == "&":
                 self.set(str(binds[x + 1]), MalList(exprs[x:]))
                 break
             else:
                 self.set(str(binds[x]), exprs[x])
Пример #9
0
def dissoc(args: List[MalExpression]) -> MalExpression:
    if len(args) == 0:
        raise MalInvalidArgumentException(MalNil(),
                                          "no arguments supplied to dissoc")
    elif len(args) == 1:
        return args[0]
    if not isinstance(args[0], MalHash_map):
        raise MalInvalidArgumentException(args[0], "not a hash map")
    dict_a_copy: Dict[str, MalExpression] = args[0].native().copy()
    list_b: List[MalExpression] = MalList(args[1:]).native()
    for key in list_b:
        try:
            del dict_a_copy[key.unreadable_str()]
        except KeyError:
            pass
    return MalHash_map(dict_a_copy)
Пример #10
0
def eval_ast(ast: MalExpression,
             env: Dict[str, MalFunctionCompiled]) -> MalExpression:
    if isinstance(ast, MalSymbol):
        try:
            return env[str(ast)]
        except KeyError:
            raise MalUnknownSymbolException(str(ast))
    if isinstance(ast, MalList):
        return MalList([EVAL(x, env) for x in ast.native()])
    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)
    return ast
Пример #11
0
def entry_point(argv):
    repl_env = Env()

    def REP(str, env):
        return PRINT(EVAL(READ(str), env))

    # core.py: defined using python
    for k, v in core.ns.items():
        repl_env.set(_symbol(unicode(k)), MalFunc(v))
    repl_env.set(types._symbol(u'eval'),
                 MalEval(None, env=repl_env, EvalFunc=EVAL))
    mal_args = []
    if len(argv) >= 3:
        for a in argv[2:]:
            mal_args.append(MalStr(unicode(a)))
    repl_env.set(_symbol(u'*ARGV*'), MalList(mal_args))

    # core.mal: defined using the language itself
    REP("(def! not (fn* (a) (if a false true)))", repl_env)
    REP(
        "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))",
        repl_env)

    if len(argv) >= 2:
        REP('(load-file "' + argv[1] + '")', repl_env)
        return 0

    while True:
        try:
            line = mal_readline.readline("user> ")
            if line == "": continue
            print(REP(line, repl_env))
        except EOFError as e:
            break
        except reader.Blank:
            continue
        except types.MalException as e:
            print(u"Error: %s" % printer._pr_str(e.object, False))
        except Exception as e:
            print("Error: %s" % e)
            #print("".join(traceback.format_exception(*sys.exc_info())))
    return 0
Пример #12
0
def eval_ast(ast, env):
    if types._symbol_Q(ast):
        assert isinstance(ast, MalSym)
        return env.get(ast)
    elif types._list_Q(ast):
        res = []
        for a in ast.values:
            res.append(EVAL(a, env))
        return MalList(res)
    elif types._vector_Q(ast):
        res = []
        for a in ast.values:
            res.append(EVAL(a, env))
        return MalVector(res)
    elif types._hash_map_Q(ast):
        new_dct = {}
        for k in ast.dct.keys():
            new_dct[k] = EVAL(ast.dct[k], env)
        return MalHashMap(new_dct)
    else:
        return ast  # primitive value, return unchanged
Пример #13
0
def assoc(x, *y):
    assert len(y) % 2 == 0
    assert type(x) == MalList and x.opener == "{"

    tmp = MalList("{")
    tmp_dict = {}

    for i in range(0, len(x), 2):
        tmp_dict[x[i]] = x[i + 1]

    for i in range(0, len(y), 2):
        tmp_dict[y[i]] = y[i + 1]

    for key in tmp_dict:
        tmp.append(key)
        tmp.append(tmp_dict[key])

    return tmp
Пример #14
0
def vals(args):
    hm = args[0]
    return MalList(hm.dct.values())
Пример #15
0
def keys(args):
    hm = args[0]
    keys = []
    for k in hm.dct.keys(): keys.append(MalStr(k))
    return MalList(keys)
Пример #16
0
def EVAL(ast: MalExpression, env: Env) -> MalExpression:
    while True:
        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))
        ast_native = ast.native()
        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
        elif len(ast_native) == 0:
            return ast

        first_str = str(ast_native[0])
        if first_str == "def!":
            name: str = str(ast_native[1])
            value: MalExpression = EVAL(ast_native[2], env)
            return env.set(name, value)
        elif first_str == "let*":
            assert len(ast_native) == 3
            let_env = Env(env)
            bindings: MalExpression = ast_native[1]
            assert isinstance(bindings, MalList) or isinstance(
                bindings, MalVector)
            bindings_list: List[MalExpression] = 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))
            env = let_env
            ast = ast_native[2]
            continue
        elif first_str == "do":
            for x in range(1, len(ast_native) - 1):
                EVAL(ast_native[x], env)
            ast = ast_native[len(ast_native) - 1]
            continue
        elif first_str == "if":
            condition = EVAL(ast_native[1], env)

            if isinstance(condition,
                          MalNil) or (isinstance(condition, MalBoolean)
                                      and condition.native() is False):
                if len(ast_native) >= 4:
                    ast = ast_native[3]
                    continue
                else:
                    return MalNil()
            else:
                ast = ast_native[2]
                continue
        elif first_str == "fn*":
            raw_ast = ast_native[2]
            raw_params = ast_native[1]

            def fn(args: List[MalExpression]) -> MalExpression:
                f_ast = raw_ast
                f_env = Env(outer=env, binds=raw_params.native(), exprs=args)
                return EVAL(f_ast, f_env)

            return MalFunctionRaw(fn=fn,
                                  ast=raw_ast,
                                  params=raw_params,
                                  env=env)
        elif first_str == "quote":
            return (MalList(ast_native[1].native()) if isinstance(
                ast_native[1], MalVector) else ast_native[1])
        elif first_str == "quasiquote":
            ast = quasiquote(ast_native[1])
            continue
        else:
            f, *args = (EVAL(form, env) for form in ast_native)
            if isinstance(f, MalFunctionRaw):
                ast = f.ast()

                env = Env(
                    outer=f.env(),
                    binds=f.params().native(),
                    exprs=args,
                )
                continue
            elif isinstance(f, MalFunctionCompiled):
                return f.call(args)
            else:
                raise MalInvalidArgumentException(f, "not a function")
Пример #17
0
def qq_foldr(xs: List[MalExpression]) -> MalList:
    return functools.reduce(qq_loop, reversed(xs), MalList([]))
Пример #18
0
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()
Пример #19
0
def concat(args: List[MalExpression]) -> MalExpression:
    result_list: List[MalExpression] = []
    for x in args:
        assert isinstance(x, MalList) or isinstance(x, MalVector)
        result_list = result_list + x.native()
    return MalList(result_list)
Пример #20
0
def concat(*a):
    temp = MalList("(")
    for next_list in a:
        for next_item in next_list:
            temp.append(next_item)
    return temp
Пример #21
0
def vec(a):
    temp = MalList("[")
    temp.extend(a)
    return temp
Пример #22
0
def eval_(ast, env: Env):
    while 1:
        ast = macroexpand(ast, env)
        if type(ast) != MalList or ast.opener != "(":
            return eval_ast(ast, env)
        if len(ast) == 0:
            return ast

        if ast[0] == "def!":
            second_param = eval_(ast[2], env)
            env.set_(ast[1], second_param)
            return second_param
        if ast[0] == "let*":
            let_env = Env(env)
            bindings = ast[1]
            i = 0
            while 1:
                try:
                    let_env.set_(bindings[i], eval_(bindings[i + 1], let_env))
                    i += 2
                except IndexError:
                    break
            env = let_env
            ast = ast[2]
            continue
        if ast[0] == "do":
            do_ast = MalList("(")
            do_ast += ast[1:-1]
            eval_ast(do_ast, env)
            ast = ast[-1]
            continue
        if ast[0] == "if":
            cond = eval_(ast[1], env)
            if cond == 0 and type(cond) == int:
                cond = True # Counting number 0 as True
            if cond is None:
                cond = False
            if cond != False:
                ast = ast[2]
                continue
            if cond == False and len(ast) <= 3:
                return None
            ast = ast[3]
            continue
        if ast[0] == "fn*":
            def closure(binds, exprs, *args):
                fn_env = Env(env, binds=binds, exprs=args)
                return eval_(exprs, fn_env)
            return {
                    "ast": ast[2],
                    "params": ast[1],
                    "env": env,
                    "fn": lambda *x: closure(ast[1], ast[2], *x),
                    }
        if ast[0] == "quote":
            return ast[1]
        if ast[0] == "quasiquote" or ast[0] == "quasiquoteexpand":
            def quasiquote(param):
                def in_list(param):
                    res = MalList("(")
                    for elt in reversed(param):
                        if type(elt) == MalList and len(elt) > 1 and elt[0] == "splice-unquote":
                            tmp = MalList("(")
                            tmp.append("concat")
                            tmp.append(elt[1])
                            tmp.append(res)
                            res = tmp
                        else:
                            tmp = MalList("(")
                            tmp.append("cons")
                            tmp.append(quasiquote(elt))
                            tmp.append(res)
                            res = tmp
                    return res
                if type(param) == MalList and param.opener == "(" and len(param) > 0 and param[0] == "unquote":
                    return param[1]
                elif type(param) == MalList and param.opener == "(":
                    return in_list(param)
                elif (type(param) == MalList and param.opener == "{") or (type(param) == str):
                    tmp = MalList("(")
                    tmp.append("quote")
                    tmp.append(param)
                    return tmp
                elif type(param) == MalList and param.opener == "[":
                    tmp = MalList("(")
                    tmp.append("vec")
                    tmp.append(in_list(param))
                    return tmp
                else:
                    return param

            if ast[0] == "quasiquote":
                ast = quasiquote(ast[1])
                continue
            else:
                return quasiquote(ast[1])

        if ast[0] == "defmacro!":
            second_param = eval_(ast[2], env)
            if type(second_param) != dict:
                second_param.is_macro = True 
            else:
                second_param["is_macro"] = True
            env.set_(ast[1], second_param)
            return second_param
        if ast[0] == "macroexpand":
            return macroexpand(ast[1], env)
        else:
            eval_list = eval_ast(ast, env)
            if type(eval_list[0]) == dict:
                f = eval_list[0]
                ast = f["ast"]
                env = Env(outer=f["env"], binds=f["params"], exprs=eval_list[1:])
                continue
            else:
                return eval_list[0](*eval_list[1:])
Пример #23
0
 def in_list(param):
     res = MalList("(")
     for elt in reversed(param):
         if type(elt) == MalList and len(elt) > 1 and elt[0] == "splice-unquote":
             tmp = MalList("(")
             tmp.append("concat")
             tmp.append(elt[1])
             tmp.append(res)
             res = tmp
         else:
             tmp = MalList("(")
             tmp.append("cons")
             tmp.append(quasiquote(elt))
             tmp.append(res)
             res = tmp
     return res
Пример #24
0
def rest(x):
    temp = MalList("(")
    if x is not None and len(x) > 0:
        temp += x[1:]
    return temp
Пример #25
0
 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)),
 "list":
 MalFunctionCompiled(lambda args: MalList(args)),
 "list?":
 MalFunctionCompiled(lambda args: list_q(args[0])),
 "empty?":
 MalFunctionCompiled(lambda args: empty_q(args[0])),
 "count":
 MalFunctionCompiled(lambda args: count(args[0])),
 "=":
 MalFunctionCompiled(lambda args: equal(args[0], args[1])),
 "<":
 MalFunctionCompiled(lambda args: less(args[0], args[1])),
 "<=":
 MalFunctionCompiled(lambda args: less_equal(args[0], args[1])),
 ">":
 MalFunctionCompiled(lambda args: less(args[1], args[0])),
 ">=":
Пример #26
0
def cons(args):
    x, seq = args[0], args[1]
    if not isinstance(seq, MalList):
        throw_str("cons called with non-list/non-vector")
    return MalList([x] + seq.values)
Пример #27
0
def EVAL(ast: MalExpression, env: Env) -> MalExpression:
    while True:
        ast = macroexpand(ast, env)
        ast_native = ast.native()
        if not isinstance(ast, MalList):
            return eval_ast(ast, env)
        elif len(ast_native) == 0:
            return ast

        first_str = str(ast_native[0])
        if first_str == "macroexpand":
            return macroexpand(ast.native()[1], env)
        elif first_str == "def!":
            name: str = str(ast_native[1])
            value: MalExpression = EVAL(ast_native[2], env)
            return env.set(name, value)
        if first_str == "defmacro!":
            name = str(ast_native[1])
            value = EVAL(ast_native[2], env)
            assert isinstance(value, MalFunctionCompiled) or isinstance(
                value, MalFunctionRaw)
            value.make_macro()
            return env.set(name, value)
        elif first_str == "let*":
            assert len(ast_native) == 3
            let_env = Env(env)
            bindings: MalExpression = ast_native[1]
            assert isinstance(bindings, MalList) or isinstance(
                bindings, MalVector)
            bindings_list: List[MalExpression] = 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))
            env = let_env
            ast = ast_native[2]
            continue
        elif first_str == "do":
            for x in range(1, len(ast_native) - 1):
                EVAL(ast_native[x], env)
            ast = ast_native[len(ast_native) - 1]
            continue
        elif first_str == "if":
            condition = EVAL(ast_native[1], env)

            if isinstance(condition,
                          MalNil) or (isinstance(condition, MalBoolean)
                                      and condition.native() is False):
                if len(ast_native) >= 4:
                    ast = ast_native[3]
                    continue
                else:
                    return MalNil()
            else:
                ast = ast_native[2]
                continue
        elif first_str == "fn*":
            raw_ast = ast_native[2]
            raw_params = ast_native[1]

            def fn(args: List[MalExpression]) -> MalExpression:
                f_ast = raw_ast
                f_env = Env(outer=env, binds=raw_params.native(), exprs=args)
                return EVAL(f_ast, f_env)

            return MalFunctionRaw(fn=fn,
                                  ast=raw_ast,
                                  params=raw_params,
                                  env=env)
        elif first_str == "quote":
            return (MalList(ast_native[1].native()) if isinstance(
                ast_native[1], MalVector) else ast_native[1])
        elif first_str == "quasiquote":
            ast = quasiquote(ast_native[1])
            continue
        elif first_str == "try*":
            try:
                return EVAL(ast_native[1], env)
            except MalException as e:
                if len(ast_native) < 3:
                    raise e
                catch_block = ast_native[2]
                assert (isinstance(catch_block, MalList)
                        and isinstance(catch_block.native()[0], MalSymbol)
                        and str(catch_block.native()[0]) == "catch*"
                        and len(catch_block.native()) == 3)
                exception_symbol = catch_block.native()[1]
                assert isinstance(exception_symbol, MalSymbol)
                env = Env(env)
                env.set(str(exception_symbol), e.native())
                ast = catch_block.native()[2]
                continue
        else:
            evaled_ast = eval_ast(ast, env)
            f = evaled_ast.native()[0]
            args = evaled_ast.native()[1:]
            if isinstance(f, MalFunctionRaw):
                ast = f.ast()

                env = Env(
                    outer=f.env(),
                    binds=f.params().native(),
                    exprs=evaled_ast.native()[1:],
                )
                continue
            elif isinstance(f, MalFunctionCompiled):
                return f.call(args)
            else:
                raise MalInvalidArgumentException(f, "not a function")
Пример #28
0
def cons(a, b):
    temp = MalList("(")
    temp.append(a)
    for next_item in b:
        temp.append(next_item)
    return temp
Пример #29
0

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")
Пример #30
0
 def quasiquote(param):
     def in_list(param):
         res = MalList("(")
         for elt in reversed(param):
             if type(elt) == MalList and len(elt) > 1 and elt[0] == "splice-unquote":
                 tmp = MalList("(")
                 tmp.append("concat")
                 tmp.append(elt[1])
                 tmp.append(res)
                 res = tmp
             else:
                 tmp = MalList("(")
                 tmp.append("cons")
                 tmp.append(quasiquote(elt))
                 tmp.append(res)
                 res = tmp
         return res
     if type(param) == MalList and param.opener == "(" and len(param) > 0 and param[0] == "unquote":
         return param[1]
     elif type(param) == MalList and param.opener == "(":
         return in_list(param)
     elif (type(param) == MalList and param.opener == "{") or (type(param) == str):
         tmp = MalList("(")
         tmp.append("quote")
         tmp.append(param)
         return tmp
     elif type(param) == MalList and param.opener == "[":
         tmp = MalList("(")
         tmp.append("vec")
         tmp.append(in_list(param))
         return tmp
     else:
         return param
Пример #31
0
def cons(first: MalExpression, rest: MalExpression) -> MalExpression:
    assert isinstance(rest, MalList) or isinstance(rest, MalVector)
    return MalList([first] + rest.native())