Files
Viper_RegressionTesting/GenericTest2/App/main.vp
T
TermiNexus 63cab96f53 fix(generictest2): 去掉 generic_swap 的幽灵类型形参 [T]
T 未被签名/函数体任何位置引用,签名形参注解为 IntPair | t.CPtr,泛型函数类型实参推断无法为它找到形参槽(_annotation_refers_type_param 返回 0),触发 fail-fast(禁止静默默认 int)。该函数本就不需要泛型,去掉 [T] 即语义正确。
2026-10-03 15:20:33 +08:00

274 lines
8.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import t
import stdio
import c
import testcheck
# ============================================================
# Test 1: 泛型函数 - 不同整数类型特化
# ============================================================
def square[T](x: T) -> T:
return x * x
def test_generic_square_types():
testcheck.section("Test 1: generic square with different types")
r1: t.CInt = square(5)
r2: t.CInt = square(10)
testcheck.check(r1 == 25 and r2 == 100, "square (5^2=25 10^2=100)", "square expect 25 100")
# ============================================================
# Test 2: 泛型函数 - 三参数
# ============================================================
def clamp[T](val: T, lo: T, hi: T) -> T:
if val < lo:
return lo
if val > hi:
return hi
return val
def test_generic_clamp():
testcheck.section("Test 2: generic clamp")
r1: t.CInt = clamp(5, 0, 10)
r2: t.CInt = clamp(-3, 0, 10)
r3: t.CInt = clamp(15, 0, 10)
testcheck.check(r1 == 5 and r2 == 0 and r3 == 10, "clamp (5 0 10)", "clamp expect 5 0 10")
# ============================================================
# Test 3: 泛型类 - Stack[T]
# ============================================================
class Stack[T]():
data: t.CArray[t.CInt, 16]
top: t.CInt
def __init__(self):
self.top = 0
def push(self, val: T):
self.data[self.top] = t.CInt(val)
self.top += 1
def pop(self) -> T:
self.top -= 1
return T(self.data[self.top])
def is_empty(self) -> t.CInt:
if self.top == 0:
return 1
return 0
def size_of(self) -> t.CSizeT:
return self.__sizeof__()
def type_size(self) -> t.CSizeT:
return Stack[T].__sizeof__()
def test_generic_stack():
testcheck.section("Test 3: generic Stack[T]")
# 显式标注 Stack[int]:T 无法从实参推断(__init__ 无参),且 T 决定
# push/pop 的元素宽度(t.CInt(val) ↔ i32),静默默认 int 已被禁止。
s = Stack[int]()
s.push(10)
s.push(20)
s.push(30)
r1: t.CInt = s.pop()
r2: t.CInt = s.pop()
r3: t.CInt = s.pop()
testcheck.check(r1 == 30 and r2 == 20 and r3 == 10, "Stack (pop=30 20 10)", "Stack expect 30 20 10")
# ============================================================
# Test 4: 泛型函数 - swap via pointer
# ============================================================
class IntPair:
a: t.CInt
b: t.CInt
def generic_swap(p: IntPair | t.CPtr):
tmp: t.CInt = c.Deref(p).a
c.Deref(p).a = c.Deref(p).b
c.Deref(p).b = tmp
def test_generic_swap():
testcheck.section("Test 4: generic swap via pointer")
p: IntPair = IntPair()
p.a = 100
p.b = 200
generic_swap(c.Addr(p))
testcheck.check(p.a == 200 and p.b == 100, "swap (a=200 b=100)", "swap expect 200 100")
# ============================================================
# Test 5: 泛型类 - Range[T] 迭代器
# ============================================================
class Range[T]():
start: T
end_val: T
step: T
def __init__(self, s: T, e: T, st: T):
self.start = T(s)
self.end_val = T(e)
self.step = T(st)
def sum_all(self) -> T:
result: T = T(0)
i: T = self.start
while i < self.end_val:
result = result + i
i = i + self.step
return result
def test_generic_range():
testcheck.section("Test 5: generic Range[T]")
r = Range(0, 10, 1) # 0+1+2+...+9=45
s: t.CInt = r.sum_all()
testcheck.check(s == 45, "Range sum (0..9=45)", "Range sum expect 45")
# ============================================================
# Test 6: 泛型函数 - 数组求和(非泛型数组参数)
# ============================================================
def array_sum(arr: t.CArray[t.CInt, 8], n: t.CInt) -> t.CInt:
result: t.CInt = 0
for i in range(n):
result += arr[i]
return result
def test_generic_array_sum():
testcheck.section("Test 6: array sum")
arr: t.CArray[t.CInt, 8] = [0]
for i in range(8):
arr[i] = (i + 1) * 10
s: t.CInt = array_sum(arr, 8)
testcheck.check(s == 360, "array sum (360)", "array sum expect 360")
# ============================================================
# Test 7: 泛型函数 - 比较并返回较大值
# ============================================================
def max_of_three[T](a: T, b: T, c_val: T) -> T:
m: T = a
if b > m:
m = b
if c_val > m:
m = c_val
return m
def test_generic_max_three():
testcheck.section("Test 7: generic max of three")
r1: t.CInt = max_of_three(1, 2, 3)
r2: t.CInt = max_of_three(10, 30, 20)
r3: t.CInt = max_of_three(50, 50, 50)
testcheck.check(r1 == 3 and r2 == 30 and r3 == 50, "max3 (3 30 50)", "max3 expect 3 30 50")
# ============================================================
# Test 8: 泛型类 - 带方法的容器
# ============================================================
class Container[T]():
values: t.CArray[t.CInt, 8]
size: t.CInt
def __init__(self):
self.size = 0
def add(self, v: T):
self.values[self.size] = t.CInt(v)
self.size += 1
def get(self, idx: t.CInt) -> T:
return T(self.values[idx])
def contains(self, v: T) -> t.CInt:
for i in range(self.size):
if self.values[i] == t.CInt(v):
return 1
return 0
def total(self) -> T:
result: T = T(0)
for i in range(self.size):
result = result + T(self.values[i])
return result
def test_generic_container():
testcheck.section("Test 8: generic Container[T]")
# 显式标注 Container[int]:__init__ 无参 ⇒ T 无从推断;
# 元素由 add(10)/contains(20)/total() 证据确定是 int(t.CArray[t.CInt, 8])。
c = Container[int]()
c.add(10)
c.add(20)
c.add(30)
has20: t.CInt = c.contains(20)
has99: t.CInt = c.contains(99)
total: t.CInt = c.total()
testcheck.check(has20 == 1 and has99 == 0 and total == 60, "Container (has20=1 has99=0 total=60)", "Container expect 1 0 60")
# ============================================================
# Test 9: 泛型函数 - 阶乘
# ============================================================
def factorial[T](n: T) -> T:
result: T = T(1)
i: T = T(2)
while i <= n:
result = result * i
i = i + T(1)
return result
def test_generic_factorial():
testcheck.section("Test 9: generic factorial")
r1: t.CInt = factorial(5)
r2: t.CInt = factorial(10)
testcheck.check(r1 == 120 and r2 == 3628800, "factorial (5!=120 10!=3628800)", "factorial expect 120 3628800")
# ============================================================
# Test 10: 泛型类 - 累加器
# ============================================================
class Accumulator[T]():
total: T
def __init__(self, start: T):
self.total = T(start)
def add_val(self, v: T):
self.total = self.total + v
def get_result(self) -> T:
return self.total
def test_generic_accumulator():
testcheck.section("Test 10: generic Accumulator[T]")
a = Accumulator(0)
a.add_val(10)
a.add_val(20)
a.add_val(30)
r: t.CInt = a.get_result()
testcheck.check(r == 60, "Accumulator (result=60)", "Accumulator expect 60")
# ============================================================
# Test 11: 泛型结构体 sizeof (修复验证)
# 特化后 Stack[int] = { [16 x i32], i32 } = 68 字节
# 验证 obj.__sizeof__() 和类内部 self.__sizeof__() 均返回正确大小
# ============================================================
def test_generic_sizeof_bug():
testcheck.section("Test 11: generic sizeof (fixed)")
# 同 Test 3:无参构造必须显式标注类型实参;Stack[int] = { [16 x i32], i32 } = 68。
s = Stack[int]()
s.push(10)
sz: t.CSizeT = s.__sizeof__()
inner_sz: t.CSizeT = s.size_of()
type_sz: t.CSizeT = s.type_size()
stdio.printf("Stack[int] obj.__sizeof__() = %lu, self.__sizeof__() = %lu, Stack[T].__sizeof__() = %lu (expect 68)\n", sz, inner_sz, type_sz)
testcheck.check(sz == 68, "obj.__sizeof__() == 68 OK", "obj.__sizeof__() FAILED")
testcheck.check(inner_sz == 68, "self.__sizeof__() == 68 OK", "self.__sizeof__() FAILED")
testcheck.check(type_sz == 68, "Stack[T].__sizeof__() == 68 OK", "Stack[T].__sizeof__() FAILED")
def main() -> t.CInt:
testcheck.begin("GenericTest2: Advanced Generic Tests")
test_generic_square_types()
test_generic_clamp()
test_generic_stack()
test_generic_swap()
test_generic_range()
test_generic_array_sum()
test_generic_max_three()
test_generic_container()
test_generic_factorial()
test_generic_accumulator()
test_generic_sizeof_bug()
return testcheck.end()