498 lines
9.1 KiB
Plaintext
498 lines
9.1 KiB
Plaintext
|
[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_extensions 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 :: int
|
||
|
r0 :: tuple[int, float, int]
|
||
|
r1 :: int
|
||
|
r2 :: float
|
||
|
r3, t :: tuple[float, float, float]
|
||
|
L0:
|
||
|
r0 = (x, 2.5, -14)
|
||
|
r1 = r0[0]
|
||
|
r2 = CPyFloat_FromTagged(r1)
|
||
|
r3 = (r2, 2.5, -7.0)
|
||
|
t = r3
|
||
|
return 1
|