272 lines
9.7 KiB
Plaintext
272 lines
9.7 KiB
Plaintext
import stdio
|
||
import t, c
|
||
import memhub
|
||
import stdlib
|
||
import llvmlite
|
||
import string
|
||
|
||
|
||
# ============================================================
|
||
# nested_match_test - 嵌套 match REnum 检测测试
|
||
#
|
||
# 验证 BUG 2 修复:当 match 嵌套在另一个 match 的 case 块中时,
|
||
# 内层 match 能正确识别 REnum 变体并生成正确的 case 列表。
|
||
#
|
||
# 修复前:内层 match 走非 REnum 路径,case 列表为空。
|
||
# 修复后:内层 match 能正确识别 REnum 变体。
|
||
# ============================================================
|
||
|
||
# 内存池(测试内部使用)
|
||
_mbuddy: rawptr[memhub.MemBuddy]
|
||
|
||
# 测试用内存大小(64KB,足够构造 LLVMType 值)
|
||
_NMATCH_POOL_SIZE: t.CDefine = 65536
|
||
|
||
|
||
def _init_mbuddy() -> int:
|
||
"""初始化内存池,返回 0=成功, 1=失败"""
|
||
global _mbuddy
|
||
arena: bytes = stdlib.malloc(_NMATCH_POOL_SIZE)
|
||
if arena is None:
|
||
stdio.printf("FAIL: malloc for arena failed\n")
|
||
return 1
|
||
mb: rawptr[memhub.MemBuddy] = stdlib.malloc(memhub.MemBuddy.__sizeof__())
|
||
if mb is None:
|
||
stdio.printf("FAIL: MemBuddy init failed\n")
|
||
return 1
|
||
mb.__before_init__()
|
||
mb.__init__(arena, sizet(_NMATCH_POOL_SIZE))
|
||
_mbuddy = mb
|
||
return 0
|
||
|
||
|
||
def test_single_match() -> int:
|
||
"""Test 1: 单层 match(基线测试)"""
|
||
stdio.printf("--- Test 1: 单层 match LLVMType ---\n")
|
||
|
||
ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(_mbuddy)
|
||
if ty is None:
|
||
stdio.printf("FAIL: Int32 returned None\n")
|
||
return 1
|
||
|
||
match ty:
|
||
case llvmlite.LLVMType.Int(bits):
|
||
stdio.printf("Int(%d) OK\n", bits)
|
||
if bits == 32:
|
||
stdio.printf("bits==32 OK\n")
|
||
return 0
|
||
stdio.printf("bits==%d FAIL\n", bits)
|
||
return 1
|
||
case _:
|
||
stdio.printf("single match default FAIL\n")
|
||
return 1
|
||
|
||
|
||
def test_nested_match_other() -> int:
|
||
"""Test 2: 嵌套 match(case 块内 match 另一个 REnum 值)
|
||
|
||
BUG 2 核心测试:在 match 的 case 块内嵌套 match 另一个 REnum 值。
|
||
"""
|
||
stdio.printf("--- Test 2: 嵌套 match(case 块内 match 另一值)---\n")
|
||
|
||
ty_outer: rawptr[llvmlite.LLVMType] = llvmlite.Int32(_mbuddy)
|
||
ty_inner: rawptr[llvmlite.LLVMType] = llvmlite.Int8(_mbuddy)
|
||
|
||
match ty_outer:
|
||
case llvmlite.LLVMType.Int(bits):
|
||
# 在 Int 的 case 块内嵌套 match 另一个 REnum 值
|
||
match ty_inner:
|
||
case llvmlite.LLVMType.Int(inner_bits):
|
||
stdio.printf("outer Int(%d), inner Int(%d) OK\n", bits, inner_bits)
|
||
if bits == 32 and inner_bits == 8:
|
||
stdio.printf("values OK\n")
|
||
return 0
|
||
stdio.printf("values FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("inner match default FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("outer match default FAIL\n")
|
||
return 1
|
||
|
||
|
||
def test_nested_match_pointee() -> int:
|
||
"""Test 3: 嵌套 match 同一值的子结构(Ptr 的 pointee)
|
||
|
||
模拟 HandlesStruct.vp 中 get_struct_type_from_value 的嵌套 match 模式。
|
||
"""
|
||
stdio.printf("--- Test 3: 嵌套 match pointee ---\n")
|
||
|
||
# 构造 Ptr(Int32) 类型
|
||
inner_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int32(_mbuddy)
|
||
ptr_ty: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(_mbuddy, inner_ty)
|
||
|
||
match ptr_ty:
|
||
case llvmlite.LLVMType.Ptr(pointee):
|
||
# 在 Ptr 的 case 块内嵌套 match pointee
|
||
match pointee:
|
||
case llvmlite.LLVMType.Int(bits):
|
||
stdio.printf("Ptr(Int(%d)) OK\n", bits)
|
||
if bits == 32:
|
||
stdio.printf("pointee bits==32 OK\n")
|
||
return 0
|
||
stdio.printf("pointee bits==%d FAIL\n", bits)
|
||
return 1
|
||
case _:
|
||
stdio.printf("pointee match default FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("outer Ptr match FAIL\n")
|
||
return 1
|
||
|
||
|
||
def test_three_level_nested() -> int:
|
||
"""Test 4: 3 层嵌套 match
|
||
|
||
模拟 HandlesStruct.vp 中 _ensure_field_types_in_module 的嵌套模式:
|
||
外层 match → case 块内 match pointee → 再嵌套 match 另一值。
|
||
"""
|
||
stdio.printf("--- Test 4: 3 层嵌套 match ---\n")
|
||
|
||
# 构造 Ptr(Ptr(Int32)) 类型
|
||
innermost: rawptr[llvmlite.LLVMType] = llvmlite.Int32(_mbuddy)
|
||
mid_ptr: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(_mbuddy, innermost)
|
||
outer_ptr: rawptr[llvmlite.LLVMType] = llvmlite.Ptr(_mbuddy, mid_ptr)
|
||
|
||
# 另一个值用于第 3 层 match
|
||
extra_ty: rawptr[llvmlite.LLVMType] = llvmlite.Int16(_mbuddy)
|
||
|
||
match outer_ptr:
|
||
case llvmlite.LLVMType.Ptr(p1):
|
||
# 第 2 层 match p1
|
||
match p1:
|
||
case llvmlite.LLVMType.Ptr(p2):
|
||
# 第 3 层 match p2
|
||
match p2:
|
||
case llvmlite.LLVMType.Int(bits):
|
||
stdio.printf("Ptr(Ptr(Int(%d))) OK\n", bits)
|
||
case _:
|
||
stdio.printf("level 3 default FAIL\n")
|
||
return 1
|
||
# 第 3 层 match 另一个值(验证 case 块内多次 match)
|
||
match extra_ty:
|
||
case llvmlite.LLVMType.Int(ebits):
|
||
stdio.printf("extra Int(%d) in nested OK\n", ebits)
|
||
if ebits == 16:
|
||
stdio.printf("3-level values OK\n")
|
||
return 0
|
||
stdio.printf("3-level values FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("extra match FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("level 2 default FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("level 1 default FAIL\n")
|
||
return 1
|
||
|
||
|
||
def test_nested_match_in_if() -> int:
|
||
"""Test 5: 在 if 块内嵌套 match
|
||
|
||
另一种常见的嵌套场景:if 条件块内使用 match。
|
||
"""
|
||
stdio.printf("--- Test 5: if 块内嵌套 match ---\n")
|
||
|
||
ty: rawptr[llvmlite.LLVMType] = llvmlite.Float(_mbuddy)
|
||
|
||
if ty is not None:
|
||
match ty:
|
||
case llvmlite.LLVMType.Float(bits):
|
||
# 在 Float 的 case 块内再 match
|
||
ty2: rawptr[llvmlite.LLVMType] = llvmlite.Double(_mbuddy)
|
||
match ty2:
|
||
case llvmlite.LLVMType.Float(bits2):
|
||
stdio.printf("Float(%d) + Double(%d) OK\n", bits, bits2)
|
||
if bits == 32 and bits2 == 64:
|
||
stdio.printf("float values OK\n")
|
||
return 0
|
||
stdio.printf("float values FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("inner float match FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("outer float match FAIL\n")
|
||
return 1
|
||
stdio.printf("ty is None FAIL\n")
|
||
return 1
|
||
|
||
|
||
def test_nested_match_mismatch() -> int:
|
||
"""Test 6: 嵌套 match 不同变体(验证 default 分支)
|
||
|
||
确保嵌套 match 的 default 分支(case _)能正确触发。
|
||
"""
|
||
stdio.printf("--- Test 6: 嵌套 match 不同变体(default 分支)---\n")
|
||
|
||
# 外层是 Int,内层是 Float - 验证内层 match 不会误匹配 Int
|
||
ty_outer: rawptr[llvmlite.LLVMType] = llvmlite.Int32(_mbuddy)
|
||
ty_inner: rawptr[llvmlite.LLVMType] = llvmlite.Float(_mbuddy)
|
||
|
||
match ty_outer:
|
||
case llvmlite.LLVMType.Int(bits):
|
||
match ty_inner:
|
||
case llvmlite.LLVMType.Int(wrong_bits):
|
||
stdio.printf("FAIL: Float matched as Int(%d)\n", wrong_bits)
|
||
return 1
|
||
case llvmlite.LLVMType.Float(fbits):
|
||
stdio.printf("outer Int(%d), inner Float(%d) OK\n", bits, fbits)
|
||
if bits == 32 and fbits == 32:
|
||
stdio.printf("mismatch values OK\n")
|
||
return 0
|
||
stdio.printf("mismatch values FAIL\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("inner default FAIL (should be Float)\n")
|
||
return 1
|
||
case _:
|
||
stdio.printf("outer default FAIL\n")
|
||
return 1
|
||
|
||
|
||
def nested_match_test() -> int:
|
||
stdio.printf("=== nested_match_test: 嵌套 match REnum 检测测试 ===\n\n")
|
||
|
||
# 初始化内存池
|
||
if _init_mbuddy() != 0:
|
||
stdio.printf("FAIL: 内存池初始化失败\n")
|
||
return 1
|
||
|
||
r: int = 0
|
||
|
||
stdio.fflush(None)
|
||
if test_single_match() != 0:
|
||
r = 1
|
||
stdio.fflush(None)
|
||
if test_nested_match_other() != 0:
|
||
r = 1
|
||
stdio.fflush(None)
|
||
if test_nested_match_pointee() != 0:
|
||
r = 1
|
||
stdio.fflush(None)
|
||
if test_three_level_nested() != 0:
|
||
r = 1
|
||
stdio.fflush(None)
|
||
if test_nested_match_in_if() != 0:
|
||
r = 1
|
||
stdio.fflush(None)
|
||
if test_nested_match_mismatch() != 0:
|
||
r = 1
|
||
stdio.fflush(None)
|
||
|
||
if r == 0:
|
||
stdio.printf("\n=== nested_match_test: ALL PASS ===\n")
|
||
else:
|
||
stdio.printf("\n=== nested_match_test: SOME FAIL ===\n")
|
||
|
||
return r
|