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
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()
def cgen_function_decl(node, label, is_member_function=False, class_name=''): emit_label(label) ut.symbolTable = ut.SymbolTable(is_member_function) for i in range(len(node.ref_child[2].ref_child) - 1, -1, -1): name, type = cgen_variable(node.ref_child[2].ref_child[i]) if type[0]: type = type[1:] ut.symbolTable.add_param(type, name, True) else: type = type[1] ut.symbolTable.add_param(type, name) if is_member_function: name = 'this' type = class_name ut.symbolTable.add_param(type, name) ut.this_type = class_name else: ut.this_type = None ut.symbolTable.finish_params() ut.disFp = 0 emit_move('$fp', '$sp') ret = cgen_stmt_block(node.ref_child[3]) emit_move("$sp", "$fp") emit("jr $ra") # if not ret.attribute[AttName.has_return] and (node.ref_child[0].data != "void") and (label != "_____main"): # raise ReturnWarning( # "Function in node " + str(node) + " return anything in a path!" # ) return
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
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)
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
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
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()
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
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