def cgen_new_array(node): emit_comment('cgen_new_array') stack_handler.add_checkpoint() len_expr = cgen_expr(node.ref_child[1]) (member_type, dimension) = expr_type(node.ref_child[2]) if len_expr.get_type() != Type.int: raise TypeError("in node: \n" + node.__repr__() + "\n length of new_array isn't int.") len_expr_address = len_expr.get_address() len_expr_address.load() emit_li('$t0', '4') emit_addi('$s0', '$s0', '1') emit('mult $s0, $t0') emit('mflo $a0') emit_li('$v0', 9) emit_syscall() # Set length emit_addi('$s0', '$s0', '-1') emit('sw $s0, 0($v0)') emit_addi('$s0', '$s0', '1') emit_move('$s0', '$v0') stack_handler.back_to_last_checkpoint() expr_set_node_attributes(node, Type.array) node.get_address().store() node.set_array_dim(dimension + 1) node.set_array_member_type(member_type) return node
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 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_expr_new(node): class_name = expr_ident(node.ref_child[1]) expr_set_node_attributes(node, class_name) obj_size = ut.class_handler.get_object_size(class_name) emit_li('$a0', obj_size) emit_li('$v0', 9) emit_syscall() emit_move('$s0', '$v0') node.get_address().store() emit('la $s0, ' + class_name) emit('sw $s0, 0($v0)') return node
def cgen(parseTree): ut.class_analyzer = ClassAnalyzer(parseTree) emit('.text') emit('j main') init_global_variables(parseTree.nodes[0]) init_class_decls(parseTree.nodes[0]) init_functions(parseTree.nodes[0]) init_member_functions(parseTree.nodes[0]) emit("main: move $t8, $sp") emit_addi("$sp", "$sp", str(-4 * (len(ut.globalSymbolTable.variables) + 1))) ut.fill_vtable() emit('jal _____main') emit_li('$v0', 10) emit_syscall() emit('') ut.add_vtables() ut.print_data_section()
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 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_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