def gen(self, context: Context, target: str): """Code generation for negation, implemented by subtracting from zero. """ self.left.gen(context, target) context.add_line("\tSUB {},r0,{}".format(target, target)) return
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): """Code generation for assignment: calculate into register, then store into memory """ log.debug("Generating code for assignment") var_symbol = context.get_var_symbol(self.var.name) self.expr.gen(context, target) context.add_line("\tSTORE {},{}".format(target, var_symbol))
def gen(self, context: Context, target: str): """Code generation for a variable reference. Generates code to load the value of that variable from memory. """ log.debug("Generating code for reference to variable {}".format( self.name)) symbol = context.get_var_symbol(self.name) context.add_line("\tLOAD {},{}".format(target, symbol)) return
def gen(self, context: Context, target: str): """Load a constant from memory into a register""" const_label = context.get_const_symbol(self.val) context.add_line("\tLOAD {},{} # Const {}".format( target, const_label, self.val))
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