| [case testFloatAdd] | |
| def f(x: float, y: float) -> float: | |
| return x + y | |
| def g(x: float) -> float: | |
| z = x - 1.5 | |
| return 2.5 * z | |
| [out] | |
| def f(x, y): | |
| x, y, r0 :: float | |
| L0: | |
| r0 = x + y | |
| return r0 | |
| def g(x): | |
| x, r0, z, r1 :: float | |
| L0: | |
| r0 = x - 1.5 | |
| z = r0 | |
| r1 = 2.5 * z | |
| return r1 | |
| [case testFloatBoxAndUnbox] | |
| from typing import Any | |
| def f(x: float) -> object: | |
| return x | |
| def g(x: Any) -> float: | |
| return x | |
| [out] | |
| def f(x): | |
| x :: float | |
| r0 :: object | |
| L0: | |
| r0 = box(float, x) | |
| return r0 | |
| def g(x): | |
| x :: object | |
| r0 :: float | |
| L0: | |
| r0 = unbox(float, x) | |
| return r0 | |
| [case testFloatNegAndPos] | |
| def f(x: float) -> float: | |
| y = +x * -0.5 | |
| return -y | |
| [out] | |
| def f(x): | |
| x, r0, y, r1 :: float | |
| L0: | |
| r0 = x * -0.5 | |
| y = r0 | |
| r1 = -y | |
| return r1 | |
| [case testFloatCoerceFromInt] | |
| def from_int(x: int) -> float: | |
| return x | |
| def from_literal() -> float: | |
| return 5 | |
| def from_literal_neg() -> float: | |
| return -2 | |
| [out] | |
| def from_int(x): | |
| x :: int | |
| r0 :: float | |
| L0: | |
| r0 = CPyFloat_FromTagged(x) | |
| return r0 | |
| def from_literal(): | |
| L0: | |
| return 5.0 | |
| def from_literal_neg(): | |
| L0: | |
| return -2.0 | |
| [case testConvertBetweenFloatAndInt] | |
| def to_int(x: float) -> int: | |
| return int(x) | |
| def from_int(x: int) -> float: | |
| return float(x) | |
| [out] | |
| def to_int(x): | |
| x :: float | |
| r0 :: int | |
| L0: | |
| r0 = CPyTagged_FromFloat(x) | |
| return r0 | |
| def from_int(x): | |
| x :: int | |
| r0 :: float | |
| L0: | |
| r0 = CPyFloat_FromTagged(x) | |
| return r0 | |
| [case testFloatOperatorAssignment] | |
| def f(x: float, y: float) -> float: | |
| x += y | |
| x -= 5.0 | |
| return x | |
| [out] | |
| def f(x, y): | |
| x, y, r0, r1 :: float | |
| L0: | |
| r0 = x + y | |
| x = r0 | |
| r1 = x - 5.0 | |
| x = r1 | |
| return x | |
| [case testFloatOperatorAssignmentWithInt] | |
| def f(x: float, y: int) -> None: | |
| x += y | |
| x -= 5 | |
| [out] | |
| def f(x, y): | |
| x :: float | |
| y :: int | |
| r0, r1, r2 :: float | |
| L0: | |
| r0 = CPyFloat_FromTagged(y) | |
| r1 = x + r0 | |
| x = r1 | |
| r2 = x - 5.0 | |
| x = r2 | |
| return 1 | |
| [case testFloatComparison] | |
| def lt(x: float, y: float) -> bool: | |
| return x < y | |
| def eq(x: float, y: float) -> bool: | |
| return x == y | |
| [out] | |
| def lt(x, y): | |
| x, y :: float | |
| r0 :: bit | |
| L0: | |
| r0 = x < y | |
| return r0 | |
| def eq(x, y): | |
| x, y :: float | |
| r0 :: bit | |
| L0: | |
| r0 = x == y | |
| return r0 | |
| [case testFloatOpWithLiteralInt] | |
| def f(x: float) -> None: | |
| y = x * 2 | |
| z = 1 - y | |
| b = z < 3 | |
| c = 0 == z | |
| [out] | |
| def f(x): | |
| x, r0, y, r1, z :: float | |
| r2 :: bit | |
| b :: bool | |
| r3 :: bit | |
| c :: bool | |
| L0: | |
| r0 = x * 2.0 | |
| y = r0 | |
| r1 = 1.0 - y | |
| z = r1 | |
| r2 = z < 3.0 | |
| b = r2 | |
| r3 = 0.0 == z | |
| c = r3 | |
| return 1 | |
| [case testFloatCallFunctionWithLiteralInt] | |
| def f(x: float) -> None: pass | |
| def g() -> None: | |
| f(3) | |
| f(-2) | |
| [out] | |
| def f(x): | |
| x :: float | |
| L0: | |
| return 1 | |
| def g(): | |
| r0, r1 :: None | |
| L0: | |
| r0 = f(3.0) | |
| r1 = f(-2.0) | |
| return 1 | |
| [case testFloatAsBool] | |
| def f(x: float) -> int: | |
| if x: | |
| return 2 | |
| else: | |
| return 5 | |
| [out] | |
| def f(x): | |
| x :: float | |
| r0 :: bit | |
| L0: | |
| r0 = x != 0.0 | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| return 4 | |
| L2: | |
| return 10 | |
| L3: | |
| unreachable | |
| [case testCallSqrtViaMathModule] | |
| import math | |
| def f(x: float) -> float: | |
| return math.sqrt(x) | |
| [out] | |
| def f(x): | |
| x, r0 :: float | |
| L0: | |
| r0 = CPyFloat_Sqrt(x) | |
| return r0 | |
| [case testFloatFinalConstant] | |
| from typing import Final | |
| X: Final = 123.0 | |
| Y: Final = -1.0 | |
| def f() -> float: | |
| a = X | |
| return a + Y | |
| [out] | |
| def f(): | |
| a, r0 :: float | |
| L0: | |
| a = 123.0 | |
| r0 = a + -1.0 | |
| return r0 | |
| [case testFloatDefaultArg] | |
| def f(x: float = 1.5) -> float: | |
| return x | |
| [out] | |
| def f(x, __bitmap): | |
| x :: float | |
| __bitmap, r0 :: u32 | |
| r1 :: bit | |
| L0: | |
| r0 = __bitmap & 1 | |
| r1 = r0 == 0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| x = 1.5 | |
| L2: | |
| return x | |
| [case testFloatMixedOperations] | |
| def f(x: float, y: int) -> None: | |
| if x < y: | |
| z = x + y | |
| x -= y | |
| z = y + z | |
| if y == x: | |
| x -= 1 | |
| [out] | |
| def f(x, y): | |
| x :: float | |
| y :: int | |
| r0 :: float | |
| r1 :: bit | |
| r2, r3, z, r4, r5, r6, r7, r8 :: float | |
| r9 :: bit | |
| r10 :: float | |
| L0: | |
| r0 = CPyFloat_FromTagged(y) | |
| r1 = x < r0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = CPyFloat_FromTagged(y) | |
| r3 = x + r2 | |
| z = r3 | |
| r4 = CPyFloat_FromTagged(y) | |
| r5 = x - r4 | |
| x = r5 | |
| r6 = CPyFloat_FromTagged(y) | |
| r7 = r6 + z | |
| z = r7 | |
| L2: | |
| r8 = CPyFloat_FromTagged(y) | |
| r9 = r8 == x | |
| if r9 goto L3 else goto L4 :: bool | |
| L3: | |
| r10 = x - 1.0 | |
| x = r10 | |
| L4: | |
| return 1 | |
| [case testFloatDivideSimple] | |
| def f(x: float, y: float) -> float: | |
| z = x / y | |
| z = z / 2.0 | |
| return z / 3 | |
| [out] | |
| def f(x, y): | |
| x, y :: float | |
| r0 :: bit | |
| r1 :: bool | |
| r2, z, r3, r4 :: float | |
| L0: | |
| r0 = y == 0.0 | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| r1 = raise ZeroDivisionError('float division by zero') | |
| unreachable | |
| L2: | |
| r2 = x / y | |
| z = r2 | |
| r3 = z / 2.0 | |
| z = r3 | |
| r4 = z / 3.0 | |
| return r4 | |
| [case testFloatDivideIntOperand] | |
| def f(n: int, m: int) -> float: | |
| return n / m | |
| [out] | |
| def f(n, m): | |
| n, m :: int | |
| r0 :: float | |
| L0: | |
| r0 = CPyTagged_TrueDivide(n, m) | |
| return r0 | |
| [case testFloatResultOfIntDivide] | |
| def f(f: float, n: int) -> float: | |
| x = f / n | |
| return n / x | |
| [out] | |
| def f(f, n): | |
| f :: float | |
| n :: int | |
| r0 :: float | |
| r1 :: bit | |
| r2 :: bool | |
| r3, x, r4 :: float | |
| r5 :: bit | |
| r6 :: bool | |
| r7 :: float | |
| L0: | |
| r0 = CPyFloat_FromTagged(n) | |
| r1 = r0 == 0.0 | |
| if r1 goto L1 else goto L2 :: bool | |
| L1: | |
| r2 = raise ZeroDivisionError('float division by zero') | |
| unreachable | |
| L2: | |
| r3 = f / r0 | |
| x = r3 | |
| r4 = CPyFloat_FromTagged(n) | |
| r5 = x == 0.0 | |
| if r5 goto L3 else goto L4 :: bool | |
| L3: | |
| r6 = raise ZeroDivisionError('float division by zero') | |
| unreachable | |
| L4: | |
| r7 = r4 / x | |
| return r7 | |
| [case testFloatExplicitConversions] | |
| def f(f: float, n: int) -> int: | |
| x = float(n) | |
| y = float(x) # no-op | |
| return int(y) | |
| [out] | |
| def f(f, n): | |
| f :: float | |
| n :: int | |
| r0, x, y :: float | |
| r1 :: int | |
| L0: | |
| r0 = CPyFloat_FromTagged(n) | |
| x = r0 | |
| y = x | |
| r1 = CPyTagged_FromFloat(y) | |
| return r1 | |
| [case testFloatModulo] | |
| def f(x: float, y: float) -> float: | |
| return x % y | |
| [out] | |
| def f(x, y): | |
| x, y :: float | |
| r0 :: bit | |
| r1 :: bool | |
| r2, r3 :: float | |
| r4, r5, r6, r7 :: bit | |
| r8, r9 :: float | |
| L0: | |
| r0 = y == 0.0 | |
| if r0 goto L1 else goto L2 :: bool | |
| L1: | |
| r1 = raise ZeroDivisionError('float modulo') | |
| unreachable | |
| L2: | |
| r2 = x % y | |
| r3 = r2 | |
| r4 = r3 == 0.0 | |
| if r4 goto L5 else goto L3 :: bool | |
| L3: | |
| r5 = x < 0.0 | |
| r6 = y < 0.0 | |
| r7 = r5 == r6 | |
| if r7 goto L6 else goto L4 :: bool | |
| L4: | |
| r8 = r3 + y | |
| r3 = r8 | |
| goto L6 | |
| L5: | |
| r9 = copysign(0.0, y) | |
| r3 = r9 | |
| L6: | |
| return r3 | |
| [case testFloatFloorDivide] | |
| def f(x: float, y: float) -> float: | |
| return x // y | |
| def g(x: float, y: int) -> float: | |
| return x // y | |
| [out] | |
| def f(x, y): | |
| x, y, r0 :: float | |
| L0: | |
| r0 = CPyFloat_FloorDivide(x, y) | |
| return r0 | |
| def g(x, y): | |
| x :: float | |
| y :: int | |
| r0, r1 :: float | |
| L0: | |
| r0 = CPyFloat_FromTagged(y) | |
| r1 = CPyFloat_FloorDivide(x, r0) | |
| return r1 | |
| [case testFloatNarrowToIntDisallowed] | |
| class C: | |
| x: float | |
| def narrow_local(x: float, n: int) -> int: | |
| x = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| return x | |
| def narrow_tuple_lvalue(x: float, y: float, n: int) -> int: | |
| x, y = 1.0, n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| return y | |
| def narrow_multiple_lvalues(x: float, y: float, n: int) -> int: | |
| x = a = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| a = y = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| return x + y | |
| def narrow_attribute(c: C, n: int) -> int: | |
| c.x = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| return c.x | |
| def narrow_using_int_literal(x: float) -> int: | |
| x = 1 # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| return x | |
| def narrow_using_declaration(n: int) -> int: | |
| x: float | |
| x = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| return x | |
| [case testFloatInitializeFromInt] | |
| def init(n: int) -> None: | |
| # These are strictly speaking safe, since these don't narrow, but for consistency with | |
| # narrowing assignments, generate errors here | |
| x: float = n # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| y: float = 5 # E: Incompatible value representations in assignment (expression has type "int", variable has type "float") | |
| [case testFloatCoerceTupleFromIntValues] | |
| from __future__ import annotations | |
| def f(x: int) -> None: | |
| t: tuple[float, float, float] = (x, 2.5, -7) | |
| [out] | |
| def f(x): | |
| x, r0 :: int | |
| r1 :: tuple[int, float, int] | |
| r2 :: int | |
| r3 :: float | |
| r4, t :: tuple[float, float, float] | |
| L0: | |
| r0 = x | |
| r1 = (r0, 2.5, -14) | |
| r2 = r1[0] | |
| r3 = CPyFloat_FromTagged(r2) | |
| r4 = (r3, 2.5, -7.0) | |
| t = r4 | |
| return 1 |