def gen(self, context: Context, target: str): """Code generation for an binary operations """ log.debug("Generating code for binary operator") # You can use the same register for the left operand as # the 'target' register passed in. For the right operand, # you need to allocate a new register to pass as the # 'target' of the right operand. # After you have evaluated left and right operands, # generate an instruction that looks like # OP target,target,other_register # where OP is the operation code (like ADD, SUB, etc) # for the particular binop. Subclasses Plus, Minus, # etc do not repeat this 'gen' method, but instead just # define the _opcode method to provide the needed # operation code. # After generating code for this operation, be sure to # free the register you allocated for the right operand. self.left.gen(context, target) reg = context.alloc_reg() self.right.gen(context, target=reg) context.add_line("\t{} {},{},{}".format(self._opcode(), target, target, reg)) context.free_reg(reg) # free the register
def gen(self, context: Context, target: str): """Translate 'while' loop into explicit jumps. """ loop_head = context.new_label("loop") loop_exit = context.new_label("endloop") context.add_line("{}: #While loop".format(loop_head)) reg = context.alloc_reg() self.cond.gen(context, target=reg) # Is it zero? context.add_line("\tSUB r0,{},r0 ".format(reg)) context.add_line("\tJUMP/Z {}".format(loop_exit)) context.free_reg(reg) self.expr.gen(context, target) context.add_line("\tJUMP {}".format(loop_head)) context.add_line("{}: ".format(loop_exit))
def gen(self, context: Context, target: str): """ Generate code for an if/else. """ # The outline of the code you should generate is: # <code for expression> # subtract expression result from zero # if zero, jump to elsepart # <code for 'then' part> # jump to endif # elsepart: # <code for elsepart> # fi: # Generate fresh labels for the 'elsepart' and 'fi' each time, # since there could be more than one 'if' statement in a program. # Look at the 'while' statement above for examples of code # generation for tests, jumps, and labels. # # Example: # if 10 - 9: ---> condition # ------ # x = 5 ---> then # else: # x = 0 ---> else # initialize labels and registers elsepart = context.new_label("else") fi = context.new_label("end else") reg = context.alloc_reg() self.cond.gen(context, target=reg) # generate condition # If part # Is it zero? context.add_line("\tSUB r0,{},r0 ".format(reg)) context.add_line("\tJUMP/Z {}".format(elsepart)) self.thenpart.gen(context, target) # generate then part context.add_line("JUMP {}".format(fi)) # Else part context.add_line("{}: #Else loop".format(elsepart)) self.elsepart.gen(context, target) # generate else part context.add_line("{}".format(fi)) context.free_reg(reg) # free the register