Example #1
0
def compile_atom(atom, c):
    if isinstance(atom, AVectorAtom):
        values = atom.getVector().getAtom()

        for value in values:
            load_value(value, c)

        c.BUILD_LIST(len(values))
        return True


    if isinstance(atom, ADictAtom):
        values = atom.getDict().getAtom()
        n = len(values) / 2

        c.LOAD_GLOBAL('dict')
        for i in range(n):
            load_value(values[i * 2], c)
            load_value(values[i * 2 + 1], c)

        c.CALL_FUNCTION(0, n)
        return True


    if isinstance(atom, AListAtom):
        xs = atom.getList().getAtom()
        head = xs[0]

        if isinstance(head, AListAtom):
            for x in xs:
                load_value(x, c)

            c.CALL_FUNCTION(len(xs) - 1)

            return True

        if isinstance(head, AIdentifierAtom):
            fn = head.getIdentifier().getText()

            c.set_lineno(head.getIdentifier().getLine())

            if fn == 'def':
                var = xs[1].getIdentifier().getText()
                if load_value(xs[2], c):

                    c.STORE_GLOBAL(var)
                    c.LOAD_CONST(var)
                    return True

            if fn == 'print':
                if load_value(xs[1], c):
                    c.PRINT_ITEM()
                    c.PRINT_NEWLINE()
                    c.LOAD_CONST(None)
                    return True

            if fn == 'if' or fn == 'ife':
                false_part = Label()
                finish = Label()

                load_value(xs[1], c) # eval condition

                c(false_part.JUMP_IF_FALSE)
                c.POP_TOP() # discard boolean result
                load_value(xs[2], c)
                c(finish.JUMP_ABSOLUTE)

                c(false_part)
                c.POP_TOP() # discard boolean result

                if len(xs) == 4:
                    load_value(xs[3], c)
                else:
                    c.LOAD_CONST(None)

                c(finish)

                return True

            if fn == 'let':
                pair = xs[1].getVector().getAtom()
                body = xs[2]
                n = len(pair) / 2

                for i in range(n):
                    load_value(pair[i * 2 + 1], c)
                    print pair[i * 2]
                    unpack_var(pair[i * 2], c)

                load_value(body, c)

                # todo: DELETE_FAST

                return True

            if fn == 'for':
                pair = xs[1].getVector().getAtom()
                var = pair[0]
                ls = pair[1]
                body = xs[2]

                for_loop = Label()
                for_end = Label()

                load_value(ls, c)

                c.GET_ITER()
                c(for_loop)
                c(for_end.FOR_ITER)

                unpack_var(pair[0], c)

                load_value(body, c)

                c.POP_TOP()

                c(for_loop.JUMP_ABSOLUTE)
                c(for_end)

                return True


            if fn == 'defn':
                name = xs[1].getIdentifier().getText()
                arguments = xs[2].getVector().getAtom()
                body = xs[3]
                func_code = Code()

                func_code.co_filename = c.co_filename
                func_code.co_name = name
                func_code.co_argcount = len(arguments)
                func_code.co_varnames = [arg.getIdentifier().getText() for arg in arguments]

                load_value(body, func_code)

                func_code.RETURN_VALUE()

                c.LOAD_CONST(func_code.code())
                c.MAKE_FUNCTION(0)
                c.STORE_GLOBAL(name)

                c.LOAD_CONST(name)

                return True

            if fn == 'fn':
                arguments = xs[1].getVector().getAtom()
                body = xs[2]
                func_code = Code()

                func_code.co_filename = c.co_filename
                func_code.co_argcount = len(arguments)
                func_code.co_varnames = [arg.getIdentifier().getText() for arg in arguments]
                # func_code.co_cellvars = []

                load_value(body, func_code)

                func_code.RETURN_VALUE()

                c.LOAD_CONST(func_code.code())
                c.MAKE_FUNCTION(0)

                return True

            if fn == 'import':
                pkg = xs[1].getIdentifier().getText()

                c.LOAD_CONST(-1)

                if len(xs) == 3:

                   names = [t.getIdentifier().getText() for t in xs[2].getVector().getAtom()]
                   imports = tuple(names)

                   c.LOAD_CONST(imports)
                   c.IMPORT_NAME(pkg)

                   for name in names:
                       c.IMPORT_FROM(name)
                       c.STORE_GLOBAL(name)

                else:
                    c.LOAD_CONST(None)
                    c.IMPORT_NAME(pkg)
                    c.STORE_GLOBAL(pkg)

                return True

            if fn == '.':
                if isinstance(xs[1], AIdentifierAtom):
                    load_value(xs[2], c)
                    c.LOAD_ATTR(xs[1].getIdentifier().getText())
                else:
                    c.LOAD_GLOBAL('getattr')
                    load_value(xs[2], c)
                    load_value(xs[1], c)
                    c.CALL_FUNCTION(2)

                return True

            if fn == 'exec':
                load_value(xs[1], c)
                c.MAKE_FUNCTION(0)
                c.CALL_FUNCTION(0)
                return True

            if load_var(head, c):
                for x in xs[1:]:
                    load_value(x, c)

                c.CALL_FUNCTION(len(xs) - 1)
                return True

    return False