177 lines
5.4 KiB
Python
177 lines
5.4 KiB
Python
import t
|
||
import stdio
|
||
import testcheck
|
||
import stdlib
|
||
import memhub
|
||
import string
|
||
from linkedlist import GSListNode, GSList
|
||
|
||
|
||
# ============================================================
|
||
# G5: 验证 GSList[T] 被降级为 opaque 的问题
|
||
#
|
||
# 版本 2: 不使用 malloc/MemBuddy,直接用构造函数(像 G3 那样)
|
||
# 这样能隔离 GSList opaque 问题
|
||
# ============================================================
|
||
|
||
|
||
# G5Node: 继承 GSListNode[G5Node](Phase2 路径,正确特化)
|
||
@t.NoVTable
|
||
class G5Node(GSListNode[G5Node]):
|
||
Value: t.CInt
|
||
|
||
def __init__(self):
|
||
self.Next = None
|
||
self.Value = 0
|
||
|
||
|
||
# G5ListWrapper: 包装 GSList[G5Node],测试 GSList 字段访问
|
||
# 注意:GSList[G5Node] 走 Phase2 特化路径
|
||
# 用 pool 工厂函数分配 GSList,避免栈分配悬垂指针
|
||
GSLIST_SIZE: t.CDefine = 24 # Head(8) + Tail(8) + Count(8)
|
||
|
||
@t.NoVTable
|
||
class G5ListWrapper:
|
||
List: GSList[G5Node] | t.CPtr
|
||
|
||
def __init__(self, pool: memhub.MemBuddy | t.CPtr):
|
||
gsl: GSList[G5Node] | t.CPtr = pool.alloc(GSLIST_SIZE)
|
||
if gsl is None:
|
||
self.List = None
|
||
return
|
||
string.memset(gsl, 0, GSLIST_SIZE)
|
||
self.List = gsl
|
||
|
||
|
||
# ============================================================
|
||
# Test 1: G5Node 字段访问(基准测试,应通过)
|
||
# ============================================================
|
||
|
||
def test_g5node_create():
|
||
testcheck.section("Test 1: G5Node create and field access")
|
||
n: G5Node = G5Node()
|
||
n.Value = 42
|
||
v: t.CInt = n.Value
|
||
testcheck.check(v == 42, "G5Node.Value = 42", "expect 42")
|
||
|
||
|
||
def test_g5node_next():
|
||
testcheck.section("Test 2: G5Node.Next field (GSListNode inheritance)")
|
||
n1: G5Node = G5Node()
|
||
n2: G5Node = G5Node()
|
||
n1.Value = 10
|
||
n2.Value = 20
|
||
n1.Next = n2
|
||
next_node: G5Node = n1.Next
|
||
if next_node is None:
|
||
testcheck.check(False, "n1.Next is None", "FAIL")
|
||
return
|
||
v: t.CInt = next_node.Value
|
||
testcheck.check(v == 20, "n1.Next.Value = 20", "expect 20")
|
||
|
||
|
||
# ============================================================
|
||
# Test 3: GSList 字段访问 — 核心测试
|
||
# ============================================================
|
||
|
||
def test_gslist_create():
|
||
testcheck.section("Test 3: GSList[G5Node] create")
|
||
lst: GSList[G5Node] | t.CPtr = GSList[G5Node]()
|
||
if lst is None:
|
||
testcheck.check(False, "GSList[G5Node]() is None", "FAIL")
|
||
return
|
||
# 检查初始状态
|
||
head: G5Node | t.CPtr = lst.Head
|
||
tail: G5Node | t.CPtr = lst.Tail
|
||
count: t.CSizeT = lst.Count
|
||
testcheck.check(head is None, "initial Head is None", "expect None")
|
||
testcheck.check(tail is None, "initial Tail is None", "expect None")
|
||
testcheck.check(count == 0, "initial Count = 0", "expect 0")
|
||
|
||
|
||
def test_gslist_append():
|
||
testcheck.section("Test 4: GSList[G5Node].append 3 nodes")
|
||
lst: GSList[G5Node] | t.CPtr = GSList[G5Node]()
|
||
if lst is None:
|
||
testcheck.check(False, "GSList[G5Node]() is None", "FAIL")
|
||
return
|
||
a: G5Node = G5Node()
|
||
b: G5Node = G5Node()
|
||
c: G5Node = G5Node()
|
||
a.Value = 1
|
||
b.Value = 2
|
||
c.Value = 3
|
||
|
||
lst.append(a)
|
||
lst.append(b)
|
||
lst.append(c)
|
||
|
||
# 验证 Count
|
||
count: t.CSizeT = lst.Count
|
||
testcheck.check(count == 3, "Count = 3 after 3 appends", "expect 3")
|
||
|
||
# 验证 Head
|
||
head: G5Node | t.CPtr = lst.Head
|
||
if head is None:
|
||
testcheck.check(False, "Head is None", "FAIL")
|
||
return
|
||
testcheck.check(head.Value == 1, "Head.Value = 1", "expect 1")
|
||
|
||
# 验证 Tail
|
||
tail: G5Node | t.CPtr = lst.Tail
|
||
if tail is None:
|
||
testcheck.check(False, "Tail is None", "FAIL")
|
||
return
|
||
testcheck.check(tail.Value == 3, "Tail.Value = 3", "expect 3")
|
||
|
||
# 遍历链表验证顺序
|
||
sum: t.CInt = 0
|
||
cur: G5Node | t.CPtr = lst.Head
|
||
while cur is not None:
|
||
sum = sum + cur.Value
|
||
cur = cur.Next
|
||
testcheck.check(sum == 6, "chain sum = 1+2+3 = 6", "expect 6")
|
||
|
||
|
||
# ============================================================
|
||
# Test 5: G5ListWrapper.List 字段访问(嵌套 GSList 测试)
|
||
# ============================================================
|
||
|
||
def test_wrapper_list_field():
|
||
testcheck.section("Test 5: G5ListWrapper.List field (nested GSList, pool alloc)")
|
||
arena: bytes = stdlib.malloc(4096)
|
||
if arena is None:
|
||
testcheck.check(False, "malloc arena", "FAIL")
|
||
return
|
||
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 4096)
|
||
wrapper: G5ListWrapper = G5ListWrapper(pool)
|
||
if wrapper is None:
|
||
testcheck.check(False, "G5ListWrapper(pool) is None", "FAIL")
|
||
return
|
||
if wrapper.List is None:
|
||
testcheck.check(False, "wrapper.List is None", "FAIL")
|
||
return
|
||
|
||
n: G5Node = G5Node()
|
||
n.Value = 999
|
||
wrapper.List.append(n)
|
||
|
||
# 通过 wrapper.List 访问 GSList 字段
|
||
head: G5Node | t.CPtr = wrapper.List.Head
|
||
if head is None:
|
||
testcheck.check(False, "wrapper.List.Head is None", "FAIL")
|
||
return
|
||
count: t.CSizeT = wrapper.List.Count
|
||
testcheck.check(head.Value == 999, "wrapper.List.Head.Value = 999", "expect 999")
|
||
testcheck.check(count == 1, "wrapper.List.Count = 1", "expect 1")
|
||
|
||
|
||
def main() -> t.CInt:
|
||
testcheck.begin("G5: GSList[T] field access (Phase2 path, pool alloc for wrapper)")
|
||
test_g5node_create()
|
||
test_g5node_next()
|
||
test_gslist_create()
|
||
test_gslist_append()
|
||
test_wrapper_list_field()
|
||
return testcheck.end()
|