Files
ViperC/Test/App/nested_match_test.vp
T

269 lines
9.3 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 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: memhub.MemBuddy | t.CPtr
# 测试用内存大小(64KB,足够构造 LLVMType 值)
_NMATCH_POOL_SIZE: t.CDefine = 65536
def _init_mbuddy() -> int:
"""初始化内存池,返回 0=成功, 1=失败"""
arena: bytes = stdlib.malloc(_NMATCH_POOL_SIZE)
if arena is None:
stdio.printf("FAIL: malloc for arena failed\n")
return 1
mb: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, _NMATCH_POOL_SIZE)
if mb is None:
stdio.printf("FAIL: MemBuddy init failed\n")
return 1
_mbuddy = mb
return 0
def test_single_match() -> int:
"""Test 1: 单层 match(基线测试)"""
stdio.printf("--- Test 1: 单层 match LLVMType ---\n")
ty: llvmlite.LLVMType | t.CPtr = 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: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(_mbuddy)
ty_inner: llvmlite.LLVMType | t.CPtr = 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: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(_mbuddy)
ptr_ty: llvmlite.LLVMType | t.CPtr = 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: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(_mbuddy)
mid_ptr: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(_mbuddy, innermost)
outer_ptr: llvmlite.LLVMType | t.CPtr = llvmlite.Ptr(_mbuddy, mid_ptr)
# 另一个值用于第 3 层 match
extra_ty: llvmlite.LLVMType | t.CPtr = 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: llvmlite.LLVMType | t.CPtr = llvmlite.Float(_mbuddy)
if ty is not None:
match ty:
case llvmlite.LLVMType.Float(bits):
# 在 Float 的 case 块内再 match
ty2: llvmlite.LLVMType | t.CPtr = 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: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(_mbuddy)
ty_inner: llvmlite.LLVMType | t.CPtr = 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