把 81 个 .vp 文件的中文 # 注释与三引号文档串改写为简洁英文,每个连续注释块 <=2 行;运行时中文字符串字面量(testcheck.begin/print 等用户可见消息)保持原样。骨架比对 HEAD 与工作区 112 文件漂移 0,全量 77/77 顺序回归通过。
174 lines
5.2 KiB
Plaintext
174 lines
5.2 KiB
Plaintext
import t
|
|
import stdio
|
|
import testcheck
|
|
import stdlib
|
|
import memhub
|
|
import string
|
|
from linkedlist import GSListNode, GSList
|
|
|
|
|
|
# ============================================================
|
|
# G5: verify GSList[T] is not degraded to an opaque type; uses direct
|
|
# construction (no malloc/MemBuddy) to isolate the issue.
|
|
# ============================================================
|
|
|
|
|
|
# G5Node: inherits GSListNode[G5Node] (Phase2 path, correct specialization)
|
|
@t.NoVTable
|
|
class G5Node(GSListNode[G5Node]):
|
|
Value: int
|
|
|
|
def __init__(self):
|
|
self.Next = None
|
|
self.Value = 0
|
|
|
|
|
|
# G5ListWrapper: wraps GSList[G5Node] (Phase2 specialization path) to test
|
|
# field access; a pool factory allocates it, avoiding dangling stack pointers.
|
|
define GSLIST_SIZE = 24 # Head(8) + Tail(8) + Count(8)
|
|
|
|
@t.NoVTable
|
|
class G5ListWrapper:
|
|
List: GSList[G5Node]*
|
|
|
|
def __init__(self, pool: memhub.MemBuddy*):
|
|
gsl: GSList[G5Node]* = pool.alloc(GSLIST_SIZE)
|
|
if gsl is None:
|
|
self.List = None
|
|
return
|
|
string.memset(gsl, 0, GSLIST_SIZE)
|
|
self.List = gsl
|
|
|
|
|
|
# ============================================================
|
|
# Test 1: G5Node field access (baseline, should pass)
|
|
# ============================================================
|
|
|
|
def test_g5node_create():
|
|
testcheck.section("Test 1: G5Node create and field access")
|
|
n: G5Node = G5Node()
|
|
n.Value = 42
|
|
v: int = 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: int = next_node.Value
|
|
testcheck.check(v == 20, "n1.Next.Value = 20", "expect 20")
|
|
|
|
|
|
# ============================================================
|
|
# Test 3: GSList field access (core test)
|
|
# ============================================================
|
|
|
|
def test_gslist_create():
|
|
testcheck.section("Test 3: GSList[G5Node] create")
|
|
lst: GSList[G5Node]* = GSList[G5Node]()
|
|
if lst is None:
|
|
testcheck.check(False, "GSList[G5Node]() is None", "FAIL")
|
|
return
|
|
# check initial state
|
|
head: G5Node* = lst.Head
|
|
tail: G5Node* = lst.Tail
|
|
count: sizet = 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]* = 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)
|
|
|
|
# verify Count
|
|
count: sizet = lst.Count
|
|
testcheck.check(count == 3, "Count = 3 after 3 appends", "expect 3")
|
|
|
|
# verify Head
|
|
head: G5Node* = lst.Head
|
|
if head is None:
|
|
testcheck.check(False, "Head is None", "FAIL")
|
|
return
|
|
testcheck.check(head.Value == 1, "Head.Value = 1", "expect 1")
|
|
|
|
# verify Tail
|
|
tail: G5Node* = lst.Tail
|
|
if tail is None:
|
|
testcheck.check(False, "Tail is None", "FAIL")
|
|
return
|
|
testcheck.check(tail.Value == 3, "Tail.Value = 3", "expect 3")
|
|
|
|
# walk the chain to verify order
|
|
sum: int = 0
|
|
cur: G5Node* = 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 field access (nested GSList, pool alloc)
|
|
# ============================================================
|
|
|
|
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* = 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)
|
|
|
|
# access GSList fields through wrapper.List
|
|
head: G5Node* = wrapper.List.Head
|
|
if head is None:
|
|
testcheck.check(False, "wrapper.List.Head is None", "FAIL")
|
|
return
|
|
count: sizet = 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() -> int:
|
|
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()
|