def transform_operator_assignment_stmt(builder: IRBuilder, stmt: OperatorAssignmentStmt) -> None: """Operator assignment statement such as x += 1""" builder.disallow_class_assignments([stmt.lvalue], stmt.line) target = builder.get_assignment_target(stmt.lvalue) target_value = builder.read(target, stmt.line) rreg = builder.accept(stmt.rvalue) # the Python parser strips the '=' from operator assignment statements, so re-add it op = stmt.op + '=' res = builder.binary_op(target_value, rreg, op, stmt.line) # usually operator assignments are done in-place # but when target doesn't support that we need to manually assign builder.assign(target, res, res.line)
def transform_basic_comparison(builder: IRBuilder, op: str, left: Value, right: Value, line: int) -> Value: negate = False if op == 'is not': op, negate = 'is', True elif op == 'not in': op, negate = 'in', True target = builder.binary_op(left, right, op, line) if negate: target = builder.unary_op(target, 'not', line) return target
def gen_glue_ne_method(builder: IRBuilder, cls: ClassIR, line: int) -> FuncIR: """Generate a __ne__ method from a __eq__ method. """ builder.enter() rt_args = (RuntimeArg("self", RInstance(cls)), RuntimeArg("rhs", object_rprimitive)) # The environment operates on Vars, so we make some up fake_vars = [(Var(arg.name), arg.type) for arg in rt_args] args = [ builder.read( builder.environment.add_local_reg( var, type, is_arg=True ), line ) for var, type in fake_vars ] # type: List[Value] builder.ret_types[-1] = object_rprimitive # If __eq__ returns NotImplemented, then __ne__ should also not_implemented_block, regular_block = BasicBlock(), BasicBlock() eqval = builder.add(MethodCall(args[0], '__eq__', [args[1]], line)) not_implemented = builder.primitive_op(not_implemented_op, [], line) builder.add(Branch( builder.binary_op(eqval, not_implemented, 'is', line), not_implemented_block, regular_block, Branch.BOOL_EXPR)) builder.activate_block(regular_block) retval = builder.coerce( builder.unary_op(eqval, 'not', line), object_rprimitive, line ) builder.add(Return(retval)) builder.activate_block(not_implemented_block) builder.add(Return(not_implemented)) blocks, env, ret_type, _ = builder.leave() return FuncIR( FuncDecl('__ne__', cls.name, builder.module_name, FuncSignature(rt_args, ret_type)), blocks, env)
def transform_op_expr(builder: IRBuilder, expr: OpExpr) -> Value: if expr.op in ('and', 'or'): return builder.shortcircuit_expr(expr) return builder.binary_op(builder.accept(expr.left), builder.accept(expr.right), expr.op, expr.line)