Example #1
0
 def test_if_gen(self):
     context = Context()
     target = context.allocate_register()
     e = If(EQ(Var("x"), IntConst(1)),
            Assign(Var("y"), Minus(Var("x"), IntConst(1))),
            Assign(Var("x"), IntConst(2)))
     e.gen(context, target)
     expected = """
     LOAD  r14,var_x
     LOAD  r13,const_1
     SUB  r0,r14,r13
     JUMP/PM  else_1 #==
     LOAD  r14,var_x
     LOAD  r13,const_1
     SUB   r14,r14,r13
     STORE r14,var_y
     JUMP  fi_2
     else_1:
     LOAD r14,const_2
     STORE r14,var_x
     fi_2:
     const_1: DATA 1
     const_2: DATA 2
     var_x: DATA 0
     var_y: DATA 0
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #2
0
    def gen(self, context: Context, target: str):
        """Code generation for a constant reference.
        Generates code to load the value of that constant
        from memory.
        """

        context.add_line(f"   LOAD  {target},r0,r0[510]")
Example #3
0
 def gen(self, context: Context, target: str):
     """Generate code into the context object.
     Result of expression evaluation will be
     left in target register.
     """
     label = context.get_const_symbol(self.value)
     context.add_line(f"    LOAD {target},{label}")
     return
Example #4
0
 def gen(self, context: Context, target: str):
     """
     Generate code for the lhs then rhs
     """
     register = context.allocate_register()
     self.left.gen(context, target=register)
     self.right.gen(context, target=register)
     context.free_register(register)
Example #5
0
 def test_42n(self):
     const = IntConst(-42)
     context = Context()
     const.gen(context, "r12")
     expected = """
          LOAD  r12,const_n_42
     const_n_42:  DATA -42
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #6
0
 def test_var(self):
     var = Var("silly")
     context = Context()
     var.gen(context, "r8")
     expected = """
           LOAD  r8,var_silly
      var_silly:  DATA 0
      """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #7
0
 def gen(self, context: Context, target: str):
     self.left.gen(context, target)
     pos = context.new_label("already_positive")
     context.add_line(f"    SUB  r0,{target},r0  # <Abs>")
     context.add_line(f"    JUMP/PZ {pos}")
     context.add_line(f"    SUB {target},r0,{target}  # Flip the sign")
     context.add_line(f"{pos}:   # </Abs>")
Example #8
0
 def test_neg_gen(self):
     context = Context()
     target = context.allocate_register()
     e = Neg(IntConst(8))
     e.gen(context, target)
     expected = """
     LOAD r14,const_8
     SUB  r14,r0,r14 # Flip the sign
     const_8: DATA 8
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #9
0
 def test_assign(self):
     context = Context()
     assignment = Assign(Var("universe"), IntConst(42))
     assignment.gen(context, "r5")
     expected = """
           LOAD  r5,const_42
           STORE r5,var_universe
      const_42: DATA 42
      var_universe: DATA 0
      """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #10
0
 def test_div_gen(self):
     context = Context()
     target = context.allocate_register()
     e = Div(Var("x"), IntConst(3))
     e.gen(context, target)
     expected = """
     LOAD r14,var_x
     LOAD r13,const_3
     DIV  r14,r14,r13
     const_3: DATA 3
     var_x:   DATA 0
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #11
0
 def test_abs_gen(self):
     context = Context()
     target = context.allocate_register()
     e = Abs(IntConst(-3))
     e.gen(context, target)
     expected = """
     LOAD r14,const_n_3
     SUB  r0,r14,r0  # <Abs>
     JUMP/PZ already_positive_1
     SUB r14,r0,r14  # Flip the sign
     already_positive_1:   # </Abs>
     const_n_3:  DATA -3
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #12
0
 def test_LE_iffalse(self):
     """>=, jump if false"""
     context = Context()
     target = context.allocate_register()
     e = LE(IntConst(3), IntConst(5))
     e.condjump(context, target, "here_if_false", jump_cond=False)
     expected = """
     LOAD  r14,const_3
     LOAD  r13,const_5
     SUB   r0,r14,r13
     JUMP/P  here_if_false #<=
     const_3: DATA 3
     const_5: DATA 5
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #13
0
 def test_LT_iftrue(self):
     """<, jump if true"""
     context = Context()
     target = context.allocate_register()
     e = LT(IntConst(3), IntConst(5))
     e.condjump(context, target, "here_if_true")
     expected = """
     LOAD  r14,const_3
     LOAD  r13,const_5
     SUB   r0,r14,r13
     JUMP/M  here_if_true #<
     const_3: DATA 3
     const_5: DATA 5
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #14
0
 def gen(self, context: Context, target: str):
     """Looping"""
     loop_head = context.new_label("while_do")
     loop_exit = context.new_label("od")
     context.add_line(f"{loop_head}:")
     self.cond.condjump(context, target, loop_exit, jump_cond=False)
     self.expr.gen(context, target)
     context.add_line(f"   JUMP  {loop_head}")
     context.add_line(f"{loop_exit}:")
Example #15
0
    def gen(self, context: Context, target: str):

        predicate = context.new_label("if")
        self.cond.condjump(context, target, predicate, jump_cond=False)
        otherwise = context.new_label("else")
        context.add_line(f"{predicate}")
        #self.cond.gen(context, target)
        execute = context.new_label("fi")
        context.add_line(f"   JUMP  {execute}")
Example #16
0
 def test_while_gen(self):
     context = Context()
     target = context.allocate_register()
     e = While(EQ(Var("x"), Var("x")), Assign(Var("x"), Minus(Var("x"), IntConst(1))))
     e.gen(context, target)
     expected = """
     while_do_1: 
     LOAD  r14,var_x
     LOAD  r13,var_x
     SUB  r0,r14,r13
     JUMP/PM  od_2    #==
     LOAD  r14,var_x
     LOAD  r13,const_1
     SUB   r14,r14,r13
     STORE r14,var_x
     JUMP  while_do_1
     od_2: 
     const_1: DATA 1
     var_x: DATA 0
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #17
0
    def gen(self, context: Context, target: str):
        """If"""
        # loop_head = context.new_label("if")
        # loop_else = context.new_label("else")
        # loop_exit = context.new_label("fi")
        #

        loop_else = context.new_label("else")
        loop_exit = context.new_label("fi")
        self.cond.condjump(context, target, loop_else, jump_cond=False)
        self.thenpart.gen(context, target)
        context.add_line(f"JUMP {loop_exit}")
        context.add_line(f"{loop_else}:")
        self.elsepart.gen(context, target)
        context.add_line(f"{loop_exit}:")
Example #18
0
 def test_binop_combo(self):
     """Combining the operations involves some register
     management.
     """
     e = Plus(Times(Var("x"), Var("y")), Minus(IntConst(2), IntConst(3)))
     context = Context()
     target = context.allocate_register()
     e.gen(context, target)
     expected = """
     LOAD r14,var_x
     LOAD r13,var_y
     MUL r14,r14,r13
     LOAD r13,const_2
     LOAD r12,const_3
     SUB r13,r13,r12
     ADD r14,r14,r13
     const_2: DATA 2
     const_3: DATA 3
     var_x: DATA 0
     var_y: DATA 0
     """
     generated = context.get_lines()
     self.codeEqual(generated, expected)
Example #19
0
    def test_seq(self):
        context = Context()
        assignment_1 = Assign(Var("x"), IntConst(7))
        assignment_1.gen(context, "r14")

        assignment_2 = Assign(Var("y"), Var("x"))
        assignment_2.gen(context, "r14")

        assignment_3 = Assign(Var("z"), Var("y"))
        assignment_3.gen(context, "r14")
        expected = """
            LOAD r14,const_7
           STORE  r14,var_x
            LOAD r14,var_x
           STORE  r14,var_y
            LOAD r14,var_y
           STORE  r14,var_z
        const_7:  DATA 7
        var_x:  DATA 0
        var_y:  DATA 0
        var_z:  DATA 0
        """
        generated = context.get_lines()
        self.codeEqual(generated, expected)
Example #20
0
 def condjump(self,
              context: Context,
              target: str,
              label: str,
              jump_cond: bool = True):
     """Generate jump to label conditional on relation. """
     self.left.gen(context, target)
     reg = context.allocate_register()
     self.right.gen(context, reg)
     if jump_cond:
         cond = self.cond_code_true
     else:
         cond = self.cond_code_false
     # All relations are implemented by subtraction.  What varies is
     # the condition code controlling the jump.
     context.add_line(f"   SUB  r0,{target},{reg}")
     context.add_line(f"   JUMP/{cond}  {label}  #{self.opsym}")
     context.free_register(reg)
Example #21
0
 def gen(self, context: Context, target: str):
     """Get value from input by loading instruction from memory address 510"""
     self.expr.eval()
     context.add_line(f"   LOAD  {target},r0,r0[510]")
Example #22
0
 def gen(self, context: Context, target: str):
     self.left.gen(context, target)
     context.add_line(f"    SUB {target},r0,{target}  # Flip the sign")
Example #23
0
 def gen(self, context: Context, target: str):
     self.left.gen(context, target)
     reg = context.allocate_register()
     self.right.gen(context, reg)
     context.add_line(f"   {self._opcode()}  {target},{target},{reg}")
     context.free_register(reg)
Example #24
0
 def gen(self, context: Context, target: str):
     """
     Negation: subtract from 0
     """
     self.left.gen(context, target)
     context.add_line(f"   SUB  {target},r0,{target} # Flip the sign")
Example #25
0
 def lvalue(self, context: Context) -> str:
     """Return the label that the compiler will use for this variable"""
     return context.get_var_symbol(self.name)
Example #26
0
 def gen(self, context: Context, target: str):
     """Store value of expression into variable"""
     loc = self.left.lvalue(context)
     self.right.gen(context, target)
     context.add_line(f"   STORE  {target},{loc}")
Example #27
0
 def gen(self, context: Context, target: str):
     """We print by storing to the memory-mapped address 511"""
     self.expr.gen(context, target)
     context.add_line(f"   STORE  {target},r0,r0[511]")