Example #1
0
def read_form(reader):
    tok = reader.peek()
    val = None
    if not tok:
        val = mtypes.MslNil()
    elif tok[0] == ';':
        reader.next()
        val = None
    elif tok == '\'':
        reader.next()
        return mtypes.MslList([
            mtypes.MslSymbol('quote'),
            read_form(reader)
        ])
    elif tok == '`':
        reader.next()
        return mtypes.MslList([
            mtypes.MslSymbol('quasiquote'),
            read_form(reader)
        ])
    elif tok == '~':
        reader.next()
        return mtypes.MslList([
            mtypes.MslSymbol('unquote'),
            read_form(reader)
        ])
    elif tok == '~@':
        reader.next()
        return mtypes.MslList([
            mtypes.MslSymbol('slice-unquote'),
            read_form(reader)
        ])
    elif tok == '@':
        reader.next()
        return mtypes.MslList([
            mtypes.MslSymbol('deref'),
            read_form(reader)
        ])

    elif tok == ')':
        raise Exception("Unexpected ')' reading form")
    elif tok == '(':
        val = read_list(reader)

    elif tok == ']':
        raise Exception("Unexpected ']'")
    elif tok == '[':
        val = read_vector(reader)

    elif tok == '}':
        raise Exception("Unexpected '}'")
    elif tok == '{':
        val = read_hashmap(reader)

    else:
        val = read_atom(reader)

    return val
Example #2
0
def c_cons(x, seq):
    print('params', x, seq)
    lst1 = mtypes.MslList([x])
    lst2 = mtypes.MslList([seq])
    print('lst1', lst1)
    print('lst2', lst2)
    res = lst1.values + lst2.values
    print('res', res)
    return mtypes.MslList(res)
Example #3
0
File: msl.py Project: lun-4/msli
def quasiquote(ast, qflag=False):
    print("qquote", ast)
    if not is_pair(ast):
        if isinstance(ast, mtypes.MslList):
            if len(ast) > 0:
                return ast[0]
            else:
                return ast
        else:
            if isinstance(ast, mtypes.MslSymbol):
                return mtypes.MslList([
                    mtypes.MslSymbol("quote"),
                    ast
                ])
            else:
                return ast

    elif ast[0] == mtypes.MslSymbol('unquote'):
        return ast[1]

    elif is_pair(ast[0]) and ast[0][0] == mtypes.MslSymbol('splice-unquote'):
        if len(ast[1:]) > 0:
            lst = [
                mtypes.MslSymbol("concat"),
                ast[0][1],
            ]
            lst.append(quasiquote(ast[1:]))
            return mtypes.MslList(lst)
        else:
            lst = [
                ast[0][1],
            ]
            return mtypes.MslList(lst)

    else:
        if len(ast[1:]) > 0:
            lst = [
                mtypes.MslSymbol("cons"),
                quasiquote(ast[0]),
            ]
            lst.append(quasiquote(ast[1:], True))

            return mtypes.MslList(lst)
        else:
            lst = [
                quasiquote(ast[0], True),
            ]
            return mtypes.MslList(lst)
Example #4
0
File: msl.py Project: lun-4/msli
def eval_ast(ast, env):
    if not hasattr(ast, 'type'):
        merror.error("eval_ast: Error evaluating AST(%s) %s" % (type(ast), repr(ast)))

    if ast.type == 'symbol':
        return env.get(ast.symval)
    elif ast.type == 'list':
        res = []
        for e in ast.values:
            evaled = msl_eval(e, env)
            res.append(evaled)
        return mtypes.MslList(res)
    elif ast.type == 'vec':
        res = []
        for e in ast.values:
            evaled = msl_eval(e, env)
            res.append(evaled)
        return mtypes.MslVector(res)
    elif ast.type == 'hashmap':
        newhm = mtypes.MslHashmap([])
        for k in ast.hm:
            newhm.hm[k] = msl_eval(ast.hm[k], env)
        return newhm
    else:
        return ast
Example #5
0
def c_cons(x, y):
    print(x, y)
    newlist = mtypes.MslList([])
    newlist.append(x)
    if isinstance(y, mtypes.MslList):
        #newlist.values.extend(y.values)
        newlist.extend(y)
    else:
        newlist.append(y)
    return newlist
Example #6
0
def c_concat(*args):
    final_lst = mtypes.MslList([])
    for lst in args:
        final_lst.values.extend(lst)
    return final_lst
Example #7
0
def make_list(*args):
    return mtypes.MslList(args)
Example #8
0
File: msl.py Project: lun-4/msli
def msl_eval(ast, env):
    while True:
        # print('ast', repr(ast))
        if hasattr(ast, 'type'):
            if ast.type == 'list':
                if len(ast) == 0:
                    return ast
                else:
                    funcname = ast.values[0]

                    if hasattr(funcname, 'type'):
                        if funcname.type == 'symbol':
                            funcname = funcname.symval

                    if funcname == 'def!':
                        a1, a2 = ast.values[1], ast.values[2]
                        res = msl_eval(a2, env)
                        return env.set(a1.symval, res)

                    elif funcname == "let*":
                        a1, a2 = ast.values[1], ast.values[2]
                        let_env = menv.Enviroment(env)

                        for i in range(0, len(a1), 2):
                            let_env.set(a1.values[i].symval, msl_eval(a1.values[i+1], let_env))
                        env = let_env
                        ast = a2
                        continue

                    elif funcname == 'exit' or funcname == 'quit':
                        a1 = ast.values[1]
                        if not isinstance(a1, mtypes.MslNumber):
                            raise RuntimeError('A number is required')
                        sys.exit(a1.num)

                    elif funcname == 'do':
                        vals = mtypes.MslList(ast.values[1:-1])
                        eval_ast(vals, env)
                        ast = ast[-1]
                        continue

                    elif funcname == 'if':
                        a1, a2 = ast.values[1], ast.values[2]

                        cond = msl_eval(a1, env)

                        if (cond == None) or (not cond):
                            if len(ast.values) > 3:
                                ast = ast.values[3]
                                continue
                            else:
                                ast = None
                                continue
                        else:
                            ast = a2
                            continue

                    elif funcname == 'fn*':
                        a1, a2 = ast.values[1], ast.values[2]
                        return mtypes.MslFunction(msl_eval, menv.Enviroment, a2, env, a1)

                    elif funcname == 'quote':
                        return ast.values[1]

                    elif funcname == 'quasiquote':
                        ast = quasiquote(ast[1], False)
                        continue

                    else:
                        d = eval_ast(ast, env)
                        f = d[0]

                        if hasattr(f, '__ast__'):
                            ast = f.__ast__
                            env = f.__gen__env(d.values[1:])
                            continue
                        else:
                            if callable(f):
                                return f(*d.values[1:])
            # my beautiful hack
            elif isinstance(ast, mtypes.MslPList):
                possible_fname = ast[0]

                print('pfname', possible_fname)

                '''
                TODO:

                msl> `(1 2 (3 4))
                pfname List([Symbol('cons'), Number(3), P_List([Number(4)])])
                pfname Number(4)
                (1 2 3 4)

                should give (1 2 (3 4))

                '''

                if isinstance(possible_fname, mtypes.MslList):
                    if isinstance(possible_fname[0], mtypes.MslSymbol):
                        if env.find(possible_fname[0].symval):
                            '''print("got func %s in plist" % possible_fname[0].symval)
                            print("fargs %r" % possible_fname[1:])'''

                            d = eval_ast(possible_fname, env)
                            f = d[0]
                            # ast = mtypes.MslList(ast.values)
                            return f(*d.values[1:])
            else:
                return eval_ast(ast, env)
        else:
            return eval_ast(ast, env)
        return ast