Example #1
0
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
Example #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
Example #3
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
Example #4
0
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)
    f, *args = (EVAL(form, env) for form in ast.native())
    try:
        return f.call(args)
    except AttributeError:
        raise MalInvalidArgumentException(f, "attribute error")
Example #5
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
Example #6
0
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):
        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
    f, *args = (EVAL(form, env) for form in ast.native())
    return f.call(args)
Example #7
0
def do_vector(ml):
    return MalVector(ml.values)
Example #8
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")
Example #9
0
File: core.py Project: jig/mal-fork
def vec(args):
    seq = args[0]
    if isinstance(seq, MalList):
        return MalVector(seq.values)
    else:
        throw_str("vec called on non-sequence")
Example #10
0
def vector(args: List[MalExpression]) -> MalExpression:
    return MalVector(args)
Example #11
0
def EVAL(ast, env):
    while True:
        #print("EVAL %s" % printer._pr_str(ast))
        if types._symbol_Q(ast):
            assert isinstance(ast, MalSym)
            return env.get(ast)
        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)
        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 isinstance(a0, MalSym):
                a0sym = a0.value
            else:
                a0sym = u"__<*fn*>__"

            if u"def!" == a0sym:
                a1, a2 = ast[1], ast[2]
                res = EVAL(a2, env)
                return env.set(a1, res)
            elif u"let*" == a0sym:
                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 u"quote" == a0sym:
                return ast[1]
            elif u"quasiquote" == a0sym:
                ast = quasiquote(ast[1])  # Continue loop (TCO)
            elif u"defmacro!" == a0sym:
                func = EVAL(ast[2], env)
                func.ismacro = True
                return env.set(ast[1], func)
            elif u"try*" == a0sym:
                if len(ast) < 3:
                    return EVAL(ast[1], env)
                a1, a2 = ast[1], ast[2]
                a20 = a2[0]
                if isinstance(a20, MalSym):
                    if a20.value == u"catch*":
                        try:
                            return EVAL(a1, env)
                        except types.MalException as exc:
                            exc = exc.object
                            catch_env = Env(env, _list(a2[1]), _list(exc))
                            return EVAL(a2[2], catch_env)
                        except Exception as exc:
                            exc = MalStr(unicode("%s" % exc))
                            catch_env = Env(env, _list(a2[1]), _list(exc))
                            return EVAL(a2[2], catch_env)
                return EVAL(a1, env)
            elif u"do" == a0sym:
                if len(ast) == 0:
                    return nil
                for i in range(1, len(ast) - 1):
                    EVAL(ast[i], env)
                ast = ast[-1]  # Continue loop (TCO)
            elif u"if" == a0sym:
                a1, a2 = ast[1], ast[2]
                cond = EVAL(a1, env)
                if cond is nil or cond is false:
                    if len(ast) > 3: ast = ast[3]  # Continue loop (TCO)
                    else: return nil
                else:
                    ast = a2  # Continue loop (TCO)
            elif u"fn*" == a0sym:
                a1, a2 = ast[1], ast[2]
                return MalFunc(None, a2, env, a1, EVAL)
            else:
                f = EVAL(a0, env)
                args = ast.rest()
                if f.ismacro:
                    ast = f.apply(ast.rest())  # Continue loop (TCO)
                else:
                    res = []
                    for a in args.values:
                        res.append(EVAL(a, env))
                    el = MalList(res)
                    if isinstance(f, MalFunc):
                        if f.ast:
                            ast = f.ast
                            env = f.gen_env(el)  # Continue loop (TCO)
                        else:
                            return f.apply(el)
                    else:
                        raise Exception("%s is not callable" % f)
Example #12
0
 def visit_mVector(self, node, children) -> MalVector:
     return MalVector(children)
Example #13
0
File: core.py Project: jig/mal-fork
def vec(arg: MalExpression) -> MalExpression:
    assert isinstance(arg, MalList) or isinstance(arg, MalVector)
    return MalVector(arg.native())