(
builder: IRBuilder, op: str, lhs: Expression, rhs: Expression, line: int
)
| 961 | |
| 962 | |
| 963 | def try_specialize_in_expr( |
| 964 | builder: IRBuilder, op: str, lhs: Expression, rhs: Expression, line: int |
| 965 | ) -> Value | None: |
| 966 | left: Value | None = None |
| 967 | items: list[Value] | None = None |
| 968 | |
| 969 | if isinstance(rhs, (TupleExpr, ListExpr)): |
| 970 | left = builder.accept(lhs) |
| 971 | items = [builder.accept(item) for item in rhs.items] |
| 972 | elif isinstance(builder.node_type(rhs), RTuple): |
| 973 | left = builder.accept(lhs) |
| 974 | tuple_val = builder.accept(rhs) |
| 975 | assert isinstance(tuple_val.type, RTuple) |
| 976 | items = [builder.add(TupleGet(tuple_val, i)) for i in range(len(tuple_val.type.types))] |
| 977 | |
| 978 | if items is not None: |
| 979 | assert left is not None |
| 980 | n_items = len(items) |
| 981 | # x in y -> x == y[0] or ... or x == y[n] |
| 982 | # x not in y -> x != y[0] and ... and x != y[n] |
| 983 | if n_items > 1: |
| 984 | if op == "in": |
| 985 | cmp_op = "==" |
| 986 | else: |
| 987 | cmp_op = "!=" |
| 988 | out = BasicBlock() |
| 989 | for item in items: |
| 990 | cmp = transform_basic_comparison(builder, cmp_op, left, item, line) |
| 991 | bool_val = builder.builder.bool_value(cmp) |
| 992 | next_block = BasicBlock() |
| 993 | if op == "in": |
| 994 | builder.add_bool_branch(bool_val, out, next_block) |
| 995 | else: |
| 996 | builder.add_bool_branch(bool_val, next_block, out) |
| 997 | builder.activate_block(next_block) |
| 998 | result_reg = Register(bool_rprimitive) |
| 999 | end = BasicBlock() |
| 1000 | if op == "in": |
| 1001 | values = builder.false(), builder.true() |
| 1002 | else: |
| 1003 | values = builder.true(), builder.false() |
| 1004 | builder.assign(result_reg, values[0], line) |
| 1005 | builder.goto(end) |
| 1006 | builder.activate_block(out) |
| 1007 | builder.assign(result_reg, values[1], line) |
| 1008 | builder.goto(end) |
| 1009 | builder.activate_block(end) |
| 1010 | return result_reg |
| 1011 | # x in [y]/(y) -> x == y |
| 1012 | # x not in [y]/(y) -> x != y |
| 1013 | elif n_items == 1: |
| 1014 | if op == "in": |
| 1015 | cmp_op = "==" |
| 1016 | else: |
| 1017 | cmp_op = "!=" |
| 1018 | right = items[0] |
| 1019 | return transform_basic_comparison(builder, cmp_op, left, right, line) |
| 1020 | # x in []/() -> False |
no test coverage detected
searching dependent graphs…