Beispiel #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
Beispiel #2
0
def print_double():
    l1 = create_label()
    l2 = create_label()
    emit('la $s0, __epsilon')
    emit('l.s $f1, 0($s0)')
    emit('abs.s $f7, $f0')
    emit('c.eq.s $f7, $f0')
    emit('bc1t ' + l1)
    emit('sub.s $f0, $f0, $f1')
    emit_jump(l2)
    emit_label(l1)
    emit('add.s $f0, $f0, $f1')
    emit_label(l2)
    emit('cvt.w.s $f1, $f0')
    emit('mfc1 $a0, $f1')
    emit_li('$v0', 1)
    emit_syscall()
    emit('la $a0, __dot')
    emit_li('$v0', 4)
    emit_syscall()
    emit('abs.s $f0, $f0')
    emit('cvt.w.s $f1, $f0')
    emit('cvt.s.w $f1, $f1')
    emit('sub.s $f0, $f0, $f1')
    emit('la $s0, __ten')
    emit('l.s $f3, 0($s0)')
    for i in range(4):
        emit('mul.s $f0, $f0, $f3')
        emit('cvt.w.s $f1, $f0')
        emit('mfc1 $a0, $f1')
        emit('cvt.s.w $f1, $f1')
        emit('sub.s $f0, $f0, $f1')
        emit_li('$v0', 1)
        emit_syscall()
Beispiel #3
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
Beispiel #4
0
def cgen_expr_equal(node):
    emit_comment('cgen_expr_equal')
    stack_handler.add_checkpoint()

    left_child = cgen_expr(node.ref_child[0])
    right_child = cgen_expr(node.ref_child[2])

    left_child_address = left_child.get_address()
    right_child_address = right_child.get_address()

    if not expr_convertable(left_child.get_type(),
                            right_child.get_type()) and not expr_convertable(
                                right_child.get_type(), left_child.get_type()):
        emit_li("$s0", 0)
    elif left_child.get_type() == Type.double:
        expr_float_cmp(left_child_address, right_child_address, 'eq')
    elif left_child.get_type() == Type.string:
        left_child_address.load()
        emit_move('$s1', '$s0')
        right_child_address.load()
        emit_move('$s2', '$s0')
        emit_li('$s0', 1)

        first_label = create_label()
        second_label = create_label()
        out_label = create_label()

        emit_label(first_label)
        emit_load_byte('$t0', '$s1')
        emit_load_byte('$t1', '$s2')
        emit_addi('$s1', '$s1', '1')
        emit_addi('$s2', '$s2', '1')
        emit('beq $t0, $t1, ' + second_label)
        emit_li('$s0', 0)
        emit_label(second_label)
        emit('beqz $t0, ' + out_label)
        emit('beqz $t1, ' + out_label)
        emit_jump(first_label)
        emit_label(out_label)

    else:
        left_child_address.load()
        emit_move('$s1', '$s0')
        right_child_address.load()
        emit("xor $t0, $s0, $s1")

        emit("slt $t1, $t0, $zero")
        emit("slt $t0, $zero, $t0")
        emit("or $t0, $t0, $t1")

        emit("li $t1, 1")
        emit("sub $s0, $t1, $t0")
        emit("")

    stack_handler.back_to_last_checkpoint()

    expr_set_node_attributes(node, Type.bool)
    node.get_address().store()
    return node
Beispiel #5
0
def cgen_constant_string(node):
    emit_comment('cgen_constant_string')
    expr_set_node_attributes(node, Type.string)
    child = node.ref_child[0]

    value = child.data
    label = create_label()
    emit_data(label, '.asciiz ' + value)
    emit_data(create_label(), '.space ' + str(4 - (len(value) - 2) % 4))

    emit('la $s0, ' + label)
    node.get_address().store()
    return node
Beispiel #6
0
def cgen_readline(
        node):  # after calling this function address of the string is in $S0
    emit_comment('cgen_readline()')
    l1 = create_label()
    l2 = create_label()
    l3 = create_label()
    l4 = create_label()
    ut.disFp -= 4
    node.set_address(Address(ut.disFp, 0, False))
    node.set_type(Type.string)
    emit_addi("$sp", "$sp", "-4")
    emit('''li $v0, 8
li $a1, 400
la $a0, __read
syscall
li $a1, 1
li $a2, 0''')
    emit_label(l1)
    emit('''lbu $a2, 0($a0)
li $a3, 10''')
    emit("beq $a2, $a3, " + l2)
    emit_li('$a3', 13)
    emit("beq $a2, $a3, " + l2)
    emit_li('$a3', 0)
    emit("beq $a2, $a3, " + l2)
    emit_addi('$a1', '$a1', '1')
    emit_addi('$a0', '$a0', '1')
    emit_jump(l1)
    emit_label(l2)
    emit('''li $v0, 9
move $a0, $a1
syscall
move $v1, $v0
la $a0, __read''')
    emit_label(l3)
    emit('''lbu $a2, 0($a0)
sb $zero, 0($a0)
li $a3, 10''')
    emit("beq $a2, $a3, " + l4)
    emit_li('$a3', 13)
    emit("beq $a2, $a3, " + l4)
    emit_li('$a3', 0)
    emit("beq $a2, $a3, " + l4)
    emit('''sb $a2, 0($v0)
addi $v0, $v0, 1
addi $a0, $a0, 1''')
    emit_jump(l3)
    emit_label(l4)
    emit("sw $v1, 0($sp)")
    return node
Beispiel #7
0
def expr_float_cmp(left_child_address, right_child_address, operation):
    left_child_address.load()
    emit("mov.s $f2, $f0")
    right_child_address.load()
    emit("c." + operation + ".s $f2, $f0")
    label = create_label()
    emit_li('$s0', 1)
    emit('bc1t ' + label)
    emit_li('$s0', 0)
    emit_label(label)
Beispiel #8
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()
Beispiel #9
0
def cgen_constant_double(node):
    emit_comment('cgen_constant_double')
    expr_set_node_attributes(node, Type.double)
    child = node.ref_child[0]

    value = str(child.data).lower()
    label = create_label()

    emit_data(label, '.float ' + value)

    emit('la $t0, ' + label)
    emit_load_double('$f0', '$t0')

    node.get_address().store()
    return node
Beispiel #10
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
Beispiel #11
0
def parse_function(decl):
    return_node = decl.ref_child[0]
    return_type = get_type(return_node)

    if len(return_type) > 2:
        return_type = return_type[1:]
    else:
        return_type = return_type[1]

    id_node = decl.ref_child[1]
    func_name = get_name(id_node)

    formal_node = decl.ref_child[2]
    input_types = get_formals(formal_node)

    function_decl = FunctionDecl(return_type, input_types, func_name,
                                 create_label())
    return function_decl
Beispiel #12
0
def cgen_readint(node):
    L1 = create_label()
    L2 = create_label()
    L3 = create_label()
    L4 = create_label()
    L5 = create_label()
    L6 = create_label()
    L7 = create_label()
    L8 = create_label()
    L9 = create_label()
    L10 = create_label()
    L7_ = create_label()
    L_1 = create_label()
    L_2 = create_label()
    L_3 = create_label()
    L_4 = create_label()
    L_5 = create_label()
    L_6 = create_label()
    L_7 = create_label()
    exitt = create_label()
    exit = create_label()
    LL1 = create_label()
    LL2 = create_label()
    LL3 = create_label()
    LL4 = create_label()
    LL5 = create_label()
    LL6 = create_label()
    LL7 = create_label()
    LL8 = create_label()
    expr_set_node_attributes(node, Type.int)

    emit_li('$v0', 8)
    emit_li('$a1', 400)
    emit('la $a0, __read')
    emit_li('$t0', 0)
    emit_li('$t1', 0)
    emit_li('$t4', 10)
    emit_syscall()
    emit_load_byte('$t2', '$a0')
    emit_addi('$a0', '$a0', '1')
    emit_li('$t3', 13)
    emit('bne $t3, $t2, ' + LL1)
    emit_jump(exit)
    emit_label(LL1)
    emit_li('$t3', 0)
    emit('bne $t3, $t2, ' + LL2)
    emit_jump(exit)
    emit_label(LL2)
    emit_li('$t3', 10)
    emit('bne $t3, $t2, ' + L1)
    emit_jump(exit)
    emit_label(L1)
    emit_li('$t3', 45)
    emit('bne $t3, $t2, ' + L2)
    emit_li('$t1', 1)
    emit_jump(L3)
    emit_label(L2)
    emit_li('$t3', 43)
    emit('bne $t3, $t2, ' + L4)
    emit_label(L3)
    emit_load_byte('$t2', '$a0')
    emit_addi('$a0', '$a0', '1')
    emit_label(L4)
    emit_li('$t3', 13)
    emit('bne $t2, $t3, ' + LL3)
    emit_jump(exit)
    emit_label(LL3)
    emit_li('$t3', 0)
    emit('bne $t2, $t3, ' + LL4)
    emit_jump(exit)
    emit_label(LL4)
    emit_li('$t3', 10)
    emit('bne $t2, $t3, ' + L_7)
    emit_jump(exit)
    emit_label(L_7)
    emit_addi('$t2', '$t2', '-48')
    emit_li('$t3', 0)
    emit('bge $t2, $t3, ' + L5)
    emit_li('$t1', -1)
    emit_jump(L_1)
    emit_label(L5)
    emit_li('$t3', 10)
    emit('bgt $t3, $t2, ' + L6)
    emit_li('$t1', -1)
    emit_jump(L_1)
    emit_label(L6)
    emit_li('$t3', 0)
    emit_move('$t0', '$t2')
    emit('bne $t2, $t3, ' + L_1)
    emit_load_byte('$t2', '$a0')
    emit_addi('$a0', '$a0', '1')
    emit_li('$t3', 13)
    emit('bne $t2, $t3, ' + LL5)
    emit_jump(exit)
    emit_label(LL5)
    emit_li('$t3', 0)
    emit('bne $t2, $t3, ' + LL6)
    emit_jump(exit)
    emit_label(LL6)
    emit_li('$t3', 10)
    emit('bne $t2, $t3, ' + L7)
    emit_jump(exit)
    emit_label(L7)
    emit_li('$t3', 88)
    emit('beq $t2, $t3, ' + L7_)
    emit_li('$t3', 120)
    emit('beq $t2, $t3, ' + L7_)
    emit_jump(L8)
    emit_label(L7_)
    emit_li('$t4', 16)
    emit_jump(L_1)
    emit_label(L8)
    emit_li('$t3', 48)
    emit('bge $t2, $t3, ' + L9)
    emit_li('$t1', -1)
    emit_jump(L_1)
    emit_label(L9)
    emit_li('$t3', 57)
    emit('ble $t2, $t3, ' + L10)
    emit_li('$t1', -1)
    emit_jump(L_1)
    emit_label(L10)
    emit_addi('$t2', '$t2', '-48')
    emit_move('$t0', '$t2')
    emit_label(L_1)
    emit_load_byte('$t2', '$a0')
    emit_addi('$a0', '$a0', '1')
    emit_li('$t3', 13)
    emit('bne $t2, $t3, ' + LL7)
    emit_jump(exitt)
    emit_label(LL7)
    emit_li('$t3', 0)
    emit('bne $t2, $t3, ' + LL8)
    emit_jump(exitt)
    emit_label(LL8)
    emit_li('$t3', 10)
    emit('bne $t2, $t3, ' + L_2)
    emit_jump(exitt)
    emit_label(L_2)
    emit_li('$t3', 48)
    emit('blt $t2, $t3, ' + L_5)
    emit_li('$t3', 57)
    emit('bgt $t2, $t3, ' + L_3)
    emit_addi('$t2', '$t2', '-48')
    emit('mul $t0, $t0, $t4')
    emit('add $t0, $t0, $t2')
    emit_jump(L_1)
    emit_label(L_3)
    emit_li('$t3', 65)
    emit('blt $t2, $t3, ' + L_5)
    emit_li('$t3', 70)
    emit('bgt $t2, $t3, ' + L_4)
    emit_addi('$t2', '$t2', '-55')
    emit('bge $t2, $t4, ' + L_5)
    emit('mul $t0, $t0, $t4')
    emit('add $t0, $t0, $t2')
    emit_jump(L_1)
    emit_label(L_4)
    emit_li('$t3', 97)
    emit('blt $t2, $t3, ' + L_5)
    emit_li('$t3', 102)
    emit('bgt $t2, $t3, ' + L_5)
    emit_addi('$t2', '$t2', '-87')
    emit('bge $t2, $t4, ' + L_5)
    emit('mul $t0, $t0, $t4')
    emit('add $t0, $t0, $t2')
    emit_jump(L_1)
    emit_label(L_5)
    emit_li('$t1', -1)
    emit_jump(L_1)
    emit_label(exitt)
    emit_li('$t4', -1)
    emit('bne $t4, $t1, ' + L_6)
    emit_li('$t0', 0)
    emit_jump(exit)
    emit_label(L_6)
    emit_li('$t4', 1)
    emit('bne $t4, $t1, ' + exit)
    emit('sub $t0, $zero, $t0')
    emit_label(exit)
    emit_move('$s0', '$t0')
    node.get_address().store()
    return node