Generate a native float binary arithmetic operation. This follows Python semantics (e.g. raise exception on division by zero). Add a FloatOp directly if you want low-level semantics. Args: op: Binary operator (e.g. '+' or '*')
(self, lhs: Value, rhs: Value, op: str, line: int)
| 2454 | return self.add(IntOp(type, lhs, rhs, op, line)) |
| 2455 | |
| 2456 | def float_op(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: |
| 2457 | """Generate a native float binary arithmetic operation. |
| 2458 | |
| 2459 | This follows Python semantics (e.g. raise exception on division by zero). |
| 2460 | Add a FloatOp directly if you want low-level semantics. |
| 2461 | |
| 2462 | Args: |
| 2463 | op: Binary operator (e.g. '+' or '*') |
| 2464 | """ |
| 2465 | op_id = float_op_to_id[op] |
| 2466 | if op_id in (FloatOp.DIV, FloatOp.MOD): |
| 2467 | if not (isinstance(rhs, Float) and rhs.value != 0.0): |
| 2468 | c = self.compare_floats(rhs, Float(0.0), FloatComparisonOp.EQ, line) |
| 2469 | err, ok = BasicBlock(), BasicBlock() |
| 2470 | self.add(Branch(c, err, ok, Branch.BOOL, rare=True)) |
| 2471 | self.activate_block(err) |
| 2472 | if op_id == FloatOp.DIV: |
| 2473 | msg = "float division by zero" |
| 2474 | else: |
| 2475 | msg = "float modulo" |
| 2476 | self.add(RaiseStandardError(RaiseStandardError.ZERO_DIVISION_ERROR, msg, line)) |
| 2477 | self.add(Unreachable()) |
| 2478 | self.activate_block(ok) |
| 2479 | if op_id == FloatOp.MOD: |
| 2480 | # Adjust the result to match Python semantics (FloatOp follows C semantics). |
| 2481 | return self.float_mod(lhs, rhs, line) |
| 2482 | else: |
| 2483 | return self.add(FloatOp(lhs, rhs, op_id, line)) |
| 2484 | |
| 2485 | def float_mod(self, lhs: Value, rhs: Value, line: int) -> Value: |
| 2486 | """Perform x % y on floats using Python semantics.""" |
no test coverage detected