Beispiel #1
0
def simplify(expr, env):
    if isinstance(expr, sym):
        try:
            return env[expr]
        except KeyError:
            raise NameError("symbol %s is not defined"%(expr,))
    elif isinstance(expr, hack):
        return simplify(expr[0], expr[1])
    elif isinstance(expr, linked_list):
        f = expr[0]
        if isinstance(f, jcli_parser.syntax):
            f=f.value
        if f == sym('define'):
            if len(expr) != 3:
                raise SyntaxError("bad syntax in define")
            env[expr[1].value] = eval_ast(expr[2], env)
        elif f == sym('lambda'):
            if len(expr) != 3:
                raise SyntaxError("bad syntax in lambda")                
            arg_names = expr[1].value
            body = expr[2]
            def function(*args):
                c = closure(env)
                if len(arg_names) != len(args):
                    raise TypeError(
                        'function expected %s arguments, got %s'
                        %(len(arg_names), len(args)))
                for arg_name, arg in zip(arg_names, args):
                    c[arg_name.value] = arg
                out = hack((body.value, c))
                return out
            return function
        elif f == sym('if'):
            if len(expr) != 4:
                raise SyntaxError("bad syntax in if")
            if eval_ast(expr[1], env):
                return hack((expr[2].value, env))
            else:
                return hack((expr[3].value, env))
        elif f == sym('quote'):
            if len(expr) != 2:
                raise SyntaxError("bad syntax in quote")
            return quote(jcli_parser.syntax_to_list(expr[1]))
        elif f == sym('begin'):
            out = None
            for sub_expr in cdr(expr):
                out = eval_ast(sub_expr, env)
            return out
        else:
            return apply(
                eval_ast(expr[0], env),
                map(lambda x: eval_ast(x, env), cdr(expr)))
    else:
        return expr
Beispiel #2
0
def eval(string, bindings=None, builtins=None):
    if builtins is None:
        builtins = jcli_globals
    if bindings is None:
        bindings = closure(builtins)
    else:
    	bindings = {sym(k): bindings[k] for k in bindings.keys()}
        bindings.update(builtins)
    asts = jcli_parser.parse(string)
    return list(map(lambda ast: eval_ast(ast, bindings), asts))
Beispiel #3
0
def match_quote(tokens):
    if len(tokens) < 2:
        return None
    if tokens[0].name != "QUOTE":
        return None
    match = match_expr(tokens[1:])
    if match is not None:
        t = tokens[0]
        quote = syntax(sym("quote"), t.line_no, t.char_no)
        expr = linked_list([quote, match[0]])
        return syntax(expr, t.line_no, t.char_no), match[1] + 1
Beispiel #4
0
def match_literal(tokens):
    if len(tokens) == 0:
        return None
    token = tokens[0]
    name = token.name
    string = token.string
    value = None
    if name == "INTEGER":
        value = int(string)
    if name == "FLOAT":
        value = float(string)
    if name == "BOOL":
        value = bool(string)
    if name == "STRING":
        value = str(string)
    if name == "ID":
        value = sym(string)
    if value is not None:
        return syntax(value, token.line_no, token.char_no), 1
Beispiel #5
0
from jcli_datatypes import linked_list, sym, quote, closure, car, cdr, cons, null

import jcli_tokenizer
import jcli_parser
import operator

jcli_globals = {
    sym('eval'): lambda x: (
        eval_ast(x.value, closure(jcli_globals))
        if isinstance(x, quote)
        else x),
    sym('+'): operator.add,
    sym('-'): operator.sub,
    sym('*'): operator.mul,
 #   sym('/'): operator.div,
    sym('='): operator.eq,
    sym('or'): lambda x,y: x or y,
    sym('and'): lambda x,y: x and y,
    sym('not'): lambda x: not x,
    sym('cons'): lambda x,y: cons(x, y.value),
    sym('car'): lambda x: car(x.value),
    sym('cdr'): lambda x: cdr(x.value),}

def eval(string, bindings=None, builtins=None):
    if builtins is None:
        builtins = jcli_globals
    if bindings is None:
        bindings = closure(builtins)
    else:
    	bindings = {sym(k): bindings[k] for k in bindings.keys()}
        bindings.update(builtins)