def transform_Mul(self, node): if node.is_int: return ir.IntConst(node.evaluate_int(self.prog)) # We are guaranteed that node.a will be an integer, so we don't need to worry about transforming it c = node.a.evaluate_int(prog) # copy of a negative = False if c == 0: return ir.IntConst(0) if c < 0: negative = True c = -c self.expr_depth += 1 power = self.transform(node.b) self.expr_depth -= 1 s = ir.IntConst(0) while True: if c & 1 == 1: s = ir.Add(power, s) c = c // 2 if c <= 0: break power = ir.Add(power, power) if negative: return ir.Sub(ir.IntConst(0), s) else: return s
def transform_Div(self, node): if node.is_int: return ir.IntConst(node.evaluate_int(self.prog)) new_var = VarRef(ir.IRNode.fresh_name()) return self.transform( PredicateExpr( new_var.var_name, TypeHint(new_var, node.a, Equals(node.a, Mul(node.b, new_var)))))
def transform_Mul(self, node): # If they are both ints, translate to an IR node that will multiply # This will fail at runtime if one/both of the variables doesn't get substituted before this runs if not node.a.is_int and not node.b.is_int: return ir.Mul(self.transform(node.a), self.transform(node.b)) # We assumed above that a was the int, but it might not be; if it wasn't, just swap the two if not node.a.is_int: node.a, node.b = node.b, node.a if node.is_int: return ir.IntConst(node.evaluate_int(self.prog)) # We are guaranteed that node.a will be an integer, so we don't need to worry about transforming it c = node.a.evaluate_int(prog) # copy of a negative = False if c == 0: return ir.IntConst(0) if c < 0: negative = True c = -c self.expr_depth += 1 power = self.transform(node.b) self.expr_depth -= 1 s = ir.IntConst(0) while True: if c & 1 == 1: s = ir.Add(power, s) c = c // 2 if c <= 0: break power = ir.Add(power, power) if negative: return ir.Sub(ir.IntConst(0), s) else: return s
def transform_IntConst(self, node): return ir.IntConst(node.val)