예제 #1
0
    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
예제 #2
0
    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)))))
예제 #3
0
    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
예제 #4
0
 def transform_IntConst(self, node):
     return ir.IntConst(node.val)