def cgen_while(node): emit_comment('cgen_while') expr = node.ref_child[0] stmt = node.ref_child[1] top = ut.disFp l1 = create_label() l2 = create_label() node.attribute[AttName.exit_label] = l2 emit_label(l1) t = cgen_expr(expr) 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) emit_jump(l1) emit_label(l2) emit_li("$t6", top) ut.emit_add("$t6", "$t6", "$fp") emit_move("$sp", "$t6") return
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_stmt_block(node): emit_comment('cgen_stmt_block') ut.symbolTable.add_scope() top = ut.disFp node.attribute[AttName.has_return] = False for child_node in node.ref_child: if child_node.data == "variabledecl": cgen_variable_decl(child_node) else: ret = cgen_stmt(child_node) if ret.attribute[AttName.has_return]: node.attribute[AttName.has_return] = True align_stack(top) ut.symbolTable.remove_scope() 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_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 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