Beispiel #1
0
def func_get(hm, key):
    if not isinstance(hm, parser.LispHashMap):
        return parser.NilSymbol()
    v = hm.lookup(key)
    if v is None:
        return parser.NilSymbol()
    else:
        return v
Beispiel #2
0
def func_seq(arg):
    if (isinstance(arg, parser.NilSymbol)):
        return parser.NilSymbol()
    if (isinstance(arg, parser.LispList)
            or isinstance(arg, parser.LispVector)):
        if len(arg.values) == 0:
            return parser.NilSymbol()
        return parser.LispList(arg.values)
    if isinstance(arg, parser.LispString):
        if len(arg.str) == 0:
            return parser.NilSymbol()
        return parser.LispList([parser.LispString(x) for x in list(arg.str)])
Beispiel #3
0
def func_prn(*args):
    outs = ""
    for a in args:
        s = printer.pr_str(a, True)
        outs += s
    print(outs)
    return parser.NilSymbol()
Beispiel #4
0
def read_atom(readerInst):
    """ this function will look at the contents of the token and return the appropriate scalar (simple/single) data type value. Initially, you can just implement numbers(integers) and symbols. This will allow you to proceed through the next couple of steps before you will need to implement the other fundamental MAL types: nil, true, false, and string. The remaining MAL types: keyword, vector, hash-map, and atom do not need to be implemented until step 9 (but can be implemented at any point between this step and that). BTW, symbol types are just objects that contain a single string name value."""

    if not readerInst.has_token():
        raise SyntaxError('reached EOF')

    malItem = readerInst.next()

    try:
        intNum = int(malItem)
        return parser.IntSymbol(intNum)
    except ValueError:
        #print ("malItem:", malItem)
        #print ("len:", len(malItem))
        if ((len(malItem) > 1) and (malItem[0] == '"')
                and (malItem[-1] == '"')):
            s = printer.unescape(malItem[1:-1])
            #print ("making lisp string:", s)
            #for i,c in enumerate(s):
            #    print (i, c)
            return parser.LispString(s)

        if ((len(malItem) > 1) and (malItem[0] == ':')):
            s = malItem[1:]
            return parser.LispKeyword(s)
        if malItem == 'nil':
            return parser.NilSymbol()
        elif malItem == 'true':
            return parser.TrueSymbol()
        elif malItem == 'false':
            return parser.FalseSymbol()
        else:
            return parser.StrSymbol(malItem)
Beispiel #5
0
def func_first(arg):
    if isinstance(arg, parser.NilSymbol):
        return arg
    if (isinstance(arg, parser.LispList)
            or isinstance(arg, parser.LispVector)):
        if len(arg.values) == 0:
            return parser.NilSymbol()
        return arg.values[0]
    raise ArgumentError("should be list or vector")
Beispiel #6
0
def func_readline(arg):
    prompt = printer.pr_str(arg, False)

    try:
        if sys.version_info[0] >= 3:
            #print(prompt, end='', flush=True)
            in_str = input(prompt)
        else:
            in_str = raw_input(prompt)
        return parser.LispString(in_str)
    except EOFError:
        return parser.NilSymbol()
Beispiel #7
0
def func_conj(*args):
    first = args[0]
    first_values = list(first.values)
    #print(type(first))
    #print(type(first.values))
    rest = list(args[1:])
    #print(type(rest))
    if isinstance(first, parser.LispList):
        rest.reverse()
        return parser.LispList(rest + first_values)
    if isinstance(first, parser.LispVector):
        return parser.LispVector(first_values + rest)
    return parser.NilSymbol()
Beispiel #8
0
def EVAL(ast, env):
    while True:
        #print ("evaluating", ast)
        if not isinstance(ast, parser.LispList):
            return eval_ast(ast, env)
        if len(ast.values) == 0:
            return ast

        ast = macro_expand(ast, env)
        if not isinstance(ast, parser.LispList):
            return eval_ast(ast, env)
        
        op = ast.values[0]
        #print ("op", op)
        if isinstance(op, parser.StrSymbol) and op.val == 'def!':
            """call the set method of the current environment (second parameter of
            EVAL called env) using the unevaluated first parameter (second
            list element) as the symbol key and the evaluated second
            parameter as the value."""
            val = EVAL(ast.values[2], env)
            env.set(ast.values[1].val, val)
            return val
        if isinstance(op, parser.StrSymbol) and op.val == 'defmacro!':
            val = EVAL(ast.values[2], env)
            val.setMacro(True)
            env.set(ast.values[1].val, val)
            return val
        elif isinstance(op, parser.StrSymbol) and op.val == 'let*':
            newenv = environment.Environment(env, [], [])
            for i in range(0, len(ast.values[1].values), 2):
                name = ast.values[1].values[i].val
                val = EVAL(ast.values[1].values[i+1], newenv)
                newenv.set(name, val)
            env = newenv
            ast = ast.values[2]
            continue
        elif isinstance(op, parser.StrSymbol) and op.val == 'do':
            ret = None
            for t in ast.values[1:-1]:
                #print ("evaluating",t)
                ret = EVAL(t, env)
                #print ("got ret")
                #print ("env:", env)
            ast = ast.values[-1]
            continue
        elif isinstance(op, parser.StrSymbol) and op.val == 'if':
            #print ("evaluating if")
            test = EVAL(ast.values[1], env)
            #print ("test:", test)
            if not (isinstance(test, parser.NilSymbol) or isinstance(test, parser.FalseSymbol)):
                # true eval
                #print ("test was true, evaluating", ast.values[2])
                ast = ast.values[2]
                continue
            elif len(ast.values) > 3:
                #print ("test was false, evaluating else", ast.values[3])
                #else
                ast = ast.values[3]
                continue
            else:
                #print ("test was false, returning Nil")
                return parser.NilSymbol()
        elif isinstance(op, parser.StrSymbol) and op.val == 'fn*':
            newenv = environment.Environment(env, [], [])
            params = [x.val for x in ast.values[1].values]
            body = ast.values[2]
            #print ("making func", params, body)
            funcClosure = parser.FuncClosure(newenv, params, body, EVAL)
            return funcClosure
        elif isinstance(op, parser.StrSymbol) and op.val == 'quote':
            return ast.values[1]
        elif isinstance(op, parser.StrSymbol) and op.val == 'quasiquote':
            ast = quasiquote(ast.values[1])
            continue
        elif isinstance(op, parser.StrSymbol) and op.val == 'macroexpand':
            return macro_expand(ast.values[1], env)
        elif isinstance(op, parser.StrSymbol) and op.val == 'try*':
            catchop = ast.values[2].values[0]
            if isinstance(catchop, parser.StrSymbol) and catchop.val == 'catch*':
                try:
                    return EVAL(ast.values[1], env)
                except parser.MalException as me:
                    ex_label = ast.values[2].values[1].val
                    newenv = environment.Environment(env, [ex_label], [me.mal_obj])
                    return EVAL(ast.values[2].values[2], newenv)
                    
                except Exception as e:
                    ex_label = ast.values[2].values[1].val
                    ex_str = parser.LispString(str(e))
                    newenv = environment.Environment(env, [ex_label], [ex_str])
                    return EVAL(ast.values[2].values[2], newenv)
            else:
                return EVAL(ast.values[1], env)
        else:
            ast_list = eval_ast(ast, env)
            
            if isinstance(ast_list.values[0], parser.FuncClosure):
                func = ast_list.values[0]

                ast = func.body
                env = func.prepareEnv(ast_list.values[1:])
                continue
    
            #print ("about to call", ast_list.values[0])
            
            return ast_list.values[0](*ast_list.values[1:])
Beispiel #9
0
def func_meta(arg):
    if hasattr(arg, "metadata"):
        return arg.metadata
    else:
        return parser.NilSymbol()
Beispiel #10
0
def func_println(*args):
    strings = [printer.pr_str(a, False) for a in args]
    joined = " ".join(strings)
    print(joined)
    return parser.NilSymbol()
Beispiel #11
0
def EVAL(ast, env):
    while True:
        #print ("evaluating", ast)
        if not isinstance(ast, parser.LispList):
            return eval_ast(ast, env)
        if len(ast.values) == 0:
            return ast

        op = ast.values[0]
        #print ("op", op)
        if isinstance(op, parser.StrSymbol) and op.val == 'def!':
            """call the set method of the current environment (second parameter of
            EVAL called env) using the unevaluated first parameter (second
            list element) as the symbol key and the evaluated second
            parameter as the value."""
            val = EVAL(ast.values[2], env)
            env.set(ast.values[1].val, val)
            return val
        elif isinstance(op, parser.StrSymbol) and op.val == 'let*':
            newenv = environment.Environment(env)
            for i in range(0, len(ast.values[1]), 2):
                name = ast.values[1][i].val
                val = EVAL(ast.values[1][i + 1], newenv)
                newenv.set(name, val)
            env = newenv
            ast = ast.values[2]
            continue
        elif isinstance(op, parser.StrSymbol) and op.val == 'do':
            ret = None
            for t in ast.values[1:-1]:
                #print ("evaluating",t)
                ret = EVAL(t, env)
                #print ("got ret")
                #print ("env:", env)
            ast = ast.values[-1]
            continue
        elif isinstance(op, parser.StrSymbol) and op.val == 'if':
            #print ("evaluating if")
            test = EVAL(ast.values[1], env)
            #print ("test:", test)
            if not (isinstance(test, parser.NilSymbol)
                    or isinstance(test, parser.FalseSymbol)):
                # true eval
                #print ("test was true, evaluating", ast.values[2])
                ast = ast.values[2]
                continue
            elif len(ast.values) > 3:
                #print ("test was false, evaluating else", ast.values[3])
                #else
                ast = ast.values[3]
                continue
            else:
                #print ("test was false, returning Nil")
                return parser.NilSymbol()
        elif isinstance(op, parser.StrSymbol) and op.val == 'fn*':
            newenv = environment.Environment(env, [], [])
            params = [x.val for x in ast.values[1].values]
            body = ast.values[2]
            #print ("making func", params, body)
            funcClosure = parser.FuncClosure(newenv, params, body, EVAL)
            return funcClosure

        else:
            ast_list = eval_ast(ast, env)

            if isinstance(ast_list.values[0], parser.FuncClosure):
                func = ast_list.values[0]

                ast = func.body
                env = func.prepareEnv(ast_list.values[1:])
                continue

            #print ("about to call", ast_list.values[0])

            return ast_list.values[0](*ast_list.values[1:])