예제 #1
0
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
예제 #2
0
파일: stepA_mal.py 프로젝트: asarhaddon/mal
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
예제 #3
0
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")
예제 #4
0
    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:
예제 #5
0
파일: step3_env.py 프로젝트: asarhaddon/mal
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)
예제 #6
0
파일: core.py 프로젝트: zzhgithub/mal
    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)),
예제 #7
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)
    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")
예제 #8
0
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):
예제 #9
0
 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(),
     )
예제 #10
0
 def test_print_function(self):
     self.assertEqual("#<function>", str(MalFunctionCompiled(lambda x: MalInt(0))))
예제 #11
0
파일: step3_env.py 프로젝트: zzhgithub/mal
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):