Esempio n. 1
0
def find_vars(t, stat=None, func=None):
    if func is not None:
        prefix = func.name + "_"
    else:
        prefix = ""

    if stat == None:
        stat = TreeStats()
    if isinstance(t, list):
        for x in reversed(t):
            find_vars(x, stat=stat, func=func)
    elif isinstance(t, tuple):
        if t[0] == A_PRINT:
            stat.use_print = True
        elif t[0] == A_READ:
            stat.use_read = True
        if t[0] == A_FUNCTION:
            stat.funcs[t[1][0].name] = {
                'args': t[1][0].args,
                'args_count': len(t[1][0].args),
                'info': t[1][0]
            }
            for v in t[1][0].args:
                var = "%s_%s" % (t[1][0].name, v)
                stat.vars.append(var)
                t[1][0].inner_vars.append(var)

            find_vars(t[1][1], stat=stat, func=t[1][0])
        else:
            find_vars(t[1], stat=stat, func=func)
    else:
        if isinstance(t, str) and typeof(t) == T_VAR:
            if prefix + t not in stat.vars:
                stat.vars.append(prefix + t)
                if func is not None:
                    func.inner_vars.append(prefix + t)

        if isinstance(t, str) and typeof(t) == T_STRING:
            if t not in stat.strs:
                stat.strs.append(t)
    return stat
Esempio n. 2
0
def find_vars(t, stat=None, func=None):
    if func is not None:
        prefix = func.name + "_"
    else:
        prefix = ""

    if stat == None:
        stat = TreeStats()
    if isinstance(t, list):
        for x in reversed(t):
            find_vars(x, stat=stat, func=func)
    elif isinstance(t, tuple):
        if t[0] == A_PRINT:
            stat.use_print = True
        elif t[0] == A_READ:
            stat.use_read = True
        if t[0] == A_FUNCTION:
            stat.funcs[t[1][0].name] = {'args': t[1][0].args,
                                        'args_count': len(t[1][0].args),
                                        'info': t[1][0]}
            for v in t[1][0].args:
                var = "%s_%s" % (t[1][0].name, v)
                stat.vars.append(var)
                t[1][0].inner_vars.append(var)

            find_vars(t[1][1], stat=stat, func=t[1][0])
        else:
            find_vars(t[1], stat=stat, func=func)
    else:
        if isinstance(t, str) and typeof(t) == T_VAR:
            if prefix + t not in stat.vars:
                stat.vars.append(prefix + t)
                if func is not None:
                    func.inner_vars.append(prefix + t)

        if isinstance(t, str) and typeof(t) == T_STRING:
            if t not in stat.strs:
                stat.strs.append(t)
    return stat
Esempio n. 3
0
def gen_text_section(t, stat, p=None, prefix=""):
    if p is None:
        p = PseudoAsm()

    make_asm_node = partial(
        make_asm_node_p, p=p, shift=(0 if len(prefix) == 0 else 1))
    aa_push = partial(make_asm_node, cmd=C_PUSH)
    aa_pop = partial(make_asm_node, cmd=C_POP, o=None)
    aa_mov = partial(make_asm_node, cmd=C_MOV)
    aa_call = partial(make_asm_node, cmd=C_CALL, o=None)
    aa_add = partial(make_asm_node, cmd=C_ADD)
    aa_sub = partial(make_asm_node, cmd=C_SUB)
    aa_imul = partial(make_asm_node, cmd=C_IMUL, o=None)
    aa_idiv = partial(make_asm_node, cmd=C_IDIV, o=None)
    aa_cmp = partial(make_asm_node, cmd=C_CMP, o=None)
    aa_jmp = partial(make_asm_node, cmd=C_JMP)
    aa_label = partial(make_asm_node, cmd=C_LABEL, o=None)
    aa_neg = partial(make_asm_node, cmd=C_NEG, o=None)
    aa_push_num = partial(aa_push, o=C_OPT_NO)
    aa_push_addr = partial(aa_push, o=C_OPT_ADDR)
    aa_ret = partial(make_asm_node, cmd=C_RET, o=None, v=None)

    iterate = t
    if isinstance(t, list):
        iterate = reversed(t)
    if isinstance(t, (str, tuple)):
        iterate = [t]
    for node in iterate:
        p.text.append((C_COMMENT, None, None))
        if isinstance(node, str):
            tnode = typeof(node)
            if tnode == T_NUMBER:
                aa_push_num(v=node)
            elif tnode == T_VAR:
                aa_push_addr(v="v%s" % prefix + node)
            else:
                raise ParserError(
                    "Error generating ASM code on node %s" % node)

        elif node[0] == A_BLOCK:
            gen_text_section(node[1], stat, p=p, prefix=prefix)

        elif node[0] == A_FUNCTION:
            p.funcNum += 1
            p.text.append((C_COMMENT, None, None))
            p.text.append((C_COMMENT, None, "Function %s" % node[1][0].name))
            aa_jmp(o=None, v="Func%dEnd" % p.funcNum, shift=1)
            aa_label(v="Func_%s" % node[1][0].name, shift=1)
            for i, arg in enumerate(node[1][0].args):
                var = "v%s_%s" % (node[1][0].name, arg)
                aa_mov(o=[C_OPT_NO, C_OPT_ADDR], v=["eax",
                       "esp+%d" % ((i + 1) * 4)], shift=1)
                aa_mov(o=[C_OPT_ADDR, C_OPT_NO], v=[var, "eax"], shift=1)
            gen_text_section(
                node[1][1], stat, p=p, prefix=node[1][0].name + "_")
            aa_label(v="Func%dEnd" % p.funcNum, shift=1)

        elif node[0] == A_RETURN:
            # print (node[1])
            aa_mov(
                o=[C_OPT_NO, C_OPT_ADDR], v=["eax", "v%s" % prefix + node[1]])
            # aa_push_num(v="eax")
            aa_ret()

        elif node[0] == A_PRINT:
            if typeof(node[1]) == T_STRING:
                strnum = stat.strs.index(node[1])

                aa_push_num(v="str%d" % strnum)
                aa_call(v="printf")
                aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "4"])
                aa_push_addr(v="stdout")
                aa_call(v="fflush")
                aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "4"])

            elif typeof(node[1]) == T_VAR:
                aa_mov(o=[C_OPT_NO, C_OPT_ADDR], v=["eax",
                       "v%s" % prefix + node[1]])
                aa_push_num(v="eax")
                aa_push_num(v="numbs")
                aa_call(v="printf")
                aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "8"])
                aa_push_addr(v="stdout")
                aa_call(v="fflush")
                aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "4"])
            else:
                raise ParserError("Error print argument: %s" % node)

        elif node[0] == A_READ:
            assert typeof(node[1]) == T_VAR

            aa_push_num(v="v%s" % prefix + node[1])
            aa_push_num(v="numbs_in_format")
            aa_call(v="scanf")
            aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "8"])
            aa_call(v="getchar")

        elif node[0] == A_ASSIGN:
            var = node[1][0]
            gen_text_section(node[1][1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_mov(o=[C_OPT_ADDR, C_OPT_NO], v=["v%s" % prefix + var, "eax"])

        elif node[0] == A_IF:
            p.ifNum += 1
            gen_text_section(node[1][0], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_cmp(o=[C_OPT_NO, C_OPT_NO], v=["eax", "0"])
            aa_jmp(o="jnz", v="llIf%dElse" % p.ifNum)
            # then
            gen_text_section(node[1][1], stat, p=p, prefix=prefix)
            aa_jmp(o=None, v="llIf%dEnd" % p.ifNum)
            # else
            aa_label(v="llIf%dElse" % p.ifNum)
            gen_text_section(node[1][2], stat, p=p, prefix=prefix)

            aa_label(v="llIf%dEnd" % p.ifNum)

        elif node[0] == '+':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_add(o=[C_OPT_NO, C_OPT_NO], v=["eax", "ebx"])
            aa_push_num(v="eax")

        elif node[0] in ['>=', '<=', '>', '<', '=']:
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            p.labelNum += 1
            op = {'>=': 'jge',
                  '<=': 'jle',
                  '>': 'jg',
                  '<': 'jl',
                  '=': 'je',
                  }
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_cmp(v=["eax", "ebx"])
            aa_jmp(o=op[node[0]], v="ll%d" % p.labelNum)
            aa_push_num(v="1")
            aa_jmp(o=None, v="ell%d" % p.labelNum)
            aa_label(v="ll%d" % p.labelNum)
            aa_push_num(v="0")
            aa_label(v="ell%d" % p.labelNum)

        elif node[0] == '-':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            if len(node[1]) == 2:
                aa_pop(v="eax")
                aa_pop(v="ebx")
                aa_sub(o=[C_OPT_NO, C_OPT_NO], v=["eax", "ebx"])
                aa_push_num(v="eax")
            else:
                aa_pop(v="eax")
                aa_neg(v="eax")
                aa_push_num(v="eax")

        elif node[0] == '*':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_imul(v="ebx")
            aa_push_num(v="eax")

        elif node[0] == '/':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_idiv(v="ebx")
            aa_push_num(v="eax")

        elif node[0] == '%':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_idiv(v="ebx")
            aa_push_num(v="edx")

        elif node[0] == A_WHILE:
            p.loopNum += 1

            aa_label(v="llWhile%d" % p.loopNum)
            gen_text_section(node[1][0], stat, p=p, prefix=prefix)

            aa_pop(v="eax")
            aa_cmp(o=[C_OPT_NO, C_OPT_NO], v=["eax", "0"])
            aa_jmp(o="jnz", v="llWhile%dEnd" % p.loopNum)

            gen_text_section(node[1][1], stat, p=p, prefix=prefix)

            aa_jmp(o=None, v="llWhile%d" % p.loopNum)
            aa_label(v="llWhile%dEnd" % p.loopNum)

        elif node[0] == A_CALL:
            if stat.funcs[node[1]]['args_count'] != len(node[2]):
                raise ParserError("Call %s passing %d arguments. %d expected" %
                                 (node[1], len(node[2]), stat.funcs[node[1]]['args_count']))

            for iv in stat.funcs[node[1]]['info'].inner_vars:
                aa_push_addr(v="v%s" % iv)

            for arg in reversed(node[2]):
                gen_text_section(arg, stat, p=p, prefix=prefix)

            aa_call(v="Func_%s" % node[1])
            aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", str(4 * len(node[2]))])

            for iv in reversed(stat.funcs[node[1]]['info'].inner_vars):
                aa_pop(v="edx")
                aa_mov(o=[C_OPT_ADDR, C_OPT_NO], v=["v%s" % iv, "edx"])

            aa_push_num(v="eax")

        elif node[0] in ['/', '%']:
            raise NotImplementedError(
                "%s operation is not implemented yet" % node[0])
        else:
            raise ParserError(
                "Error generating ASM code on node %s" % repr(node))
Esempio n. 4
0
def gen_text_section(t, stat, p=None, prefix=""):
    if p is None:
        p = PseudoAsm()

    make_asm_node = partial(make_asm_node_p,
                            p=p,
                            shift=(0 if len(prefix) == 0 else 1))
    aa_push = partial(make_asm_node, cmd=C_PUSH)
    aa_pop = partial(make_asm_node, cmd=C_POP, o=None)
    aa_mov = partial(make_asm_node, cmd=C_MOV)
    aa_call = partial(make_asm_node, cmd=C_CALL, o=None)
    aa_add = partial(make_asm_node, cmd=C_ADD)
    aa_sub = partial(make_asm_node, cmd=C_SUB)
    aa_imul = partial(make_asm_node, cmd=C_IMUL, o=None)
    aa_idiv = partial(make_asm_node, cmd=C_IDIV, o=None)
    aa_cmp = partial(make_asm_node, cmd=C_CMP, o=None)
    aa_jmp = partial(make_asm_node, cmd=C_JMP)
    aa_label = partial(make_asm_node, cmd=C_LABEL, o=None)
    aa_neg = partial(make_asm_node, cmd=C_NEG, o=None)
    aa_push_num = partial(aa_push, o=C_OPT_NO)
    aa_push_addr = partial(aa_push, o=C_OPT_ADDR)
    aa_ret = partial(make_asm_node, cmd=C_RET, o=None, v=None)

    iterate = t
    if isinstance(t, list):
        iterate = reversed(t)
    if isinstance(t, (str, tuple)):
        iterate = [t]
    for node in iterate:
        p.text.append((C_COMMENT, None, None))
        if isinstance(node, str):
            tnode = typeof(node)
            if tnode == T_NUMBER:
                aa_push_num(v=node)
            elif tnode == T_VAR:
                aa_push_addr(v="v%s" % prefix + node)
            else:
                raise ParserError("Error generating ASM code on node %s" %
                                  node)

        elif node[0] == A_BLOCK:
            gen_text_section(node[1], stat, p=p, prefix=prefix)

        elif node[0] == A_FUNCTION:
            p.funcNum += 1
            p.text.append((C_COMMENT, None, None))
            p.text.append((C_COMMENT, None, "Function %s" % node[1][0].name))
            aa_jmp(o=None, v="Func%dEnd" % p.funcNum, shift=1)
            aa_label(v="Func_%s" % node[1][0].name, shift=1)
            for i, arg in enumerate(node[1][0].args):
                var = "v%s_%s" % (node[1][0].name, arg)
                aa_mov(o=[C_OPT_NO, C_OPT_ADDR],
                       v=["eax", "esp+%d" % ((i + 1) * 4)],
                       shift=1)
                aa_mov(o=[C_OPT_ADDR, C_OPT_NO], v=[var, "eax"], shift=1)
            gen_text_section(node[1][1],
                             stat,
                             p=p,
                             prefix=node[1][0].name + "_")
            aa_label(v="Func%dEnd" % p.funcNum, shift=1)

        elif node[0] == A_RETURN:
            # print (node[1])
            aa_mov(o=[C_OPT_NO, C_OPT_ADDR],
                   v=["eax", "v%s" % prefix + node[1]])
            # aa_push_num(v="eax")
            aa_ret()

        elif node[0] == A_PRINT:
            if typeof(node[1]) == T_STRING:
                strnum = stat.strs.index(node[1])

                aa_push_num(v="str%d" % strnum)
                aa_call(v="printf")
                aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "4"])
                aa_push_addr(v="stdout")
                aa_call(v="fflush")
                aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "4"])

            elif typeof(node[1]) == T_VAR:
                aa_mov(o=[C_OPT_NO, C_OPT_ADDR],
                       v=["eax", "v%s" % prefix + node[1]])
                aa_push_num(v="eax")
                aa_push_num(v="numbs")
                aa_call(v="printf")
                aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "8"])
                aa_push_addr(v="stdout")
                aa_call(v="fflush")
                aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "4"])
            else:
                raise ParserError("Error print argument: %s" % node)

        elif node[0] == A_READ:
            assert typeof(node[1]) == T_VAR

            aa_push_num(v="v%s" % prefix + node[1])
            aa_push_num(v="numbs_in_format")
            aa_call(v="scanf")
            aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", "8"])
            aa_call(v="getchar")

        elif node[0] == A_ASSIGN:
            var = node[1][0]
            gen_text_section(node[1][1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_mov(o=[C_OPT_ADDR, C_OPT_NO], v=["v%s" % prefix + var, "eax"])

        elif node[0] == A_IF:
            p.ifNum += 1
            gen_text_section(node[1][0], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_cmp(o=[C_OPT_NO, C_OPT_NO], v=["eax", "0"])
            aa_jmp(o="jnz", v="llIf%dElse" % p.ifNum)
            # then
            gen_text_section(node[1][1], stat, p=p, prefix=prefix)
            aa_jmp(o=None, v="llIf%dEnd" % p.ifNum)
            # else
            aa_label(v="llIf%dElse" % p.ifNum)
            gen_text_section(node[1][2], stat, p=p, prefix=prefix)

            aa_label(v="llIf%dEnd" % p.ifNum)

        elif node[0] == '+':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_add(o=[C_OPT_NO, C_OPT_NO], v=["eax", "ebx"])
            aa_push_num(v="eax")

        elif node[0] in ['>=', '<=', '>', '<', '=']:
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            p.labelNum += 1
            op = {
                '>=': 'jge',
                '<=': 'jle',
                '>': 'jg',
                '<': 'jl',
                '=': 'je',
            }
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_cmp(v=["eax", "ebx"])
            aa_jmp(o=op[node[0]], v="ll%d" % p.labelNum)
            aa_push_num(v="1")
            aa_jmp(o=None, v="ell%d" % p.labelNum)
            aa_label(v="ll%d" % p.labelNum)
            aa_push_num(v="0")
            aa_label(v="ell%d" % p.labelNum)

        elif node[0] == '-':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            if len(node[1]) == 2:
                aa_pop(v="eax")
                aa_pop(v="ebx")
                aa_sub(o=[C_OPT_NO, C_OPT_NO], v=["eax", "ebx"])
                aa_push_num(v="eax")
            else:
                aa_pop(v="eax")
                aa_neg(v="eax")
                aa_push_num(v="eax")

        elif node[0] == '*':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_imul(v="ebx")
            aa_push_num(v="eax")

        elif node[0] == '/':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_idiv(v="ebx")
            aa_push_num(v="eax")

        elif node[0] == '%':
            gen_text_section(node[1], stat, p=p, prefix=prefix)
            aa_pop(v="eax")
            aa_pop(v="ebx")
            aa_idiv(v="ebx")
            aa_push_num(v="edx")

        elif node[0] == A_WHILE:
            p.loopNum += 1

            aa_label(v="llWhile%d" % p.loopNum)
            gen_text_section(node[1][0], stat, p=p, prefix=prefix)

            aa_pop(v="eax")
            aa_cmp(o=[C_OPT_NO, C_OPT_NO], v=["eax", "0"])
            aa_jmp(o="jnz", v="llWhile%dEnd" % p.loopNum)

            gen_text_section(node[1][1], stat, p=p, prefix=prefix)

            aa_jmp(o=None, v="llWhile%d" % p.loopNum)
            aa_label(v="llWhile%dEnd" % p.loopNum)

        elif node[0] == A_CALL:
            if stat.funcs[node[1]]['args_count'] != len(node[2]):
                raise ParserError(
                    "Call %s passing %d arguments. %d expected" %
                    (node[1], len(node[2]), stat.funcs[node[1]]['args_count']))

            for iv in stat.funcs[node[1]]['info'].inner_vars:
                aa_push_addr(v="v%s" % iv)

            for arg in reversed(node[2]):
                gen_text_section(arg, stat, p=p, prefix=prefix)

            aa_call(v="Func_%s" % node[1])
            aa_add(o=[C_OPT_NO, C_OPT_NO], v=["esp", str(4 * len(node[2]))])

            for iv in reversed(stat.funcs[node[1]]['info'].inner_vars):
                aa_pop(v="edx")
                aa_mov(o=[C_OPT_ADDR, C_OPT_NO], v=["v%s" % iv, "edx"])

            aa_push_num(v="eax")

        elif node[0] in ['/', '%']:
            raise NotImplementedError("%s operation is not implemented yet" %
                                      node[0])
        else:
            raise ParserError("Error generating ASM code on node %s" %
                              repr(node))