Exemplo n.º 1
0
def cgen_for(node):
    emit_comment('cgen_for')
    expr1 = node.ref_child[0]
    expr2 = node.ref_child[1]
    expr3 = node.ref_child[2]
    stmt = node.ref_child[3]
    top = ut.disFp
    l1 = create_label()
    l2 = create_label()
    node.attribute[AttName.exit_label] = l2
    if expr1.data != "nothing":
        cgen_expr(expr1)
    align_stack(top)
    emit_label(l1)
    t = cgen_expr(expr2)
    if t.attribute[AttName.type] != Type.bool:
        raise TypeError("error in node " + str(node) +
                        "\n type of the decision statement must be bool!")
    t.attribute[AttName.address].load_address()
    emit_load("$t0", "$s0")
    align_stack(top)
    emit("beqz $t0, " + l2)
    cgen_stmt(stmt)
    align_stack(top)
    if expr3.data != "nothing":
        cgen_expr(expr3)
    align_stack(top)
    emit_jump(l1)
    emit_label(l2)

    emit_li("$t6", top)
    ut.emit_add("$t6", "$t6", "$fp")
    emit_move("$sp", "$t6")

    return
Exemplo n.º 2
0
def cgen_if1(expr, stmt1, stmt2):
    emit_comment('cgen_if1')
    l1 = create_label()
    l2 = create_label()
    top = ut.disFp
    t1 = cgen_expr(expr)
    if t1.attribute[AttName.type] != Type.bool:
        raise TypeError("error in node " + str(expr) +
                        "\n type of the decision statement must be bool!")
    t1.attribute[AttName.address].load_address()
    emit_load("$t0", "$s0")
    align_stack(top)
    emit("beqz $t0, " + l1)
    st1 = cgen_stmt(stmt1)
    ret = 0
    if st1.attribute[AttName.has_return]:
        ret += 1
    align_stack(top)
    emit_jump(l2)
    emit_label(l1)
    st2 = cgen_stmt(stmt2)
    if st2.attribute[AttName.has_return]:
        ret += 1
    align_stack(top)
    emit_label(l2)
    return ret
Exemplo n.º 3
0
def cgen_return_stmt(node):
    # checking validity of statement
    func = node.ref_parent
    while func is not None and func.data != "functiondecl":
        func = func.ref_parent

    # return isn't in any function!
    if func is None:
        raise FunctionError("Error in return node " + str(node) +
                            ", return node must be use in a funcion!")

    # return for void functions
    if node.ref_child[0].data == "nothing":
        if func.ref_child[0].data == "void":
            emit_move("$sp", "$fp")
            emit("jr $ra")
            return
        else:
            raise TypeError("Error in return statement for function in node" +
                            str(func) + ", function type must be void")

    # return for non void functions
    type = get_type(func.ref_child[0])  # type of parent function
    expr = cgen_expr(node.ref_child[0])  # expr node of return

    # checking equality of types
    # if not type[0]:  # type isn't array
    #     if type[1] != expr.attribute[AttName.type]:
    #         raise TypeError(
    #             "Error in return statement in node" + str(node) + ", type of function and return isn't match!"
    #         )
    # else:  # type is array
    #     if type[1] != expr.attribute[AttName.array_member_type]:  # checking type of members
    #         raise TypeError(
    #             "Error in return statement in node" + str(node) + ", type of function and returned array isn't match!"
    #         )
    #     if type[2] != expr.attribute[AttName.array_dim]:  # checking dimension
    #         raise TypeError(
    #             "Error in return statement in node" + str(node) +
    #             ", dimension of returned array isn't match to function array dimension!"
    #         )

    # load return statement to $v0 and jump to callee
    expr.attribute[AttName.address].load()
    emit_move("$v0", "$s0")
    emit_move("$sp", "$fp")
    emit("jr $ra")

    return node.ref_child[0].data != "nothing"
Exemplo n.º 4
0
def cgen_stmt(node):
    emit_comment('cgen_stmt')

    child = node.ref_child[0]
    top = ut.disFp

    if child.data == "stmt":
        ret = cgen_stmt(child)
        node.attribute[AttName.has_return] = ret.attribute[AttName.has_return]
    elif child.data == "forstmt":
        cgen_for(child)
        node.attribute[AttName.has_return] = False
    elif child.data == "whilestmt":
        cgen_while(child)
        node.attribute[AttName.has_return] = False
    elif child.data == "ifstmt":
        ret = cgen_if(child)
        node.attribute[AttName.has_return] = ret.attribute[AttName.has_return]
    elif child.data == "stmtblock":
        ret = cgen_stmt_block(child)
        node.attribute[AttName.has_return] = ret.attribute[AttName.has_return]
    elif child.data == "expr":
        cgen_expr(child)
        align_stack(top)
        node.attribute[AttName.has_return] = False
    elif child.data == "breakstmt":
        cgen_break(child)
        node.attribute[AttName.has_return] = False
    elif child.data == "printstmt":
        cgen_print_stmt(child)
        node.attribute[AttName.has_return] = False
    elif child.data == "returnstmt":
        ret = cgen_return_stmt(child)
        node.attribute[AttName.has_return] = ret

    return node
Exemplo n.º 5
0
def cgen_if2(expr, stmt):
    emit_comment('cgen_if2')
    l1 = create_label()
    top = ut.disFp
    t1 = cgen_expr(expr)
    if t1.attribute[AttName.type] != Type.bool:
        raise TypeError("error in node " + str(expr) +
                        "\n type of the decision statement must be bool!")
    t1.attribute[AttName.address].load_address()
    emit_load("$t0", "$s0")
    align_stack(top)
    emit("beqz $t0, " + l1)
    cgen_stmt(stmt)
    align_stack(top)
    emit_label(l1)
    return
Exemplo n.º 6
0
def cgen_print_stmt(node):
    emit_comment('cgen_print_stmt')
    top = ut.disFp

    for child in node.ref_child:
        expr = cgen_expr(child)
        address = expr.attribute[AttName.address]
        type = expr.attribute[AttName.type]
        address.load_address()
        if type == Type.double:
            emit_load_double("$f12", "$s0")
            emit_li("$v0", 2)
            emit_syscall()
            #print_double()
        elif type == "string":
            emit_load("$a0", "$s0")
            emit_li("$v0", 4)
            emit_syscall()
        elif type == Type.bool:
            l1 = create_label()
            l2 = create_label()
            emit_load('$s0', '$s0')
            emit('beqz $s0, ' + l1)
            emit('la $a0, __true')
            emit_jump(l2)
            emit_label(l1)
            emit('la $a0, __false')
            emit_label(l2)
            emit_li("$v0", 4)
            emit_syscall()
        else:
            emit_load("$a0", "$s0")
            emit_li("$v0", 1)
            emit_syscall()

        align_stack(top)

    emit('la $a0, __newLine')
    emit_li("$v0", 4)
    emit_syscall()