def assign_plus(self, a, b, c): if is_number(b) or a == c: b, c = c, b # a := b + number if is_number(c): a, b = self.alloregs(a, b) if a != b: self.cmd('COPY a b', a=a, b=b) if c <= 5: # small number addition for c in xrange(c): self.cmd('INC a', a=a) else: c = self.num(c, 9) self.cmd('ADD a c', a=a, c=c) return a, b, c = self.alloregs(a, b, c) if a != b: self.cmd('COPY a b', a=a, b=b) if b == c: # a := b + b self.cmd('SHL a', a=a) else: # a := b + c self.cmd('ADD a c', a=a, c=c)
def if_gt(self, a, b, block_jump): if is_number(a) and is_number(b): if a > b: self.cmd('JUMP blockjump', blockjump=block_jump) return if a == b: # a > a always false return if is_number(a): _, b = self.alloregs(b, b) a = self.num(a, 8) elif is_number(b): _, a = self.alloregs(a, a) self.cmd('COPY 8 a', a=a) b = self.num(b, 9) else: _, a, b = self.alloregs(a, a, b) self.cmd('COPY 8 a', a=a) self.cmd(''' SUB 8 b JZERO 8 $END JUMP blockjump ''', b=b, blockjump=block_jump)
def if_leq(self, a, b, block_jump): if is_number(a) and is_number(b): if a <= b: self.cmd('JUMP blockjump', blockjump=block_jump) return if a == b: # a <= a always true self.cmd('JUMP blockjump', blockjump=block_jump) return if is_number(a): _, b = self.alloregs(b, b) a = self.num(a, 8) elif is_number(b): _, a = self.alloregs(a, a) if b == 0: self.cmd('JZERO a blockjump', a=a, blockjump=block_jump) return self.cmd('COPY 8 a', a=a) b = self.num(b, 9) else: _, a, b = self.alloregs(a, a, b) self.cmd('COPY 8 a', a=a) self.cmd(''' SUB 8 b JZERO 8 blockjump ''', b=b, blockjump=block_jump)
def if_geq(self, a, b, block_jump): if is_number(a) and is_number(b): if a >= b: self.cmd('JUMP blockjump', blockjump=block_jump) return if a == b: # a >= a always true self.cmd('JUMP blockjump', blockjump=block_jump) return if is_number(a): _, b = self.alloregs(b, b) self.cmd('COPY 9 b', b=b) a = self.num(a, 8) elif is_number(b): _, a = self.alloregs(a, a) b = self.num(b, 9) else: _, a, b = self.alloregs(a, a, b) self.cmd('COPY 9 b', b=b) self.cmd(''' SUB 9 a JZERO 9 blockjump ''', a=a, blockjump=block_jump)
def if_neq(self, a, b, block_jump): if is_number(a) and is_number(b) and a == b: return if a == b: # a != a always false return if is_number(a): a, b = b, a if is_number(b): _, a = self.alloregs(a, a) if b == 0: self.cmd(''' JZERO a $END JUMP blockjump ''', a=a, blockjump=block_jump) return b = self.num(b, 9) self.cmd('COPY 8 a', a=a) else: _, a, b = self.alloregs(a, a, b) self.cmd('COPY 8 a', a=a) self.cmd('COPY 9 b', b=b) self.cmd(''' SUB 8 b JZERO 8 $CHECK JUMP blockjump $CHECK SUB 9 a JZERO 9 $END JUMP blockjump ''', a=a, b=b, blockjump=block_jump)
def assign_times(self, a, b, c): if is_number(b): b, c = c, b if is_number(c): # todo << and *1 multiplication a, b = self.alloregs(a, b) c = self.num(c, 9) self.cmd('COPY 8 b', b=b) else: a, b, c = self.alloregs(a, b, c) self.cmd('COPY 9 c', c=c) self.cmd('COPY 8 b', b=b) self.mul(8, 9, a)
def assign_divide(self, a, b, c): if is_number(b): a, c = self.alloregs(a, c) self.num(b, 6) self.cmd('COPY 7 c', c=c) elif is_number(c): a, b = self.alloregs(a, b) self.num(c, 7) self.cmd('COPY 6 b', b=b) else: a, b, c = self.alloregs(a, b, c) self.cmd('COPY 6 b', b=b) self.cmd('COPY 7 c', c=c) self.div(6, 7, 8, a, 9)
def assign_modulo(self, a, b, c): if is_number(b): a, c = self.alloregs(a, c) self.cmd('COPY 6 c', c=c) b = self.num(b, a) elif is_number(c): a, b = self.alloregs(a, b) if a != c: self.cmd('COPY a b', a=a, b=b) c = self.num(c, 6) else: a, b, c = self.alloregs(a, b, c) self.cmd('COPY 6 c', c=c) self.cmd('COPY a b', a=a, b=b) self.div(a, 6, 7, 8, 9)
def gen_put(self, cmd): _, a = cmd if is_number(a): a = self.num(a, 9) else: _, a = self.alloregs(a, a) self.cmd('WRITE a', a=a)
def assign_minus(self, a, b, c): # a := b - number if is_number(c): a, b = self.alloregs(a, b) if a != b: self.cmd('COPY a b', a=a, b=b) if c <= 5: # small number subtraction for c in xrange(c): self.cmd('DEC a', a=a) else: c = self.num(c, 9) self.cmd('SUB a c', a=a, c=c) return # a := number - c if is_number(b): a, c = self.alloregs(a, c) if a == c: self.cmd('COPY 9 c', c=c) c = 9 b = self.num(b, a) self.cmd('SUB b c', b=b, c=c) return a, b, c = self.alloregs(a, b, c) if b == c: # a := b - b self.cmd('RESET a', a=a) return if a == c: # a := b - a self.cmd('COPY 9 c', c=c) c = 9 if a != b: self.cmd('COPY a b', a=a, b=b) self.cmd('SUB a c', a=a, c=c)