Exemplo n.º 1
0
 def visit_comparison_expr(self, expr: ComparisonExpr) -> Expression:
     results = []
     for index in range(len(expr.operators)):
         left, right = expr.operands[index], expr.operands[index + 1]
         operator = expr.operators[index]
         opExpr = OpExpr(operator, left, right)
         result = opExpr.accept(self)
         results.append(result)
     # Do the and of all comparisons
     for r in results:
         if not isinstance(r, IntExpr):
             raise Exception
         if r.value == 0:
             return IntExpr(0)
     return IntExpr(1)
Exemplo n.º 2
0
    def visit_BinOp(self, n: ast27.BinOp) -> OpExpr:
        op = self.from_operator(n.op)

        if op is None:
            raise RuntimeError('cannot translate BinOp ' + str(type(n.op)))

        return OpExpr(op, self.visit(n.left), self.visit(n.right))
Exemplo n.º 3
0
 def visit_JoinedStr(self, n: ast3.JoinedStr) -> Expression:
     result_expression = StrExpr('')  # type: Expression
     for value_expr in self.translate_expr_list(n.values):
         string_method = MemberExpr(value_expr, '__str__')
         string_method.set_line(value_expr)
         stringified_value_expr = CallExpr(string_method, [], [])
         stringified_value_expr.set_line(value_expr)
         result_expression = OpExpr('+', result_expression,
                                    stringified_value_expr)
         result_expression.set_line(value_expr)
     return result_expression
Exemplo n.º 4
0
 def visit_op_expr(self, e: OpExpr) -> None:
     super().visit_op_expr(e)
     if e.op in ['and', 'or']:
         target = self.get_type(e)
         e.left = self.coerce(e.left, target, self.get_type(e.left),
                              self.type_context())
         e.right = self.coerce(e.right, target, self.get_type(e.right),
                               self.type_context())
     else:
         method_type = e.method_type
         if self.dynamic_funcs[-1] or isinstance(method_type, AnyType):
             e.left = self.coerce_to_dynamic(e.left, self.get_type(e.left),
                                             self.type_context())
             e.right = self.coerce(e.right, AnyType(),
                                   self.get_type(e.right),
                                   self.type_context())
         elif method_type:
             method_callable = cast(Callable, method_type)
             operand = e.right
             # For 'in', the order of operands is reversed.
             if e.op == 'in':
                 operand = e.left
             # TODO arg_types[0] may not be reliable
             operand = self.coerce(operand, method_callable.arg_types[0],
                                   self.get_type(operand),
                                   self.type_context())
             if e.op == 'in':
                 e.left = operand
             else:
                 e.right = operand
Exemplo n.º 5
0
 def visit_op_expr(self, e: OpExpr) -> None:
     super().visit_op_expr(e)
     if e.op in ["and", "or"]:
         target = self.get_type(e)
         e.left = self.coerce(e.left, target, self.get_type(e.left), self.type_context())
         e.right = self.coerce(e.right, target, self.get_type(e.right), self.type_context())
     else:
         method_type = e.method_type
         if self.dynamic_funcs[-1] or isinstance(method_type, AnyType):
             e.left = self.coerce_to_dynamic(e.left, self.get_type(e.left), self.type_context())
             e.right = self.coerce(e.right, AnyType(), self.get_type(e.right), self.type_context())
         elif method_type:
             method_callable = cast(Callable, method_type)
             operand = e.right
             # For 'in', the order of operands is reversed.
             if e.op == "in":
                 operand = e.left
             # TODO arg_types[0] may not be reliable
             operand = self.coerce(
                 operand, method_callable.arg_types[0], self.get_type(operand), self.type_context()
             )
             if e.op == "in":
                 e.left = operand
             else:
                 e.right = operand
Exemplo n.º 6
0
 def visit_op_expr(self, e: OpExpr) -> None:
     super().visit_op_expr(e)
     if e.op in ['and', 'or']:
         target = self.get_type(e)
         e.left = self.coerce(e.left, target,
                              self.get_type(e.left), self.type_context())
         e.right = self.coerce(e.right, target,
                               self.get_type(e.right), self.type_context())
     else:
         method_type = e.method_type
         if self.dynamic_funcs[-1] or isinstance(method_type, AnyType):
             e.left = self.coerce_to_dynamic(e.left, self.get_type(e.left),
                                             self.type_context())
             e.right = self.coerce(e.right, AnyType(),
                                   self.get_type(e.right),
                                   self.type_context())
         elif method_type:
             method_callable = cast(Callable, method_type)
             operand = e.right
             # TODO arg_types[0] may not be reliable
             operand = self.coerce(operand, method_callable.arg_types[0],
                                   self.get_type(operand),
                                   self.type_context())               
             e.right = operand
Exemplo n.º 7
0
 def group(vals):
     if len(vals) == 2:
         return OpExpr(op, vals[0], vals[1])
     else:
         return OpExpr(op, vals[0], group(vals[1:]))
Exemplo n.º 8
0
 def group(self, vals: List[Expression], op: str) -> OpExpr:
     if len(vals) == 2:
         return OpExpr(op, vals[0], vals[1])
     else:
         return OpExpr(op, vals[0], self.group(vals[1:], op))
Exemplo n.º 9
0
 def group(vals: List[Expression]) -> OpExpr:
     if len(vals) == 2:
         return OpExpr(op, vals[0], vals[1])
     else:
         return OpExpr(op, vals[0], group(vals[1:]))
Exemplo n.º 10
0
 def visit_op_expr(self, node: OpExpr) -> Node:
     new = OpExpr(node.op, self.node(node.left), self.node(node.right))
     new.method_type = self.optional_type(node.method_type)
     return new
Exemplo n.º 11
0
def transform_comparison_expr(builder: IRBuilder, e: ComparisonExpr) -> Value:
    # x in (...)/[...]
    # x not in (...)/[...]
    first_op = e.operators[0]
    if (first_op in ['in', 'not in']
            and len(e.operators) == 1
            and isinstance(e.operands[1], (TupleExpr, ListExpr))):
        items = e.operands[1].items
        n_items = len(items)
        # x in y -> x == y[0] or ... or x == y[n]
        # x not in y -> x != y[0] and ... and x != y[n]
        # 16 is arbitrarily chosen to limit code size
        if 1 < n_items < 16:
            if e.operators[0] == 'in':
                bin_op = 'or'
                cmp_op = '=='
            else:
                bin_op = 'and'
                cmp_op = '!='
            lhs = e.operands[0]
            mypy_file = builder.graph['builtins'].tree
            assert mypy_file is not None
            bool_type = Instance(cast(TypeInfo, mypy_file.names['bool'].node), [])
            exprs = []
            for item in items:
                expr = ComparisonExpr([cmp_op], [lhs, item])
                builder.types[expr] = bool_type
                exprs.append(expr)

            or_expr: Expression = exprs.pop(0)
            for expr in exprs:
                or_expr = OpExpr(bin_op, or_expr, expr)
                builder.types[or_expr] = bool_type
            return builder.accept(or_expr)
        # x in [y]/(y) -> x == y
        # x not in [y]/(y) -> x != y
        elif n_items == 1:
            if e.operators[0] == 'in':
                cmp_op = '=='
            else:
                cmp_op = '!='
            e.operators = [cmp_op]
            e.operands[1] = items[0]
        # x in []/() -> False
        # x not in []/() -> True
        elif n_items == 0:
            if e.operators[0] == 'in':
                return builder.false()
            else:
                return builder.true()

    if first_op in ('is', 'is not') and len(e.operators) == 1:
        right = e.operands[1]
        if isinstance(right, NameExpr) and right.fullname == 'builtins.None':
            # Special case 'is None' / 'is not None'.
            return translate_is_none(builder, e.operands[0], negated=first_op != 'is')

    # TODO: Don't produce an expression when used in conditional context
    # All of the trickiness here is due to support for chained conditionals
    # (`e1 < e2 > e3`, etc). `e1 < e2 > e3` is approximately equivalent to
    # `e1 < e2 and e2 > e3` except that `e2` is only evaluated once.
    expr_type = builder.node_type(e)

    # go(i, prev) generates code for `ei opi e{i+1} op{i+1} ... en`,
    # assuming that prev contains the value of `ei`.
    def go(i: int, prev: Value) -> Value:
        if i == len(e.operators) - 1:
            return transform_basic_comparison(
                builder, e.operators[i], prev, builder.accept(e.operands[i + 1]), e.line)

        next = builder.accept(e.operands[i + 1])
        return builder.builder.shortcircuit_helper(
            'and', expr_type,
            lambda: transform_basic_comparison(
                builder, e.operators[i], prev, next, e.line),
            lambda: go(i + 1, next),
            e.line)

    return go(0, builder.accept(e.operands[0]))
Exemplo n.º 12
0
 def visit_op_expr(self, node: OpExpr) -> Node:
     new = OpExpr(node.op, self.node(node.left), self.node(node.right))
     new.method_type = self.optional_type(node.method_type)
     return new
Exemplo n.º 13
0
 def group(vals: List[Node]) -> Node:
     if len(vals) == 2:
         return OpExpr(op, vals[0], vals[1])
     else:
         return OpExpr(op, vals[0], group(vals[1:]))
Exemplo n.º 14
0
 def group(self, op: str, vals: List[Expression], n: ast3.expr) -> OpExpr:
     if len(vals) == 2:
         e = OpExpr(op, vals[0], vals[1])
     else:
         e = OpExpr(op, vals[0], self.group(op, vals[1:], n))
     return self.set_line(e, n)