Esempio n. 1
0
    def _make_accessors(self, info):
        """Build get() and set() function based on info.
        """
        name = self._array_name(info)
        fname = self._make_getter_name(info)
        size = info.sizeof()
        params = [("int", f"x{i}") for i in range(len(info.size))]
        mults = [
            BinaryOp("*", a, ID(b[1]))
            for a, b in zip(info.size[1:], params[:-1])
        ]

        offset = ID(params[-1][1])
        for m in mults:
            offset = BinaryOp("+", m, offset)

        cases = [
            Case(Constant("int", str(i)), [Return(ID(f"{name}_{i}"))])
            for i in range(size)
        ]
        body = Compound([Switch(offset, Compound(cases))])
        self.accessors.add(make_function(info.type, fname, params, body))

        cases = [
            Case(Constant("int", str(i)),
                 [Assignment("=", ID(f"{name}_{i}"), ID("value")),
                  Break()]) for i in range(size)
        ]
        body = Compound([Switch(offset, Compound(cases))])
        type_ = (info.type.name
                 if type(info.type) == Struct else info.type.names[0])
        setter = make_function(IdentifierType(["void"]),
                               fname.replace("get", "set", 1),
                               params + [(type_, "value")], body)
        self.accessors.add(setter)
Esempio n. 2
0
    def visit_UnaryOp(self, pyc_unary_op: UnaryOp):
        # convert pyc_unary operator to pyc_assignment
        op = pyc_unary_op.op
        if op == '++' or op == 'p++':
            op = '+'
        elif op == '--' or op == 'p--':
            op = '-'
        elif op == '+' or op == '-':
            bin_op = BinaryOp(op, Constant('int', '0', pyc_unary_op.coord), pyc_unary_op.expr, pyc_unary_op.coord)
            return self.visit(bin_op)
        # else:
        #     raise NotImplementedError('op=', op)
        right = BinaryOp(op, pyc_unary_op.expr, Constant('int', '1', pyc_unary_op.coord), pyc_unary_op.coord)
        pyc_assign = Assignment('=', pyc_unary_op.expr, right, pyc_unary_op.coord)

        return self.visit(pyc_assign)
Esempio n. 3
0
 def cached_provider_call(self):
     provider = self.provider
     entity_flag = self.memo_flag_name
     return If(cond=UnaryOp(op='!', expr=ID(name=entity_flag)),
               iftrue=Compound(block_items=[ FuncCall(name=ID(name=provider), args=None),
                                             Assignment(op='=',
                                                        lvalue=ID(name=entity_flag),
                                                        rvalue=Constant(type='bool', value='true'))]),
               iffalse=None)
Esempio n. 4
0
 def visit_UnaryOp(self, node):
     _ops = {
         "!": lambda x: 1 if x == 0 else 0,
         "+": lambda x: x,
         "-": lambda x: -x
     }
     self.generic_visit(node)
     if is_const(node.expr) and node.op in _ops:
         val = str(_ops[node.op](parse_int(node.expr.value)))
         new_node = Constant("int", val)
         self.replace(node, new_node)
 def visit_Enum(self, node):
     if not node.values:
         return
     generator = c_generator.CGenerator()
     for i, elem in enumerate(node.values.enumerators):
         if not elem.value:
             continue
         try:
             raw_val = generator.visit(elem.value)
             for item in node.values.enumerators:
                 try:
                     if item.value and item.value.type == 'int':
                         raw_val = raw_val.replace(item.name, item.value.value)
                 except:
                     pass
             cooked_value = eval(raw_val)
             elem.value = Constant(type='int', value=str(cooked_value))
         except:
             pass
Esempio n. 6
0
def make_int_constant(value):
    return Constant(type='int', value=str(value))
Esempio n. 7
0
    def visit_BinaryOp(self, node):
        """C99-Section 6.5
        """
        _ops = {
            "+": lambda x, y: x + y,
            "-": lambda x, y: x - y,
            "*": lambda x, y: x * y,
            "/": lambda x, y: x // y,
            "%": lambda x, y: abs(x) % abs(y) * (1 - 2 * (x < 0)),
            "<<": lambda x, y: x << y,
            ">>": lambda x, y: x >> y,
            "&": lambda x, y: x & y,
            "|": lambda x, y: x | y,
            "&&": lambda x, y: 0 if not bool(x) else int(bool(x & y)),
            "||": lambda x, y: 1 if bool(x) else int(bool(x | y))
        }
        self.generic_visit(node)

        # Commutative axioms
        for n1, n2 in ((node.left, node.right), (node.right, node.left)):
            if self.is_int_const(n1):
                v1 = parse_int(n1.value)
                if v1 == 0:
                    if node.op in ("+", "-"):
                        self.replace(node, n2)  # 0+x = 0-x = 0
                    elif node.op == "*":
                        self.replace(node, n1)  # 0*x = 0
                elif v1 == 1 and node.op == "*":
                    self.replace(node, n2)  # 1*x = x
                elif v1 == -1 and node.op == "*":
                    self.replace(node, UnaryOp("-", n2))  # -1*x = -x

        # Non-commutative axioms
        if self.is_int_const(node.left):
            v = parse_int(node.left.value)
            if v == 0 and node.op in (">>", "<<", "/", "%"):
                self.replace(node, node.left)  # 0<<x = 0>>x = 0/x = 0%x = 0

        if self.is_int_const(node.right):
            v = parse_int(node.right.value)
            if v == 0 and node.op in ("<<", ">>"):
                self.replace(node, node.left)  # x<<0 = x>>0 = x
            elif v == 1 and node.op == "/":
                self.replace(node, node.left)  # x/1 = x
            elif v == -1 and node.op == "/":
                self.replace(node, UnaryOp("-", node.left))  # x/-1 = -x
            elif abs(v) == 1 and node.op == "%":
                node.right.value = "0"
                self.replace(node, node.right)  # x%1 = 0

        # Generic folding
        ULLONG_MAX = 18446744073709551615
        if self.is_int_const(node.left) and self.is_int_const(node.right):
            if node.op in _ops:
                try:
                    val = _ops[node.op](
                        parse_int(node.left.value),
                        parse_int(node.right.value))
                    # print(">>>",val)
                    if abs(val) <= ULLONG_MAX:
                        new_node = Constant("int", str(val))
                        self.replace(node, new_node)
                except ZeroDivisionError:
                    pass