예제 #1
0
def rep(line):
    try:
        print(pr_str(eval(read_str(line), repl_env)))
    except Exception as e:
        if isinstance(e.args[0], Val):
            print(pr_str(Val("error", e.args[0])))
        else:
            print(pr_str(Val("error", Val("string", str(e)))))
예제 #2
0
def eval(ast, env):
    if ast.type != "list":
        return eval_ast(ast, env)
    if len(ast.value) == 0:
        return ast

    symbol = ast.value[0].value
    if symbol == "def!":
        evaluated = eval(ast.value[2], env)
        env.set(ast.value[1].value, evaluated)
        return evaluated

    if symbol == "let*":
        new_env = Env(env)
        params = ast.value[1].value

        i = 0
        while i < len(params):
            new_env.set(params[i].value, eval(params[i + 1], new_env))
            i += 2
        return eval(ast.value[2], new_env)

    if symbol == "do":
        evaluated = None
        for i in ast.value[1:]:
            evaluated = eval(i, env)
        return evaluated

    if symbol == "if":
        evaluated = None
        cond = eval(ast.value[1], env)
        if cond.type != "nil" and (cond.type != "bool" or cond.value == True):
            return eval(ast.value[2], env)
        if len(ast.value) > 3:
            return eval(ast.value[3], env)
        return Val("nil", [])
    if symbol == "fn*":
        def func(*exprs_t):
            new_env = Env(env)
            params = ast.value[1].value
            exprs = list(exprs_t)
            i = 0
            while i < len(params):
                if params[i].value == "&":
                    new_env.set(params[i + 1].value, Val("list", exprs[i:]))
                    break
                new_env.set(params[i].value, exprs[i])
                i += 1

            return eval(ast.value[2], new_env)

        return Val("fn", func)
    new_ast = eval_ast(ast, env)
    fn = new_ast.value[0]

    return fn.value(*new_ast.value[1:])
예제 #3
0
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
from reader import read_str, Val
from printer import pr_str
from env import Env
from core import ns

repl_env = Env()
for key in ns:
    repl_env.set(key, ns[key])
repl_env.set("eval", Val("fn", lambda a: eval(a, repl_env)))
repl_env.set("*host-language*", Val("string", "Python"))


def eval_ast(ast, env):
    if ast.type == "symbol":
        return env.get(ast.value)
    if ast.type in ("list", "vector"):
        items = map(lambda ast: eval(ast, env), ast.value)
        return Val(ast.type, items)
    if ast.type == "hashmap":
        new_val = {}
        for key, value in ast.value.items():
            new_val[key] = eval(value, env)
        return Val("hashmap", new_val)
    return ast


def is_pair(ast):