diff --git a/ArgparseTest/App/main.vp b/ArgparseTest/App/main.vp index c6992e4..33e55b2 100644 --- a/ArgparseTest/App/main.vp +++ b/ArgparseTest/App/main.vp @@ -8,7 +8,7 @@ import argparse import testcheck -# 全局 MBuddy 指针 +# Global MBuddy pointer _mbuddy: memhub.MemBuddy* @@ -17,7 +17,7 @@ def main() -> int: global _mbuddy testcheck.begin("ArgparseTest: 命令行参数解析") - # 初始化内存管理器 + # Initialize the memory manager arena: bytes = stdlib.malloc(16 * 1024 * 1024) if arena is None: testcheck.fail("malloc arena failed") @@ -26,8 +26,8 @@ def main() -> int: _mbuddy = memhub.MemBuddy(arena, 16 * 1024 * 1024) argparse._mbuddy = _mbuddy - # 构造模拟 argv: myprog --input test.txt -c 42 --verbose output.dat - argv_buf: bytes = _mbuddy.alloc(8 * 7) # 7 个指针 + # Build a synthetic argv: myprog --input test.txt -c 42 --verbose output.dat + argv_buf: bytes = _mbuddy.alloc(8 * 7) # 7 pointers argv: str* = (str*)(argv_buf) # argv[0] = "myprog" @@ -74,9 +74,7 @@ def main() -> int: argc: INT = 7 - # ============================================================ - # Test 1: 基本解析 (--input, -c, --verbose, output) - # ============================================================ + # Test 1: basic parsing (--input, -c, --verbose, output) testcheck.section("Test 1: 基本解析") parser = argparse.ArgumentParser("myprog", "A test program for argparse", pool=_mbuddy) parser.add_argument("--input", "-i", argparse.STRING, 0, None, True, argparse.STORE, "input file path") @@ -99,9 +97,7 @@ def main() -> int: else: testcheck.fail("parse_args returned NULL") - # ============================================================ - # Test 2: --name=value 语法 - # ============================================================ + # Test 2: --name=value syntax testcheck.section("Test 2: --name=value 语法") argv2_buf: bytes = _mbuddy.alloc(8 * 3) @@ -134,9 +130,7 @@ def main() -> int: else: testcheck.fail("parse_args returned NULL") - # ============================================================ - # Test 3: -v COUNT 计数动作 - # ============================================================ + # Test 3: -v COUNT counting action testcheck.section("Test 3: COUNT 计数动作") argv3_buf: bytes = _mbuddy.alloc(8 * 4) @@ -177,9 +171,7 @@ def main() -> int: else: testcheck.fail("parse_args returned NULL") - # ============================================================ - # Test 4: 关键字参数调用 add_argument - # ============================================================ + # Test 4: keyword arguments to add_argument testcheck.section("Test 4: 关键字参数") parser3 = argparse.ArgumentParser("myprog", "Keyword arg test", pool=_mbuddy) diff --git a/AstTest/App/main.vp b/AstTest/App/main.vp index ee7b77c..fa5efbd 100644 --- a/AstTest/App/main.vp +++ b/AstTest/App/main.vp @@ -10,16 +10,16 @@ import ast import w32.win32console -# MBuddy arena 大小:1MB +# MBuddy arena size: 1MB define ARENA_SIZE = 1048576 -# mpool 内存大小:512KB +# mpool memory size: 512KB define POOL_SIZE = 524288 -# dump 缓冲区大小:256KB +# dump buffer size: 256KB define DUMP_SIZE = 262144 def classify_list(lst: list[ast.AST*]*, depth: int): - """递归遍历 list[AST | t.CPtr] 容器,逐元素分类(orelse/args/comparators 等)""" + """Recursively walk a list[AST | t.CPtr] container, classify each element.""" if lst is None: return n: sizet = lst.__len__() @@ -28,13 +28,8 @@ def classify_list(lst: list[ast.AST*]*, depth: int): def classify_print(node: ast.AST*, depth: int): - """递归遍历 parse 树,用 isinstance 运行时判定每个节点的类别并打印。 - - 依赖 TPV isinstance 的 vtable 子类集合比较: - - isinstance(node, ast.Stmt) → 语句节点(Assign/If/For/While/...) - - isinstance(node, ast.ExprNode) → 表达式节点(Name/Constant/BinOp/...) - - 两者皆非 → 其他(Module/Expression/...) - 验证运行时(非编译期静态)正确区分 Stmt 与 ExprNode。 + """Recursively walk the parse tree and print each node's category at runtime + via TPV isinstance vtable subclass-set comparison (Stmt vs ExprNode vs other). """ if node is None: return @@ -46,9 +41,8 @@ def classify_print(node: ast.AST*, depth: int): printf("EXPR %s\n", node.type_name()) else: printf("OTHER %s\n", node.type_name()) - # 按 kind 遍历语句持有的表达式字段(语句 body 块均在 children)。 - # 属性访问前先 cast 成具体节点类:node 静态类型是 ast.AST, - # 直接访问 node.value 会在 AST 基类字段表 fast-fail(按需过滤原则)。 + # Walk statement expression fields by kind (bodies live in children); cast to + # the concrete class first, since ast.AST base-class field access fast-fails. k: int = node.kind() if k == ast.ASTKind.Assign: asg: ast.Assign* = (ast.Assign*)(node) @@ -92,7 +86,7 @@ def classify_print(node: ast.AST*, depth: int): classify_list(call_nd.args, depth + 1) else: pass - # children(语句 body 块) + # children (statement bodies) if node.children is not None: n: sizet = node.children.__len__() for i in range(n): @@ -105,7 +99,7 @@ def main() -> CInt | CExport: printf("AST Comprehensive Test Start\n") - # 初始化全局 MBuddy 内存分配器 + # Initialize the global MBuddy allocator arena: bytes = stdlib.malloc(ARENA_SIZE) if arena == None: printf("FAIL: arena alloc failed\n") @@ -118,7 +112,7 @@ def main() -> CInt | CExport: sys._mbuddy = mbuddy_obj ast._mbuddy = mbuddy_obj - # 为 ast 解析器创建 mpool + # Create an mpool for the ast parser pool_mem: bytes = stdlib.malloc(POOL_SIZE) if pool_mem == None: printf("FAIL: malloc for pool failed\n") @@ -128,14 +122,14 @@ def main() -> CInt | CExport: printf("FAIL: memhub.MemPool init failed\n") return 1 - # dump 缓冲区(独立分配) + # dump buffer (separately allocated) dump_mem: bytes = stdlib.malloc(DUMP_SIZE) if dump_mem == None: printf("FAIL: malloc for dump failed\n") return 1 dump_buf: char* = char(dump_mem, t.CPtr) - # 综合测试源码:覆盖 CPython 主要语法 + # Comprehensive test source covering main CPython syntax src: str = """x = 1 y = 2 z = x + y @@ -165,7 +159,7 @@ class Point: printf("Parsing comprehensive source...\n") - # 解析 + # Parse ast._init_tables(pool) lx_dbg: t.CPtr = ast.new_lexer(pool) if lx_dbg == None: @@ -195,19 +189,17 @@ class Point: printf("ast.dump returned, now printing buffer...\n") printf("=== AST DUMP ===\n%s\n=== END ===\n", dump_buf) - # ============================================================ - # Stmt/Expr 运行时区分测试(isinstance vtable 子类集合比较) - # ============================================================ + # ===== Stmt/Expr runtime distinction test (isinstance vtable compare) ===== printf("=== STMT/EXPR RUNTIME DISTINGUISH TEST ===\n") classify_print(tree, 0) - # 断言 1: Module 既非 Stmt 亦非 ExprNode(顶层容器) + # Assert 1: Module is neither Stmt nor ExprNode (top-level container) if isinstance(tree, ast.Stmt) != 0 or isinstance(tree, ast.ExprNode) != 0: printf("FAIL: Module misclassified as Stmt/ExprNode\n") else: printf("PASS: Module is neither Stmt nor ExprNode\n") - # 断言 2: 顶层 body 每条语句均为 Stmt + # Assert 2: every top-level body statement is a Stmt top_ok: int = 1 top_n: sizet = tree.children.__len__() for i2 in range(top_n): @@ -218,21 +210,21 @@ class Point: if top_ok != 0: printf("PASS: all %lld top-level nodes are Stmt\n", top_n) - # 断言 3: Assign 是 Stmt 且不是 ExprNode + # Assert 3: Assign is Stmt, not ExprNode first_assign: ast.Assign* = (ast.Assign*)(tree.children.get(0)) if isinstance(first_assign, ast.Stmt) != 0 and isinstance(first_assign, ast.ExprNode) == 0: printf("PASS: Assign is Stmt, not ExprNode\n") else: printf("FAIL: Assign classification wrong\n") - # 断言 4: Assign.value(表达式)是 ExprNode 且不是 Stmt + # Assert 4: Assign.value (an expression) is ExprNode, not Stmt if isinstance(first_assign.value, ast.ExprNode) != 0 \ and isinstance(first_assign.value, ast.Stmt) == 0: printf("PASS: Assign.value is ExprNode (%s)\n", first_assign.value.type_name()) else: printf("FAIL: Assign.value not ExprNode\n") - # 断言 5: 表达式语句 Expr(如 print(x))属于 Stmt(Statement 语义) + # Assert 5: expression statement Expr (e.g. print(x)) is a Stmt if top_n >= 15: if_node: ast.If* = (ast.If*)(tree.children.get(14)) if if_node.children is not None and if_node.children.__len__() > 0: diff --git a/BuddyTest/App/main.vp b/BuddyTest/App/main.vp index fd9c7aa..77d83ee 100644 --- a/BuddyTest/App/main.vp +++ b/BuddyTest/App/main.vp @@ -10,9 +10,8 @@ def main() -> CInt | CExport: w32.win32console.SetConsoleCP(65001) w32.win32console.SetConsoleOutputCP(65001) - # memhub 的 [MEMDBG] 悬空/重复 free 检测默认开启(_memdbg_enable=1)。 - # BuddyTest 含"故意双重 free,期望静默拒绝且状态不损坏"的负向用例, - # 若保持开启会在第二次 free 处终止进程 → 在此关闭 debug 模式。 + # BuddyTest has a negative case that deliberately double-frees. With memhub's + # [MEMDBG] checks on (_memdbg_enable=1) the second free aborts, so disable it. memhub._memdbg_enable = 0 return mbuddytest.mbuddy_main() diff --git a/BuddyTest/App/mbuddytest.vp b/BuddyTest/App/mbuddytest.vp index 13e82c6..7f3a803 100644 --- a/BuddyTest/App/mbuddytest.vp +++ b/BuddyTest/App/mbuddytest.vp @@ -11,7 +11,7 @@ import w32.win32sync import w32.win32base -# 线程函数: 在共享 MBuddy 上执行 alloc/free (测试 spinlock 线程安全) +# Thread body: alloc/free on a shared MBuddy to exercise the spinlock def _thread_alloc_free(param: t.CPtr) -> uint32: bd: memhub.MemBuddy* = (memhub.MemBuddy*)(param) i: CInt @@ -29,7 +29,7 @@ def mbuddy_main() -> CInt: testcheck.begin("BuddyTest: 伙伴系统内存分配器测试") - # === 基础 alloc/free 测试 === + # === Basic alloc/free === testcheck.section("基础 alloc/free") arena: bytes = stdlib.malloc(65536) bd: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena, 65536) @@ -43,7 +43,7 @@ def mbuddy_main() -> CInt: testcheck.check(p1 != None and p2 != None and p3 != None, "3 allocs OK", "alloc FAILED") - # 写入数据验证指针可用 + # Write data to verify the returned pointer is usable p_c: CUInt8T | CPtr = CPtr(p1) p_c[0] = CUInt8T(0xAB) p_c[1] = CUInt8T(0xCD) @@ -57,19 +57,19 @@ def mbuddy_main() -> CInt: bd.free(p3) testcheck.ok("3 frees OK") - # 释放后验证合并: free_count 应回到初始分解块数 (10) - # 4096-264 内非 2 的幂: 65536-264=65272 二进制分解为 10 个 2 的幂块 + # After free, coalescing must restore the initial 10 free blocks + # (65536 - 264 = 65272 decomposes into 10 power-of-two blocks) testcheck.check(bd.free_count() == 10, "coalesce: free_count=10 OK", "coalesce: free_count != 10") - # 合并后应能分配大块 + # Coalesced space must allow a large alloc again big: bytes = bd.alloc(16000) testcheck.check(big != None, "big alloc OK", "big alloc FAILED") bd.free(big) stdlib.free(arena) - # === calloc 测试 (验证清零) === + # === calloc (verify zeroing) === testcheck.section("calloc 清零") arena2: bytes = stdlib.malloc(4096) viperlib.snprintf(buf, 256, "arena2 = %p", arena2) @@ -103,7 +103,7 @@ def mbuddy_main() -> CInt: stdlib.free(arena2) - # === realloc 扩展测试 === + # === realloc grow === testcheck.section("realloc 扩展") arena3: bytes = stdlib.malloc(4096) bd3: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena3, 4096) @@ -130,7 +130,7 @@ def mbuddy_main() -> CInt: stdlib.free(arena3) - # === 原地收缩测试 (验证无泄漏) === + # === in-place shrink (verify no leak) === testcheck.section("原地收缩 (realloc shrink)") arena_shrink: bytes = stdlib.malloc(4096) bds: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_shrink, 4096) @@ -139,15 +139,15 @@ def mbuddy_main() -> CInt: testcheck.check(sp != None, "alloc 256 OK", "alloc 256 FAILED") fc_before: CSizeT = bds.free_count() - # realloc 到更小尺寸: 256+8=264 -> order 4 (512); 32+8=40 -> order 1 (64) - # new_order(1) <= old_order(4), 应原地返回同一指针 + # Shrink 256 -> 32: order 4 (264) to order 1 (40); since new order <= old, + # realloc must return the same pointer in place sp2: bytes = bds.realloc(sp, 32) fc_after: CSizeT = bds.free_count() testcheck.check(sp2 == sp, "shrink same ptr OK", "shrink ptr changed") testcheck.check(fc_after == fc_before, "shrink no leak OK", "shrink LEAKED blocks") - # 验证数据仍可读写 + # Data must remain readable/writable after shrink sp_c: CUInt8T | CPtr = CPtr(sp2) sp_c[0] = CUInt8T(0x42) testcheck.check(sp_c[0] == CUInt8T(0x42), "shrink data OK", "shrink data FAILED") @@ -157,32 +157,32 @@ def mbuddy_main() -> CInt: stdlib.free(arena_shrink) - # === 边界情况测试 === + # === Edge cases === testcheck.section("边界情况") arena4: bytes = stdlib.malloc(4096) bd4: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena4, 4096) - # alloc(0) 应返回 None + # alloc(0) must return None z: bytes = bd4.alloc(0) testcheck.check(z == None, "alloc(0)=None OK", "alloc(0) should be None") - # free(None) 应安全 + # free(None) must be safe bd4.free(None) testcheck.ok("free(None) safe") - # realloc(None, size) 等价于 alloc + # realloc(None, size) behaves like alloc rn: bytes = bd4.realloc(None, 32) testcheck.check(rn != None, "realloc(None)=alloc OK", "realloc(None) FAILED") bd4.free(rn) - # realloc(ptr, 0) 等价于 free + # realloc(ptr, 0) behaves like free rz: bytes = bd4.alloc(32) rz2: bytes = bd4.realloc(rz, 0) testcheck.check(rz2 == None, "realloc(ptr,0)=free OK", "realloc(ptr,0) should be None") stdlib.free(arena4) - # === 非法指针防护测试 === + # === Illegal pointer defense === testcheck.section("非法指针防护") arena5: bytes = stdlib.malloc(4096) bd5: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena5, 4096) @@ -190,7 +190,7 @@ def mbuddy_main() -> CInt: valid: bytes = bd5.alloc(32) testcheck.check(valid != None, "alloc for illegal test OK", "alloc FAILED") - # 1. free 随机地址 (地址 1) + # 1. free a random address (address 1) bd5.free(t.CPtr(uint64(1))) testcheck.ok("free(addr=1) ignored") @@ -198,39 +198,39 @@ def mbuddy_main() -> CInt: bd5.free(None) testcheck.ok("free(NULL) ignored") - # 3. free 越界指针 (arena 之前) + # 3. free an out-of-range pointer (before arena) bd5.free(t.CPtr(uint64(arena5))) testcheck.ok("free(before arena) ignored") - # 4. free 越界指针 (arena 之后) + # 4. free an out-of-range pointer (after arena) bd5.free(t.CPtr(uint64(arena5) + 99999)) testcheck.ok("free(after arena) ignored") - # 5. free 未对齐指针 (arena + 1, 在 mem 区域内但不对齐) + # 5. free a misaligned pointer (inside mem but not aligned) bd5.free(t.CPtr(uint64(bd5.base) + 1)) testcheck.ok("free(misaligned) ignored") - # 6. 验证合法 free 仍正常工作 (释放后应能再次分配) + # 6. a valid free must still work (block reusable after) bd5.free(valid) retry5: bytes = bd5.alloc(32) testcheck.check(retry5 != None, "valid free still works OK", "valid free BROKEN") if retry5 != None: bd5.free(retry5) - # 7. realloc 非法指针应返回 None + # 7. realloc on an illegal pointer must return None r_illegal: bytes = bd5.realloc(t.CPtr(1), 64) testcheck.check(r_illegal == None, "realloc(illegal)=None OK", "realloc(illegal) should be None") stdlib.free(arena5) - # === OOM 内存耗尽测试 === + # === OOM exhaustion === testcheck.section("OOM 内存耗尽") arena6: bytes = stdlib.malloc(4096) bd6: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena6, 4096) - # 持续分配直到失败 + # Allocate until failure alloc_count: CInt = 0 - ptrs_arr: bytes = stdlib.malloc(8 * 256) # 存储指针的数组 + ptrs_arr: bytes = stdlib.malloc(8 * 256) # Pointer storage array ptrs: CUInt64T | CPtr = CPtr(ptrs_arr) while alloc_count < 256: @@ -244,11 +244,11 @@ def mbuddy_main() -> CInt: testcheck.info(buf) testcheck.check(alloc_count > 0, "OOM: got some allocs OK", "OOM: no allocs at all") - # 尝试再分配应失败 + # Another alloc must now fail oom_p: bytes = bd6.alloc(32) testcheck.check(oom_p == None, "OOM: alloc fails OK", "OOM: alloc should fail") - # 释放一个块后应能再次分配 + # After freeing one block, allocation must succeed again if alloc_count > 0: first_ptr: bytes = t.CPtr(ptrs[0]) bd6.free(first_ptr) @@ -257,51 +257,51 @@ def mbuddy_main() -> CInt: if retry != None: bd6.free(retry) - # 释放所有块 + # Free all blocks for idx in range(1, alloc_count): cur_p: bytes = t.CPtr(ptrs[idx]) bd6.free(cur_p) - # 全部释放后应能合并回初始分解块数 (6) + # Full free must coalesce back to the initial 6 blocks testcheck.check(bd6.free_count() == 6, "OOM: full coalesce OK", "OOM: free_count != 6 after full free") stdlib.free(ptrs_arr) stdlib.free(arena6) - # === 空闲链表状态测试 === + # === Free-list state === testcheck.section("空闲链表状态") arena7: bytes = stdlib.malloc(4096) bd7: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena7, 4096) - # 初始: 非 2 的幂 arena (4096-264=3832) 二进制分解为 6 个块 + # Initial: non-power-of-two arena (4096 - 264 = 3832) splits into 6 blocks testcheck.check(bd7.free_count() == 6, "init: 6 free blocks OK", "init: free_count != 6") - # 分配后: 空闲块数应增加 (分裂产生多个小块) + # After alloc: free count grows because a block is split a1: bytes = bd7.alloc(32) fc1: CSizeT = bd7.free_count() viperlib.snprintf(buf, 256, "after alloc(32): free_count=%lu", fc1) testcheck.info(buf) testcheck.check(fc1 > 1, "after alloc: split OK", "after alloc: no split") - # 再分配 + # Second alloc a2: bytes = bd7.alloc(32) fc2: CSizeT = bd7.free_count() testcheck.check(fc2 >= 1, "after 2nd alloc: free >= 1 OK", "after 2nd alloc: free < 1") - # 释放 a1: 空闲块数应增加 + # Free a1: free count must increase bd7.free(a1) fc3: CSizeT = bd7.free_count() testcheck.check(fc3 > fc2, "after free a1: free increased OK", "after free a1: free not increased") - # 释放 a2: 应合并, 空闲块数回到初始 6 块 + # Free a2: coalescing must restore the initial 6 blocks bd7.free(a2) testcheck.check(bd7.free_count() == 6, "after free all: coalesced to 6 OK", "after free all: free_count != 6") stdlib.free(arena7) - # === with 上下文管理器测试 === + # === with context manager === testcheck.section("with 上下文管理器") arena8: bytes = stdlib.malloc(4096) with memhub.MemBuddy(arena8, 4096) as wbd: @@ -309,16 +309,16 @@ def mbuddy_main() -> CInt: wp2: bytes = wbd.alloc(64) testcheck.check(wp1 != None and wp2 != None, "with: allocs OK", "with: allocs FAILED") - # 退出 with 块时 __exit__ 自动 reset + # Leaving the with block triggers __exit__ auto-reset - # 退出后重新进入,验证 reset 生效 + # Re-enter after exit to verify the reset took effect with memhub.MemBuddy(arena8, 4096) as wbd2: wp3: bytes = wbd2.alloc(1024) testcheck.check(wp3 != None, "with: reset+realloc OK", "with: reset+realloc FAILED") stdlib.free(arena8) - # === 双重 free 检测测试 === + # === Double-free detection === testcheck.section("双重 free 检测") arena_df: bytes = stdlib.malloc(4096) bd_df: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_df, 4096) @@ -326,17 +326,17 @@ def mbuddy_main() -> CInt: df: bytes = bd_df.alloc(64) testcheck.check(df != None, "df: alloc OK", "df: alloc FAILED") - # 第一次 free + # First free bd_df.free(df) fc_df1: CSizeT = bd_df.free_count() testcheck.ok("first free OK") - # 第二次 free (双重 free) — 应被静默拒绝 + # Second free (double free): must be silently rejected bd_df.free(df) fc_df2: CSizeT = bd_df.free_count() testcheck.check(fc_df2 == fc_df1, "double free rejected OK", "double free CORRUPTED state") - # 验证分配器仍正常工作 + # Allocator must still be functional df2: bytes = bd_df.alloc(64) testcheck.check(df2 != None, "df: alloc after double-free OK", "df: alloc after double-free FAILED") if df2 != None: @@ -344,36 +344,36 @@ def mbuddy_main() -> CInt: stdlib.free(arena_df) - # === 自检功能测试 === + # === Self-check === testcheck.section("自检功能") arena_sc: bytes = stdlib.malloc(4096) bd_sc: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_sc, 4096) - # 初始状态自检 + # Self-check on initial state testcheck.check(bd_sc.self_check() == 0, "self_check init OK", "self_check init FAILED") - # 分配后自检 + # Self-check after alloc sc_p1: bytes = bd_sc.alloc(32) sc_p2: bytes = bd_sc.alloc(128) testcheck.check(bd_sc.self_check() == 0, "self_check after alloc OK", "self_check after alloc FAILED") - # 部分释放后自检 + # Self-check after partial free bd_sc.free(sc_p1) testcheck.check(bd_sc.self_check() == 0, "self_check after partial free OK", "self_check after partial free FAILED") - # 全部释放后自检 (应合并回单个大块) + # Self-check after full free (should coalesce to one block) bd_sc.free(sc_p2) testcheck.check(bd_sc.self_check() == 0, "self_check after full free OK", "self_check after full free FAILED") - # 双重 free 后自检 (验证状态未损坏) + # Self-check after double free (state must be intact) sc_p3: bytes = bd_sc.alloc(64) bd_sc.free(sc_p3) - bd_sc.free(sc_p3) # 双重 free,应被拒绝 + bd_sc.free(sc_p3) # Double free, must be rejected testcheck.check(bd_sc.self_check() == 0, "self_check after double-free OK", "self_check after double-free CORRUPTED") stdlib.free(arena_sc) - # === 并发多线程测试 (spinlock) === + # === Concurrent threads (spinlock) === testcheck.section("并发多线程 (spinlock)") arena_mt: bytes = stdlib.malloc(65536) bd_mt: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_mt, 65536) @@ -383,19 +383,19 @@ def mbuddy_main() -> CInt: handles: CUInt64T | CPtr = CPtr(handles_arr) tid: CUInt32T = 0 - # 创建 4 个线程并发 alloc/free + # Spawn 4 threads doing concurrent alloc/free t_idx: CInt for t_idx in range(NUM_THREADS): h: bytes = w32.win32process.CreateThread(None, 0, _thread_alloc_free, t.CPtr(bd_mt), 0, &tid) handles[t_idx] = CUInt64T(h) - # 等待所有线程完成 + # Wait for all threads to finish for t_idx in range(NUM_THREADS): h: bytes = t.CPtr(handles[t_idx]) w32.win32sync.WaitForSingleObject(h, w32.win32base.INFINITE) w32.win32base.CloseHandle(h) - # 验证分配器状态: 自检通过,所有块已合并 + # Verify allocator state: self-check passes and all blocks coalesced testcheck.check(bd_mt.self_check() == 0, "mt: self_check OK", "mt: self_check FAILED") testcheck.check(bd_mt.free_count() == 10, "mt: free_count=10 OK", "mt: free_count != 10 (leaked)") @@ -405,18 +405,18 @@ def mbuddy_main() -> CInt: stdlib.free(handles_arr) stdlib.free(arena_mt) - # === 极端边界测试 === + # === Extreme boundaries === testcheck.section("极端边界") - # 1. 分配尺寸恰巧是块边界 + # 1. Alloc size exactly at a block boundary arena_ex: bytes = stdlib.malloc(4096) bd_ex: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_ex, 4096) - # 24 + 16 = 40 > 32(8 头 + 8 哨兵),需要 order 1 (64 字节) + # 24 + 16 = 40 > 32 (8 header + 8 sentinel), needs order 1 (64 bytes) exact_fit: bytes = bd_ex.alloc(24) testcheck.check(exact_fit != None, "exact fit order 0 OK", "exact fit order 0 FAILED") - # 25 + 16 = 41 > 32, 需要 order 1 (64 字节) + # 25 + 16 = 41 > 32, needs order 1 (64 bytes) over_fit: bytes = bd_ex.alloc(25) testcheck.check(over_fit != None, "over by 1 byte OK", "over by 1 byte FAILED") @@ -424,14 +424,13 @@ def mbuddy_main() -> CInt: bd_ex.free(over_fit) testcheck.check(bd_ex.free_count() == 6, "boundary: coalesce OK", "boundary: coalesce FAILED") - # 2. 单次分配接近最大块上限(order6=2048,非 2 的幂 arena 的最大分解块) - # 可用数据区 = 2048 - 8(头) - 8(哨兵),alloc(max_usable) 的 needed 恰好 - # = 2048,正好填满 order6 最大块 + # 2. Alloc near the largest block limit (order6 = 2048): usable = 2048 - 16, + # so alloc(max_usable) exactly fills one order6 block max_usable: CSizeT = 2048 - 16 viperlib.snprintf(buf, 256, "mem_size=%lu, max_block=2048, max_usable=%lu", bd_ex.mem_size, max_usable) testcheck.info(buf) - # 恰好用完 order6 块(其余 5 个分解块空闲) + # Exactly consumes the order6 block (5 other blocks stay free) exact_max: bytes = bd_ex.alloc(max_usable) testcheck.check(exact_max != None, "exact max alloc OK", "exact max alloc FAILED") testcheck.check(bd_ex.free_count() == 5, "max alloc: 5 free blocks left OK", "max alloc: free_count != 5") @@ -439,12 +438,12 @@ def mbuddy_main() -> CInt: bd_ex.free(exact_max) testcheck.check(bd_ex.free_count() == 6, "max free: coalesce OK", "max free: coalesce FAILED") - # 再次分配同样大小 — 验证合并后可再次使用 + # Alloc the same size again to verify coalesced space is reusable exact_max2: bytes = bd_ex.alloc(max_usable) testcheck.check(exact_max2 != None, "exact max re-alloc OK", "exact max re-alloc FAILED") bd_ex.free(exact_max2) - # 3. 分配超过 arena 上限 — 应失败 + # 3. Alloc beyond the arena limit must fail over_max: bytes = bd_ex.alloc(bd_ex.mem_size) testcheck.check(over_max == None, "over max: fails OK", "over max: should fail") @@ -453,7 +452,7 @@ def mbuddy_main() -> CInt: stdlib.free(arena_ex) - # 4. Arena 太小 (仅够 free_lists 开销, 264 字节) + # 4. Arena too small (only fits the 264-byte free-list overhead) arena_tiny: bytes = stdlib.malloc(264) bd_tiny: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_tiny, 264) testcheck.check(bd_tiny.stats() == 0, "tiny arena: stats=0 OK", "tiny arena: stats != 0") @@ -461,12 +460,12 @@ def mbuddy_main() -> CInt: testcheck.check(tiny_p == None, "tiny arena: alloc fails OK", "tiny arena: should fail") stdlib.free(arena_tiny) - # 5. Arena 刚好够一个最小块 (264 + 32 = 296) + # 5. Arena fits exactly one minimal block (264 + 32 = 296) arena_one: bytes = stdlib.malloc(296) bd_one: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_one, 296) testcheck.check(bd_one.stats() == 32, "one block: stats=32 OK", "one block: stats != 32") - # 最小块 32 字节 = 数据 16 + 头 8 + 哨兵 8,alloc(16) 恰好填满 + # Minimal block 32 = data 16 + header 8 + sentinel 8; alloc(16) fills it one_p: bytes = bd_one.alloc(16) testcheck.check(one_p != None, "one block: alloc OK", "one block: alloc FAILED") @@ -477,20 +476,20 @@ def mbuddy_main() -> CInt: testcheck.check(bd_one.free_count() == 1, "one block: free OK", "one block: free FAILED") stdlib.free(arena_one) - # 6. 2 的幂 arena vs 非 2 的幂 arena + # 6. Power-of-two vs non-power-of-two arena arena_pow2: bytes = stdlib.malloc(512) bd_pow2: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_pow2, 512) - # 512 - 264 = 248, 二进制分解 = 128+64+32 = 224 (尾 24 字节碎片不入池) + # 512 - 264 = 248, decomposes to 128 + 64 + 32 = 224 (24-byte tail dropped) testcheck.check(bd_pow2.stats() == 224, "pow2 arena: stats=224 OK", "pow2 arena: stats != 224") stdlib.free(arena_pow2) arena_non2: bytes = stdlib.malloc(500) bd_non2: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_non2, 500) - # 500 - 264 = 236, 二进制分解 = 128+64+32 = 224 (尾 12 字节碎片不入池) + # 500 - 264 = 236, decomposes to 128 + 64 + 32 = 224 (12-byte tail dropped) testcheck.check(bd_non2.stats() == 224, "non-pow2 arena: stats=224 OK", "non-pow2 arena: stats != 224") stdlib.free(arena_non2) - # 7. 压力测试: 反复 alloc/free 同一尺寸 1000 次 + # 7. Stress: 1000 alloc/free cycles of the same size arena_stress: bytes = stdlib.malloc(4096) bd_stress: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_stress, 4096) @@ -506,7 +505,7 @@ def mbuddy_main() -> CInt: testcheck.check(bd_stress.free_count() == 6, "stress: free_count=6 OK", "stress: leaked") stdlib.free(arena_stress) - # 8. 分配全部最小块然后全部释放 + # 8. Allocate all minimal blocks, then free them all arena_fill: bytes = stdlib.malloc(4096) bd_fill: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_fill, 4096) @@ -527,7 +526,7 @@ def mbuddy_main() -> CInt: testcheck.check(fill_count > 0, "fill: got blocks OK", "fill: no blocks") testcheck.check(bd_fill.self_check() == 0, "fill: self_check OK", "fill: self_check FAILED") - # 全部释放 + # Free all fi: CInt for fi in range(fill_count): fp2: bytes = t.CPtr(fill_ptrs[fi]) diff --git a/BuiltinDecoratorTest/App/main.vp b/BuiltinDecoratorTest/App/main.vp index 5b8f1f1..b2de7f6 100644 --- a/BuiltinDecoratorTest/App/main.vp +++ b/BuiltinDecoratorTest/App/main.vp @@ -6,7 +6,7 @@ import testcheck # ============================================================ -# 测试 1:@property getter +# Test 1: @property getter # ============================================================ class Rect: width: int @@ -39,7 +39,7 @@ def test_property_getter(): # ============================================================ -# 测试 2:@property.setter +# Test 2: @property.setter # ============================================================ class Temperature: _celsius: double @@ -73,7 +73,7 @@ def test_property_setter(): # ============================================================ -# 测试 3:@property.getter(重新定义 getter) +# Test 3: @property.getter redefinition # ============================================================ class Counter: _count: int @@ -102,7 +102,7 @@ def test_property_getter_redef(): # ============================================================ -# 测试 4:@property.deleter +# Test 4: @property.deleter # ============================================================ class Config: _value: int @@ -143,7 +143,7 @@ def test_property_deleter(): # ============================================================ -# 测试 5:@staticmethod +# Test 5: @staticmethod # ============================================================ class MathUtils: @staticmethod @@ -157,13 +157,13 @@ class MathUtils: def test_staticmethod(): testcheck.section("@staticmethod") - # 通过类名调用 + # call via class name testcheck.check(MathUtils.add(3, 4) == 7, "MathUtils.add(3,4)==7", "MathUtils.add(3,4) expect 7") testcheck.check(MathUtils.max_val(5, 10) == 10, "MathUtils.max(5,10)==10", "MathUtils.max(5,10) expect 10") # ============================================================ -# 测试 6:@classmethod +# Test 6: @classmethod # ============================================================ class Point: x: double @@ -190,7 +190,7 @@ class Point: def test_classmethod(): testcheck.section("@classmethod") - # 通过类名调用 + # call via class name p1: Point = Point.origin() testcheck.check(p1.x > -0.01 and p1.x < 0.01, "origin.x ~= 0", "origin.x expect ~0") testcheck.check(p1.y > -0.01 and p1.y < 0.01, "origin.y ~= 0", "origin.y expect ~0") @@ -203,7 +203,7 @@ def test_classmethod(): # ============================================================ -# 测试 7:综合测试 — @property + @staticmethod + @classmethod +# Test 7: combined @property + @staticmethod + @classmethod # ============================================================ class Circle: _radius: double @@ -237,14 +237,14 @@ class Circle: def test_combined(): testcheck.section("Combined @property + @staticmethod + @classmethod") - # 先测试直接构造 + # first test direct construction cr0: Circle = Circle(1.0) testcheck.check(cr0.radius > 0.99 and cr0.radius < 1.01, "direct radius ~= 1", "direct radius expect ~1") testcheck.check(cr0.area > 3.14 and cr0.area < 3.15, "direct area ~= pi", "direct area expect ~pi") cr0.radius = 2.0 testcheck.check(cr0.radius > 1.99 and cr0.radius < 2.01, "direct radius 2.0", "direct radius expect 2.0") testcheck.check(cr0.area > 12.56 and cr0.area < 12.58, "direct area ~= 4pi", "direct area expect ~4pi") - # 测试 classmethod + # test classmethod cr1: Circle = Circle.unit() testcheck.check(cr1.radius > 0.99 and cr1.radius < 1.01, "unit radius ~= 1", "unit radius expect ~1") testcheck.check(Circle.is_unit(1.0), "is_unit(1.0)", "is_unit(1.0) should be true") @@ -252,7 +252,7 @@ def test_combined(): # ============================================================ -# 主函数 +# main # ============================================================ def main() -> int | t.CExport: testcheck.begin("Builtin Decorator Test") diff --git a/CPythonTest/App/cpython.vp b/CPythonTest/App/cpython.vp index c678272..1321105 100644 --- a/CPythonTest/App/cpython.vp +++ b/CPythonTest/App/cpython.vp @@ -1,17 +1,13 @@ import t, c -# ============================================================ -# PyObject — 所有 Python 对象的基类 -# ============================================================ +# --- PyObject: base class of all Python objects --- class PyObject: ob_refcnt: t.CLong ob_type: t.CPtr -# ============================================================ -# 引用计数 -# ============================================================ +# --- Reference counting --- extern def Py_INCREF(op: PyObject*) extern def Py_DECREF(op: PyObject*) extern def Py_XINCREF(op: PyObject*) @@ -19,9 +15,7 @@ extern def Py_XDECREF(op: PyObject*) extern def Py_DecRef(op: PyObject*) -# ============================================================ -# 解释器初始化/终止 -# ============================================================ +# --- Interpreter init/finalize --- extern def Py_Initialize() extern def Py_Finalize() extern def Py_InitializeEx(initsigs: int) @@ -29,9 +23,7 @@ extern def Py_FinalizeEx() -> int extern def Py_IsInitialized() -> int -# ============================================================ -# PyConfig -# ============================================================ +# --- PyConfig --- class PySTATUS: func: const str err_msg: const str @@ -107,9 +99,7 @@ extern def Py_DecodeLocale(s: const str) -> str extern def PyStatus_Exception(status: PySTATUS) -> int -# ============================================================ -# 整数操作 (PyLong) -# ============================================================ +# --- Integer ops (PyLong) --- extern def PyLong_FromLong(v: int) -> PyObject* extern def PyLong_FromUnsignedLong(v: t.CUnsignedLong) -> PyObject* extern def PyLong_FromLongLong(v: t.CLong) -> PyObject* @@ -126,17 +116,13 @@ extern def PyLong_AsSsize_t(obj: PyObject*) -> t.CPtrDiffT extern def PyLong_AsSize_t(obj: PyObject*) -> sizet -# ============================================================ -# 浮点数操作 (PyFloat) -# ============================================================ +# --- Float ops (PyFloat) --- extern def PyFloat_FromDouble(v: double) -> PyObject* extern def PyFloat_AsDouble(obj: PyObject*) -> double extern def PyFloat_FromString(s: PyObject*) -> PyObject* -# ============================================================ -# 字符串操作 (PyUnicode / PyBytes) -# ============================================================ +# --- String ops (PyUnicode / PyBytes) --- extern def PyUnicode_FromString(u: const str) -> PyObject* extern def PyUnicode_FromStringAndSize(u: const str, size: sizet) -> PyObject* extern def PyUnicode_FromFormat(fmt: const str) -> PyObject* @@ -161,9 +147,7 @@ extern def PyBytes_FromObject(o: PyObject*) -> PyObject* extern def PyBytes_FromFormat(fmt: const str) -> PyObject* -# ============================================================ -# 布尔 / None -# ============================================================ +# --- Bool / None --- extern def PyBool_FromLong(v: t.CLong) -> PyObject* Py_True: PyObject | t.CPtr | t.State @@ -171,9 +155,7 @@ Py_False: PyObject | t.CPtr | t.State Py_None: PyObject | t.CPtr | t.State -# ============================================================ -# 列表操作 (PyList) -# ============================================================ +# --- List ops (PyList) --- extern def PyList_New(len: sizet) -> PyObject* extern def PyList_Size(lst: PyObject*) -> sizet extern def PyList_GetItem(lst: PyObject*, idx: sizet) -> PyObject* @@ -187,9 +169,7 @@ extern def PyList_Reverse(lst: PyObject*) -> int extern def PyList_AsTuple(lst: PyObject*) -> PyObject* -# ============================================================ -# 元组操作 (PyTuple) -# ============================================================ +# --- Tuple ops (PyTuple) --- extern def PyTuple_New(len: sizet) -> PyObject* extern def PyTuple_Size(tup: PyObject*) -> sizet extern def PyTuple_GetItem(tup: PyObject*, idx: sizet) -> PyObject* @@ -198,9 +178,7 @@ extern def PyTuple_GetSlice(tup: PyObject*, lo: sizet, hi: sizet) -> PyObject* extern def PyTuple_Pack(n: sizet) -> PyObject* -# ============================================================ -# 字典操作 (PyDict) -# ============================================================ +# --- Dict ops (PyDict) --- extern def PyDict_New() -> PyObject* extern def PyDict_GetItem(d: PyObject*, key: PyObject*) -> PyObject* extern def PyDict_GetItemString(d: PyObject*, key: const str) -> PyObject* @@ -220,9 +198,7 @@ extern def PyDict_Merge(d: PyObject*, other: PyObject*, override: int) -> int extern def PyDict_Update(d: PyObject*, other: PyObject*) -> int -# ============================================================ -# 对象通用操作 -# ============================================================ +# --- Object common ops --- extern def PyObject_Str(obj: PyObject*) -> PyObject* extern def PyObject_Repr(obj: PyObject*) -> PyObject* extern def PyObject_Type(obj: PyObject*) -> PyObject* @@ -254,9 +230,7 @@ extern def PyObject_GetIter(obj: PyObject*) -> PyObject* extern def PyIter_Next(obj: PyObject*) -> PyObject* -# ============================================================ -# 比较常量 -# ============================================================ +# --- Comparison constants --- Py_LT: int | t.State Py_LE: int | t.State Py_EQ: int | t.State @@ -265,9 +239,7 @@ Py_GT: int | t.State Py_GE: int | t.State -# ============================================================ -# 模块操作 -# ============================================================ +# --- Module ops --- extern def PyImport_ImportModule(name: const str) -> PyObject* extern def PyImport_Import(name: PyObject*) -> PyObject* extern def PyImport_ImportModuleLevelObject(name: PyObject*, globs: PyObject*, locs: PyObject*, fromlist: PyObject*, level: int) -> PyObject* @@ -277,9 +249,7 @@ extern def PyImport_GetModuleDict() -> PyObject* extern def PyImport_ImportModuleEx(name: const str, globs: PyObject*, locs: PyObject*, fromlist: PyObject*) -> PyObject* -# ============================================================ -# 模块创建 -# ============================================================ +# --- Module creation --- class PyMethodDef: ml_name: const str ml_meth: t.CPtr @@ -314,9 +284,7 @@ extern def PyModule_AddIntConstant(mod: PyObject*, name: const str, val: t.CLong extern def PyModule_AddStringConstant(mod: PyObject*, name: const str, val: const str) -> int -# ============================================================ -# GIL 管理 -# ============================================================ +# --- GIL management --- extern def PyGILState_Ensure() -> int extern def PyGILState_Release(state: int): pass extern def PyEval_SaveThread() -> t.CPtr @@ -329,9 +297,7 @@ extern def PyEval_ThreadsInitialized() -> int extern def PyEval_InitThreads(): pass -# ============================================================ -# 错误处理 -# ============================================================ +# --- Error handling --- extern def PyErr_Occurred() -> PyObject* extern def PyErr_Clear(): pass extern def PyErr_Fetch(tp: PyObject**, val: PyObject**, tb: PyObject**): pass @@ -346,9 +312,7 @@ extern def PyErr_ExceptionMatches(exc: PyObject*) -> int | t.State: pass extern def PyErr_GivenExceptionMatches(given: PyObject*, exc: PyObject*) -> int | t.State: pass -# ============================================================ -# 内置异常类型 -# ============================================================ +# --- Built-in exception types --- PyExc_BaseException: PyObject | t.CPtr | t.State PyExc_Exception: PyObject | t.CPtr | t.State PyExc_TypeError: PyObject | t.CPtr | t.State @@ -373,16 +337,12 @@ PyExc_IsADirectoryError: PyObject | t.CPtr | t.State PyExc_NotADirectoryError: PyObject | t.CPtr | t.State -# ============================================================ -# 内置函数 -# ============================================================ +# --- Built-in functions --- extern def Py_BuildValue(fmt: const str) -> PyObject* extern def Py_VaBuildValue(fmt: const str, va: t.CPtr) -> PyObject* -# ============================================================ -# 类型检查 -# ============================================================ +# --- Type checks --- extern def PyLong_Check(obj: PyObject*) -> int extern def PyFloat_Check(obj: PyObject*) -> int extern def PyUnicode_Check(obj: PyObject*) -> int @@ -394,9 +354,7 @@ extern def PyBool_Check(obj: PyObject*) -> int extern def PyNone_Check(obj: PyObject*) -> int -# ============================================================ -# 内存管理 -# ============================================================ +# --- Memory management --- extern def PyMem_Malloc(size: sizet) -> t.CPtr extern def PyMem_Realloc(ptr: t.CPtr, size: sizet) -> t.CPtr extern def PyMem_Free(ptr: t.CPtr) @@ -409,18 +367,14 @@ extern def PyObject_Init(obj: PyObject*, tp: t.CPtr) -> PyObject* extern def PyObject_InitVar(obj: PyObject*, tp: t.CPtr, size: sizet) -> PyObject* -# ============================================================ -# 文件操作 -# ============================================================ +# --- File ops --- extern def PyFile_FromString(filename: const str, mode: const str) -> PyObject* extern def PyFile_AsFile(file: PyObject*) -> t.CPtr extern def PyFile_WriteObject(obj: PyObject*, file: PyObject*, flags: int) -> int extern def PyFile_WriteString(s: const str, file: PyObject*) -> int -# ============================================================ -# 编译/执行 -# ============================================================ +# --- Compile/execute --- extern def Py_CompileString(s: const str, filename: const str, start: int) -> PyObject* extern def PyEval_EvalCode(code: PyObject*, globs: PyObject*, locs: PyObject*) -> PyObject* extern def PyEval_EvalCodeEx(code: PyObject*, globs: PyObject*, locs: PyObject*, args: PyObject**, argc: int, kws: PyObject**, kwc: int, defs: PyObject**, defc: int, kwdefs: PyObject*, closure: PyObject*) -> PyObject*: pass @@ -430,9 +384,7 @@ extern def PyEval_CallFunction(callable: PyObject*, fmt: const str) -> PyObject* extern def PyEval_CallMethod(obj: PyObject*, method: const str, fmt: const str) -> PyObject*: pass -# ============================================================ -# PyRun -# ============================================================ +# --- PyRun --- extern def PyRun_SimpleString(cmd: const str) -> int extern def PyRun_SimpleFile(fp: t.CPtr, filename: const str) -> int extern def PyRun_AnyFile(fp: t.CPtr, filename: const str) -> int @@ -444,9 +396,7 @@ Py_file_input: int | t.State Py_eval_input: int | t.State -# ============================================================ -# Capsule -# ============================================================ +# --- Capsule --- extern def PyCapsule_New(ptr: t.CPtr, name: const str, dtor: t.CPtr) -> PyObject* extern def PyCapsule_GetPointer(cap: PyObject*, name: const str) -> t.CPtr extern def PyCapsule_GetName(cap: PyObject*) -> str @@ -456,9 +406,7 @@ extern def PyCapsule_SetName(cap: PyObject*, name: const str) -> int extern def PyCapsule_SetDestructor(cap: PyObject*, dtor: t.CPtr) -> int -# ============================================================ -# 序列操作 -# ============================================================ +# --- Sequence ops --- extern def PySequence_Check(obj: PyObject*) -> int extern def PySequence_Size(obj: PyObject*) -> sizet extern def PySequence_Length(obj: PyObject*) -> sizet @@ -477,9 +425,7 @@ extern def PySequence_List(obj: PyObject*) -> PyObject* extern def PySequence_Tuple(obj: PyObject*) -> PyObject* -# ============================================================ -# 映射操作 -# ============================================================ +# --- Mapping ops --- extern def PyMapping_Check(obj: PyObject*) -> int extern def PyMapping_Size(obj: PyObject*) -> sizet extern def PyMapping_Length(obj: PyObject*) -> sizet @@ -492,9 +438,7 @@ extern def PyMapping_Values(obj: PyObject*) -> PyObject* extern def PyMapping_Items(obj: PyObject*) -> PyObject* -# ============================================================ -# 数字操作 -# ============================================================ +# --- Number ops --- extern def PyNumber_Add(o1: PyObject*, o2: PyObject*) -> PyObject* extern def PyNumber_Subtract(o1: PyObject*, o2: PyObject*) -> PyObject* extern def PyNumber_Multiply(o1: PyObject*, o2: PyObject*) -> PyObject* @@ -518,17 +462,13 @@ extern def PyNumber_Float(obj: PyObject*) -> PyObject* extern def PyNumber_Check(obj: PyObject*) -> int -# ============================================================ -# 弱引用 -# ============================================================ +# --- Weak references --- extern def PyWeakref_NewRef(obj: PyObject*, cb: PyObject*) -> PyObject* extern def PyWeakref_GetObject(ref: PyObject*) -> PyObject* extern def PyWeakref_Check(obj: PyObject*) -> int -# ============================================================ -# 属性描述符 -# ============================================================ +# --- Property descriptors --- class PyGetSetDef: name: const str get: t.CPtr @@ -544,9 +484,7 @@ class PyMemberDef: doc: const str -# ============================================================ -# sys 模块 -# ============================================================ +# --- sys module --- extern def PySys_GetObject(name: const str) -> PyObject* extern def PySys_SetObject(name: const str, val: PyObject*) -> int extern def PySys_ResetWarnOptions(): pass @@ -558,17 +496,13 @@ extern def PySys_FormatStdout(fmt: const str): pass extern def PySys_FormatStderr(fmt: const str): pass -# ============================================================ -# 内存视图 -# ============================================================ +# --- Memory view --- extern def PyMemoryView_FromObject(obj: PyObject*) -> PyObject* extern def PyMemoryView_GetContiguous(obj: PyObject*, btype: int, order: char) -> PyObject* extern def PyMemoryView_Check(obj: PyObject*) -> int -# ============================================================ -# set / frozenset -# ============================================================ +# --- set / frozenset --- extern def PySet_New(iterable: PyObject*) -> PyObject* extern def PySet_Add(s: PyObject*, key: PyObject*) -> int extern def PySet_Discard(s: PyObject*, key: PyObject*) -> int @@ -580,9 +514,7 @@ extern def PyFrozenSet_New(iterable: PyObject*) -> PyObject* extern def PyFrozenSet_Check(obj: PyObject*) -> int -# ============================================================ -# slice -# ============================================================ +# --- slice --- extern def PySlice_New(start: PyObject*, stop: PyObject*, step: PyObject*) -> PyObject* extern def PySlice_GetIndicesEx(sl: PyObject*, length: sizet, start: sizet*, stop: sizet*, step: sizet*, slicelen: sizet*) -> int extern def PySlice_Unpack(sl: PyObject*, start: t.CPtrDiffT*, stop: t.CPtrDiffT*, step: t.CPtrDiffT*): pass @@ -590,11 +522,9 @@ extern def PySlice_AdjustIndices(length: sizet, start: t.CPtrDiffT*, stop: t.CPt extern def PySlice_Check(obj: PyObject*) -> int -# ============================================================ -# 类型包装类 — 带运算符重载 -# ============================================================ +# --- Type wrapper classes: operator overloading --- -# --- PyLongObj: Python 整数包装 --- +# --- PyLongObj: Python integer wrapper --- class PyLongObj: ptr: PyObject* @@ -637,7 +567,7 @@ class PyLongObj: Py_DecRef(self.ptr) -# --- PyFloatObj: Python 浮点数包装 --- +# --- PyFloatObj: Python float wrapper --- class PyFloatObj: ptr: PyObject* @@ -685,7 +615,7 @@ class PyFloatObj: Py_DecRef(self.ptr) -# --- PyUnicodeObj: Python 字符串包装 --- +# --- PyUnicodeObj: Python string wrapper --- class PyUnicodeObj: ptr: PyObject* @@ -716,7 +646,7 @@ class PyUnicodeObj: Py_DecRef(self.ptr) -# --- PyListObj: Python 列表包装 --- +# --- PyListObj: Python list wrapper --- class PyListObj: ptr: PyObject* @@ -745,7 +675,7 @@ class PyListObj: Py_DecRef(self.ptr) -# --- PyDictObj: Python 字典包装 --- +# --- PyDictObj: Python dict wrapper --- class PyDictObj: ptr: PyObject* diff --git a/CPythonTest/App/main.vp b/CPythonTest/App/main.vp index f233b7b..93f9cfe 100644 --- a/CPythonTest/App/main.vp +++ b/CPythonTest/App/main.vp @@ -17,35 +17,35 @@ def test_long_operations(): testcheck.section("PyLong operations") cpython.Py_Initialize() - # 创建整数 + # Create int py_num: cpython.PyObject | CPtr = cpython.PyLong_FromLong(12345) testcheck.check(py_num != 0, "PyLong_FromLong != NULL", "PyLong_FromLong != NULL") - # 整数转字符串 + # Int to string py_str: cpython.PyObject | CPtr = cpython.PyObject_Str(py_num) testcheck.check(py_str != 0, "PyObject_Str != NULL", "PyObject_Str != NULL") - # 获取 C 字符串 + # Get C string c_str: char | CPtr = cpython.PyUnicode_AsUTF8(py_str) testcheck.check(c_str != 0, "PyUnicode_AsUTF8 != NULL", "PyUnicode_AsUTF8 != NULL") printf(" PyLong_FromLong(12345) -> str = %s\n", c_str) - # 读取回来 + # Read back val: CLong = cpython.PyLong_AsLong(py_num) testcheck.check(val == 12345, "PyLong_AsLong == 12345", "PyLong_AsLong == 12345") - # 负数 + # Negative py_neg: cpython.PyObject | CPtr = cpython.PyLong_FromLong(-999) neg_val: CLong = cpython.PyLong_AsLong(py_neg) testcheck.check(neg_val == -999, "PyLong_FromLong(-999) == -999", "PyLong_FromLong(-999) == -999") - # 浮点数转整数 + # Float to int py_dbl: cpython.PyObject | CPtr = cpython.PyFloat_FromDouble(3.14159) testcheck.check(py_dbl != 0, "PyFloat_FromDouble != NULL", "PyFloat_FromDouble != NULL") dbl_val: CDouble = cpython.PyFloat_AsDouble(py_dbl) testcheck.check(dbl_val > 3.14 and dbl_val < 3.15, "PyFloat_AsDouble ~= 3.14", "PyFloat_AsDouble ~= 3.14") - # 清理 + # Cleanup cpython.Py_DecRef(py_dbl) cpython.Py_DecRef(py_neg) cpython.Py_DecRef(py_str) @@ -58,27 +58,27 @@ def test_string_operations(): testcheck.section("PyUnicode operations") cpython.Py_Initialize() - # 从 C 字符串创建 + # Create from C string py_s1: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("Hello, Viper!") testcheck.check(py_s1 != 0, "PyUnicode_FromString != NULL", "PyUnicode_FromString != NULL") - # 获取 UTF8 + # Get UTF-8 utf8: char | CPtr = cpython.PyUnicode_AsUTF8(py_s1) testcheck.check(utf8 != 0, "AsUTF8 != NULL", "AsUTF8 != NULL") printf(" PyUnicode_FromString -> %s\n", utf8) - # 字符串长度 + # String length length: CLong = cpython.PyUnicode_GetLength(py_s1) testcheck.check(length == 13, "GetLength == 13", "GetLength == 13") - # 字符串拼接 + # String concat py_s2: cpython.PyObject | CPtr = cpython.PyUnicode_FromString(" World") py_concat: cpython.PyObject | CPtr = cpython.PyUnicode_Concat(py_s1, py_s2) concat_utf8: char | CPtr = cpython.PyUnicode_AsUTF8(py_concat) testcheck.check(py_concat != 0, "Concat != NULL", "Concat != NULL") printf(" Concat -> %s\n", concat_utf8) - # 清理 + # Cleanup cpython.Py_DecRef(py_concat) cpython.Py_DecRef(py_s2) cpython.Py_DecRef(py_s1) @@ -90,11 +90,11 @@ def test_list_operations(): testcheck.section("PyList operations") cpython.Py_Initialize() - # 创建列表 + # Create list py_list: cpython.PyObject | CPtr = cpython.PyList_New(0) testcheck.check(py_list != 0, "PyList_New != NULL", "PyList_New != NULL") - # Append 元素 + # Append elements py_i1: cpython.PyObject | CPtr = cpython.PyLong_FromLong(10) py_i2: cpython.PyObject | CPtr = cpython.PyLong_FromLong(20) py_i3: cpython.PyObject | CPtr = cpython.PyLong_FromLong(30) @@ -102,11 +102,11 @@ def test_list_operations(): cpython.PyList_Append(py_list, py_i2) cpython.PyList_Append(py_list, py_i3) - # 检查大小 + # Check size list_size: CSizeT = cpython.PyList_Size(py_list) testcheck.check(list_size == 3, "PyList_Size == 3", "PyList_Size == 3") - # 获取元素 + # Get elements item0: cpython.PyObject | CPtr = cpython.PyList_GetItem(py_list, 0) val0: CLong = cpython.PyLong_AsLong(item0) testcheck.check(val0 == 10, "list[0] == 10", "list[0] == 10") @@ -115,7 +115,7 @@ def test_list_operations(): val2: CLong = cpython.PyLong_AsLong(item2) testcheck.check(val2 == 30, "list[2] == 30", "list[2] == 30") - # 清理 + # Cleanup cpython.Py_DecRef(py_i3) cpython.Py_DecRef(py_i2) cpython.Py_DecRef(py_i1) @@ -128,11 +128,11 @@ def test_dict_operations(): testcheck.section("PyDict operations") cpython.Py_Initialize() - # 创建字典 + # Create dict py_dict: cpython.PyObject | CPtr = cpython.PyDict_New() testcheck.check(py_dict != 0, "PyDict_New != NULL", "PyDict_New != NULL") - # 设置键值对 + # Set key/value pairs py_key1: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("name") py_val1: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("Viper") cpython.PyDict_SetItem(py_dict, py_key1, py_val1) @@ -141,24 +141,24 @@ def test_dict_operations(): py_val2: cpython.PyObject | CPtr = cpython.PyLong_FromLong(1) cpython.PyDict_SetItem(py_dict, py_key2, py_val2) - # 检查大小 + # Check size dict_size: CSizeT = cpython.PyDict_Size(py_dict) testcheck.check(dict_size == 2, "PyDict_Size == 2", "PyDict_Size == 2") - # 获取值 + # Get value got_val: cpython.PyObject | CPtr = cpython.PyDict_GetItem(py_dict, py_key1) testcheck.check(got_val != 0, "GetItem(name) != NULL", "GetItem(name) != NULL") got_str: char | CPtr = cpython.PyUnicode_AsUTF8(got_val) testcheck.check(got_str != 0, "name == Viper", "name == Viper") printf(" dict['name'] = %s\n", got_str) - # 使用 GetItemString + # Use GetItemString got_ver: cpython.PyObject | CPtr = cpython.PyDict_GetItemString(py_dict, "version") testcheck.check(got_ver != 0, "GetItemString(version) != NULL", "GetItemString(version) != NULL") ver_val: CLong = cpython.PyLong_AsLong(got_ver) testcheck.check(ver_val == 1, "version == 1", "version == 1") - # 清理 + # Cleanup cpython.Py_DecRef(py_val2) cpython.Py_DecRef(py_key2) cpython.Py_DecRef(py_val1) @@ -172,15 +172,15 @@ def test_pyrun_string(): testcheck.section("PyRun_SimpleString") cpython.Py_Initialize() - # 执行简单 Python 代码 + # Run simple Python code rc: CInt = cpython.PyRun_SimpleString("print('Hello from embedded Python!')") testcheck.check(rc == 0, "PyRun_SimpleString == 0", "PyRun_SimpleString == 0") - # 执行赋值 + # Run assignment rc2: CInt = cpython.PyRun_SimpleString("x = 6 * 7") testcheck.check(rc2 == 0, "PyRun_SimpleString(assign) == 0", "PyRun_SimpleString(assign) == 0") - # 读取结果 + # Read result rc3: CInt = cpython.PyRun_SimpleString("print(f'The answer is {x}')") testcheck.check(rc3 == 0, "PyRun_SimpleString(print) == 0", "PyRun_SimpleString(print) == 0") @@ -191,12 +191,12 @@ def test_import_module(): testcheck.section("PyImport_ImportModule") cpython.Py_Initialize() - # 导入 math 模块 + # Import math module math_mod: cpython.PyObject | CPtr = cpython.PyImport_ImportModule("math") testcheck.check(math_mod != 0, "import math != NULL", "import math != NULL") if math_mod != 0: - # 获取 math.pi + # Get math.pi pi_val: cpython.PyObject | CPtr = cpython.PyObject_GetAttrString(math_mod, "pi") testcheck.check(pi_val != 0, "math.pi != NULL", "math.pi != NULL") if pi_val != 0: @@ -205,7 +205,7 @@ def test_import_module(): printf(" math.pi = %f\n", pi_dbl) cpython.Py_DecRef(pi_val) - # 获取 math.sqrt 函数 + # Get math.sqrt function sqrt_func: cpython.PyObject | CPtr = cpython.PyObject_GetAttrString(math_mod, "sqrt") testcheck.check(sqrt_func != 0, "math.sqrt != NULL", "math.sqrt != NULL") if sqrt_func != 0: diff --git a/CharTest/App/main.vp b/CharTest/App/main.vp index 9569e1a..caa23cc 100644 --- a/CharTest/App/main.vp +++ b/CharTest/App/main.vp @@ -8,23 +8,23 @@ def bump(v: char) -> char: def main() -> int | t.CExport: - # 1) char 注解:char = t.CChar = i8(标量内置类型,非指针) + # 1) char annotation: char = t.CChar = i8 (scalar builtin, not a pointer) ch: char = 65 stdio.printf("1 char annot: %d (expect 65)\n", int(ch)) - # 2) char() 强转 int→char:300 trunc 到 i8 → 44 + # 2) char() cast int to char: 300 truncates to i8, giving 44 big: char = char(300) stdio.printf("2 char cast trunc: %d (expect 44)\n", int(big)) - # 3) 函数返回 char(i8 存储) + # 3) Function returns char (stored as i8) nx: char = bump(ch) stdio.printf("3 char return: %d (expect 66)\n", int(nx)) - # 4) 单字符字面量 'Z' 赋给 char(90) + # 4) Single-char literal 'Z' assigned to char (90) lit: char = 'Z' stdio.printf("4 char literal: %d (expect 90)\n", int(lit)) - # 5) char 参与算术(i8 与 int 混合提升) + # 5) char in arithmetic (i8 promoted when mixed with int) s: int = ch + 1 stdio.printf("5 char arith: %d (expect 66)\n", s) diff --git a/ClosureCallTest/App/main.vp b/ClosureCallTest/App/main.vp index bfd3c87..1ddc770 100644 --- a/ClosureCallTest/App/main.vp +++ b/ClosureCallTest/App/main.vp @@ -3,20 +3,15 @@ import stdio import testcheck -# ============================================================ -# ClosureCallTest - t.CPtr 函数指针调用最小化复现 -# -# closure_test.py 中 f: t.CPtr = make_counter() 后调用 f() 报错: -# Undefined function: 'f' -# 根因:f 是 t.CPtr(i8*),line 322 检查 pointee 是 FunctionType 失败 -# ============================================================ +# ClosureCallTest - minimal repro: call through a t.CPtr function pointer +# f is t.CPtr (i8*); the compiler must treat its pointee as callable. -# nonlocal 关键字测试:嵌套函数修改外层局部变量 +# nonlocal test: a nested function mutates an outer local def make_counter() -> t.CPtr: count: int = 0 - # 内部函数(闭包)捕获 count + # Inner closure captures count def counter() -> int: nonlocal count count = count + 1 @@ -26,7 +21,7 @@ def make_counter() -> t.CPtr: def test_closure_call(): - """验证 t.CPtr 函数指针调用""" + """Verify calling a t.CPtr function pointer.""" testcheck.section("Closure call via t.CPtr") f: t.CPtr = make_counter() v: int = f() diff --git a/ClosureTest/App/main.vp b/ClosureTest/App/main.vp index f5d99bd..cf66f5d 100644 --- a/ClosureTest/App/main.vp +++ b/ClosureTest/App/main.vp @@ -3,7 +3,7 @@ import stdio import testcheck # ============================================================ -# Test 1: global 在嵌套函数中 +# Test 1: global in nested function # ============================================================ g_val: int = 100 @@ -22,7 +22,7 @@ def test_global_in_nested(): testcheck.check(g_val == 150, "global nested (g_val == 150)", "global nested (expect 150)") # ============================================================ -# Test 2: nonlocal 在多层嵌套中 +# Test 2: nonlocal across multiple nesting levels # ============================================================ def test_nonlocal_multi_level(): testcheck.section("Test 2: nonlocal multi-level") @@ -42,7 +42,7 @@ def test_nonlocal_multi_level(): testcheck.check(x == 1111, "nonlocal multi (x == 1111)", "nonlocal multi (expect 1111)") # ============================================================ -# Test 3: global 和 nonlocal 混合 +# Test 3: global and nonlocal mixed # ============================================================ g_mixed: int = 0 @@ -61,7 +61,7 @@ def test_global_nonlocal_mixed(): testcheck.check(g_mixed == 20 and local_var == 40, "mixed (global==20 local==40)", "mixed (expect global=20 local=40)") # ============================================================ -# Test 4: lambda 捕获多个变量 +# Test 4: lambda captures multiple variables # ============================================================ def test_lambda_multi_capture(): testcheck.section("Test 4: lambda multi-capture") @@ -72,7 +72,7 @@ def test_lambda_multi_capture(): testcheck.check(r == 30, "lambda multi-capture (a+b == 30)", "lambda multi-capture (expect 30)") # ============================================================ -# Test 5: lambda 带参数 + 捕获 +# Test 5: lambda with argument + capture # ============================================================ def test_lambda_arg_capture(): testcheck.section("Test 5: lambda arg + capture") @@ -82,7 +82,7 @@ def test_lambda_arg_capture(): testcheck.check(r == 142, "lambda arg+capture (100+42 == 142)", "lambda arg+capture (expect 142)") # ============================================================ -# Test 6: 嵌套函数返回值 +# Test 6: nested function return value # ============================================================ def test_nested_return(): testcheck.section("Test 6: nested function return") @@ -95,7 +95,7 @@ def test_nested_return(): testcheck.check(r == 10 and x == 10, "nested return (r==10 x==10)", "nested return (expect r=10 x=10)") # ============================================================ -# Test 7: nonlocal 与循环变量 +# Test 7: nonlocal with loop variable # ============================================================ def test_nonlocal_loop(): testcheck.section("Test 7: nonlocal with loop") @@ -110,7 +110,7 @@ def test_nonlocal_loop(): testcheck.check(total == 20, "nonlocal loop (total == 20)", "nonlocal loop (expect 20)") # ============================================================ -# Test 8: global 数组操作 +# Test 8: global array operation # ============================================================ g_arr: t.CArray[int, 4] = [0] @@ -125,7 +125,7 @@ def test_global_array(): testcheck.check(total == 100, "global array (total == 100)", "global array (expect 100)") # ============================================================ -# Test 9: 嵌套函数条件调用 +# Test 9: nested function conditional call # ============================================================ def test_nested_conditional(): testcheck.section("Test 9: nested conditional call") @@ -140,7 +140,7 @@ def test_nested_conditional(): testcheck.check(result == 42, "nested conditional (result == 42)", "nested conditional (expect 42)") # ============================================================ -# Test 10: lambda 链式调用 +# Test 10: lambda chained calls # ============================================================ def test_lambda_chain(): testcheck.section("Test 10: lambda chain") diff --git a/ClosureTest2/App/main.vp b/ClosureTest2/App/main.vp index 39ee0e0..a1a9559 100644 --- a/ClosureTest2/App/main.vp +++ b/ClosureTest2/App/main.vp @@ -3,7 +3,7 @@ import stdio import testcheck # ============================================================ -# Test 1: nonlocal 在条件分支中修改 +# Test 1: nonlocal modified in conditional branches # ============================================================ def test_nonlocal_conditional(): testcheck.section("Test 1: nonlocal in conditional branches") @@ -20,7 +20,7 @@ def test_nonlocal_conditional(): testcheck.check(x == 120, "nonlocal conditional (x == 120)", "nonlocal conditional (expect 120)") # ============================================================ -# Test 2: 多个nonlocal变量同时修改 +# Test 2: multiple nonlocal variables modified together # ============================================================ def test_nonlocal_multi_var(): testcheck.section("Test 2: multiple nonlocal variables") @@ -37,7 +37,7 @@ def test_nonlocal_multi_var(): testcheck.check(a == 2 and b == 3 and c_val == 1, "multi nonlocal (a==2 b==3 c==1)", "multi nonlocal (expect 2 3 1)") # ============================================================ -# Test 3: global 在多个函数中交叉修改 +# Test 3: global modified across multiple functions # ============================================================ g_counter: int = 0 @@ -60,7 +60,7 @@ def test_global_cross_functions(): testcheck.check(g_counter == 13, "global cross (g_counter == 13)", "global cross (expect 13)") # ============================================================ -# Test 4: 嵌套函数修改外层局部变量(引用捕获) +# Test 4: nested function modifies outer local (reference capture) # ============================================================ def test_nested_ref_capture(): testcheck.section("Test 4: nested function ref capture") @@ -74,7 +74,7 @@ def test_nested_ref_capture(): testcheck.check(total == 100, "ref capture (total == 100)", "ref capture (expect 100)") # ============================================================ -# Test 5: lambda捕获后修改原变量 +# Test 5: modify original variable after lambda capture # ============================================================ def test_lambda_capture_then_modify(): testcheck.section("Test 5: lambda capture then modify") @@ -86,7 +86,7 @@ def test_lambda_capture_then_modify(): testcheck.check(r1 == 10 and r2 == 10, "lambda value capture (before==10 after==10)", "lambda value capture (expect 10 10)") # ============================================================ -# Test 6: 嵌套函数中nonlocal与循环结合 +# Test 6: nonlocal combined with loop # ============================================================ def test_nonlocal_loop_accumulate(): testcheck.section("Test 6: nonlocal with loop accumulate") @@ -102,7 +102,7 @@ def test_nonlocal_loop_accumulate(): testcheck.check(sum_val == 21 and count == 8, "loop accumulate (sum==21 count==8)", "loop accumulate (expect 21 8)") # ============================================================ -# Test 7: 三层嵌套中每层修改不同变量 +# Test 7: three-level nesting, each level modifies a different var # ============================================================ def test_deep_nested_vars(): testcheck.section("Test 7: deep nested different vars") @@ -125,7 +125,7 @@ def test_deep_nested_vars(): testcheck.check(a == 2 and b == 20 and c_val == 200, "deep nested (a==2 b==20 c==200)", "deep nested (expect 2 20 200)") # ============================================================ -# Test 8: global + nonlocal 在同一嵌套函数中 +# Test 8: global and nonlocal in the same nested function # ============================================================ g_state: int = 0 @@ -144,7 +144,7 @@ def test_global_nonlocal_same_func(): testcheck.check(g_state == 5 and local_state == 10, "global+nonlocal same (g==5 l==10)", "global+nonlocal same (expect 5 10)") # ============================================================ -# Test 9: lambda带默认参数与捕获 +# Test 9: lambda with argument and capture # ============================================================ def test_lambda_default_and_capture(): testcheck.section("Test 9: lambda with arg and capture") @@ -155,7 +155,7 @@ def test_lambda_default_and_capture(): testcheck.check(r1 == 300 and r2 == 500, "lambda arg+capture (100*3==300 100*5==500)", "lambda arg+capture (expect 300 500)") # ============================================================ -# Test 10: 嵌套函数多次调用累积 +# Test 10: nested function accumulates over multiple calls # ============================================================ def test_nested_accumulate(): testcheck.section("Test 10: nested function accumulate") @@ -169,7 +169,7 @@ def test_nested_accumulate(): testcheck.check(total == 60, "nested accumulate (total == 60)", "nested accumulate (expect 60)") # ============================================================ -# Test 11: nonlocal在while循环中 +# Test 11: nonlocal in while loop # ============================================================ def test_nonlocal_while(): testcheck.section("Test 11: nonlocal in while loop") @@ -184,7 +184,7 @@ def test_nonlocal_while(): testcheck.check(result == 15, "nonlocal while (result == 15)", "nonlocal while (expect 15)") # ============================================================ -# Test 12: 嵌套函数修改结构体字段 +# Test 12: nested function modifies struct fields # ============================================================ class Point: x: int diff --git a/DecoratorTest/App/main.vp b/DecoratorTest/App/main.vp index f7f3b14..b0e5603 100644 --- a/DecoratorTest/App/main.vp +++ b/DecoratorTest/App/main.vp @@ -2,22 +2,10 @@ import t from stdio import printf import testcheck -# ============================================================ -# 自定义装饰器处理函数 -# 调用约定 (v4): -# i32 decor_name(i8* ctx, i8* func_name, i32 phase, -# i8* args_ptr, i8* ret_ptr, i8* decor_args_ptr) -# -# ctx: 栈帧局部上下文(32字节),每次调用独立,线程/递归安全 -# args_ptr: 可读写,装饰器可修改函数入参 -# ret_ptr: 后置阶段可读写,装饰器可修改返回值 -# 返回值(前置阶段): -# 0 = 跳过原函数调用 -# 1 = 正常调用一次 -# N = 循环调用 N 次 -# ============================================================ +# Custom decorator handler calling convention (v4): i32 decor(ctx, func_name, phase, args_ptr, ret_ptr, decor_args_ptr). +# ctx: per-call frame-local context (32 bytes); args_ptr/ret_ptr are read-write; pre-phase returns 0=skip, 1=call once, N=loop N. -# @log 装饰器:打印函数进入/退出,返回 1(正常调用一次) +# @log: print enter/exit, return 1 (call once) def log(ctx: t.CPtr, func_name: str, phase: int, args_ptr: t.CPtr, ret_ptr: t.CPtr, @@ -29,7 +17,7 @@ def log(ctx: t.CPtr, func_name: str, phase: int, printf("[LOG] << %s exit\n", func_name) return 0 -# @trace 装饰器:详细追踪 +# @trace: verbose tracing def trace(ctx: t.CPtr, func_name: str, phase: int, args_ptr: t.CPtr, ret_ptr: t.CPtr, @@ -41,10 +29,8 @@ def trace(ctx: t.CPtr, func_name: str, phase: int, printf("[TRACE] %s returned\n", func_name) return 0 -# @timing 装饰器:使用全局变量记录计时 -# 注意:理想情况下应使用 ctx 栈帧局部上下文替代全局变量, -# 但 Viper 当前前端尚不支持 i8* 到 i32* 的指针转型, -# 因此暂时使用全局变量演示计时逻辑 +# @timing: measures elapsed time using a global counter. +# A global is used because i8* to i32* pointer casts are not supported yet. _timing_tmp: int = 0 def timing(ctx: t.CPtr, func_name: str, phase: int, @@ -61,7 +47,7 @@ def timing(ctx: t.CPtr, func_name: str, phase: int, printf("[TIMING] %s took %d ms\n", func_name, elapsed) return 0 -# @repeat 装饰器(带参数,流程劫持):循环调用原函数 N 次 +# @repeat (with args, flow hijack): call the original function N times def repeat(ctx: t.CPtr, func_name: str, phase: int, args_ptr: t.CPtr, ret_ptr: t.CPtr, @@ -73,7 +59,7 @@ def repeat(ctx: t.CPtr, func_name: str, phase: int, printf("[REPEAT] %s all iterations done\n", func_name) return 0 -# @skip 装饰器:跳过原函数调用(流程劫持,返回 0) +# @skip: skip the original call (flow hijack, returns 0) _skip_count: int = 0 def skip(ctx: t.CPtr, func_name: str, phase: int, @@ -89,7 +75,7 @@ def skip(ctx: t.CPtr, func_name: str, phase: int, printf("[SKIP] %s post (ret_ptr=%p)\n", func_name, ret_ptr) return 0 -# @count_calls 装饰器:统计函数被调用次数(递归保护测试用) +# @count_calls: count invocations (used to test recursion guard) _call_count: int = 0 def count_calls(ctx: t.CPtr, func_name: str, phase: int, @@ -106,19 +92,14 @@ def count_calls(ctx: t.CPtr, func_name: str, phase: int, return 0 -# ============================================================ -# 测试 1:单个装饰器 @log -# ============================================================ +# --- Test 1: single @log --- @log def add(a: int, b: int) -> int | t.CExport: return a + b -# ============================================================ -# 测试 2:链式装饰器 @log @trace => log(trace(f)) -# 执行顺序:log_pre → trace_pre → f → trace_post → log_post -# ============================================================ +# --- Test 2: chained @log @trace (log(trace(f))) --- @log @trace @@ -126,45 +107,35 @@ def multiply(a: int, b: int) -> int | t.CExport: return a * b -# ============================================================ -# 测试 3:装饰器修饰 void 返回函数 -# ============================================================ +# --- Test 3: @log on void function --- @log def greet(name: str) -> void | t.CExport: printf("Hello, %s!\n", name) -# ============================================================ -# 测试 4:装饰器修饰无参数函数 -# ============================================================ +# --- Test 4: @log on no-arg function --- @log def get_value() -> int | t.CExport: return 42 -# ============================================================ -# 测试 5:@timing 装饰器 -# ============================================================ +# --- Test 5: @timing --- @timing export def compute(x: int) -> int: return x * x + 1 -# ============================================================ -# 测试 6:带参数装饰器 @repeat(3) — 流程劫持,循环调用 3 次 -# ============================================================ +# --- Test 6: @repeat(3) flow hijack --- @repeat(3) export def echo(msg: str): printf(" echo: %s\n", msg) -# ============================================================ -# 测试 7:链式 @timing @log -# ============================================================ +# --- Test 7: chained @timing @log --- @timing @log @@ -175,9 +146,7 @@ export def power(base: int, exp: int) -> int: return result -# ============================================================ -# 测试 8:@skip 装饰器 — 流程劫持,跳过原函数调用 -# ============================================================ +# --- Test 8: @skip flow hijack --- @skip def dangerous() -> int | t.CExport: @@ -185,9 +154,7 @@ def dangerous() -> int | t.CExport: return 999 -# ============================================================ -# 测试 9:@repeat(3) 修饰有返回值的函数 -# ============================================================ +# --- Test 9: @repeat(3) with return value --- @repeat(3) def accumulate(x: int) -> int | t.CExport: @@ -195,11 +162,7 @@ def accumulate(x: int) -> int | t.CExport: return x * 10 -# ============================================================ -# 测试 10:递归装饰保护 — @count_calls 修饰递归函数 -# v4 递归保护:最外层 wrapper 检查全局标志位, -# 递归调用时跳过所有装饰逻辑,仅最外层调用触发装饰器 -# ============================================================ +# --- Test 10: recursion guard, @count_calls on recursive fn --- @count_calls def factorial(n: int) -> int | t.CExport: @@ -208,10 +171,7 @@ def factorial(n: int) -> int | t.CExport: return n * factorial(n - 1) -# ============================================================ -# 测试 11:@log 修饰递归函数 — 验证递归保护 -# 递归保护确保只有最外层调用打印 LOG,内部递归不触发 -# ============================================================ +# --- Test 11: @log on recursive fib --- @log def fib(n: int) -> int | t.CExport: @@ -220,66 +180,64 @@ def fib(n: int) -> int | t.CExport: return fib(n - 1) + fib(n - 2) -# ============================================================ -# 主函数 -# ============================================================ +# --- main --- def main() -> int | t.CExport: testcheck.begin("Decorator Test v4") - # 测试 1:单个 @log + # Test 1: single @log testcheck.section("Test 1: single @log") r1: int = add(3, 4) printf("add(3,4) = %d\n", r1) testcheck.check(r1 == 7, "add(3,4) = 7", "add(3,4) expect 7") - # 测试 2:链式 @log @trace + # Test 2: chained @log @trace testcheck.section("Test 2: chained @log @trace") r2: int = multiply(5, 6) printf("multiply(5,6) = %d\n", r2) testcheck.check(r2 == 30, "multiply(5,6) = 30", "multiply(5,6) expect 30") - # 测试 3:void 返回 + # Test 3: void return testcheck.section("Test 3: @log on void function") greet("Viper") testcheck.ok("@log on void function greet") - # 测试 4:无参数 + # Test 4: no arguments testcheck.section("Test 4: @log on no-arg function") r4: int = get_value() printf("get_value() = %d\n", r4) testcheck.check(r4 == 42, "get_value() = 42", "get_value() expect 42") - # 测试 5:@timing + # Test 5: @timing testcheck.section("Test 5: @timing") r5: int = compute(7) printf("compute(7) = %d\n", r5) testcheck.check(r5 == 50, "compute(7) = 50", "compute(7) expect 50") - # 测试 6:@repeat(3) — 流程劫持,循环 3 次 + # Test 6: @repeat(3) flow hijack, loops 3 times testcheck.section("Test 6: @repeat(3) flow hijack") echo("hello") testcheck.ok("@repeat(3) flow hijack echo") - # 测试 7:链式 @timing @log + # Test 7: chained @timing @log testcheck.section("Test 7: chained @timing @log") r7: int = power(2, 10) printf("power(2,10) = %d\n", r7) testcheck.check(r7 == 1024, "power(2,10) = 1024", "power(2,10) expect 1024") - # 测试 8:@skip — 跳过原函数调用 + # Test 8: @skip, skips the original call testcheck.section("Test 8: @skip flow hijack") r8: int = dangerous() printf("dangerous() = %d (should be 0, skipped)\n", r8) testcheck.check(r8 == 0, "dangerous() skipped = 0", "dangerous() expect 0") - # 测试 9:@repeat(3) 有返回值 + # Test 9: @repeat(3) with return value testcheck.section("Test 9: @repeat(3) with return value") r9: int = accumulate(5) printf("accumulate(5) = %d (last iteration result)\n", r9) testcheck.check(r9 == 50, "accumulate(5) = 50", "accumulate(5) expect 50") - # 测试 10:递归装饰保护 — @count_calls + # Test 10: recursion guard, @count_calls testcheck.section("Test 10: recursive decoration protection") global _call_count _call_count = 0 @@ -288,7 +246,7 @@ def main() -> int | t.CExport: printf(" decorator call count = %d (should be 1, not 5)\n", _call_count) testcheck.check(r10 == 120 and _call_count == 1, "factorial(5)=120, calls=1", "factorial(5) expect 120, calls=1") - # 测试 11:@log 递归保护 — fib + # Test 11: @log recursion guard, fib testcheck.section("Test 11: @log on recursive fib") r11: int = fib(6) printf("fib(6) = %d (should be 8)\n", r11) diff --git a/DefaultArgTest/App/main.vp b/DefaultArgTest/App/main.vp index 02df278..bbb27ba 100644 --- a/DefaultArgTest/App/main.vp +++ b/DefaultArgTest/App/main.vp @@ -5,12 +5,12 @@ import remote import random -# 同模块:单个尾随默认值 +# Same module: single trailing default def local_one(x: int, cap: sizet = 4096) -> sizet: return cap -# 同模块:多个尾随默认值 +# Same module: multiple trailing defaults def local_quad(a: int, b: int = 10, c: int = 20, d: int = 30) -> int: return a + b * 100 + c * 10000 + d * 1000000 @@ -18,26 +18,26 @@ def local_quad(a: int, b: int = 10, c: int = 20, d: int = 30) -> int: def main() -> int: testcheck.begin("DefaultArgTest: default / named / out-of-order arguments") - # ① 同模块默认值 + # Same-module defaults testcheck.section("same-module defaults") r1: sizet = local_one(1) testcheck.check(r1 == 4096, "local_one(1) cap = 4096", "local_one(1) cap != 4096") r2: int = local_quad(1) testcheck.check(r2 == 30201001, "local_quad(1) = 30201001", "local_quad(1) != 30201001") - # ② 跨模块默认值 + # Cross-module defaults testcheck.section("cross-module defaults") r3: sizet = remote.one(1) testcheck.check(r3 == 4096, "remote.one(1) cap = 4096", "remote.one(1) cap != 4096") r4: sizet = remote.write(1, 2, False) testcheck.check(r4 == 4096, "remote.write(1,2,False) cap = 4096", "remote.write(1,2,False) cap != 4096") - # ③ 显式覆盖默认值 + # Explicit override testcheck.section("explicit override") r5: sizet = remote.one(1, 8) testcheck.check(r5 == 8, "remote.one(1,8) cap = 8", "remote.one(1,8) cap != 8") - # ④ 命名 / 乱序传参 + # Named / out-of-order arguments testcheck.section("named / out-of-order arguments") r6: sizet = remote.one(cap = 8, x = 1) testcheck.check(r6 == 8, "remote.one(cap = 8, x = 1) = 8", "remote.one(cap = 8, x = 1) != 8") @@ -48,7 +48,7 @@ def main() -> int: r9: int = remote.many(z = 3, x = 1, y = 2) testcheck.check(r9 == 9, "remote.many(z = 3, x = 1, y = 2) = 9", "remote.many(z = 3, x = 1, y = 2) != 9") - # ⑤ 多个尾随默认值只给前几个 + # Multiple trailing defaults: pass only the leading ones testcheck.section("partial trailing defaults") r10: int = local_quad(1, 2) testcheck.check(r10 == 30200201, "local_quad(1,2) = 30200201", "local_quad(1,2) != 30200201") @@ -61,8 +61,8 @@ def main() -> int: r14: int = remote.quad(1) testcheck.check(r14 == 30201001, "remote.quad(1) = 30201001", "remote.quad(1) != 30201001") - # ⑥ include 模块(顶层 .vp)默认值:vrandom.randrange(start, stop, step = 1) - # stop-start==1 ⇒ width==1 ⇒ 结果恒为 start;step 未填充时会退化为 0/垃圾 + # Include-module (top-level .vp) defaults: vrandom.randrange(start, stop, step = 1) + # stop-start==1 means width==1, so result is always start; unset step degrades to 0/garbage testcheck.section("include-module defaults") r15: int = random.randrange(5, 6) testcheck.check(r15 == 5, "vrandom.randrange(5,6) = 5 (step default)", "vrandom.randrange(5,6) != 5") diff --git a/DefaultArgTest/App/remote.vp b/DefaultArgTest/App/remote.vp index c93ac60..9b77b6d 100644 --- a/DefaultArgTest/App/remote.vp +++ b/DefaultArgTest/App/remote.vp @@ -1,21 +1,21 @@ import t -# 跨模块:单个尾随默认值(对照 includes/json/__writer.vp 的 write 形态) +# Cross-module: single trailing default (mirrors write in includes/json/__writer.vp) def one(x: int, cap: sizet = 4096) -> sizet: return cap -# 跨模块:4 参、最后一个有默认值(与 json.write(pool, val, pretty, cap=4096) 同形) +# Cross-module: 4 params, last has a default (same shape as json.write(pool, val, pretty, cap=4096)) def write(a: int, b: int, pretty: bool, cap: sizet = 4096) -> sizet: return cap -# 跨模块:多个尾随默认值 +# Cross-module: multiple trailing defaults def quad(a: int, b: int = 10, c: int = 20, d: int = 30) -> int: return a + b * 100 + c * 10000 + d * 1000000 -# 跨模块:乱序/命名传参(wiki 04-functions.md 的 add 形态) +# Cross-module: named / out-of-order args (add shape in wiki 04-functions.md) def many(x: int, y: int, z: int = 1) -> int: return (x + y) * z diff --git a/DefineTest/App/main.vp b/DefineTest/App/main.vp index edbd688..a6a12f3 100644 --- a/DefineTest/App/main.vp +++ b/DefineTest/App/main.vp @@ -8,11 +8,8 @@ import testcheck # ============================================================ -# DefineTest - CDefine 宏 / c.CIf / platmacro 专项测试 -# -# 从 TestProject3/App/definetest.vp 独立提取。 -# 验证: CDefine 常量、宏函数、c.CIf/c.CIfdef/c.CIfndef、 -# platmacro 平台宏(输出以 print 为准,人工核对)。 +# DefineTest: CDefine constants/macros, c.CIf family, platmacro. +# Prints results for manual inspection. # ============================================================ diff --git a/DictTest/App/main.vp b/DictTest/App/main.vp index b5f3cb4..126b17b 100644 --- a/DictTest/App/main.vp +++ b/DictTest/App/main.vp @@ -15,11 +15,11 @@ def main() -> CInt | CExport: testcheck.begin("DictTest: 万能 dict (Variant 存储) 测试") - # 分配内存竞技场 + # allocate memory arena arena: bytes = stdlib.malloc(65536) bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536) - # === Test 1: dict set_int / c.Deref 基本操作 === + # === Test 1: dict set_int / c.Deref basic ops === testcheck.section("Test 1: dict set_int / c.Deref 基本操作") d: dict = dict(bd) d.set_int("alpha", 10) @@ -29,9 +29,8 @@ def main() -> CInt | CExport: stdio.printf("len=%lu\n", n) testcheck.check(n == 3, "dict len OK (3)", "dict len FAILED") - # dict 的 int 值按 int(i32)写入(见 _dict.vp set_int 的 int_ptr),读回须 - # 给出有元素类型的指针:c.Deref 的宽度只认 pointee 类型,i8*(t.CPtr)恒读 - # 1 字节,不再按赋值目标注解反推 4 字节。 + # dict int values are stored as i32; reading back requires a typed pointer + # because c.Deref uses the pointee width (i8* always reads 1 byte). p1: t.CPtr = d["alpha"] stdio.printf("p1=%p\n", p1) p2: t.CPtr = d["beta"] @@ -47,7 +46,7 @@ def main() -> CInt | CExport: testcheck.check(v2 == 20, "dict[beta]==20 OK", "dict[beta] FAILED") testcheck.check(v3 == 30, "dict[gamma]==30 OK", "dict[gamma] FAILED") - # === Test 2: 更新已有键 === + # === Test 2: update existing key === testcheck.section("Test 2: 更新已有键") d.set_int("beta", 99) p2b: t.CPtr = d["beta"] @@ -74,7 +73,7 @@ def main() -> CInt | CExport: testcheck.check(has_alpha == 1, "contains alpha OK", "contains alpha FAILED") testcheck.check(has_missing == 0, "not contains missing OK", "contains missing FAILED") - # === Test 5: 迭代器 === + # === Test 5: iterator === testcheck.section("Test 5: 迭代器 for key in dict") iter_count: int = 0 for key in d: @@ -84,7 +83,7 @@ def main() -> CInt | CExport: iter_count += 1 testcheck.check(iter_count == 3, "dict iter OK (3)", "dict iter FAILED") - # === Test 6: dict set_str 字符串值 === + # === Test 6: dict set_str string values === testcheck.section("Test 6: dict set_str 字符串值") d2: dict = dict(bd) d2.set_str("name", "Alice") @@ -101,12 +100,12 @@ def main() -> CInt | CExport: city: str = city_p lang: str = lang_p stdio.printf("name=%s city=%s lang=%s\n", name, city, lang) - # i8* == 是指针地址比较(C-Like 语义),内容比较需显式 strcmp + # i8* == compares addresses (C-like); content compare needs strcmp testcheck.check(string.strcmp(name, "Alice") == 0, "dict str name OK", "dict str name FAILED") testcheck.check(string.strcmp(city, "Beijing") == 0, "dict str city OK", "dict str city FAILED") testcheck.check(string.strcmp(lang, "TransPyC") == 0, "dict str lang OK", "dict str lang FAILED") - # === Test 7: dict[str] 迭代 === + # === Test 7: dict[str] iteration === testcheck.section("Test 7: dict 迭代 (str values)") str_iter_count: int = 0 for k in d2: @@ -116,7 +115,7 @@ def main() -> CInt | CExport: str_iter_count += 1 testcheck.check(str_iter_count == 3, "dict str iter OK (3)", "dict str iter FAILED") - # === Test 8: 扩容测试 === + # === Test 8: expansion (>8 elements) === testcheck.section("Test 8: 扩容测试 (>8 个元素)") d3: dict = dict(bd) for i in range(20): @@ -127,7 +126,7 @@ def main() -> CInt | CExport: stdio.printf("d3 len=%lu (after 20 inserts)\n", n3) testcheck.check(n3 == 20, "dict expand OK (20)", "dict expand FAILED") - # 验证几个值 + # verify a few values k5: str = stdlib.malloc(16) stdio.sprintf(k5, "key5") p5: t.CPtr = d3[k5] @@ -198,7 +197,7 @@ def main() -> CInt | CExport: testcheck.check(rta == 1, "round-trip a OK", "round-trip a FAILED") testcheck.check(rtb == 2, "round-trip b OK", "round-trip b FAILED") - # === Test 13: 嵌套 dict === + # === Test 13: nested dict === testcheck.section("Test 13: 嵌套 dict") outer: dict = dict(bd) inner: dict = dict(bd) @@ -215,7 +214,7 @@ def main() -> CInt | CExport: testcheck.check(sa == 1, "nested sub.a OK", "nested sub.a FAILED") testcheck.check(sb == 2, "nested sub.b OK", "nested sub.b FAILED") - # === Test 14: get_vtype 类型标签 === + # === Test 14: get_vtype type tag === testcheck.section("Test 14: get_vtype 类型标签") vt1: int = d.get_vtype("alpha") vt2: int = d2.get_vtype("name") diff --git a/DocTest/App/main.vp b/DocTest/App/main.vp index 5dbf976..05aae5a 100644 --- a/DocTest/App/main.vp +++ b/DocTest/App/main.vp @@ -6,18 +6,18 @@ import testcheck import remote -# 同模块函数(有 docstring) +# Same-module function (has docstring). def local_func() -> int: "Local function docstring." return 0 -# 同模块函数(无 docstring) +# Same-module function (no docstring). def no_doc_func() -> int: return 0 -# 同模块类(有 docstring) +# Same-module class (has docstring). class LocalClass: "Local class docstring." value: int @@ -28,7 +28,7 @@ class LocalClass: def _check_doc_adaptive(name: str, doc: str, expected: str): - """自适应检查 docstring:非空时验证匹配,空时视为优化剥离""" + """Check docstring: verify when present, treat null as optimized out.""" if doc is None: testcheck.ok(f"{name}: __doc__ optimized out (null)") return @@ -39,7 +39,7 @@ def _check_doc_adaptive(name: str, doc: str, expected: str): def _check_doc_null(name: str, doc: str): - """检查 docstring 为 null(无 docstring 的符号)""" + """Check that a symbol's docstring is null.""" if doc is None: testcheck.ok(f"{name}: __doc__ is null") else: diff --git a/EdgeCaseTest/App/main.vp b/EdgeCaseTest/App/main.vp index 977a363..209f80b 100644 --- a/EdgeCaseTest/App/main.vp +++ b/EdgeCaseTest/App/main.vp @@ -45,10 +45,8 @@ renum Opt: None_ = 0 -# ============================================================ -# Test 5: 前向引用检测 — _class_graph 正确识别父类 -# (注:检测已修复,但成员继承仍需父类先处理) -# ============================================================ +# Test 5: forward reference detection - _class_graph resolves the base class. +# Member inheritance still requires the base class to be processed first. class Parent: a: int @@ -63,9 +61,7 @@ class Child(Parent): return self.a + self.b -# ============================================================ -# Test 6: 多层继承 A -> B -> C,CVTable 向上传播 -# ============================================================ +# Test 6: multi-level inheritance A -> B -> C, CVTable propagates upward class Base: x: int @@ -87,24 +83,18 @@ class Leaf(Mid): return self.z -# ============================================================ -# Test 7: 类型别名用于注解 -# ============================================================ +# Test 7: type alias in annotation val: myint = 42 -# ============================================================ -# Test 8: BigEndian 字节序 -# ============================================================ +# Test 8: BigEndian byte order class NetHeader: magic: int | t.BigEndian length: t.CShort | t.BigEndian normal: int -# ============================================================ -# Test 9: import t as tt; tt.CInt 作为类型注解 -# ============================================================ +# Test 9: import t as tt; tt.CInt as type annotation # class TtStruct: # x: tt.CInt # y: tt.CFloat @@ -118,9 +108,7 @@ class TtPoint: y: int -# ============================================================ -# Test 11: import t as tt; @tt.Object 装饰器 -# ============================================================ +# Test 11: import t as tt; @tt.Object decorator class TtObject: val: int diff --git a/EqTest/App/main.vp b/EqTest/App/main.vp index 8758e4a..6403cd5 100644 --- a/EqTest/App/main.vp +++ b/EqTest/App/main.vp @@ -14,12 +14,12 @@ def main() -> CInt | CExport: testcheck.begin("== 重载和 is 地址比较测试") - # === Test 1: str == str 值比较 === + # === Test 1: str == str value compare === testcheck.section("Test 1: str == str 值比较") s1: str = "hello" s2: str = "hello" s3: str = "world" - # i8* == 是指针地址比较(C-Like 语义),内容比较需显式 strcmp + # i8* == compares addresses (C-like); use strcmp for content compare testcheck.check(string.strcmp(s1, s2) == 0, "str == str (same value) OK", "str == str (same value) FAILED") testcheck.check(string.strcmp(s1, s3) != 0, "str != str (diff value) OK", "str != str (diff value) FAILED") @@ -28,16 +28,16 @@ def main() -> CInt | CExport: testcheck.check(string.strcmp(s1, s3) != 0, "str != str (diff) OK", "str != str (diff) FAILED") testcheck.check(string.strcmp(s1, s2) == 0, "str == str (same) via != OK", "str == str (same) via != FAILED") - # === Test 3: str == 字面量 === + # === Test 3: str == literal === testcheck.section("Test 3: str == literal") testcheck.check(string.strcmp(s1, "hello") == 0, "str == literal OK", "str == literal FAILED") testcheck.check(string.strcmp(s1, "world") != 0, "str != literal OK", "str != literal FAILED") - # === Test 4: str is str 地址比较 === + # === Test 4: str is str address compare === testcheck.section("Test 4: str is str address compare") - # s1 和 s2 是不同的字符串变量,地址不同 + # s1 and s2 are distinct variables with different addresses testcheck.check(not (s1 is s2), "str is str (diff addr) OK", "str is str (diff addr) FAILED") - # s1 is s1 应该为 True(同一变量) + # s1 is s1 is True (same variable) testcheck.check(s1 is s1, "str is self OK", "str is self FAILED") # === Test 5: int == int === @@ -48,32 +48,32 @@ def main() -> CInt | CExport: testcheck.check(i1 == i2, "int == int (same) OK", "int == int (same) FAILED") testcheck.check(not (i1 == i3), "int != int (diff) OK", "int != int (diff) FAILED") - # === Test 6: None 比较 === + # === Test 6: None compare === testcheck.section("Test 6: None compare") null_ptr: str = None testcheck.check(null_ptr == None, "ptr == None OK", "ptr == None FAILED") testcheck.check(not (s1 == None), "str != None OK", "str != None FAILED") - # === Test 7: 整型 vs None(整数上的 None 隐式为 0)=== - # 语义(TPC / TPV 统一):x is None ≡ x == None ≡ x == 0;x is not None ≡ x != None ≡ x != 0 + # === Test 7: int vs None (None on int is implicitly 0) === + # Unified semantics: x is None, x == None and x == 0 agree (and negations) testcheck.section("Test 7: int vs None") nz: int = 7 zr: int = 0 - # 非零整数 ⇒ 不等于 None + # nonzero int => not None testcheck.check(not (nz is None), "int(7) is None -> false OK", "int(7) is None FAILED") testcheck.check(nz is not None, "int(7) is not None -> true OK", "int(7) is not None FAILED") testcheck.check(not (nz == None), "int(7) == None -> false OK", "int(7) == None FAILED") testcheck.check(nz != None, "int(7) != None -> true OK", "int(7) != None FAILED") - # 零值 ⇒ 等价于 None + # zero => equivalent to None testcheck.check(zr is None, "int(0) is None -> true OK", "int(0) is None FAILED") testcheck.check(not (zr is not None), "int(0) is not None -> false OK", "int(0) is not None FAILED") testcheck.check(zr == None, "int(0) == None -> true OK", "int(0) == None FAILED") testcheck.check(not (zr != None), "int(0) != None -> false OK", "int(0) != None FAILED") - # None 在左侧的镜像方向(TPV 此前该方向分支有误,恒判相等) + # mirrored None-on-left direction testcheck.check(not (None is nz), "None is int(7) -> false OK", "None is int(7) FAILED") testcheck.check(None is zr, "None is int(0) -> true OK", "None is int(0) FAILED") - # === Test 8: 其它整型位宽 vs None(i8 / i64,防"从空指针 load"回归)=== + # === Test 8: other int widths vs None (i8/i64, guards null-pointer load) === testcheck.section("Test 8: char / sizet vs None") c8: char = 0 c8nz: char = 65 diff --git a/ExpandKeywordsTest/App/main.vp b/ExpandKeywordsTest/App/main.vp index f9eadab..deaffe5 100644 --- a/ExpandKeywordsTest/App/main.vp +++ b/ExpandKeywordsTest/App/main.vp @@ -5,50 +5,50 @@ import testcheck # ============================================================ -# ExpandKeywordsTest - 验证 def 别名关键字 fn/fun/func/function -# 语义与 def 完全相同(定义/调用/嵌套/泛型/空函数体) +# ExpandKeywordsTest - verify def alias keywords fn/fun/func/function; +# identical semantics to def (define/call/nest/generic/empty body). # ============================================================ -# fn: 单参数返回 +# fn: single argument, returns value fn add_one(x: int) -> int: return x + 1 -# fun: 双参数返回 +# fun: two arguments, returns value fun add_two(a: int, b: int) -> int: return a + b -# func: 浮点参数返回 +# func: float arguments func mul_float(a: double, b: double) -> double: return a * b -# function: 内部用 def 定义再调用(别名与 def 混用) +# function: defines and calls an inner def (alias mixed with def) function get_ten() -> int: def inner() -> int: return 10 return inner() -# fn 泛型(PEP 695 风格类型参数) +# fn generic (PEP 695 style type parameters) fn ident[T](x: T) -> T: return x -# fn 空函数体(pass) +# fn empty body (pass) fn noop(): pass -# fun 递归 +# fun recursion fun fact(n: int) -> int: if n <= 1: return 1 return n * fact(n - 1) -# func 多语句 + 局部变量 +# func multiple statements + local variable func avg3(a: double, b: double, c: double) -> double: total: double = a + b + c return total / 3.0 diff --git a/Extern2Test/App/main.vp b/Extern2Test/App/main.vp index 33f6209..014c790 100644 --- a/Extern2Test/App/main.vp +++ b/Extern2Test/App/main.vp @@ -3,33 +3,27 @@ import stdio import testcheck -# ============================================================ -# Extern2Test - ExternalDecl/StateDecl 重定义错误最小化复现 -# -# 在 TransPyV Test 的 deco_test.py 中,这三个声明在生成的 .ll 中 -# 被声明两次(line 56-60 和 62-66),导致 llc 报错: -# llc.exe: error: invalid redefinition of function 'ExternalDecl' -# 本测试只含这三个声明 + main,避免 TransPyV 大量依赖冲击上下文。 -# ============================================================ +# Extern2Test - minimal repro: ExternalDecl/StateDecl redefinition +# Three declarations plus main; each must emit exactly one declare. -# Test 1: t.CExtern | t.CExport - 外部声明函数(pass 体) -# 声明一个外部函数,翻译器应生成 declare 而非 define +# Test 1: t.CExtern | t.CExport - external declaration (pass body) +# Translator must emit declare, not define. def ExternalDecl(x: int) -> int | t.CExtern | t.CExport: pass -# Test 2: t.State - 状态声明(等价于 CExtern | CExport) +# Test 2: t.State - state declaration (same as CExtern | CExport) def StateDecl(x: int) -> int | t.State: pass -# Test 3: t.State 返回 void +# Test 3: t.State returning void def StateVoidDecl() -> t.State: pass def test_extern_decl(): - """验证三个 extern 声明只生成一次 declare,不重复""" + """Verify the three extern declarations emit declare only once.""" testcheck.section("Extern/State declarations (no duplicate)") - # 外部声明函数,不调用(应由链接器解析符号) + # External declarations are not called; the linker resolves the symbols. testcheck.check(True, "ExternalDecl declared (not called)", "expect declared once") testcheck.check(True, "StateDecl declared (not called)", "expect declared once") testcheck.check(True, "StateVoidDecl declared (not called)", "expect declared once") diff --git a/FakeDuckTest/App/main.vp b/FakeDuckTest/App/main.vp index 091d552..01067e1 100644 --- a/FakeDuckTest/App/main.vp +++ b/FakeDuckTest/App/main.vp @@ -15,10 +15,10 @@ def main() -> CInt | CExport: w32.win32console.SetConsoleCP(65001) w32.win32console.SetConsoleOutputCP(65001) - # FakeDuck 测试: str 类型调用扩展方法 b() + # FakeDuck: str calls extension method b() a: str = "Hello" - # Type 通用基类测试: str 变量调用 Type 的方法 type_id() + # Type base class: str calls Type.type_id() tid: CInt = a.type_id() if tid == 99: @@ -26,57 +26,57 @@ def main() -> CInt | CExport: else: stdio.printf("Type FAIL: a.type_id() = %d\n", tid) - # 直接字段访问测试: 读取 a.__data__ (应等于 a 本身) + # Direct field read: a.__data__ (equals a itself) data_ptr: str = a.__data__ stdio.printf("a.__data__ = %s\n", data_ptr) - # upper() 测试: 通过 mbuddy 分配内存,返回大写字符串 + # upper(): allocates via mbuddy, returns uppercased string arena: bytes = stdlib.malloc(65536) bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536) - # 直接字段赋值: a.__mbuddy__ = bd (语法糖, 等价于 a.set_mbuddy(bd)) + # Direct field write: a.__mbuddy__ = bd (sugar for a.set_mbuddy(bd)) a.__mbuddy__ = bd upper_str: str = a.upper() stdio.printf("upper('Hello') = %s\n", upper_str) - # 验证 per-instance 不污染: b 没有设置 __mbuddy__ (初始为 NULL) + # Verify per-instance isolation: b has no __mbuddy__ (NULL) b: str = "World" - # 直接字段读取: b.__mbuddy__ (应返回 NULL) + # Direct field read: b.__mbuddy__ (returns NULL) b_buddy: memhub.MemBuddy* = b.__mbuddy__ if int(b_buddy) == 0: stdio.printf("mbuddy OK: b.__mbuddy__ is NULL (no pollution)\n") else: stdio.printf("mbuddy FAIL: b.__mbuddy__ polluted!\n") - # b 也设置 mbuddy 并 upper + # Set mbuddy on b and run upper() b.__mbuddy__ = bd upper_b: str = b.upper() stdio.printf("upper('World') = %s\n", upper_b) - # lower() 测试 + # lower() lower_str: str = a.lower() stdio.printf("lower('Hello') = %s\n", lower_str) - # capitalize() 测试 + # capitalize() cap_str: str = a.capitalize() stdio.printf("capitalize('Hello') = %s\n", cap_str) - # swapcase() 测试 + # swapcase() swap_str: str = a.swapcase() stdio.printf("swapcase('Hello') = %s\n", swap_str) - # casefold() 测试 + # casefold() cf_str: str = a.casefold() stdio.printf("casefold('Hello') = %s\n", cf_str) - # title() 测试 + # title() t_str: str = "hello world" t_str.__mbuddy__ = bd title_result: str = t_str.title() stdio.printf("title('hello world') = %s\n", title_result) - # 布尔判断函数测试 (不需要 __mbuddy__) + # Predicate methods (no __mbuddy__ needed) u: str = "HELLO" lo: str = "hello" dig: str = "12345" @@ -101,10 +101,10 @@ def main() -> CInt | CExport: stdio.printf("istitle('Hello World') = %d\n", title_s.istitle()) stdio.printf("istitle('hello world') = %d\n", t_str.istitle()) - # === split() 测试 === + # --- split() --- testcheck.begin("FakeDuck split() 测试") - # Test 1: 基本分割 + # Test 1: basic split testcheck.section("Test 1: 基本分割 'a,b,c'") s1: str = "a,b,c" s1.__mbuddy__ = bd @@ -120,7 +120,7 @@ def main() -> CInt | CExport: testcheck.check(string.strcmp(p1, "b") == 0, "split[1]=='b' OK", "split[1] FAILED") testcheck.check(string.strcmp(p2, "c") == 0, "split[2]=='c' OK", "split[2] FAILED") - # Test 2: 空字符串分割 + # Test 2: no delimiter testcheck.section("Test 2: 无分隔符 'hello'") s2: str = "hello" s2.__mbuddy__ = bd @@ -131,7 +131,7 @@ def main() -> CInt | CExport: h0: str = parts2.get(0) testcheck.check(string.strcmp(h0, "hello") == 0, "no-delim[0]=='hello' OK", "no-delim[0] FAILED") - # Test 3: 连续分隔符 + # Test 3: consecutive delimiters testcheck.section("Test 3: 连续分隔符 'a,,b'") s3: str = "a,,b" s3.__mbuddy__ = bd @@ -147,7 +147,7 @@ def main() -> CInt | CExport: testcheck.check(string.strcmp(e1, "") == 0, "consec[1]=='' OK", "consec[1] FAILED") testcheck.check(string.strcmp(e2, "b") == 0, "consec[2]=='b' OK", "consec[2] FAILED") - # Test 4: 空字符串 + # Test 4: empty string testcheck.section("Test 4: 空字符串 ''") s4: str = "" s4.__mbuddy__ = bd @@ -156,7 +156,7 @@ def main() -> CInt | CExport: stdio.printf("split('', ',') len=%lu\n", n4) testcheck.check(n4 == 1, "empty len OK (1)", "empty len FAILED expect 1") - # Test 5: 空格分割句子 + # Test 5: split on space testcheck.section("Test 5: 空格分割 'hello world foo'") s5: str = "hello world foo" s5.__mbuddy__ = bd @@ -172,7 +172,7 @@ def main() -> CInt | CExport: testcheck.check(string.strcmp(w1, "world") == 0, "space[1]=='world' OK", "space[1] FAILED") testcheck.check(string.strcmp(w2, "foo") == 0, "space[2]=='foo' OK", "space[2] FAILED") - # Test 6: 多字符分隔符 '::' + # Test 6: multi-char delimiter '::' testcheck.section("Test 6: 多字符分隔符 '::' on 'a::b::c'") s6: str = "a::b::c" s6.__mbuddy__ = bd @@ -188,7 +188,7 @@ def main() -> CInt | CExport: testcheck.check(string.strcmp(m1, "b") == 0, "multi-colon[1]=='b' OK", "multi-colon[1] FAILED") testcheck.check(string.strcmp(m2, "c") == 0, "multi-colon[2]=='c' OK", "multi-colon[2] FAILED") - # Test 7: 多字符分隔符 ', ' (逗号+空格) + # Test 7: multi-char delimiter ', ' testcheck.section("Test 7: 多字符分隔符 ', ' on 'hello, world, foo'") s7: str = "hello, world, foo" s7.__mbuddy__ = bd @@ -204,7 +204,7 @@ def main() -> CInt | CExport: testcheck.check(string.strcmp(cs1, "world") == 0, "comma-space[1]=='world' OK", "comma-space[1] FAILED") testcheck.check(string.strcmp(cs2, "foo") == 0, "comma-space[2]=='foo' OK", "comma-space[2] FAILED") - # Test 8: 多字符分隔符在首尾 + # Test 8: delimiter at edges testcheck.section("Test 8: 多字符分隔符首尾 '::a::b::'") s8: str = "::a::b::" s8.__mbuddy__ = bd @@ -222,43 +222,43 @@ def main() -> CInt | CExport: testcheck.check(string.strcmp(ed2, "b") == 0, "edge[2]=='b' OK", "edge[2] FAILED") testcheck.check(string.strcmp(ed3, "") == 0, "edge[3]=='' OK", "edge[3] FAILED") - # === with 上下文自动注入测试 === + # --- with-context auto injection --- testcheck.section("Test 9: with 上下文自动注入 __mbuddy__") arena2: bytes = stdlib.malloc(65536) with memhub.MemBuddy(arena2, 65536) as bd2: - # str 变量在 with 上下文内创建,__mbuddy__ 应自动注入(无需手动赋值) + # str created in with-block gets __mbuddy__ injected automatically w_str: str = "WithTest" - # 验证 __mbuddy__ 已自动注入(非 NULL) + # Verify __mbuddy__ is injected (non-NULL) w_buddy: memhub.MemBuddy* = w_str.__mbuddy__ testcheck.check(int(w_buddy) != 0, "with inject OK: __mbuddy__ auto-injected", "with inject FAIL: __mbuddy__ is NULL") - # upper() 不需要手动设置 __mbuddy__ + # upper() needs no manual __mbuddy__ w_upper: str = w_str.upper() stdio.printf("with upper('WithTest') = %s\n", w_upper) testcheck.check(string.strcmp(w_upper, "WITHTEST") == 0, "with upper OK", "with upper FAILED") - # lower() 不需要手动设置 __mbuddy__ + # lower() needs no manual __mbuddy__ w_lower: str = w_str.lower() stdio.printf("with lower('WithTest') = %s\n", w_lower) testcheck.check(string.strcmp(w_lower, "withtest") == 0, "with lower OK", "with lower FAILED") - # split() 不需要手动设置 __mbuddy__ + # split() needs no manual __mbuddy__ w_split_str: str = "x,y,z" w_parts = w_split_str.split(',') w_n: sizet = len(w_parts) stdio.printf("with split('x,y,z') len=%lu\n", w_n) testcheck.check(w_n == 3, "with split len OK (3)", "with split len FAILED") - # 验证多个 str 变量都获得注入 + # Verify multiple str vars all get injection w_str2: str = "Multiple" w_buddy2: memhub.MemBuddy* = w_str2.__mbuddy__ testcheck.check(int(w_buddy2) != 0, "with multi inject OK", "with multi inject FAIL") test_s: str = "www.gvsds.com" list_s: list[str]* = test_s.split('.') - # 迭代器测试: for idx, i in zip(range(len(list_s)), list_s) + # Iterator test: zip over range and list iter_count: int = 0 for iter_idx, i in zip(range(len(list_s)), list_s): stdio.printf("list_s[%d]='%s'\n", iter_idx, i) @@ -267,7 +267,7 @@ def main() -> CInt | CExport: #for i in range(3): # stdio.printf("list_s[%d]='%s'\n", i, list_s[i]) - # === zip() 内置测试 === + # --- zip() builtin --- testcheck.section("Test 10: zip(list, list) 元组解包") za: str = "a,b,c" zb: str = "1,2,3" diff --git a/FormatStringTest/App/main.vp b/FormatStringTest/App/main.vp index 587b333..d0a1cb6 100644 --- a/FormatStringTest/App/main.vp +++ b/FormatStringTest/App/main.vp @@ -5,9 +5,7 @@ import stdio import testcheck -# ============================================================ -# FormatStringTest - 格式化字符串回归测试 -# ============================================================ +# FormatStringTest - format string regression test export def main() -> int: testcheck.begin("FormatStringTest: Format String Regression") @@ -31,14 +29,12 @@ export def main() -> int: print("Dec: ", f"{42:d}") print("Float: ", f"{3.14159:.2f}") - # f-string 赋值测试(验证不再直接 printf,而是生成字符串) + # f-string assignment: must build a string, not printf directly s: str = f"Value=0x{ULONGLONG(42)}, Hex=0x{ULONGLONG(0x11):016X}" print("Assigned: ", s) - # ctraits.isptr 编译时类型判断测试 - # &s 取的是局部变量 s(str = i8*)的地址,结果是 i8**(char**); - # 与 INTPTR(= int*,见 includes/stdint.vp)层数与基座都不同, - # 且指针隐式转换已收紧(层数必须相同)⇒ 注解按实际类型写 str*(= i8**)。 + # ctraits.isptr compile-time type check. + # &s is i8** (char**); implicit pointer casts require matching depth, so annotate str*. ptr_var: str* = &s val_var: int = 42 if c.CIf(ctraits.isptr(ptr_var)): diff --git a/G3/App/main.vp b/G3/App/main.vp index 683518d..ed2da78 100644 --- a/G3/App/main.vp +++ b/G3/App/main.vp @@ -4,9 +4,8 @@ import testcheck from linkedlist import GSListNode # ============================================================ -# G3: 测试 F-bounded polymorphism -# class Node(GSListNode[Node]) — 继承泛型基类,特化自身为类型参数 -# 这与 TransPyV 中 class Value(GSListNode[Value]) 是相同的模式 +# G3: test F-bounded polymorphism. +# class Node(GSListNode[Node]) inherits a generic base specialized on itself. # ============================================================ @t.NoVTable diff --git a/G4/App/caller1.vp b/G4/App/caller1.vp index 62de98e..8de1d0e 100644 --- a/G4/App/caller1.vp +++ b/G4/App/caller1.vp @@ -6,15 +6,13 @@ from g4node import G4Node, new_g4node # ============================================================ -# caller1: 导入 G4Node 并直接访问 Next 字段(不通过访问器) -# -# 模拟 TransPyV/HandlesExprCall.py 的情况: -# 直接访问 n.Next 触发 GEP 指令,若 stub 字段缺失则 GEP 越界 +# caller1: import G4Node and access the Next field directly (no accessor). +# Direct n.Next access emits a GEP; a missing stub field makes it out of bounds. # ============================================================ def caller1_make_chain(pool: memhub.MemBuddy*) -> G4Node*: - """创建 3 节点链表,直接访问 Next 字段""" + """Create a 3-node chain, accessing Next directly.""" a: G4Node* = new_g4node(pool) b: G4Node* = new_g4node(pool) c: G4Node* = new_g4node(pool) @@ -23,19 +21,19 @@ def caller1_make_chain(pool: memhub.MemBuddy*) -> G4Node*: a.IntVal = 100 b.IntVal = 200 c.IntVal = 300 - # 直接访问 Next 字段(不通过 g4node_set_next 访问器) + # Access Next directly (bypass g4node_set_next). a.Next = b b.Next = c return a def caller1_sum_chain(head: G4Node*) -> int: - """遍历链表求和,直接访问 Next 字段""" + """Sum the chain by walking Next directly.""" if head is None: return 0 total: int = head.IntVal cur: G4Node* = head - # 直接访问 Next 字段(不通过 g4node_get_next 访问器) + # Access Next directly (bypass g4node_get_next). while cur.Next is not None: cur = cur.Next total = total + cur.IntVal diff --git a/G4/App/caller2.vp b/G4/App/caller2.vp index c28ce44..bbbc25d 100644 --- a/G4/App/caller2.vp +++ b/G4/App/caller2.vp @@ -6,14 +6,13 @@ from g4node import G4Node, new_g4node # ============================================================ -# caller2: 另一个导入 G4Node 的模块 -# -# 增加 G4Node 的跨模块引用次数,触发多模块竞争条件 +# caller2: a second module importing G4Node. +# Raises cross-module reference count to stress multi-module handling. # ============================================================ def caller2_reverse_chain(head: G4Node*) -> G4Node*: - """反转链表,直接访问 Next 字段""" + """Reverse the chain, accessing Next directly.""" if head is None: return None prev: G4Node* = None @@ -27,7 +26,7 @@ def caller2_reverse_chain(head: G4Node*) -> G4Node*: def caller2_count_nodes(head: G4Node*) -> int: - """计算链表节点数""" + """Count the chain nodes.""" count: int = 0 cur: G4Node* = head while cur is not None: diff --git a/G4/App/caller3.vp b/G4/App/caller3.vp index 7fc09e9..ce803c3 100644 --- a/G4/App/caller3.vp +++ b/G4/App/caller3.vp @@ -6,14 +6,13 @@ from g4node import G4Node, new_g4node # ============================================================ -# caller3: 第三个导入 G4Node 的模块 -# -# 进一步增加跨模块引用,模拟 TransPyV 30+ 模块环境 +# caller3: a third module importing G4Node. +# Adds more cross-module references (many-module environment). # ============================================================ def caller3_find_tail(head: G4Node*) -> G4Node*: - """找到链表尾部节点,直接访问 Next""" + """Find the chain tail, accessing Next directly.""" if head is None: return None cur: G4Node* = head @@ -23,7 +22,7 @@ def caller3_find_tail(head: G4Node*) -> G4Node*: def caller3_append(head: G4Node*, new_node: G4Node*) -> G4Node*: - """在链表末尾追加节点""" + """Append a node at the chain tail.""" if head is None: return new_node tail: G4Node* = caller3_find_tail(head) diff --git a/G4/App/main.vp b/G4/App/main.vp index 27cbe59..efa64a3 100644 --- a/G4/App/main.vp +++ b/G4/App/main.vp @@ -9,12 +9,9 @@ import caller2 import caller3 # ============================================================ -# G4: 验证 includes 中继承 GSListNode[X] 的类是否会出现 -# Next 字段缺失或类型降级的问题 -# -# G4Node 类在 includes/g4node.py 中(走 Phase1 路径) -# G4Node 有 5 个自有字段 + 1 个继承字段(Next) = 6 字段 -# caller1/caller2/caller3 模拟 TransPyV 多模块环境 +# G4: verify a class inheriting GSListNode[X] from includes keeps its +# inherited Next field (no missing field / type downgrade). +# caller1/caller2/caller3 reproduce a multi-module environment. # ============================================================ @@ -84,7 +81,7 @@ def test_g4node_chain(): def test_caller1_direct_access(): - """caller1: 直接访问 Next 字段(不通过访问器)""" + """caller1: access Next directly (no accessor).""" testcheck.section("Test 4: caller1 direct Next access") arena: bytes = stdlib.malloc(8192) if arena is None: @@ -101,7 +98,7 @@ def test_caller1_direct_access(): def test_caller2_reverse(): - """caller2: 反转链表直接访问 Next""" + """caller2: reverse the chain, accessing Next directly.""" testcheck.section("Test 5: caller2 reverse chain") arena: bytes = stdlib.malloc(8192) if arena is None: @@ -121,7 +118,7 @@ def test_caller2_reverse(): def test_caller3_append(): - """caller3: 追加节点直接访问 Next""" + """caller3: append a node, accessing Next directly.""" testcheck.section("Test 6: caller3 append node") arena: bytes = stdlib.malloc(8192) if arena is None: diff --git a/G4/includes/g4node.vp b/G4/includes/g4node.vp index 28610cd..1b5fddc 100644 --- a/G4/includes/g4node.vp +++ b/G4/includes/g4node.vp @@ -3,25 +3,17 @@ from linkedlist import GSListNode import memhub # ============================================================ -# G4Node: 继承 GSListNode[G4Node] 的测试类 -# -# 这个类在 includes 目录中,会走 Phase1 路径 -# 模拟 TransPyV 中 Value 类的结构: -# - 继承 GSListNode[G4Node] 获取 Next 字段 -# - 5 个自有字段(与 Value 相同数量) -# - @t.NoVTable 装饰器 -# -# 继承展平后应有 6 个字段:Next + 5 自有 -# 若继承展平失败,只有 5 个字段(缺少 Next) +# G4Node: test class inheriting GSListNode[G4Node] (in includes, so it uses +# the Phase1 path); flattened it must have 6 fields: Next + 5 own fields. # ============================================================ @t.NoVTable class G4Node(GSListNode[G4Node]): - Ty: t.CPtr # 模拟 Value.Ty - Name: t.CPtr # 模拟 Value.Name - IsConst: int # 模拟 Value.IsConst - IntVal: int64 # 模拟 Value.IntVal - FloatVal: double # 模拟 Value.FloatVal + Ty: t.CPtr # mirrors Value.Ty + Name: t.CPtr # mirrors Value.Name + IsConst: int # mirrors Value.IsConst + IntVal: int64 # mirrors Value.IntVal + FloatVal: double # mirrors Value.FloatVal def __init__(self): self.Ty = None @@ -32,7 +24,7 @@ class G4Node(GSListNode[G4Node]): self.Next = None -# 工厂函数(与 __values.py 中的 new_value 类似) +# factory function (similar to new_value in __values.py) def new_g4node(pool: memhub.MemBuddy*) -> G4Node*: ptr: G4Node* = pool.alloc(48) if ptr: diff --git a/G5/App/main.vp b/G5/App/main.vp index f75413d..a704df8 100644 --- a/G5/App/main.vp +++ b/G5/App/main.vp @@ -8,14 +8,12 @@ from linkedlist import GSListNode, GSList # ============================================================ -# G5: 验证 GSList[T] 被降级为 opaque 的问题 -# -# 版本 2: 不使用 malloc/MemBuddy,直接用构造函数(像 G3 那样) -# 这样能隔离 GSList opaque 问题 +# G5: verify GSList[T] is not degraded to an opaque type; uses direct +# construction (no malloc/MemBuddy) to isolate the issue. # ============================================================ -# G5Node: 继承 GSListNode[G5Node](Phase2 路径,正确特化) +# G5Node: inherits GSListNode[G5Node] (Phase2 path, correct specialization) @t.NoVTable class G5Node(GSListNode[G5Node]): Value: int @@ -25,9 +23,8 @@ class G5Node(GSListNode[G5Node]): self.Value = 0 -# G5ListWrapper: 包装 GSList[G5Node],测试 GSList 字段访问 -# 注意:GSList[G5Node] 走 Phase2 特化路径 -# 用 pool 工厂函数分配 GSList,避免栈分配悬垂指针 +# 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 @@ -44,7 +41,7 @@ class G5ListWrapper: # ============================================================ -# Test 1: G5Node 字段访问(基准测试,应通过) +# Test 1: G5Node field access (baseline, should pass) # ============================================================ def test_g5node_create(): @@ -71,7 +68,7 @@ def test_g5node_next(): # ============================================================ -# Test 3: GSList 字段访问 — 核心测试 +# Test 3: GSList field access (core test) # ============================================================ def test_gslist_create(): @@ -80,7 +77,7 @@ def test_gslist_create(): 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 @@ -106,25 +103,25 @@ def test_gslist_append(): lst.append(b) lst.append(c) - # 验证 Count + # verify Count count: sizet = lst.Count testcheck.check(count == 3, "Count = 3 after 3 appends", "expect 3") - # 验证 Head + # 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") - # 验证 Tail + # 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: @@ -134,7 +131,7 @@ def test_gslist_append(): # ============================================================ -# Test 5: G5ListWrapper.List 字段访问(嵌套 GSList 测试) +# Test 5: G5ListWrapper.List field access (nested GSList, pool alloc) # ============================================================ def test_wrapper_list_field(): @@ -156,7 +153,7 @@ def test_wrapper_list_field(): n.Value = 999 wrapper.List.append(n) - # 通过 wrapper.List 访问 GSList 字段 + # access GSList fields through wrapper.List head: G5Node* = wrapper.List.Head if head is None: testcheck.check(False, "wrapper.List.Head is None", "FAIL") diff --git a/G5/includes/g5container.vp b/G5/includes/g5container.vp index 8be61b0..bc0f12e 100644 --- a/G5/includes/g5container.vp +++ b/G5/includes/g5container.vp @@ -4,126 +4,99 @@ from linkedlist import GSListNode, GSList import memhub -# ============================================================ -# G5Node: 继承 GSListNode[G5Node] 的测试节点 -# -# 与 __function.py 中的 Line(GSListNode[Line]) 模式相同。 -# 这个类在 includes 目录中,走 Phase1 路径。 -# Phase1 的 _specialize_member_types 会将 Next 字段类型 T 降级为 i8* -# 而不是 G5Node*(与 TPV 中 Value/Line 类的情况相同) -# ============================================================ +# ===== G5Node: test node extending GSListNode[G5Node] ===== +# Phase1 _specialize_member_types degrades the Next field type T to i8*, not G5Node*. @t.NoVTable class G5Node(GSListNode[G5Node]): Value: int -# ============================================================ -# G5Container: 持有 GSList[G5Node] 字段的容器 -# -# 这是 G5 测试的核心:GSList[T] 在 Phase1 中被降级为 opaque, -# 导致 List.Head / List.Tail / List.Count 字段访问无法生成 GEP。 -# -# 与 __function.py 中的 Function(GSListNode[Function]): -# Params: GSList[Param] | t.CPtr -# Blocks: GSList[BasicBlock] | t.CPtr -# 模式完全相同。 -# ============================================================ +# ===== G5Container: container holding a GSList[G5Node] field ===== +# In Phase1 GSList[T] is opaque, so List.Head/Tail/Count access emits no GEP. @t.NoVTable class G5Container: List: GSList[G5Node]* -# ============================================================ -# 工厂函数(与 __function.py 的 new_line/new_function 模式相同) -# ============================================================ +# ===== Factory functions ===== -# G5Node 硬编码大小: Next(8) + Value(4) + padding(4) = 16 字节 +# G5Node hardcoded size: Next(8) + Value(4) + padding(4) = 16 bytes define G5NODE_SIZE = 16 def new_g5node(pool: memhub.MemBuddy*) -> G5Node*: - """从 pool 分配并零初始化一个 G5Node""" + """Allocate and zero-initialize a G5Node from pool.""" ptr: G5Node* = pool.alloc(G5NODE_SIZE) if ptr is None: return None string.memset(ptr, 0, G5NODE_SIZE) return ptr -# GSList 硬编码大小: Head(8) + Tail(8) + Count(8) = 24 字节 +# GSList hardcoded size: Head(8) + Tail(8) + Count(8) = 24 bytes define G5LIST_SIZE = 24 def new_g5list(pool: memhub.MemBuddy*) -> GSList[G5Node]*: - """从 pool 分配并零初始化一个 GSList 容器(Head/Tail/Count 全零)""" + """Allocate and zero-initialize a GSList container from pool.""" gsl: t.CPtr = pool.alloc(G5LIST_SIZE) if gsl is None: return None string.memset(gsl, 0, G5LIST_SIZE) return gsl -# G5Container 硬编码大小: List(8) = 8 字节 +# G5Container hardcoded size: List(8) = 8 bytes define G5CONTAINER_SIZE = 8 def new_g5container(pool: memhub.MemBuddy*) -> G5Container*: - """从 pool 分配并零初始化一个 G5Container""" + """Allocate and zero-initialize a G5Container from pool.""" ptr: G5Container* = pool.alloc(G5CONTAINER_SIZE) if ptr is None: return None string.memset(ptr, 0, G5CONTAINER_SIZE) return ptr -# ============================================================ -# 字段访问器(供其他模块绕过 stub 类型限制使用) -# -# 跨模块编译时,使用方模块只有 GSList 的 stub 类型(opaque), -# 导致 TransPyC 静默跳过字段访问(不生成 GEP,不报错), -# 字段值永远为 null。 -# -# 这些访问器在拥有完整类型定义的本模块内执行,能正确访问 -# 所有字段。其他模块通过函数调用获取字段值,绕过 stub 限制。 -# ============================================================ +# ===== Field accessors (bypass stub-type limits in other modules) ===== +# Cross-module GSList is opaque, so field access silently emits no GEP; these run here. def g5list_get_head(lst: GSList[G5Node]*) -> G5Node*: - """获取链表头节点""" + """Get the list head node.""" if lst is None: return None return lst.Head def g5list_get_tail(lst: GSList[G5Node]*) -> G5Node*: - """获取链表尾节点""" + """Get the list tail node.""" if lst is None: return None return lst.Tail def g5list_get_count(lst: GSList[G5Node]*) -> sizet: - """获取链表节点数""" + """Get the list node count.""" if lst is None: return 0 return lst.Count def g5list_set_head(lst: GSList[G5Node]*, node: G5Node*): - """设置链表头节点""" + """Set the list head node.""" if lst is None: return lst.Head = node def g5list_set_tail(lst: GSList[G5Node]*, node: G5Node*): - """设置链表尾节点""" + """Set the list tail node.""" if lst is None: return lst.Tail = node def g5list_set_count(lst: GSList[G5Node]*, count: sizet): - """设置链表节点数""" + """Set the list node count.""" if lst is None: return lst.Count = count def g5list_append(lst: GSList[G5Node]*, node: G5Node*): - """将 node 追加到链表末尾(O(1)) - - 直接操作 Head/Tail/Count 字段,不依赖 GSList.append 方法 - (因为跨模块时方法实现可能缺失) + """Append node to the list end (O(1)) by directly updating + Head/Tail/Count, since GSList.append may be missing cross-module. """ if lst is None or node is None: return node.Next = None @@ -135,9 +108,7 @@ def g5list_append(lst: GSList[G5Node]*, node: G5Node*): lst.Count += 1 -# ============================================================ -# G5Node 访问器 -# ============================================================ +# ===== G5Node accessors ===== def g5node_get_value(node: G5Node*) -> int: if node is None: return 0 @@ -159,9 +130,7 @@ def g5node_set_next(node: G5Node*, next_node: G5Node*): node.Next = next_node -# ============================================================ -# G5Container 访问器 -# ============================================================ +# ===== G5Container accessors ===== def g5container_get_list(container: G5Container*) -> GSList[G5Node]*: if container is None: return None diff --git a/G6/App/main.vp b/G6/App/main.vp index 773b4bd..e2cfb4e 100644 --- a/G6/App/main.vp +++ b/G6/App/main.vp @@ -4,24 +4,19 @@ import testcheck import atom -# ============================================================ -# G6: 验证 atom 模块的内联汇编原子操作 -# -# TPV 在编译 atom.py 的 __atomic_test_and_set 时崩溃 -# (ACCESS_VIOLATION in ASM args loop ai3=2) -# 此测试用 TPC 编译验证 atom 模块是否正确工作 -# ============================================================ +# G6: verify the atom module's inline-asm atomic operations. +# Compiled with TPC to validate atom behavior in this area. def test_atomic_test_and_set(): testcheck.section("Test 1: __atomic_test_and_set") flag: uint8 = 0 result: bool = atom.__atomic_test_and_set(&flag, atom.ATOMIC_ACQUIRE) - # test_and_set 返回旧值: flag=0 -> 返回 0, flag 变为 1 + # test_and_set returns the old value: flag=0 returns 0 and sets flag=1 testcheck.check(result == bool(0), "first set returns old value 0", "expect 0") testcheck.check(flag == 1, "flag is 1 after set", "expect 1") - # 第二次设置应返回 1(旧值已为 1) + # Second set returns 1 because the old value is now 1. result2: bool = atom.__atomic_test_and_set(&flag, atom.ATOMIC_ACQUIRE) testcheck.check(result2 == bool(1), "second set returns old value 1", "expect 1") @@ -35,7 +30,7 @@ def test_atomic_clear(): def test_atomic_thread_fence(): testcheck.section("Test 3: __atomic_thread_fence") - # 只是验证不崩溃 + # Only checks that the call does not crash. atom.__atomic_thread_fence(atom.ATOMIC_SEQ_CST) testcheck.ok("mfence executed OK") @@ -51,12 +46,12 @@ def test_atomic_spinlock(): testcheck.section("Test 5: spinlock pattern (test_and_set + clear)") lock: uint8 = 0 - # 获取锁 + # Acquire the lock while atom.__atomic_test_and_set(&lock, atom.ATOMIC_ACQUIRE) == bool(1): pass testcheck.check(lock == 1, "lock acquired", "expect lock=1") - # 释放锁 + # Release the lock atom.__atomic_clear(&lock, atom.ATOMIC_RELEASE) testcheck.check(lock == 0, "lock released", "expect lock=0") diff --git a/G7/App/main.vp b/G7/App/main.vp index 912f0cd..708b0be 100644 --- a/G7/App/main.vp +++ b/G7/App/main.vp @@ -5,20 +5,13 @@ import stdlib import memhub from conflict_node import Value -# ============================================================ -# 关键冲突点:全局变量名 'Value' 与类名 'Value' 相同 -# -# LlvmGenerator 预处理扫描会将 'Value' 注册为 IsVariable=True -# 覆盖 SymbolTable 中的类条目。 -# 之后 _get_or_create_struct('Value') 发现 IsVariable=True, -# 返回 _TypedPointerType 而非 IdentifiedStructType, -# 导致 _TryLoadStructFromStub 中 set_body 被跳过。 -# ============================================================ +# G7: global variable 'Value' collides with class 'Value' +# Variable registration overrides the struct symbol, so struct body setup is skipped. Value: t.CPtr = None def test_value_struct_fields(): - """验证 Value struct 有 6 个字段(Next + 5 自有)""" + """Verify the Value struct has 6 fields (Next + 5 own).""" testcheck.section("Value struct field access (6 fields expected)") arena: bytes = stdlib.malloc(4096) if arena is None: @@ -29,15 +22,15 @@ def test_value_struct_fields(): if node is None: testcheck.check(False, "alloc Value", "FAIL") return - # 写入字段 0 (Next, 继承自 GSListNode) + # Field 0: Next (inherited from GSListNode) node.Next = None - # 写入字段 1-5 (自有字段) + # Fields 1-5: own fields node.Ty = None node.Name = None node.IsConst = 1 node.IntVal = 42 node.FloatVal = 3.14 - # 读取验证 + # Read back and verify v: int = node.IntVal testcheck.check(v == 42, "Value.IntVal = 42", "expect 42") f: double = node.FloatVal diff --git a/G7/includes/conflict_node.vp b/G7/includes/conflict_node.vp index 9389a3c..e842b50 100644 --- a/G7/includes/conflict_node.vp +++ b/G7/includes/conflict_node.vp @@ -1,17 +1,8 @@ import t from linkedlist import GSListNode -# ============================================================ -# 最小化复现:类名 'Value' 与全局变量名冲突 -# -# 这个类在 includes 目录中(走 Phase1 路径),生成 stub.ll -# 继承 GSListNode[Value] 获取 Next 字段 -# 5 个自有字段 + 1 个继承字段(Next) = 6 字段 -# -# 若 _get_or_create_struct('Value') 因 SymbolTable 中 -# IsVariable=True 而返回 _TypedPointerType, -# 则 set_body 被跳过,struct 保持不完整 → GEP 越界崩溃 -# ============================================================ +# Minimal repro: class name 'Value' collides with global variable name. +# GSListNode[Value] supplies Next; if the struct body is skipped, GEP overruns crash. @t.NoVTable class Value(GSListNode[Value]): diff --git a/GenericOopTest/App/main.vp b/GenericOopTest/App/main.vp index 62d7ddf..a27df89 100644 --- a/GenericOopTest/App/main.vp +++ b/GenericOopTest/App/main.vp @@ -7,7 +7,7 @@ import stdlib import testcheck -# === 函数泛型 === +# === Generic functions === def add[T](a: T, b: T) -> T: return a + b @@ -28,7 +28,7 @@ def double_add[T](a: T, b: T) -> T: return add(a, b) + add(a, b) -# === 结构体泛型 === +# === Generic structs === class A[T](): a: T @@ -77,7 +77,7 @@ def main() -> CInt | CExport: buf: CChar | CPtr = CPtr(stdlib.malloc(256)) - # === 基础函数泛型 === + # === Basic generic functions === testcheck.section("基础函数泛型") print(add(3, 5)) print(add(1.5, 2.5)) @@ -87,7 +87,7 @@ def main() -> CInt | CExport: print(double_add(5, 7)) testcheck.ok("基础函数泛型测试完成") - # === 基础结构体泛型 === + # === Basic generic structs === testcheck.section("基础结构体泛型") a = A(100) print(a.get_a()) @@ -96,7 +96,7 @@ def main() -> CInt | CExport: print(p1.get_second()) testcheck.ok("基础结构体泛型测试完成") - # === 泛型 + OOP 组合 === + # === Generic + OOP combined === testcheck.section("泛型 + OOP 组合") calc1 = Calculator(10) print(calc1.compute(5)) @@ -108,7 +108,7 @@ def main() -> CInt | CExport: print(c1_gen.get_flag()) testcheck.ok("泛型 + OOP 组合测试完成") - # === snprintf 格式化 === + # === snprintf formatting === testcheck.section("snprintf 格式化") viperlib.snprintf(buf, 256, "int=%d, float=%.2f", 42, 3.14) print(buf) @@ -116,7 +116,7 @@ def main() -> CInt | CExport: print(buf) testcheck.ok("snprintf 格式化测试完成") - # === 新语法类型强转 (t1|t2)(x) === + # === New cast syntax (t1|t2)(x) === testcheck.section("新语法类型强转 (t1|t2)(x)") val_i64: CUInt64T = CUInt64T(42) val_i32 = (int)(val_i64) diff --git a/GenericTest/App/main.vp b/GenericTest/App/main.vp index 6e2186f..f51dca7 100644 --- a/GenericTest/App/main.vp +++ b/GenericTest/App/main.vp @@ -3,7 +3,7 @@ import stdio import testcheck # ============================================================ -# Test 1: 泛型函数 - 基本加法 +# Test 1: generic function, basic addition # ============================================================ def add[T](a: T, b: T) -> T: return a + b @@ -15,7 +15,7 @@ def test_generic_add(): testcheck.check(r1 == 8 and r2 == 300, "generic add (3+5=8, 100+200=300)", "generic add expect 8 and 300") # ============================================================ -# Test 2: 泛型函数 - 多类型参数 +# Test 2: generic function, multiple type parameters # ============================================================ def combine[T1, T2](a: T1, b: T2) -> T1: return a + T1(b) @@ -26,7 +26,7 @@ def test_generic_combine(): testcheck.check(r == 30, "generic combine (10+T1(20)=30)", "generic combine expect 30") # ============================================================ -# Test 3: 泛型函数 - 最大值 +# Test 3: generic function, maximum # ============================================================ def max_val[T](a: T, b: T) -> T: if a > b: @@ -40,7 +40,7 @@ def test_generic_max(): testcheck.check(r1 == 20 and r2 == 50, "generic max (max(10,20)=20, max(50,30)=50)", "generic max expect 20 and 50") # ============================================================ -# Test 4: 泛型类 - Box[T] +# Test 4: generic class Box[T] # ============================================================ class Box[T](): value: T @@ -61,7 +61,7 @@ def test_generic_box(): testcheck.check(v == 42, "Box[int] (get=42)", "Box[int] expect 42") # ============================================================ -# Test 5: 泛型类 - Pair[T1, T2] +# Test 5: generic class Pair[T1, T2] # ============================================================ class Pair[T1, T2](): first: T1 @@ -81,7 +81,7 @@ def test_generic_pair(): testcheck.check(r == 30, "Pair[int,int] (sum=30)", "Pair[int,int] expect 30") # ============================================================ -# Test 6: list[T, N] 固定数组 +# Test 6: list[T, N] fixed array # ============================================================ def test_fixed_array(): testcheck.section("Test 6: list[T, N] fixed array") @@ -95,7 +95,7 @@ def test_fixed_array(): testcheck.check(total == 100, "fixed array (total=100)", "fixed array expect 100") # ============================================================ -# Test 7: list[t.CChar, N] 字符数组 +# Test 7: list[t.CChar, N] char array # ============================================================ def test_char_array(): testcheck.section("Test 7: list[t.CChar, N] char array") @@ -106,7 +106,7 @@ def test_char_array(): testcheck.check(buf[0] == 72 and buf[1] == 105, "char array (H=72 i=105)", "char array expect H=72 i=105") # ============================================================ -# Test 8: 泛型函数多次特化 +# Test 8: generic function specialized multiple times # ============================================================ def identity[T](x: T) -> T: return x @@ -118,7 +118,7 @@ def test_generic_identity(): testcheck.check(r1 == 42 and r2 == 0, "identity (42=42, 0=0)", "identity expect 42 and 0") # ============================================================ -# Test 9: 泛型函数嵌套调用 +# Test 9: generic function nested call # ============================================================ def double_val[T](x: T) -> T: return add(x, x) @@ -129,7 +129,7 @@ def test_generic_nested(): testcheck.check(r == 42, "generic nested (double(21)=42)", "generic nested expect 42") # ============================================================ -# Test 10: 泛型类方法调用 +# Test 10: generic class method call # ============================================================ class Counter[T](): count: T diff --git a/GenericTest2/App/main.vp b/GenericTest2/App/main.vp index 8bc0df5..d0f948f 100644 --- a/GenericTest2/App/main.vp +++ b/GenericTest2/App/main.vp @@ -4,7 +4,7 @@ import c import testcheck # ============================================================ -# Test 1: 泛型函数 - 不同整数类型特化 +# Test 1: generic function with different int type specializations # ============================================================ def square[T](x: T) -> T: return x * x @@ -16,7 +16,7 @@ def test_generic_square_types(): testcheck.check(r1 == 25 and r2 == 100, "square (5^2=25 10^2=100)", "square expect 25 100") # ============================================================ -# Test 2: 泛型函数 - 三参数 +# Test 2: generic function with three parameters # ============================================================ def clamp[T](val: T, lo: T, hi: T) -> T: if val < lo: @@ -33,7 +33,7 @@ def test_generic_clamp(): testcheck.check(r1 == 5 and r2 == 0 and r3 == 10, "clamp (5 0 10)", "clamp expect 5 0 10") # ============================================================ -# Test 3: 泛型类 - Stack[T] +# Test 3: generic class Stack[T] # ============================================================ class Stack[T](): data: t.CArray[int, 16] @@ -63,8 +63,8 @@ class Stack[T](): def test_generic_stack(): testcheck.section("Test 3: generic Stack[T]") - # 显式标注 Stack[int]:T 无法从实参推断(__init__ 无参),且 T 决定 - # push/pop 的元素宽度(t.CInt(val) ↔ i32),静默默认 int 已被禁止。 + # Annotate Stack[int] explicitly: T is not inferable (no-arg __init__) and + # sets push/pop element width; implicit int default is forbidden. s = Stack[int]() s.push(10) s.push(20) @@ -75,7 +75,7 @@ def test_generic_stack(): 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 +# Test 4: generic swap via pointer # ============================================================ class IntPair: a: int @@ -95,7 +95,7 @@ def test_generic_swap(): testcheck.check(p.a == 200 and p.b == 100, "swap (a=200 b=100)", "swap expect 200 100") # ============================================================ -# Test 5: 泛型类 - Range[T] 迭代器 +# Test 5: generic iterable class Range[T] # ============================================================ class Range[T](): start: T @@ -117,12 +117,12 @@ class Range[T](): def test_generic_range(): testcheck.section("Test 5: generic Range[T]") - r = Range(0, 10, 1) # 0+1+2+...+9=45 + r = Range(0, 10, 1) # sum 0..9 = 45 s: int = r.sum_all() testcheck.check(s == 45, "Range sum (0..9=45)", "Range sum expect 45") # ============================================================ -# Test 6: 泛型函数 - 数组求和(非泛型数组参数) +# Test 6: generic function summing a fixed-size array argument # ============================================================ def array_sum(arr: t.CArray[int, 8], n: int) -> int: result: int = 0 @@ -139,7 +139,7 @@ def test_generic_array_sum(): testcheck.check(s == 360, "array sum (360)", "array sum expect 360") # ============================================================ -# Test 7: 泛型函数 - 比较并返回较大值 +# Test 7: generic function returning the max of three values # ============================================================ def max_of_three[T](a: T, b: T, c_val: T) -> T: m: T = a @@ -157,7 +157,7 @@ def test_generic_max_three(): testcheck.check(r1 == 3 and r2 == 30 and r3 == 50, "max3 (3 30 50)", "max3 expect 3 30 50") # ============================================================ -# Test 8: 泛型类 - 带方法的容器 +# Test 8: generic container class with methods # ============================================================ class Container[T](): values: t.CArray[int, 8] @@ -187,8 +187,8 @@ class Container[T](): 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])。 + # Annotate Container[int] explicitly: no-arg __init__ gives no T to infer; + # int is inferred from usage; storage is CArray[int, 8]. c = Container[int]() c.add(10) c.add(20) @@ -199,7 +199,7 @@ def test_generic_container(): testcheck.check(has20 == 1 and has99 == 0 and total == 60, "Container (has20=1 has99=0 total=60)", "Container expect 1 0 60") # ============================================================ -# Test 9: 泛型函数 - 阶乘 +# Test 9: generic factorial # ============================================================ def factorial[T](n: T) -> T: result: T = T(1) @@ -216,7 +216,7 @@ def test_generic_factorial(): testcheck.check(r1 == 120 and r2 == 3628800, "factorial (5!=120 10!=3628800)", "factorial expect 120 3628800") # ============================================================ -# Test 10: 泛型类 - 累加器 +# Test 10: generic accumulator class # ============================================================ class Accumulator[T](): total: T @@ -240,13 +240,12 @@ def test_generic_accumulator(): testcheck.check(r == 60, "Accumulator (result=60)", "Accumulator expect 60") # ============================================================ -# Test 11: 泛型结构体 sizeof (修复验证) -# 特化后 Stack[int] = { [16 x i32], i32 } = 68 字节 -# 验证 obj.__sizeof__() 和类内部 self.__sizeof__() 均返回正确大小 +# Test 11: generic struct sizeof; specialized Stack[int] is 68 bytes. +# Checks obj.__sizeof__() and in-class self.__sizeof__(). # ============================================================ def test_generic_sizeof_bug(): testcheck.section("Test 11: generic sizeof (fixed)") - # 同 Test 3:无参构造必须显式标注类型实参;Stack[int] = { [16 x i32], i32 } = 68。 + # Same as Test 3: no-arg construction needs an explicit type argument; Stack[int] = 68 bytes. s = Stack[int]() s.push(10) sz: sizet = s.__sizeof__() diff --git a/GenericTest3/App/main.vp b/GenericTest3/App/main.vp index 939d69e..61976ee 100644 --- a/GenericTest3/App/main.vp +++ b/GenericTest3/App/main.vp @@ -2,10 +2,8 @@ import t import stdio import testcheck -# ============================================================ -# Test 1: 泛型函数手动传类型参数 - 基本调用 -# def xxx[T](x: int) 然后调用 xxx[T](x) -# ============================================================ +# Test 1: generic function with explicit type arg - basic call +# def xxx[T](x: int) then call xxx[T](x) def double[T](x: int) -> int: return x * 2 @@ -14,9 +12,7 @@ def test_explicit_type_arg(): r: int = double[int](21) testcheck.check(r == 42, "double[t.CInt](21) = 42", "expect 42") -# ============================================================ -# Test 2: 泛型函数手动传类型参数 - 多次调用不同类型 -# ============================================================ +# Test 2: generic function with explicit type arg - multiple call types def identity[T](x: int) -> int: return x @@ -26,9 +22,7 @@ def test_identity_explicit(): r2: int = identity[int](20) testcheck.check(r1 == 10 and r2 == 20, "identity[t.CInt](10)=10 (20)=20", "expect 10 20") -# ============================================================ -# Test 3: 泛型函数手动传类型参数 - 用 T 作为参数类型 -# ============================================================ +# Test 3: generic function with explicit type arg - T as parameter type def add_one[T](x: T) -> T: return x + T(1) @@ -37,14 +31,12 @@ def test_add_one_explicit(): r: int = add_one[int](41) testcheck.check(r == 42, "add_one[t.CInt](41) = 42", "expect 42") -# ============================================================ -# Test 4: 泛型函数手动传类型参数 - 混合自动推导和手动传 -# ============================================================ +# Test 4: generic function with explicit type arg - mixed inference def test_mixed_inference_explicit(): testcheck.section("Test 4: mixed inference and explicit") - # 自动推导 + # Inferred r1: int = add_one(99) - # 手动传 + # Explicit r2: int = add_one[int](99) testcheck.check(r1 == 100 and r2 == 100, "add_one(99)=100 add_one[t.CInt](99)=100", "expect 100 100") diff --git a/GenericTest4/App/main.vp b/GenericTest4/App/main.vp index c94670a..8cf5dcf 100644 --- a/GenericTest4/App/main.vp +++ b/GenericTest4/App/main.vp @@ -2,9 +2,7 @@ import t import stdio import testcheck -# ============================================================ -# Test 1: 泛型类手动传类型参数 - Box[t.CInt](v) -# ============================================================ +# Test 1: generic class with explicit type arg - Box[t.CInt](v) class Box[T](): value: T @@ -23,9 +21,7 @@ def test_explicit_box(): v: int = b.get() testcheck.check(v == 42, "Box[t.CInt](42).get() = 42", "expect 42") -# ============================================================ -# Test 2: 泛型类手动传类型参数 - Pair[t.CInt, t.CInt] -# ============================================================ +# Test 2: generic class with explicit type arg - Pair[t.CInt, t.CInt] class Pair[T1, T2](): first: T1 second: T2 @@ -43,9 +39,7 @@ def test_explicit_pair(): r: int = p.sum_as_int() testcheck.check(r == 30, "Pair[t.CInt,t.CInt](10,20).sum = 30", "expect 30") -# ============================================================ -# Test 3: 泛型类手动传 + 自动推导混合 -# ============================================================ +# Test 3: generic class explicit + inferred mixed class Wrapper[T](): data: T @@ -57,17 +51,15 @@ class Wrapper[T](): def test_mixed_generic_class(): testcheck.section("Test 3: mixed explicit and inferred") - # 手动传 + # Explicit w1 = Wrapper[int](100) - # 自动推导 + # Inferred w2 = Wrapper(200) r1: int = w1.get() r2: int = w2.get() testcheck.check(r1 == 100 and r2 == 200, "Wrapper[t.CInt](100)=100 Wrapper(200)=200", "expect 100 200") -# ============================================================ -# Test 4: 泛型类手动传 - 方法调用 -# ============================================================ +# Test 4: generic class explicit - method calls class Counter[T](): count: T @@ -89,9 +81,7 @@ def test_explicit_counter(): r: int = c.get_count() testcheck.check(r == 3, "Counter[t.CInt](0) +3 = 3", "expect 3") -# ============================================================ -# Test 5: 泛型类手动传 - set 方法 -# ============================================================ +# Test 5: generic class explicit - set method def test_explicit_box_set(): testcheck.section("Test 5: Box[t.CInt] set method") b = Box[int](10) diff --git a/HashLibTest/App/main.vp b/HashLibTest/App/main.vp index d6ef57e..d96efef 100644 --- a/HashLibTest/App/main.vp +++ b/HashLibTest/App/main.vp @@ -10,7 +10,7 @@ import w32.win32console # ============================================== -# 工具函数:打印十六进制哈希串 +# Helper: print a hash digest as hex. # ============================================== def print_hex(buf: uint8*, length: int): for i in range(length): @@ -28,7 +28,7 @@ def main() -> int | t.CExport: testcheck.begin("HashLibTest: 哈希与校验测试") - # ---------- hashlib 摘要测试 ---------- + # ---------- hashlib digest tests ---------- testcheck.section("HASHLIB") plain: str = "hello123" @@ -67,7 +67,7 @@ def main() -> int | t.CExport: default_value_test_function(b=2, a=1) testcheck.ok("default value test completed") - # ---------- base64 编解码测试 ---------- + # ---------- base64 encode/decode tests ---------- testcheck.section("BASE64") b64_out: t.CArray[char, 256] b64_dec: t.CArray[uint8, 256] @@ -78,7 +78,7 @@ def main() -> int | t.CExport: print("Base64 解码:", b64_dec) testcheck.ok("BASE64 encode/decode completed") - # ---------- binascii 全套测试 ---------- + # ---------- binascii tests ---------- testcheck.section("BINASCII") binascii.init_binascii() raw: str = "HelloWorld!" diff --git a/HashTableTest/App/main.vp b/HashTableTest/App/main.vp index 2192244..9e0222c 100644 --- a/HashTableTest/App/main.vp +++ b/HashTableTest/App/main.vp @@ -16,11 +16,11 @@ def main() -> CInt | CExport: testcheck.begin("HashTableTest: 开放寻址哈希表测试") - # 分配内存竞技场 + # Allocate the memory arena arena: bytes = stdlib.malloc(65536) bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536) - # === Test 1: 基本插入和查找 === + # === Test 1: basic insert and lookup === testcheck.section("Test 1: 基本插入和查找 (set_int)") ht: hashtable.HashTable = hashtable.HashTable(bd) ht.set_int("alpha", 10) @@ -30,9 +30,8 @@ def main() -> CInt | CExport: stdio.printf("len=%lu\n", n) testcheck.check(n == 3, "ht len OK (3)", "ht len FAILED") - # 哈希表的 int 值按 int(i32)写入(见 hashtable.vp set_int 的 int_ptr),读回 - # 须给出有元素类型的指针:c.Deref 的宽度只认 pointee 类型,i8*(t.CPtr)恒读 - # 1 字节,不再按赋值目标注解反推 4 字节。 + # set_int stores the value as i32; read it back through a typed pointer, since + # c.Deref width follows the pointee type and i8* (t.CPtr) always reads 1 byte. p1: t.CPtr = ht["alpha"] v1: int = *(int*)(p1) p2: t.CPtr = ht["beta"] @@ -44,7 +43,7 @@ def main() -> CInt | CExport: testcheck.check(v2 == 20, "ht[beta]==20 OK", "ht[beta] FAILED") testcheck.check(v3 == 30, "ht[gamma]==30 OK", "ht[gamma] FAILED") - # === Test 2: 更新已有键 === + # === Test 2: update existing key === testcheck.section("Test 2: 更新已有键") ht.set_int("beta", 99) p2b: t.CPtr = ht["beta"] @@ -70,7 +69,7 @@ def main() -> CInt | CExport: testcheck.check(has_alpha == 1, "contains alpha OK", "contains alpha FAILED") testcheck.check(has_missing == 0, "not contains missing OK", "contains missing FAILED") - # === Test 5: 删除 === + # === Test 5: delete === testcheck.section("Test 5: 删除 (del)") deleted: int = ht.__delitem__("beta") stdio.printf("del beta=%d\n", deleted) @@ -79,11 +78,11 @@ def main() -> CInt | CExport: has_beta: int = "beta" in ht testcheck.check(has_beta == 0, "beta gone OK", "beta still exists FAILED") - # 删除不存在的 key + # Delete a nonexistent key del_missing: int = ht.__delitem__("nokey") testcheck.check(del_missing == 0, "del missing returns 0 OK", "del missing FAILED") - # === Test 6: 删除后重新插入 === + # === Test 6: re-insert after delete === testcheck.section("Test 6: 删除后重新插入") ht.set_int("beta", 555) p2c: t.CPtr = ht["beta"] @@ -92,7 +91,7 @@ def main() -> CInt | CExport: testcheck.check(v2c == 555, "ht re-insert beta OK", "ht re-insert beta FAILED") testcheck.check(len(ht) == 3, "ht len 3 after re-insert OK", "ht len after re-insert FAILED") - # === Test 7: 迭代器 === + # === Test 7: iterator === testcheck.section("Test 7: 迭代器 for key in ht") iter_count: int = 0 for key in ht: @@ -102,7 +101,7 @@ def main() -> CInt | CExport: iter_count += 1 testcheck.check(iter_count == 3, "ht iter OK (3)", "ht iter FAILED") - # === Test 8: 字符串值 === + # === Test 8: string values === testcheck.section("Test 8: 字符串值 (set_str)") ht2: hashtable.HashTable = hashtable.HashTable(bd) ht2.set_str("name", "Alice") @@ -119,12 +118,12 @@ def main() -> CInt | CExport: city: str = city_p lang: str = lang_p stdio.printf("name=%s city=%s lang=%s\n", name, city, lang) - # i8* == 是指针地址比较(C-Like 语义),内容比较需显式 strcmp + # i8* == compares pointer addresses (C-like); use strcmp for content testcheck.check(string.strcmp(name, "Alice") == 0, "ht str name OK", "ht str name FAILED") testcheck.check(string.strcmp(city, "Beijing") == 0, "ht str city OK", "ht str city FAILED") testcheck.check(string.strcmp(lang, "TransPyC") == 0, "ht str lang OK", "ht str lang FAILED") - # === Test 9: 扩容测试 === + # === Test 9: expansion test === testcheck.section("Test 9: 扩容测试 (>16 个元素)") ht3: hashtable.HashTable = hashtable.HashTable(bd) for i in range(50): @@ -135,7 +134,7 @@ def main() -> CInt | CExport: stdio.printf("ht3 len=%lu (after 50 inserts)\n", n3) testcheck.check(n3 == 50, "ht expand OK (50)", "ht expand FAILED") - # 验证几个值 + # Verify some values k5: str = stdlib.malloc(16) stdio.sprintf(k5, "key5") p5: t.CPtr = ht3[k5] @@ -157,7 +156,7 @@ def main() -> CInt | CExport: stdio.printf("ht3[key49]=%d\n", v49) testcheck.check(v49 == 4900, "ht expand key49 OK", "ht expand key49 FAILED") - # === Test 10: 扩容后迭代 === + # === Test 10: iterate after expansion === testcheck.section("Test 10: 扩容后迭代") iter_count3: int = 0 for k in ht3: @@ -165,7 +164,7 @@ def main() -> CInt | CExport: stdio.printf("ht3 iter count=%d\n", iter_count3) testcheck.check(iter_count3 == 50, "ht expand iter OK (50)", "ht expand iter FAILED") - # === Test 11: 删除后扩容 === + # === Test 11: operations after batch delete === testcheck.section("Test 11: 批量删除后操作") for j in range(25): del_buf: str = stdlib.malloc(16) @@ -175,7 +174,7 @@ def main() -> CInt | CExport: stdio.printf("ht3 len=%lu (after 25 deletes)\n", n3b) testcheck.check(n3b == 25, "ht after del OK (25)", "ht after del FAILED") - # 验证剩余的值 + # Verify remaining values k30: str = stdlib.malloc(16) stdio.sprintf(k30, "key30") p30: t.CPtr = ht3[k30] @@ -183,13 +182,13 @@ def main() -> CInt | CExport: stdio.printf("ht3[key30]=%d\n", v30) testcheck.check(v30 == 3000, "ht key30 after del OK", "ht key30 after del FAILED") - # 验证已删除的 key 不存在 + # Verify the deleted key is gone k0: str = stdlib.malloc(16) stdio.sprintf(k0, "key0") has_k0: int = k0 in ht3 testcheck.check(has_k0 == 0, "ht key0 deleted OK", "ht key0 still exists FAILED") - # === Test 12: 空表操作 === + # === Test 12: empty table operations === testcheck.section("Test 12: 空表操作") ht4: hashtable.HashTable = hashtable.HashTable(bd) testcheck.check(len(ht4) == 0, "empty ht len 0 OK", "empty ht len FAILED") diff --git a/IsinstanceTest/App/geom_lib.vp b/IsinstanceTest/App/geom_lib.vp index 494642a..49256f6 100644 --- a/IsinstanceTest/App/geom_lib.vp +++ b/IsinstanceTest/App/geom_lib.vp @@ -3,10 +3,8 @@ from t import CInt # ============================================================ -# 跨模块 isinstance 测试库 -# -# 供 main.vp import 使用:验证 isinstance 对"定义在其他模块 -# 的类"也能正确比较(对象 vtable 指针跨 obj 链接解析)。 +# Cross-module isinstance test library: classes defined here are imported by +# main.vp to verify vtable comparison resolves across object files. # ============================================================ diff --git a/IsinstanceTest/App/main.vp b/IsinstanceTest/App/main.vp index 32d4358..328527f 100644 --- a/IsinstanceTest/App/main.vp +++ b/IsinstanceTest/App/main.vp @@ -6,18 +6,12 @@ from t import CInt, CPtr, CExport # ============================================================ -# isinstance 内建函数测试(运行时 vtable 继承链比较) -# -# 场景覆盖: -# 1. CVTable 自身/子类→基类 -# 2. 运行时多态(基类指针指向子类对象) -# 3. 元组 (A, B) -# 4. 多继承(AB 同时是 A 和 B 的实例) -# 5. NoVTable 类(编译时静态判断) +# isinstance builtin test: runtime vtable inheritance-chain comparison over +# self/subclass, polymorphism, tuples, multiple inheritance, and NoVTable. # ============================================================ -# ========== CVTable 继承 ========== +# ========== CVTable inheritance ========== @t.CVTable class Animal: @@ -45,7 +39,7 @@ class Cat(Animal): return "Meow" -# ========== 多继承 ========== +# ========== multiple inheritance ========== @t.CVTable class A: @@ -70,7 +64,7 @@ class AB(A, B): self.b = b -# ========== NoVTable(编译时判断) ========== +# ========== NoVTable (compile-time) ========== @t.NoVTable class Plain: @@ -80,7 +74,7 @@ class Plain: def main() -> CInt | CExport: testcheck.begin("IsinstanceTest: isinstance 内建函数测试") - # --- 1. 自身类型 + 子类→基类 --- + # --- 1. self type and subclass -> base --- d: Dog | CPtr = Dog("dog") testcheck.check(isinstance(d, Dog) == 1, "isinstance(d, Dog) 自身 OK", "isinstance(d, Dog) FAILED") @@ -89,7 +83,7 @@ def main() -> CInt | CExport: testcheck.check(isinstance(d, Cat) == 0, "isinstance(d, Cat) 不匹配 OK", "isinstance(d, Cat) FAILED") - # --- 2. 运行时多态:基类指针指向子类对象 --- + # --- 2. runtime polymorphism: base pointer to subclass object --- a: Animal | CPtr = (Animal | CPtr)(d) testcheck.check(isinstance(a, Dog) == 1, "isinstance(Animal*, Dog 对象) 运行时多态 OK", @@ -101,13 +95,13 @@ def main() -> CInt | CExport: "isinstance(Animal*, Cat) 运行时 False OK", "isinstance(Animal*, Cat) FAILED") - # --- 3. 元组 --- + # --- 3. tuple --- testcheck.check(isinstance(d, (Cat, Dog)) == 1, "isinstance 元组命中 OK", "isinstance 元组 FAILED") testcheck.check(isinstance(d, (Cat, A)) == 0, "isinstance 元组未命中 OK", "isinstance 元组未命中 FAILED") - # --- 4. 多继承 --- + # --- 4. multiple inheritance --- ab: AB | CPtr = AB(1, 2) testcheck.check(isinstance(ab, A) == 1, "isinstance(AB, A) 多继承 OK", "isinstance(AB, A) FAILED") @@ -118,14 +112,14 @@ def main() -> CInt | CExport: testcheck.check(ab.get_a() == 1 and ab.get_b() == 2, "AB 字段/方法正常 OK", "AB 字段/方法 FAILED") - # --- 5. NoVTable(编译时静态判断) --- + # --- 5. NoVTable (compile-time static) --- p: Plain | CPtr = Plain() p.v = 42 testcheck.check(isinstance(p, Plain) == 1, "isinstance NoVTable 编译时 OK", "isinstance NoVTable FAILED") testcheck.check(p.v == 42, "NoVTable 字段正常 OK", "NoVTable 字段 FAILED") - # --- 6. 跨模块 isinstance(vtable 跨 obj 链接解析) --- + # --- 6. cross-module isinstance (vtable resolved at link time) --- cc: geom_lib.Circle | CPtr = geom_lib.Circle(5) testcheck.check(isinstance(cc, geom_lib.Circle) == 1, "跨模块 isinstance 自身 OK", "跨模块 isinstance 自身 FAILED") @@ -144,7 +138,7 @@ def main() -> CInt | CExport: testcheck.check(shp.area() == 5, "跨模块虚方法分派 OK", "跨模块虚方法分派 FAILED") testcheck.check(cc.area() == 5, "跨模块 Circle.area OK", "跨模块 Circle.area FAILED") - # --- 7. NoVTable 跨模块静态判断 --- + # --- 7. NoVTable cross-module static --- ps: geom_lib.PlainShape | CPtr = geom_lib.PlainShape() testcheck.check(isinstance(ps, geom_lib.PlainShape) == 1, "跨模块 NoVTable 静态 OK", "跨模块 NoVTable 静态 FAILED") diff --git a/IterTest/App/main.vp b/IterTest/App/main.vp index b06a852..a35e840 100644 --- a/IterTest/App/main.vp +++ b/IterTest/App/main.vp @@ -26,20 +26,20 @@ def test_for_in_char_ptr(): def test_strcpy_for_in(): testcheck.section("Test 3: strcpy using for-in") src: char* = "test" - # 手动实现 strcpy 用 for-in + # Implement strcpy by hand with for-in. import w32.win32memory buf: char* = w32.win32memory.VirtualAlloc(None, 64, 12288, 4) if uint64(buf) == 0: stdio.printf("SKIP: VirtualAlloc returned NULL\n") return string.memset(buf, 0, 64) - # 用 for-in 复制 + # Copy with for-in. p: char* = buf for ch in src: p[0] = ch p += 1 p[0] = 0 - # i8* == 是指针地址比较(C-Like 语义),字符串内容比较需显式 strcmp + # '==' on pointers compares addresses (C-like); use strcmp for contents. testcheck.check(string.strcmp(buf, "test") == 0, "strcpy for-in (result=test)", "strcpy for-in (cmp mismatch)") import w32.win32memory diff --git a/JsonTest/App/main.vp b/JsonTest/App/main.vp index 05abd2b..1370593 100644 --- a/JsonTest/App/main.vp +++ b/JsonTest/App/main.vp @@ -7,9 +7,7 @@ import string import w32.win32memory as win32mem import testcheck -# ============================================================ -# 测试 1:构造 JSON 值(使用 mpool) -# ============================================================ +# --- Test 1: construct JSON values (with mpool) --- def test_construct(pool: memhub.MemPool*): testcheck.section("Construct JsonValue (with mpool)") @@ -54,13 +52,11 @@ def test_construct(pool: memhub.MemPool*): testcheck.check(len(v9) == 0, "object empty len()==0", "object empty len()==0") -# ============================================================ -# 测试 2:构造数组和对象(Python风格API) -# ============================================================ +# --- Test 2: build arrays and objects (Pythonic API) --- def test_build_structures(pool: memhub.MemPool*): testcheck.section("Build Arrays and Objects (Pythonic API)") - # 构建数组 [1, 2, 3] + # Build array [1, 2, 3] arr: json.JsonValue* = json.array(pool) json.array_append(pool, arr, json.int_val(pool, 1)) json.array_append(pool, arr, json.int_val(pool, 2)) @@ -70,13 +66,13 @@ def test_build_structures(pool: memhub.MemPool*): testcheck.check(arr.get_item(1).as_int() == 2, "array get_item(1)==2", "array get_item(1)==2") testcheck.check(arr.get_item(2).as_int() == 3, "array get_item(2)==3", "array get_item(2)==3") - # 构建对象 {"name": "Viper", "version": 1} + # Build object {"name": "Viper", "version": 1} obj: json.JsonValue* = json.object(pool) json.object_set(pool, obj, "name", json.string_val(pool, "Viper")) json.object_set(pool, obj, "version", json.int_val(pool, 1)) testcheck.check(len(obj) == 2, "object len()==2", "object len()==2") - # Python风格取值:obj["key"] + # Pythonic access: obj["key"] name_val: json.JsonValue* = obj["name"] testcheck.check(name_val != None and string.strcmp(name_val.as_string(), "Viper") == 0, "obj['name']==Viper", "obj['name']==Viper") ver_val: json.JsonValue* = obj["version"] @@ -85,32 +81,30 @@ def test_build_structures(pool: memhub.MemPool*): testcheck.check(missing == None, "obj['missing']==None", "obj['missing']==None") -# ============================================================ -# 测试 3:JSON 解析 -# ============================================================ +# --- Test 3: parse JSON --- def test_parse(pool: memhub.MemPool*): testcheck.section("Parse JSON") - # 解析整数 + # Parse int v1: json.JsonValue* = json.parse(pool, "42") testcheck.check(v1.is_int(), "parse int is_int", "parse int is_int") testcheck.check(v1.as_int() == 42, "parse int == 42", "parse int == 42") - # 解析负数 + # Parse negative int v2: json.JsonValue* = json.parse(pool, "-7") testcheck.check(v2.as_int() == -7, "parse neg int == -7", "parse neg int == -7") - # 解析浮点数 + # Parse float v3: json.JsonValue* = json.parse(pool, "3.14") testcheck.check(v3.is_float(), "parse float is_float", "parse float is_float") testcheck.check(v3.as_float() > 3.13 and v3.as_float() < 3.15, "parse float ~= 3.14", "parse float ~= 3.14") - # 解析字符串 + # Parse string v4: json.JsonValue* = json.parse(pool, '"hello world"') testcheck.check(v4.is_string(), "parse string is_string", "parse string is_string") testcheck.check(string.strcmp(v4.as_string(), "hello world") == 0, "parse string == hello world", "parse string == hello world") - # 解析布尔 + # Parse bool v5: json.JsonValue* = json.parse(pool, "true") testcheck.check(v5.is_bool(), "parse true is_bool", "parse true is_bool") testcheck.check(v5.as_bool(), "parse true as_bool", "parse true as_bool") @@ -118,18 +112,18 @@ def test_parse(pool: memhub.MemPool*): v6: json.JsonValue* = json.parse(pool, "false") testcheck.check(not v6.as_bool(), "parse false !as_bool", "parse false !as_bool") - # 解析 null + # Parse null v7: json.JsonValue* = json.parse(pool, "null") testcheck.check(v7.is_null(), "parse null is_null", "parse null is_null") - # 解析数组 + # Parse array v8: json.JsonValue* = json.parse(pool, "[1, 2, 3]") testcheck.check(v8.is_array(), "parse array is_array", "parse array is_array") testcheck.check(len(v8) == 3, "parse array len()==3", "parse array len()==3") testcheck.check(v8.get_item(0).as_int() == 1, "parse array get_item(0)==1", "parse array get_item(0)==1") testcheck.check(v8.get_item(2).as_int() == 3, "parse array get_item(2)==3", "parse array get_item(2)==3") - # 解析对象(Python风格取值) + # Parse object (Pythonic access) v9: json.JsonValue* = json.parse(pool, '{"x": 10, "y": 20}') testcheck.check(v9.is_object(), "parse object is_object", "parse object is_object") testcheck.check(len(v9) == 2, "parse object len()==2", "parse object len()==2") @@ -139,23 +133,21 @@ def test_parse(pool: memhub.MemPool*): testcheck.check(y_val != None and y_val.as_int() == 20, "parse obj['y']==20", "parse obj['y']==20") -# ============================================================ -# 测试 4:JSON 序列化 -# ============================================================ +# --- Test 4: write JSON --- def test_write(pool: memhub.MemPool*): testcheck.section("Write JSON") - # 写整数 + # Write int v1: json.JsonValue* = json.int_val(pool, 42) s1: char* = json.write(pool, v1, False) testcheck.check(string.strcmp(s1, "42") == 0, "write int 42", "write int 42") - # 写字符串 + # Write string v2: json.JsonValue* = json.string_val(pool, "hello") s2: char* = json.write(pool, v2, False) testcheck.check(string.strcmp(s2, '"hello"') == 0, "write string hello", "write string hello") - # 写布尔 + # Write bool v3: json.JsonValue* = json.bool_val(pool, True) s3: char* = json.write(pool, v3, False) testcheck.check(string.strcmp(s3, "true") == 0, "write bool true", "write bool true") @@ -164,12 +156,12 @@ def test_write(pool: memhub.MemPool*): s4: char* = json.write(pool, v4, False) testcheck.check(string.strcmp(s4, "false") == 0, "write bool false", "write bool false") - # 写 null + # Write null v5: json.JsonValue* = json.null(pool) s5: char* = json.write(pool, v5, False) testcheck.check(string.strcmp(s5, "null") == 0, "write null", "write null") - # 写数组 + # Write array arr: json.JsonValue* = json.array(pool) json.array_append(pool, arr, json.int_val(pool, 1)) json.array_append(pool, arr, json.int_val(pool, 2)) @@ -177,7 +169,7 @@ def test_write(pool: memhub.MemPool*): s6: char* = json.write(pool, arr, False) testcheck.check(string.strcmp(s6, "[1,2,3]") == 0, "write array [1,2,3]", "write array [1,2,3]") - # 写对象 + # Write object obj: json.JsonValue* = json.object(pool) json.object_set(pool, obj, "a", json.int_val(pool, 1)) json.object_set(pool, obj, "b", json.string_val(pool, "x")) @@ -185,9 +177,7 @@ def test_write(pool: memhub.MemPool*): testcheck.check(s7 != None, "write object non-null", "write object non-null") -# ============================================================ -# 测试 5:解析复杂嵌套 JSON(Python风格API) -# ============================================================ +# --- Test 5: parse nested JSON (Pythonic API) --- def test_nested(pool: memhub.MemPool*): testcheck.section("Parse Nested JSON (Pythonic API)") @@ -196,7 +186,7 @@ def test_nested(pool: memhub.MemPool*): testcheck.check(root.is_object(), "nested is_object", "nested is_object") testcheck.check(len(root) == 4, "nested len()==4", "nested len()==4") - # Python风格取值:root["name"] + # Pythonic access: root["name"] name: json.JsonValue* = root["name"] testcheck.check(name != None and string.strcmp(name.as_string(), "Viper") == 0, "root['name']==Viper", "root['name']==Viper") @@ -204,14 +194,14 @@ def test_nested(pool: memhub.MemPool*): ver: json.JsonValue* = root["version"] testcheck.check(ver != None and ver.as_int() == 1, "root['version']==1", "root['version']==1") - # root["features"] 数组 + # root["features"] array feat: json.JsonValue* = root["features"] testcheck.check(feat != None and feat.is_array(), "root['features'] is_array", "root['features'] is_array") testcheck.check(feat != None and len(feat) == 3, "root['features'] len()==3", "root['features'] len()==3") testcheck.check(feat != None and string.strcmp(feat.get_item(0).as_string(), "fast") == 0, "root['features'][0]==fast", "root['features'][0]==fast") testcheck.check(feat != None and string.strcmp(feat.get_item(2).as_string(), "portable") == 0, "root['features'][2]==portable", "root['features'][2]==portable") - # root["nested"] 对象 + # root["nested"] object nested: json.JsonValue* = root["nested"] testcheck.check(nested != None and nested.is_object(), "root['nested'] is_object", "root['nested'] is_object") nk: json.JsonValue* = nested["key"] if nested != None else None @@ -220,30 +210,28 @@ def test_nested(pool: memhub.MemPool*): testcheck.check(nn != None and nn.as_int() == 99, "root['nested']['num']==99", "root['nested']['num']==99") -# ============================================================ -# 测试 6:mpool 重置后重新使用 -# ============================================================ +# --- Test 6: reuse mpool after reset --- def test_mpool_reuse(): testcheck.section("MPool Reuse") - # 分配内存 + # Allocate memory mem: t.CPtr = win32mem.VirtualAlloc(None, 8192, 0x3000, 0x04) testcheck.check(mem != None, "VirtualAlloc ok", "VirtualAlloc ok") pool: memhub.MemPool* = memhub.MemPool(mem, 8192) - # 第一次使用 + # First use v1: json.JsonValue* = json.int_val(pool, 100) testcheck.check(v1.as_int() == 100, "reuse round1 int==100", "reuse round1 int==100") - # 重置 mpool + # Reset mpool pool.reset() - # 第二次使用(内存复用) + # Second use (reuses memory) v2: json.JsonValue* = json.string_val(pool, "reused") testcheck.check(string.strcmp(v2.as_string(), "reused") == 0, "reuse round2 string==reused", "reuse round2 string==reused") - # 重置后再解析 + # Reset then parse again pool.reset() v3: json.JsonValue* = json.parse(pool, '{"test": true}') testcheck.check(v3.is_object(), "reuse round3 parse ok", "reuse round3 parse ok") @@ -253,13 +241,11 @@ def test_mpool_reuse(): win32mem.VirtualFree(mem, 0, 0x8000) -# ============================================================ -# 测试 7:转义字符解析 -# ============================================================ +# --- Test 7: escape characters --- def test_escape(pool: memhub.MemPool*): testcheck.section("Escape Characters") - # 解析含转义字符的字符串 + # Parse string with escapes v1: json.JsonValue* = json.parse(pool, '"hello\\nworld"') testcheck.check(v1.is_string(), "escape \\n is_string", "escape \\n is_string") sv1: char* = v1.as_string() @@ -274,13 +260,11 @@ def test_escape(pool: memhub.MemPool*): testcheck.check(v3.is_string(), "escape \\\" is_string", "escape \\\" is_string") -# ============================================================ -# 主函数 -# ============================================================ +# --- main --- def main() -> int | t.CExport: testcheck.begin("JSON Library Test (Pythonic API)") - # 使用 mpool 的 bump 分配器 + # Use mpool bump allocator mem: t.CPtr = win32mem.VirtualAlloc(None, 65536, 0x3000, 0x04) pool: memhub.MemPool* = memhub.MemPool(mem, 65536) diff --git a/LLvmLiteTest/App/main.vp b/LLvmLiteTest/App/main.vp index 7a813ae..c5a6eef 100644 --- a/LLvmLiteTest/App/main.vp +++ b/LLvmLiteTest/App/main.vp @@ -6,16 +6,11 @@ import testcheck import mlirlite -# 内存大小 -# 单端 MLIR 后 mlirlite 渲染单次 PrintModule 需约 1 MiB 缩进缓冲 + 类型/初值 -# 草稿,且本测试 27 个用例共享**同一个**池(不像 MLIRLiteTest 每用例切子池) -# ⇒ 512 KB 远不够(池耗尽)。与 MLIRLiteTest 主池同口径放大到 80 MiB。 +# Pool size: PrintModule needs ~1 MiB scratch and all 27 cases share one pool, so use 80 MiB. define POOL_SIZE = 83886080 # 80MB -# ============================================================ -# 测试 1: TypePrint 类型打印 -# ============================================================ +# --- Test 1: TypePrint --- def test_type_print(pool: memhub.MemBuddy*): testcheck.section("Test 1: TypePrint") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -29,7 +24,7 @@ def test_type_print(pool: memhub.MemBuddy*): "Int32 -> i32", "Int32 fail") - # 不透明指针: Ptr(Int32) -> !llvm.ptr + # opaque pointer: Ptr(Int32) -> !llvm.ptr ty_ptr: mlirlite.LLVMType* = core.Ptr(ty_i32) buf[0] = 0 core.PrintType(buf, 64, ty_ptr) @@ -54,9 +49,7 @@ def test_type_print(pool: memhub.MemBuddy*): "Int64 fail") -# ============================================================ -# 测试 2: ValuePrint 值打印 -# ============================================================ +# --- Test 2: ValuePrint --- def test_value_print(pool: memhub.MemBuddy*): testcheck.section("Test 2: ValuePrint") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -65,7 +58,7 @@ def test_value_print(pool: memhub.MemBuddy*): ty_i32: mlirlite.LLVMType* = core.Int32() - # 常量 42 -> "42 : i32"(MLIR attribute 文本形态) + # const 42 -> "42 : i32" (MLIR attribute text form) val42: mlirlite.Value* = mcore.ConstInt32(42) buf[0] = 0 mcore.PrintValue(buf, 64, val42) @@ -73,7 +66,7 @@ def test_value_print(pool: memhub.MemBuddy*): "ConstInt(42) -> '42 : i32'", "ConstInt fail") - # SSA 值 %0 -> "%0"(MLIR 操作数不带类型) + # SSA value %0 -> "%0" (MLIR operands carry no type) name_ssa: str = pool.alloc(16) string.strcpy(name_ssa, "%0") val_ssa: mlirlite.Value* = mcore.SSAValue(ty_i32, name_ssa) @@ -84,13 +77,7 @@ def test_value_print(pool: memhub.MemBuddy*): "SSAValue fail") -# ============================================================ -# 测试 3: 构建 add 函数 -# llvm.func @add(%a: i32, %b: i32) -> i32 { -# %0 = llvm.add %a, %b : i32 -# llvm.return %0 : i32 -# } -# ============================================================ +# --- Test 3: build add function --- def test_build_add(pool: memhub.MemBuddy*): testcheck.section("Test 3: build_add function") @@ -98,22 +85,22 @@ def test_build_add(pool: memhub.MemBuddy*): mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() - # 创建模块 + 函数 + # create module + function mod: mlirlite.Module* = mcore.NewModule("test_add") func: mlirlite.Function* = mcore.CreateFunction(mod, "add", ty_i32) - # 添加参数 + # add parameters mcore.AddParam(func, ty_i32, "%a") mcore.AddParam(func, ty_i32, "%b") - # 创建 entry 块 + # create entry block entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") - # 创建 builder + # create builder builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) - # 为参数创建 Value 包装 + # wrap parameters as Values v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_i32, "%b") @@ -123,13 +110,13 @@ def test_build_add(pool: memhub.MemBuddy*): # ret i32 %0 mlirlite.build_ret(builder, v_c) - # 打印函数 + # print function buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) - # 验证关键内容 + # verify key content testcheck.check(string.strstr(buf, "llvm.add %a, %b : i32") is not None, "contains 'llvm.add %a, %b : i32'", "missing 'llvm.add'") @@ -141,17 +128,7 @@ def test_build_add(pool: memhub.MemBuddy*): "missing function definition") -# ============================================================ -# 测试 4: 构建 if-then-else 函数(max) -# llvm.func @max(%a: i32, %b: i32) -> i32 { -# %0 = llvm.icmp "sgt" %a, %b : i32 -# llvm.cond_br %0, ^then, ^else -# ^then: -# llvm.return %a : i32 -# ^else: -# llvm.return %b : i32 -# } -# ============================================================ +# --- Test 4: build if-then-else (max) --- def test_build_if_else(pool: memhub.MemBuddy*): testcheck.section("Test 4: build if-then-else (max)") @@ -185,13 +162,13 @@ def test_build_if_else(pool: memhub.MemBuddy*): mlirlite.position_at_end(builder, else_blk) mlirlite.build_ret(builder, v_b) - # 打印函数 + # print function buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) - # 验证关键内容 + # verify key content testcheck.check(string.strstr(buf, "llvm.icmp \"sgt\"") is not None, "contains 'llvm.icmp \"sgt\"'", "missing 'llvm.icmp \"sgt\"'") @@ -206,9 +183,7 @@ def test_build_if_else(pool: memhub.MemBuddy*): "missing block label '^else:'") -# ============================================================ -# 测试 5: 完整模块 ModulePrint -# ============================================================ +# --- Test 5: ModulePrint --- def test_module_print(pool: memhub.MemBuddy*): testcheck.section("Test 5: ModulePrint") @@ -217,12 +192,12 @@ def test_module_print(pool: memhub.MemBuddy*): ty_i32: mlirlite.LLVMType* = core.Int32() ty_void: mlirlite.LLVMType* = core.Void() - # 创建模块 + # create module mod: mlirlite.Module* = mcore.NewModule("test_module") mlirlite.module_set_target(mod, "x86_64-pc-windows-gnu") mlirlite.module_set_datalayout(mod, "e-m:w-p270:32:32") - # 函数 1: add + # function 1: add func_add: mlirlite.Function* = mcore.CreateFunction(mod, "add", ty_i32) mcore.AddParam(func_add, ty_i32, "%a") mcore.AddParam(func_add, ty_i32, "%b") @@ -234,20 +209,20 @@ def test_module_print(pool: memhub.MemBuddy*): v_sum: mlirlite.Value* = mlirlite.build_add(builder1, v_a1, v_b1) mlirlite.build_ret(builder1, v_sum) - # 函数 2: void 函数 + # function 2: void function func_void: mlirlite.Function* = mcore.CreateFunction(mod, "noop", ty_void) entry2: mlirlite.BasicBlock* = mcore.CreateBlock(func_void, "entry") builder2: mlirlite.IRBuilder* = mcore.NewBuilder(func_void) mlirlite.position_at_end(builder2, entry2) mlirlite.build_ret_void(builder2) - # 打印模块 + # print module buf: str = pool.alloc(8192) buf[0] = 0 mcore.PrintModule(buf, 8192, mod) testcheck.info(buf) - # 验证关键内容 + # verify key content testcheck.check(string.strstr(buf, "module {") is not None, "contains 'module {'", "missing 'module {'") @@ -265,9 +240,7 @@ def test_module_print(pool: memhub.MemBuddy*): "missing 'llvm.return'") -# ============================================================ -# 测试 6: 数组类型打印 -# ============================================================ +# --- Test 6: ArrayType --- def test_array_type(pool: memhub.MemBuddy*): testcheck.section("Test 6: ArrayType") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -293,9 +266,7 @@ def test_array_type(pool: memhub.MemBuddy*): "nested array fail") -# ============================================================ -# 测试 7: 结构体类型打印 -# ============================================================ +# --- Test 7: StructType --- def test_struct_type(pool: memhub.MemBuddy*): testcheck.section("Test 7: StructType") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -317,7 +288,7 @@ def test_struct_type(pool: memhub.MemBuddy*): "struct {i32, i8*} -> !llvm.struct<(i32, !llvm.ptr)>", "struct fail") - # 空结构体 -> !llvm.struct<()> + # empty struct -> !llvm.struct<()> ty_empty: mlirlite.LLVMType* = core.Struct(None, 0) buf[0] = 0 core.PrintType(buf, 128, ty_empty) @@ -326,9 +297,7 @@ def test_struct_type(pool: memhub.MemBuddy*): "empty struct fail") -# ============================================================ -# 测试 8: 函数类型打印 -# ============================================================ +# --- Test 8: FuncType --- def test_func_type(pool: memhub.MemBuddy*): testcheck.section("Test 8: FuncType") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -350,7 +319,7 @@ def test_func_type(pool: memhub.MemBuddy*): "func type -> !llvm.func", "func type fail") - # void () -> !llvm.func — 无参数 void 函数类型 + # void () -> !llvm.func: no-arg void function type ty_void: mlirlite.LLVMType* = core.Void() ty_func_void: mlirlite.LLVMType* = core.Func(ty_void, None, 0) buf[0] = 0 @@ -360,9 +329,7 @@ def test_func_type(pool: memhub.MemBuddy*): "void func fail") -# ============================================================ -# 测试 9: 声明系统(declare vs define) -# ============================================================ +# --- Test 9: Declare vs Define --- def test_declare(pool: memhub.MemBuddy*): testcheck.section("Test 9: Declare vs Define") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -403,9 +370,7 @@ def test_declare(pool: memhub.MemBuddy*): "define missing body") -# ============================================================ -# 测试 10: 浮点类型与 ConstFloat -# ============================================================ +# --- Test 10: Float Types & ConstFloat --- def test_float_types(pool: memhub.MemBuddy*): testcheck.section("Test 10: Float Types & ConstFloat") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -444,8 +409,7 @@ def test_float_types(pool: memhub.MemBuddy*): "FP128 -> f128", "FP128 fail") - # ConstFloat(3.14) -> "0x40091EB851EB851F : f64" - # (位模式无精度损失;类型注解为 MLIR 形态 f64) + # ConstFloat(3.14) -> "0x40091EB851EB851F : f64" (bit pattern, lossless; MLIR type f64) val_pi: mlirlite.Value* = mcore.ConstFloat(ty_double, 3.14) buf[0] = 0 mcore.PrintValue(buf, 128, val_pi) @@ -457,9 +421,7 @@ def test_float_types(pool: memhub.MemBuddy*): "ConstFloat missing hex pattern") -# ============================================================ -# 测试 11: 浮点二元运算 -# ============================================================ +# --- Test 11: Float Binary Ops --- def test_float_binops(pool: memhub.MemBuddy*): testcheck.section("Test 11: Float Binary Ops") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -492,9 +454,7 @@ def test_float_binops(pool: memhub.MemBuddy*): "missing 'llvm.return'") -# ============================================================ -# 测试 12: 位运算与移位 -# ============================================================ +# --- Test 12: Bitwise & Shift Ops --- def test_bitwise_ops(pool: memhub.MemBuddy*): testcheck.section("Test 12: Bitwise & Shift Ops") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -530,9 +490,7 @@ def test_bitwise_ops(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "llvm.shl %2, %b : i32") is not None, "has 'llvm.shl %2, %b : i32'", "missing 'llvm.shl'") -# ============================================================ -# 测试 13: FCMP 比较 -# ============================================================ +# --- Test 13: FCMP --- def test_fcmp(pool: memhub.MemBuddy*): testcheck.section("Test 13: FCMP") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -563,9 +521,7 @@ def test_fcmp(pool: memhub.MemBuddy*): "missing 'llvm.fcmp \"oeq\"'") -# ============================================================ -# 测试 14: 类型转换 (zext, ptrtoint, inttoptr) -# ============================================================ +# --- Test 14: Casts (zext/ptrtoint/inttoptr) --- def test_casts(pool: memhub.MemBuddy*): testcheck.section("Test 14: Casts (zext/ptrtoint/inttoptr)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -603,9 +559,7 @@ def test_casts(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "llvm.inttoptr %1 : i64 to !llvm.ptr") is not None, "has 'llvm.inttoptr %1 : i64 to !llvm.ptr'", "missing 'llvm.inttoptr'") -# ============================================================ -# 测试 15: 浮点转换 (fp2si, si2fp) -# ============================================================ +# --- Test 15: FP Conversions (fp2si/si2fp) --- def test_fp_conversions(pool: memhub.MemBuddy*): testcheck.section("Test 15: FP Conversions (fp2si/si2fp)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -638,9 +592,7 @@ def test_fp_conversions(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "llvm.fptosi %0 : f64 to i32") is not None, "has 'llvm.fptosi %0 : f64 to i32'", "missing 'llvm.fptosi'") -# ============================================================ -# 测试 16: Phi 节点 -# ============================================================ +# --- Test 16: Phi Node --- def test_phi(pool: memhub.MemBuddy*): testcheck.section("Test 16: Phi Node") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -682,7 +634,7 @@ def test_phi(pool: memhub.MemBuddy*): mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) - # phi 已转为块参数:不再输出 phi 行,改为 ^merge(%…) + llvm.br ^merge(%…) + # phi lowered to block args: no phi line, emits ^merge(%...) + llvm.br ^merge(%...) testcheck.check(string.strstr(buf, "llvm.br ^merge(%c0 : i32)") is not None, "has 'llvm.br ^merge(%c0 : i32)'", "missing branch block operands") testcheck.check(string.strstr(buf, "^merge(%0: i32):") is not None, "has '^merge(%0: i32):'", "missing block arguments") testcheck.check(string.strstr(buf, "^then:") is not None, "has '^then:'", "missing '^then:'") @@ -690,9 +642,7 @@ def test_phi(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, " = phi ") is None, "phi 行不再输出", "phi line should not be emitted") -# ============================================================ -# 测试 17: Switch -# ============================================================ +# --- Test 17: Switch --- def test_switch(pool: memhub.MemBuddy*): testcheck.section("Test 17: Switch") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -737,9 +687,7 @@ def test_switch(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "^case0:") is not None, "has '^case0:'", "missing '^case0:'") -# ============================================================ -# 测试 18: Select -# ============================================================ +# --- Test 18: Select --- def test_select(pool: memhub.MemBuddy*): testcheck.section("Test 18: Select") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -768,9 +716,7 @@ def test_select(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "llvm.select %0, %a, %b : i1, i32") is not None, "has 'llvm.select %0, %a, %b : i1, i32'", "missing 'llvm.select'") -# ============================================================ -# 测试 19: 全局变量 (字符串常量 + 整数) -# ============================================================ +# --- Test 19: Global Variables --- def test_globals(pool: memhub.MemBuddy*): testcheck.section("Test 19: Global Variables") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -781,13 +727,13 @@ def test_globals(pool: memhub.MemBuddy*): mod: mlirlite.Module* = mcore.NewModule("test_globals") mlirlite.module_set_target(mod, "x86_64-pc-windows-gnu") - # 字符串常量: @.str = private unnamed_addr constant [6 x i8] c"hello\00" + # string constant: @.str = private unnamed_addr constant [6 x i8] c"hello\00" mcore.CreateGlobalString(mod, ".str", "hello") - # 整数全局变量: @counter = global i32 0 + # integer global: @counter = global i32 0 mcore.CreateGlobalInt(mod, "counter", 32, 0) - # 添加一个简单函数使模块非空 + # add a simple function to make the module non-empty func: mlirlite.Function* = mcore.CreateFunction(mod, "use_global", ty_void) entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) @@ -809,9 +755,7 @@ def test_globals(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "llvm.mlir.global @counter") is not None, "has 'llvm.mlir.global @counter'", "missing integer global") -# ============================================================ -# 测试 20: 函数与参数属性 -# ============================================================ +# --- Test 20: Function & Param Attributes --- def test_attributes(pool: memhub.MemBuddy*): testcheck.section("Test 20: Function & Param Attributes") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -822,15 +766,15 @@ def test_attributes(pool: memhub.MemBuddy*): mod: mlirlite.Module* = mcore.NewModule("test_attrs") func: mlirlite.Function* = mcore.CreateFunction(mod, "attr_test", ty_i32) - # 参数 0: i32 noundef %x + # param 0: i32 noundef %x p0: mlirlite.Param* = mcore.AddParam(func, ty_i32, "%x") mcore.ParamSetAttrs(p0, "noundef") - # 参数 1: i8* nocapture %p + # param 1: i8* nocapture %p p1: mlirlite.Param* = mcore.AddParam(func, ty_i8ptr, "%p") mcore.ParamSetAttrs(p1, "nocapture") - # 函数属性: nounwind + # function attribute: nounwind mcore.FunctionSetAttrs(func, "nounwind") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") @@ -844,8 +788,8 @@ def test_attributes(pool: memhub.MemBuddy*): mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) - # MLIR v1: 函数/参数属性(Attrs)记录但不渲染(见 includes/mlirlite/README.md §3.3)。 - # 故断言签名本身正确、且属性文本不出现(模型字段仍保留)。 + # MLIR v1 records func/param attrs but does not render them (see mlirlite README 3.3), + # so assert the signature is correct and attr text is absent; model fields remain. testcheck.check(string.strstr(buf, "llvm.func @attr_test(%x: i32, %p: !llvm.ptr) -> i32") is not None, "has 'llvm.func @attr_test(%x: i32, %p: !llvm.ptr) -> i32'", "missing attribute-test function signature") @@ -860,9 +804,7 @@ def test_attributes(pool: memhub.MemBuddy*): "func attr 'nounwind' should not be rendered") -# ============================================================ -# 测试 21: 原子操作 (atomicrmw / cmpxchg) -# ============================================================ +# --- Test 21: Atomic Ops --- def test_atomic(pool: memhub.MemBuddy*): testcheck.section("Test 21: Atomic Ops") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -893,9 +835,7 @@ def test_atomic(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "monotonic") is not None, "has 'monotonic'", "missing 'monotonic'") -# ============================================================ -# 测试 22: 内联汇编 + unreachable -# ============================================================ +# --- Test 22: Inline ASM & Unreachable --- def test_inline_asm_unreachable(pool: memhub.MemBuddy*): testcheck.section("Test 22: Inline ASM & Unreachable") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -927,9 +867,7 @@ def test_inline_asm_unreachable(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "llvm.unreachable") is not None, "has 'llvm.unreachable'", "missing 'llvm.unreachable'") -# ============================================================ -# 测试 23: SSA 验证 - 合法函数通过 -# ============================================================ +# --- Test 23: Verify Valid Function --- def test_verify_valid(pool: memhub.MemBuddy*): testcheck.section("Test 23: Verify Valid Function") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -958,9 +896,7 @@ def test_verify_valid(pool: memhub.MemBuddy*): "wrong error code for valid function") -# ============================================================ -# 测试 24: SSA 验证 - 缺少终止指令 -# ============================================================ +# --- Test 24: Verify Missing Terminator --- def test_verify_no_terminator(pool: memhub.MemBuddy*): testcheck.section("Test 24: Verify Missing Terminator") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -974,7 +910,7 @@ def test_verify_no_terminator(pool: memhub.MemBuddy*): builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") - mlirlite.build_add(builder, v_a, v_a) # 无 ret + mlirlite.build_add(builder, v_a, v_a) # no ret result: mlirlite.VerifyResult* = mcore.NewVerifyResult(4096) err_count: int = mcore.VerifyFunction(func, result) @@ -986,9 +922,7 @@ def test_verify_no_terminator(pool: memhub.MemBuddy*): "wrong error code for missing terminator") -# ============================================================ -# 测试 25: SSA 验证 - 重复定义 -# ============================================================ +# --- Test 25: Verify Duplicate Definition --- def test_verify_duplicate_def(pool: memhub.MemBuddy*): testcheck.section("Test 25: Verify Duplicate Definition") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -1004,7 +938,7 @@ def test_verify_duplicate_def(pool: memhub.MemBuddy*): v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_c: mlirlite.Value* = mlirlite.build_add(builder, v_a, v_a) - # 手动追加重复定义行 "%0 = add i32 %a, %a" + # manually append a duplicate definition line "%0 = add i32 %a, %a" dup_text: str = pool.alloc(64) string.strcpy(dup_text, "%0 = add i32 %a, %a") mlirlite.block_append_text(pool, entry, dup_text) @@ -1021,9 +955,7 @@ def test_verify_duplicate_def(pool: memhub.MemBuddy*): "wrong error code for duplicate def") -# ============================================================ -# 测试 26: SSA 验证 - 未定义引用 -# ============================================================ +# --- Test 26: Verify Undefined Use --- def test_verify_undef_use(pool: memhub.MemBuddy*): testcheck.section("Test 26: Verify Undefined Use") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -1035,12 +967,12 @@ def test_verify_undef_use(pool: memhub.MemBuddy*): mcore.AddParam(func, ty_i32, "%a") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") - # 手动追加含未定义引用的行 "%0 = add i32 %ghost, %a" + # manually append a line with an undefined reference "%0 = add i32 %ghost, %a" line1: str = pool.alloc(64) string.strcpy(line1, "%0 = add i32 %ghost, %a") mlirlite.block_append_text(pool, entry, line1) - # 手动追加终止指令 + # manually append terminator line2: str = pool.alloc(64) string.strcpy(line2, "ret i32 %0") mlirlite.block_append_text(pool, entry, line2) @@ -1056,9 +988,7 @@ def test_verify_undef_use(pool: memhub.MemBuddy*): "wrong error code for undefined use") -# ============================================================ -# 测试 27: SSA 验证 - 模块级验证(含 phi/分支,验证块标签修复) -# ============================================================ +# --- Test 27: Verify Module (phi/labels) --- def test_verify_module(pool: memhub.MemBuddy*): testcheck.section("Test 27: Verify Module (phi/labels)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -1067,7 +997,7 @@ def test_verify_module(pool: memhub.MemBuddy*): mod: mlirlite.Module* = mcore.NewModule("verify_module") - # 函数 1: 简单 add(合法) + # function 1: simple add (valid) func1: mlirlite.Function* = mcore.CreateFunction(mod, "add", ty_i32) mcore.AddParam(func1, ty_i32, "%a") mcore.AddParam(func1, ty_i32, "%b") @@ -1079,7 +1009,7 @@ def test_verify_module(pool: memhub.MemBuddy*): v_c: mlirlite.Value* = mlirlite.build_add(builder1, v_a, v_b) mlirlite.build_ret(builder1, v_c) - # 函数 2: 含 phi 与分支(合法,验证块标签不被误报为未定义) + # function 2: phi + branches (valid; block labels must not be flagged undefined) func2: mlirlite.Function* = mcore.CreateFunction(mod, "phi_test", ty_i32) f2_entry: mlirlite.BasicBlock* = mcore.CreateBlock(func2, "entry") then_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func2, "then") @@ -1122,7 +1052,7 @@ def test_verify_module(pool: memhub.MemBuddy*): def main() -> int: testcheck.begin("LLvmLiteTest: mlirlite 库(LLVM IR 生成)") - # 初始化 mpool + # init pool pool_mem: bytes = stdlib.malloc(POOL_SIZE) if pool_mem is None: stdio.printf("FAIL: malloc for pool failed\n") diff --git a/ListTest/App/main.vp b/ListTest/App/main.vp index fd655dd..7391d51 100644 --- a/ListTest/App/main.vp +++ b/ListTest/App/main.vp @@ -14,11 +14,11 @@ def main() -> CInt | CExport: testcheck.begin("ListTest: list[T] 堆容器测试") - # 创建 mbuddy arena + # Create the mbuddy arena. arena: bytes = stdlib.malloc(65536) bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536) - # === Test 1: 创建和 append === + # === Test 1: create and append === testcheck.section("Test 1: 创建和 append") nums = list[int](bd) nums.append(10) @@ -58,7 +58,7 @@ def main() -> CInt | CExport: n3: sizet = nums.__len__() testcheck.check(n3 == 0, "clear OK (0)", "clear FAILED expect 0") - # === Test 6: 容量增长 (append 超过初始容量 8) === + # === Test 6: capacity growth (append past initial capacity 8) === testcheck.section("Test 6: 容量增长") nums2 = list[int](bd) i: CInt @@ -76,7 +76,7 @@ def main() -> CInt | CExport: break testcheck.check(ok == 1, "grow data OK", "grow data FAILED") - # === Test 7: 重新 append 后验证 === + # === Test 7: verify after re-append === testcheck.section("Test 7: 重新 append") nums2.clear() nums2.append(100) diff --git a/LogicFlowTest/App/logic_test.vp b/LogicFlowTest/App/logic_test.vp index 672bc2a..95e86bf 100644 --- a/LogicFlowTest/App/logic_test.vp +++ b/LogicFlowTest/App/logic_test.vp @@ -361,9 +361,8 @@ def ForWithCaseNoBreakNested(inner_limit: int): # ============================================================ -# match case 内 break = 跳出 match(C switch 语义),**不**跳出外层循环 -# 期望 limit=5:i=0 走 _ (+0)、i=1 走 case 1 (+100) 后 break 出 match(循环继续)、 -# i=2 走 case 2 (+10)、i=3 (+3)、i=4 (+4) ⇒ 117 +# break inside match exits the match (C switch semantics), not the outer loop. +# For limit=5 the expected result is 117. # ============================================================ def MatchCaseBreakTest(limit: int) -> int: i: int = 0 @@ -381,8 +380,8 @@ def MatchCaseBreakTest(limit: int) -> int: # ============================================================ -# switch(C switch 语义):默认不穿透;case 体内写 `fallthrough` 才落到下一个 case。 -# 期望 value=1 → 1+2+3=6;value=2 → 2+3=5;value=3 → 3;其它 → 77 +# switch (C semantics): no fallthrough by default; `fallthrough` continues. +# Expected: value=1 -> 6, value=2 -> 5, value=3 -> 3, else -> 77. # ============================================================ def SwitchCaseFallthroughTest(value: int) -> int: result: int = 0 @@ -401,9 +400,8 @@ def SwitchCaseFallthroughTest(value: int) -> int: # ============================================================ -# switch 内 break = 跳出 switch(不跳出外层循环) -# 期望 limit=5:i=0 走 default (+0)、i=1 走 case 1 (+100) 后 break 出 switch、 -# i=2 走 case 2 (+10)、i=3 (+3)、i=4 (+4) ⇒ 117 +# break inside switch exits the switch, not the outer loop. +# For limit=5 the expected result is 117. # ============================================================ def SwitchCaseBreakTest(limit: int) -> int: i: int = 0 @@ -421,8 +419,8 @@ def SwitchCaseBreakTest(limit: int) -> int: # ============================================================ -# switch 多值 case:`case 1 | 2:` 命中同一个臂 -# 期望 value=1 → 10;value=2 → 10;value=3 → 30;其它 → 99 +# switch multi-value case: `case 1 | 2:` hits the same arm. +# Expected: value=1 -> 10, value=2 -> 10, value=3 -> 30, else -> 99. # ============================================================ def SwitchMultiValueTest(value: int) -> int: result: int = 0 diff --git a/LoopTest/App/main.vp b/LoopTest/App/main.vp index cb64b03..93d0c51 100644 --- a/LoopTest/App/main.vp +++ b/LoopTest/App/main.vp @@ -30,7 +30,7 @@ def test_nested_loop(): for j in range(5): if i < j: count += 1 - # 上三角: 4+3+2+1 = 10 + # Upper triangle: 4+3+2+1 = 10. testcheck.check(count == 10, "nested loop (count=10)", "nested loop (expect 10)") def test_break(): @@ -50,7 +50,7 @@ def test_continue(): if i % 3 == 0: continue sum_val += i - # 跳过 0,3,6,9,12,15,18, 剩余和 = sum(0..19) - sum(0,3,6,9,12,15,18) = 190 - 63 = 127 + # Skip multiples of 3: 190 - 63 = 127. testcheck.check(sum_val == 127, "continue (sum=127)", "continue (expect 127)") def test_range_step(): diff --git a/MLIRLiteTest/App/main.vp b/MLIRLiteTest/App/main.vp index 35d5faa..c4c51a1 100644 --- a/MLIRLiteTest/App/main.vp +++ b/MLIRLiteTest/App/main.vp @@ -74,9 +74,7 @@ def dump_mlir(pool: memhub.MemBuddy*, name: str, buf: str): stdio.printf(" [mlir] wrote %s (%d bytes)\n", path, int(string.strlen(buf))) -# ============================================================ -# 测试 1: TypePrint 类型打印(MLIR llvm 方言类型) -# ============================================================ +# Test 1: TypePrint - MLIR LLVM dialect type printing def test_type_print(pool: memhub.MemBuddy*): testcheck.section("Test 1: TypePrint (MLIR types)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -90,7 +88,7 @@ def test_type_print(pool: memhub.MemBuddy*): "Int32 -> i32", "Int32 fail") - # 不透明指针: Ptr(Int32) -> !llvm.ptr + # Opaque pointer: Ptr(Int32) -> !llvm.ptr ty_ptr: mlirlite.LLVMType* = core.Ptr(ty_i32) buf[0] = 0 core.PrintType(buf, 256, ty_ptr) @@ -137,7 +135,7 @@ def test_type_print(pool: memhub.MemBuddy*): "struct {i32, i8*} -> !llvm.struct<(i32, !llvm.ptr)>", "struct fail") - # 空结构体 -> !llvm.struct<()> + # Empty struct -> !llvm.struct<()> ty_empty: mlirlite.LLVMType* = core.Struct(None, 0) buf[0] = 0 core.PrintType(buf, 256, ty_empty) @@ -145,7 +143,7 @@ def test_type_print(pool: memhub.MemBuddy*): "empty struct -> !llvm.struct<()>", "empty struct fail") - # 函数类型 i32 (i32, i8*) -> !llvm.func + # Function type -> !llvm.func fn1: mlirlite.ParamNode* = core.NewParamNode(ty_i32) fn2: mlirlite.ParamNode* = core.NewParamNode(ty_i8ptr) fhead: mlirlite.ParamNode* = core.ParamListAppend(None, None, fn1) @@ -154,8 +152,8 @@ def test_type_print(pool: memhub.MemBuddy*): buf[0] = 0 core.PrintType(buf, 256, ty_func) dump_mlir(pool, "T01_types.mlir", buf) - # 把实际值写进失败报文:断言失败时 FAIL 行本身就能看到真实形态 - # (避免"只看到 fail、看不到实际值"导致来回猜) + # Embed the actual value in the failure message so the FAIL line shows the + # real form directly, avoiding guesswork from a bare "fail" ft_msg: str = pool.alloc(512) if ft_msg is not None: viperlib.snprintf(ft_msg, 512, @@ -166,9 +164,7 @@ def test_type_print(pool: memhub.MemBuddy*): ft_msg) -# ============================================================ -# 测试 2: ValuePrint 值打印(MLIR,仅供诊断) -# ============================================================ +# Test 2: ValuePrint - value printing (diagnostics only) def test_value_print(pool: memhub.MemBuddy*): testcheck.section("Test 2: ValuePrint (MLIR)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) @@ -177,7 +173,7 @@ def test_value_print(pool: memhub.MemBuddy*): ty_i32: mlirlite.LLVMType* = core.Int32() - # 常量 42 -> "42 : i32" + # Constant 42 -> "42 : i32" val42: mlirlite.Value* = mcore.ConstInt32(42) buf[0] = 0 mcore.PrintValue(buf, 128, val42) @@ -185,7 +181,7 @@ def test_value_print(pool: memhub.MemBuddy*): "ConstInt(42) -> '42 : i32'", "ConstInt fail") - # SSA 值 -> "%0"(MLIR 操作数不带类型) + # SSA value -> "%0" (MLIR operands carry no type) val_ssa: mlirlite.Value* = mcore.SSAValue(ty_i32, "%0") buf[0] = 0 mcore.PrintValue(buf, 128, val_ssa) @@ -195,13 +191,7 @@ def test_value_print(pool: memhub.MemBuddy*): "SSAValue fail") -# ============================================================ -# 测试 3: 构建 add 函数 -# llvm.func @add(%a: i32, %b: i32) -> i32 { -# %0 = llvm.add %a, %b : i32 -# llvm.return %0 : i32 -# } -# ============================================================ +# Test 3: build add function (llvm.func @add + llvm.add + llvm.return) def test_build_add(pool: memhub.MemBuddy*): testcheck.section("Test 3: build_add function") @@ -247,9 +237,7 @@ def test_build_add(pool: memhub.MemBuddy*): "entry block should not be labelled") -# ============================================================ -# 测试 4: if-else(max) -# ============================================================ +# Test 4: build if-then-else (max) def test_build_if_else(pool: memhub.MemBuddy*): testcheck.section("Test 4: build if-then-else (max)") @@ -301,9 +289,7 @@ def test_build_if_else(pool: memhub.MemBuddy*): "missing block label '^else:'") -# ============================================================ -# 测试 5: void 函数 -# ============================================================ +# Test 5: void function def test_build_void(pool: memhub.MemBuddy*): testcheck.section("Test 5: void function") @@ -333,9 +319,7 @@ def test_build_void(pool: memhub.MemBuddy*): "missing 'llvm.return'") -# ============================================================ -# 测试 6: 模块输出(module / declare vs define) -# ============================================================ +# Test 6: module printing (module / declare vs define) def test_module_print(pool: memhub.MemBuddy*): testcheck.section("Test 6: ModulePrint") @@ -347,7 +331,7 @@ def test_module_print(pool: memhub.MemBuddy*): mlirlite.module_set_target(mod, "x86_64-pc-windows-gnu") mlirlite.module_set_datalayout(mod, "e-m:w-p270:32:32") - # declare: llvm.func @extern_func(%x: i32) -> i32(无体) + # declare: llvm.func @extern_func(%x: i32) -> i32 (no body) func_decl: mlirlite.Function* = mcore.CreateDeclare(mod, "extern_func", ty_i32) mcore.AddParam(func_decl, ty_i32, "%x") @@ -387,9 +371,7 @@ def test_module_print(pool: memhub.MemBuddy*): "missing define body") -# ============================================================ -# 测试 7: 常量物化(操作数 42 -> llvm.mlir.constant) -# ============================================================ +# Test 7: constant materialization (operand 42 -> llvm.mlir.constant) def test_const_materialize(pool: memhub.MemBuddy*): testcheck.section("Test 7: constant materialization") @@ -423,7 +405,7 @@ def test_const_materialize(pool: memhub.MemBuddy*): "add 行引用物化后的 SSA 名 '%c0'", "add line does not reference materialized constant") - # 同 (类型,文本) 常量只物化一次:add 的两个操作数都是 42 + # Same (type, text) constant materializes once: both add operands are 42 func2: mlirlite.Function* = mcore.CreateFunction(mod, "const_twice", ty_i32) entry2: mlirlite.BasicBlock* = mcore.CreateBlock(func2, "entry") builder2: mlirlite.IRBuilder* = mcore.NewBuilder(func2) @@ -439,9 +421,7 @@ def test_const_materialize(pool: memhub.MemBuddy*): "constant dedup failed") -# ============================================================ -# 测试 8: phi -> 块参数 -# ============================================================ +# Test 8: phi -> block arguments def test_phi_block_args(pool: memhub.MemBuddy*): testcheck.section("Test 8: phi -> block arguments") @@ -497,9 +477,7 @@ def test_phi_block_args(pool: memhub.MemBuddy*): "phi line should not be emitted") -# ============================================================ -# 测试 9: 内存 / 调用 / 转换 -# ============================================================ +# Test 9: memory / call / cast def test_mem_call_cast(pool: memhub.MemBuddy*): testcheck.section("Test 9: memory / call / cast") @@ -544,9 +522,8 @@ def test_mem_call_cast(pool: memhub.MemBuddy*): testcheck.info(buf) dump_mlir(pool, "T09_mem_call_cast.mlir", buf) - # 整模块另存:mlir-opt 要求被调符号在模块作用域内**有声明**; - # 单函数文本不含 declare,会报 - # 'llvm.call' op 'callee' does not reference a symbol in the current scope + # Save the whole module: mlir-opt requires callees declared at module scope, + # otherwise single-function text without declare fails symbol resolution decl: mlirlite.Function* = mcore.CreateDeclare(mod, "callee", ty_i32) mcore.AddParam(decl, ty_i32, "%x") mbuf: str = pool.alloc(65536) @@ -571,9 +548,7 @@ def test_mem_call_cast(pool: memhub.MemBuddy*): "contains 'llvm.ptrtoint'", "missing 'llvm.ptrtoint'") -# ============================================================ -# 测试 10: 全局变量(字符串常量 / 整数 / 整型数组) -# ============================================================ +# Test 10: global variables (string constant / int / int array) def test_globals(pool: memhub.MemBuddy*): testcheck.section("Test 10: Global Variables") @@ -591,8 +566,8 @@ def test_globals(pool: memhub.MemBuddy*): # @counter = global i32 0 mcore.CreateGlobalInt(mod, "counter", 32, 0) - # @arr = [i8 1, i8 2] -> [1 : i8, 2 : i8](元素带类型注解;dense<...> 对 - # !llvm.array 非法——dense 只接受 builtin shaped 类型,实测 mlir-opt 22.1.8) + # @arr = [i8 1, i8 2] -> [1 : i8, 2 : i8] (elements carry type annotations); + # dense<...> is illegal for !llvm.array (it only accepts builtin shaped types) ty_arr2: mlirlite.LLVMType* = core.Array(ty_i8, 2) gv_arr: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "arr", ty_arr2) init_arr: str = pool.alloc(32) @@ -614,26 +589,24 @@ def test_globals(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "llvm.mlir.global") is not None, "contains 'llvm.mlir.global'", "missing 'llvm.mlir.global'") - # 符号名以 '.' 开头必须加引号(MLIR 裸名须字母/下划线开头) - # 实际形态:llvm.mlir.global … constant @".str"("hello\00") : !llvm.array<6 x i8> + # A '.'-prefixed symbol name must be quoted (MLIR bare names start with a letter or _) + # Actual form: llvm.mlir.global ... constant @".str"("hello\00") : !llvm.array<6 x i8> testcheck.check(string.strstr(buf, "@\".str\"(") is not None, "字符串全局名引号形态 '@\".str\"('", "missing quoted string global name") - # 字符串属性长度必须等于 i8 数组长度 ⇒ 尾随 NUL 必须保留在属性里 - # (剥掉 \00 会被 mlir-opt 拒绝;改为剥类型里的 NUL 则会丢 C 串终止符、破坏 ABI) + # The string attribute length must equal the i8 array length, so the trailing + # NUL must stay: mlir-opt rejects stripping \00, and dropping it breaks the ABI testcheck.check(string.strstr(buf, "hello\\00") is not None, "字符串初值保留 NUL 'hello\\00'", "missing string initializer") testcheck.check(string.strstr(buf, "!llvm.array<6 x i8>") is not None, "contains '!llvm.array<6 x i8>'", "missing string global type") testcheck.check(string.strstr(buf, "@counter(0 : i32) : i32") is not None, "整数全局 '@counter(0 : i32) : i32'", "missing integer global") - # 数组属性:元素带类型注解(dense<...> 对 !llvm.array 非法,只接受 builtin shaped 类型) + # Array attribute: elements carry type annotations (dense<...> invalid for !llvm.array) testcheck.check(string.strstr(buf, "[1 : i8, 2 : i8]") is not None, "整型数组初值 '[1 : i8, 2 : i8]'", "missing array initializer") -# ============================================================ -# 测试 11: SSA 验证(合法函数 0 错误) -# ============================================================ +# Test 11: SSA verification (valid function, 0 errors) def test_verify_valid(pool: memhub.MemBuddy*): testcheck.section("Test 11: Verify valid function") @@ -656,7 +629,7 @@ def test_verify_valid(pool: memhub.MemBuddy*): result: mlirlite.VerifyResult* = mcore.NewVerifyResult(4096) err_count: int = mcore.VerifyFunction(func, result) - # 本测试原本没有渲染步骤;为落盘验收补一次 PrintFunction(不涉及断言) + # Render once via PrintFunction for on-disk acceptance (no assertion involved) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) @@ -670,16 +643,8 @@ def test_verify_valid(pool: memhub.MemBuddy*): "wrong error code for valid function") -# ============================================================ -# 测试 12: 结构体/vtable 全局初值 → initializer region -# -# 覆盖: ① vtable 结构体(null + bitcast 符号引用);② 指针数组 + GEP 常量表达式 -# (GEP 整体视为 addressof);③ 符号名引号口径(LLVM 口径 @"m0" 剥引号后按 MLIR -# 口径重加:m0 可裸写 → @m0;数字开头的 9m 需引号 → @"9m");④ 根级裸 -# null / zeroinitializer(属性形态 `(zeroinitializer)` 被 mlir-opt 拒绝, -# 实测 22.1.8 报 "expected attribute value")→ region + llvm.mlir.zero。 -# 断言依赖的形态(含整模块)均已用 mlir-opt 22.1.8 实测通过。 -# ============================================================ +# Test 12: struct/vtable globals lower to initializer regions +# Covers vtable bitcast refs, GEP addressof, quoted names, bare null/zeroinitializer def test_struct_global(pool: memhub.MemBuddy*): testcheck.section("Test 12: struct/vtable global initializer (region)") @@ -690,8 +655,8 @@ def test_struct_global(pool: memhub.MemBuddy*): mod: mlirlite.LLVMModule* = mcore.NewModule("test_struct_global") - # ---- ① vtable 结构体 { i8*, i8*, i8* } ---- - # Initializer 是 TPV 生成的 LLVM 语法聚合串:null + bitcast 符号引用 + # ---- (1) vtable struct { i8*, i8*, i8* } ---- + # Initializer is a TPV-generated LLVM syntax aggregate: null + bitcast symbol refs vt1: mlirlite.ParamNode* = core.NewParamNode(ty_i8ptr) vt2: mlirlite.ParamNode* = core.NewParamNode(ty_i8ptr) vt3: mlirlite.ParamNode* = core.NewParamNode(ty_i8ptr) @@ -705,15 +670,15 @@ def test_struct_global(pool: memhub.MemBuddy*): string.strcpy(init_vt, "{ i8* null, i8* bitcast (i8* (i8*)* @\"m0\" to i8*), i8* bitcast (i8* (i8*)* @m1 to i8*) }") gv_vt.Initializer = init_vt - # IsConstant=1 + linkage 默认 external ⇒ 初值非空时**不输出** external 关键字 + # IsConstant=1 with default external linkage: a non-empty initializer omits the keyword mcore.GlobalSetConstant(gv_vt, 1) - # 声明被引用的方法符号,使模块自洽(mlir-opt 要求 addressof 目标可解析) + # Declare referenced method symbols so the module is self-consistent for mlir-opt d_m0: mlirlite.Function* = mcore.CreateDeclare(mod, "m0", ty_i8ptr) mcore.AddParam(d_m0, ty_i8ptr, "%self") d_m1: mlirlite.Function* = mcore.CreateDeclare(mod, "m1", ty_i8ptr) mcore.AddParam(d_m1, ty_i8ptr, "%self") - # ---- ③ 引号重加分支: LLVM 裸名 @9m(数字开头)→ MLIR 需 @"9m" ---- + # ---- (3) re-quoting branch: LLVM bare name @9m (digit start) -> MLIR @"9m" ---- vq1: mlirlite.ParamNode* = core.NewParamNode(ty_i8ptr) ty_vtq: mlirlite.LLVMType* = core.Struct(vq1, 1) gv_vtq: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "vtq", ty_vtq) @@ -725,8 +690,8 @@ def test_struct_global(pool: memhub.MemBuddy*): d_9m: mlirlite.Function* = mcore.CreateDeclare(mod, "9m", ty_i8ptr) mcore.AddParam(d_9m, ty_i8ptr, "%self") - # ---- ② 指针数组 + GEP 常量表达式 ---- - # @s0 = [3 x i8](供 GEP 常量表达式指向) + # ---- (2) pointer array + GEP constant expression ---- + # @s0 = [3 x i8], the target of the GEP constant expression mcore.CreateGlobalString(mod, "s0", "ab") ty_arr2: mlirlite.LLVMType* = core.Array(ty_i8ptr, 2) gv_arr: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "arr", ty_arr2) @@ -736,26 +701,22 @@ def test_struct_global(pool: memhub.MemBuddy*): gv_arr.Initializer = init_arr mcore.GlobalSetLinkage(gv_arr, "internal") - # ---- ②' 根级裸 GEP(TPV `_build_string_ptr_initializer` 的指针全局形态) ---- - # 初值无类型前缀,直接是 getelementptr 常量表达式 + # ---- (2') root bare GEP (TPV pointer-global form) ---- + # Initializer has no type prefix; it is a bare getelementptr constant expression gv_sp: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "sp", ty_i8ptr) init_sp: str = pool.alloc(192) string.strcpy(init_sp, "getelementptr inbounds ([3 x i8], [3 x i8]* @s0, i32 0, i32 0)") gv_sp.Initializer = init_sp - # ---- ④ 根级裸 null / zeroinitializer 全局 ---- - # 这两类初值原先走属性路径产出 `(zeroinitializer)`,被 mlir-opt 22.1.8 拒绝 - # (实测报 "expected attribute value");现改走 region: - # `@名() : <顶层类型> { ; llvm.return }`。 - # TPV 侧真实存在这类写法(FuncGenMixin / CallGenVt / TranslatorGenMixin / - # ExprGenConst 均设 Initializer = "null" 或 "zeroinitializer")。 + # ---- (4) root bare null / zeroinitializer globals ---- + # Lowered to a region with llvm.mlir.zero (mlir-opt rejects the (zeroinitializer) attr form) gv_pn: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "pnull", ty_i8ptr) init_pn: str = pool.alloc(16) string.strcpy(init_pn, "null") gv_pn.Initializer = init_pn - # 整型数组 + 裸 zeroinitializer:顶层类型取自 gv.Ty(此处 !llvm.array<2 x i32>) + # Int array + bare zeroinitializer: top-level type comes from gv.Ty (!llvm.array<2 x i32>) ty_i32: mlirlite.LLVMType* = core.Int32() ty_arr_i32: mlirlite.LLVMType* = core.Array(ty_i32, 2) gv_za: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "zarr", ty_arr_i32) @@ -769,14 +730,14 @@ def test_struct_global(pool: memhub.MemBuddy*): testcheck.info(buf) dump_mlir(pool, "T12_struct_global.mlir", buf) - # ① vtable 型: region 形态 + 顶层聚合类型;元素类型注解来自全局类型树 + # (1) vtable: region form + top-level aggregate type; element annotations from type tree testcheck.check(string.strstr(buf, "@vt() : !llvm.struct<(!llvm.ptr, !llvm.ptr, !llvm.ptr)>") is not None, "vtable 全局 region 形态 '@vt() : !llvm.struct<(…, …, …)>'", "missing vtable global region header") testcheck.check(string.strstr(buf, "llvm.mlir.undef : !llvm.struct<(!llvm.ptr, !llvm.ptr, !llvm.ptr)>") is not None, "含 'llvm.mlir.undef'(insertvalue 链起点)", "missing llvm.mlir.undef") - # LLVM 口径 @"m0" 剥引号后按 MLIR 口径裸写 @m0(m0 是合法 MLIR 裸名) + # LLVM @"m0" is unquoted to bare @m0 (a valid MLIR bare name) testcheck.check(string.strstr(buf, "llvm.mlir.addressof @m0 : !llvm.ptr") is not None, "bitcast 中的 @\"m0\" → 'llvm.mlir.addressof @m0 : !llvm.ptr'", "missing addressof for m0") @@ -795,12 +756,12 @@ def test_struct_global(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "external") is None, "external + 有初值 ⇒ 不输出 linkage 关键字", "unexpected 'external' keyword") - # ③ 数字开头的符号名需引号(_ll_name_needs_quote 判据) + # (3) digit-leading symbol names need quotes (per _ll_name_needs_quote) testcheck.check(string.strstr(buf, "llvm.mlir.addressof @\"9m\" : !llvm.ptr") is not None, "数字开头符号名重加引号 'llvm.mlir.addressof @\"9m\" : !llvm.ptr'", "missing quoted addressof for 9m") - # ② 指针数组 + GEP: GEP 常量表达式 → addressof;数组全局类型 + 下标路径 + # (2) pointer array + GEP: GEP constant -> addressof; array global type + index path testcheck.check(string.strstr(buf, "@arr() : !llvm.array<2 x !llvm.ptr>") is not None, "数组全局 region 形态 '@arr() : !llvm.array<2 x !llvm.ptr>'", "missing array global region header") @@ -814,12 +775,12 @@ def test_struct_global(pool: memhub.MemBuddy*): "下标 1 形态 '[1] : !llvm.array<2 x !llvm.ptr>'", "missing index [1] insertvalue") - # ②' 根级裸 GEP(无类型前缀): 顶层叶子 region,无 undef/insertvalue + # (2') root bare GEP: top-level leaf region, no undef/insertvalue testcheck.check(string.strstr(buf, "@sp() : !llvm.ptr") is not None, "根级裸 GEP → '@sp() : !llvm.ptr'(顶层叶子 region)", "missing root bare-GEP global") - # ④ 根级裸 null(指针全局): region 形态,属性括号为空,顶层类型取自 gv.Ty + # (4) root bare null pointer global: region form, empty parens, type from gv.Ty testcheck.check(string.strstr(buf, "@pnull() : !llvm.ptr") is not None, "根级裸 null → '@pnull() : !llvm.ptr'(region 形态)", "missing bare-null pointer global region header") @@ -830,7 +791,7 @@ def test_struct_global(pool: memhub.MemBuddy*): "region 内含 'llvm.return'", "missing llvm.return in region") - # ④' 裸 zeroinitializer(整型数组): region 形态,zero 的类型即顶层类型 + # (4') bare zeroinitializer int array: region form, zero type is the top-level type testcheck.check(string.strstr(buf, "@zarr() : !llvm.array<2 x i32>") is not None, "裸 zeroinitializer → '@zarr() : !llvm.array<2 x i32>'(region 形态)", "missing zeroinitializer array global region header") @@ -838,25 +799,14 @@ def test_struct_global(pool: memhub.MemBuddy*): "裸 zeroinitializer → 'llvm.mlir.zero : !llvm.array<2 x i32>'", "missing llvm.mlir.zero for zeroinitializer array global") - # 两类都不得再落到属性形态(mlir-opt 22.1.8 报 "expected attribute value") + # Both must never fall back to the attribute form (mlir-opt rejects it) testcheck.check(string.strstr(buf, "(zeroinitializer)") is None, "属性形态 '(zeroinitializer)' 不再出现", "rejected attribute form '(zeroinitializer)' leaked") -# ============================================================ -# 测试 13: alloca 对齐 / switch / inline_asm(v1 三项缺口的补齐) -# -# 三项的 MLIR 形态均由 mlir-opt 22.1.8 实测确定(候选与 exit 码见 -# includes/mlirlite/__function.vp 中 _MlirAlloca / _MlirSwitch / _MlirAsm 的注释): -# ① alloca 对齐 → `{alignment = 16 : i64}` -# (`align(16)`、`, align 16`、`{alignment = 16 : i32}` 均实测被拒) -# ② switch → `llvm.switch %v : i32, ^default [0: ^case0, …]` -# (设计规范里的 `llvm.switch %v, ^default […] : i32` 实测被拒:expected ':') -# 目标块带 phi 时追加块实参(与 br/cond_br 同一设施) -# ③ inline_asm → `llvm.inline_asm has_side_effects [asm_dialect = intel] "…", "…" %x : (i32) -> i32` -# (LLVM 的裸 `inteldialect` 与 `"…"(%x)` 词法均实测被拒) -# ============================================================ +# Test 13: alloca alignment / switch / inline_asm MLIR forms +# Forms verified against mlir-opt 22.1.8; switch phi targets carry block operands def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): testcheck.section("Test 13: alloca align / switch / inline_asm") @@ -867,7 +817,7 @@ def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): mod: mlirlite.LLVMModule* = mcore.NewModule("test_align_switch_asm") - # ---- ① alloca 对齐 + ③ inline_asm(builder 形态 + TPV 注入形态)---- + # ---- (1) alloca alignment + (3) inline_asm (builder + TPV-injected forms) ---- f1: mlirlite.Function* = mcore.CreateFunction(mod, "align_asm", ty_i32) mcore.AddParam(f1, ty_i32, "%x") e1: mlirlite.BasicBlock* = mcore.CreateBlock(f1, "entry") @@ -877,22 +827,22 @@ def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): # %0 = alloca i32, align 16 v_slot: mlirlite.Value* = mlirlite.build_alloca_aligned(b1, ty_i32, 16) - # call none asm sideeffect "nop", ""()(无返回值形态) + # call none asm sideeffect "nop", ""() (void form) mlirlite.build_inline_asm(b1, ty_void, "nop", "", 1) - # %1 = call i32 asm sideeffect "mov $0, $1", "=r,r"()(有返回值形态) + # %1 = call i32 asm sideeffect "mov $0, $1", "=r,r"() (returning form) v_asm: mlirlite.Value* = mlirlite.build_inline_asm(b1, ty_i32, "mov $0, $1", "=r,r", 1) v_x: mlirlite.Value* = mcore.SSAValue(ty_i32, "%x") mlirlite.build_store(b1, v_x, v_slot, 0) - # TPV CallGenCBuiltin 的注入形态(inteldialect + 带类型的输入操作数) + # TPV CallGenCBuiltin injected form (inteldialect + typed input operands) mlirlite.block_append_text(pool, e1, "%7 = call i32 asm sideeffect inteldialect \"mov $0, $1\", \"=r,r\"(i32 %x)") mlirlite.build_ret(b1, v_asm) - # ---- ② switch:3 case + default(不带 phi)---- + # ---- (2) switch: 3 cases + default (no phi) ---- f2: mlirlite.Function* = mcore.CreateFunction(mod, "sw", ty_i32) mcore.AddParam(f2, ty_i32, "%v") e2: mlirlite.BasicBlock* = mcore.CreateBlock(f2, "entry") @@ -920,7 +870,7 @@ def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): mlirlite.position_at_end(b2, dflt) mlirlite.build_ret(b2, v_v) - # ---- ②' switch:case 与 default 目标块带 phi ⇒ 块实参 ---- + # ---- (2') switch: case and default targets carry phi -> block operands ---- f3: mlirlite.Function* = mcore.CreateFunction(mod, "sw_phi", ty_i32) mcore.AddParam(f3, ty_i32, "%v") e3: mlirlite.BasicBlock* = mcore.CreateBlock(f3, "entry") @@ -951,7 +901,7 @@ def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): testcheck.info(buf) dump_mlir(pool, "T13_align_switch_asm.mlir", buf) - # ① alloca 对齐:实测形态 `{alignment = 16 : i64}`(LLVM 词法的 `, align 16` 不再出现) + # (1) alloca alignment: form is {alignment = 16 : i64} (LLVM ', align 16' is gone) testcheck.check(string.strstr(buf, "llvm.alloca %c0 x i32 {alignment = 16 : i64} : (i32) -> !llvm.ptr") is not None, "alloca 对齐 'llvm.alloca %c0 x i32 {alignment = 16 : i64} : (i32) -> !llvm.ptr'", "missing alloca alignment attribute") @@ -959,7 +909,7 @@ def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): "LLVM 词法 ', align 16' 不再出现(已转写为属性)", "raw LLVM alloca align leaked") - # ② switch:值类型紧随值(`%v : i32,`)+ 各 case/default 标签 + # (2) switch: value type follows the value (%v : i32,) plus case/default labels testcheck.check(string.strstr(buf, "llvm.switch %v : i32, ^default [0: ^case0, 1: ^case1, 2: ^case2]") is not None, "switch 实测形态 'llvm.switch %v : i32, ^default [0: ^case0, 1: ^case1, 2: ^case2]'", "missing llvm.switch") @@ -970,12 +920,12 @@ def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "^case2") is not None, "contains '^case2'", "missing '^case2'") - # ②' switch 目标块带 phi ⇒ 块实参(default 与 case 各自携带) + # (2') switch phi targets -> block operands (carried by default and case) testcheck.check(string.strstr(buf, "llvm.switch %v : i32, ^sdef(%c1 : i32) [0: ^scase(%c0 : i32)]") is not None, "switch 块实参 'llvm.switch %v : i32, ^sdef(%c1 : i32) [0: ^scase(%c0 : i32)]'", "missing switch block operands") - # 块参数的具体 SSA 名由 SSA 重编号决定(本用例实际是 %0/%1), - # 故只断言"目标块标签带参数"的形状,不绑定具体编号,避免脆断言。 + # Block-argument SSA names depend on renumbering, so assert only the shape + # "target label carries arguments", not specific names, avoiding brittle asserts testcheck.check(string.strstr(buf, "^scase(%") is not None, "case 目标块带参数 '^scase(%…: i32):'", "missing block argument for switch case target") @@ -983,7 +933,7 @@ def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): "default 目标块带参数 '^sdef(%…: i32):'", "missing block argument for switch default target") - # ③ inline_asm:无返回值 / 有返回值 / inteldialect → asm_dialect = intel + # (3) inline_asm: void / returning / inteldialect -> asm_dialect = intel testcheck.check(string.strstr(buf, "llvm.inline_asm has_side_effects \"nop\", \"\" : () -> ()") is not None, "无返回值形态 'llvm.inline_asm has_side_effects \"nop\", \"\" : () -> ()'", "missing void inline_asm") @@ -1001,20 +951,8 @@ def test_alloca_align_switch_asm(pool: memhub.MemBuddy*): "raw LLVM inteldialect keyword leaked") -# ============================================================ -# 测试 14: 变参函数 / 变参调用 / va_arg / cmpxchg / 全局属性字典(P0 缺口补齐) -# -# 五项 MLIR 形态均由 mlir-opt 22.1.8 实测 exit 0 确立(候选与 exit 码见 -# includes/mlirlite/__function.vp 的 _MlirFuncSig / _MlirCall / _MlirVaArg / -# _MlirCmpXchg 与 __module.vp 的 _MlirGlobalLine 注释): -# ① 变参函数声明 → `llvm.func @printf(%p: !llvm.ptr, ...) -> i32` -# ② 变参调用 → `… vararg(!llvm.func) : (!llvm.ptr, i32) -> i32` -# (vararg 内是**被调函数的完整 MLIR 函数类型**,含 `...`) -# ③ va_arg → `%N = "llvm.va_arg"(%ap) : (!llvm.ptr) -> i32`(generic 形态,刻意选择) -# ④ cmpxchg → 单结果 `llvm.cmpxchg` + 两条 `llvm.extractvalue`([0]=旧值、[1]=i1 成功位) -# ⑤ 全局属性字典 → `…("ab\00") {section = "data", alignment = 16 : i64} : !llvm.array<3 x i8>` -# (字典必须在**类型之前**;`unnamed_addr` 是**关键字**,不能进字典) -# ============================================================ +# Test 14: vararg function/call, va_arg, cmpxchg, global attribute dict +# Five MLIR forms verified with mlir-opt 22.1.8; the attr dict precedes the type def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): testcheck.section("Test 14: vararg / va_arg / cmpxchg / global attrs") @@ -1026,7 +964,7 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): mod: mlirlite.LLVMModule* = mcore.NewModule("test_vararg_vaarg_cmpxchg") - # ---- ① 变参函数声明: llvm.func @printf(%p: !llvm.ptr, ...) -> i32 ---- + # ---- (1) vararg declaration: llvm.func @printf(%p: !llvm.ptr, ...) -> i32 ---- f_printf: mlirlite.Function* = mcore.CreateDeclare(mod, "printf", ty_i32) mcore.AddParam(f_printf, ty_i32ptr, "%p") f_printf.IsVarArg = 1 @@ -1041,7 +979,7 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): v_arg: mlirlite.Value* = mlirlite.build_va_arg(b_va, v_ap, ty_i32) mlirlite.build_ret(b_va, v_arg) - # ---- ② 变参调用 + ④ cmpxchg(builder 的**单结果**形态)---- + # ---- (2) vararg call + (4) cmpxchg (builder single-result form) ---- f_cc: mlirlite.Function* = mcore.CreateFunction(mod, "vcall_cmpx", ty_i32) mcore.AddParam(f_cc, ty_i32ptr, "%p") mcore.AddParam(f_cc, ty_i32, "%n") @@ -1052,30 +990,29 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): v_n: mlirlite.Value* = mcore.SSAValue(ty_i32, "%n") # %0 = cmpxchg !llvm.ptr %p, i32 %n, i32 %n acq_rel monotonic - # → %0 = llvm.cmpxchg … + 两条 extractvalue;`%0` 绑定到 [0](旧值) + # -> llvm.cmpxchg + two extractvalue; %0 binds to [0] (old value) v_old: mlirlite.Value* = mlirlite.build_cmpxchg(b_cc, v_p, v_n, v_n, mlirlite.ATOMIC_ORDER_ACQ_REL, mlirlite.ATOMIC_ORDER_MONOTONIC) # %1 = call i32 (i8*, i32, ...) @printf(i8* %p, i32 %n) - # → %1 = llvm.call @printf(%p, %n) vararg(!llvm.func) - # : (!llvm.ptr, i32) -> i32 + # -> %1 = llvm.call @printf(%p, %n) vararg(!llvm.func) mlirlite.value_set_next(v_p, v_n) v_call: mlirlite.Value* = mlirlite.build_call(b_cc, "printf", v_p, 2, ty_i32, 1) - # ret 用 cmpxchg 结果 ⇒ 断言别名绑定生效(文本里应是 %_0_v = extractvalue[0]) + # ret uses the cmpxchg result to assert alias binding (text: %_0_v = extractvalue[0]) mlirlite.build_ret(b_cc, v_old) - # ---- ④' cmpxchg 双结果前缀 `%a, %b = cmpxchg …`(两名字各绑一条 extractvalue)---- + # ---- (4') cmpxchg dual-result prefix (both names bind one extractvalue each) ---- f_cc2: mlirlite.Function* = mcore.CreateFunction(mod, "cmpx2", ty_i32) mcore.AddParam(f_cc2, ty_i32ptr, "%p") mcore.AddParam(f_cc2, ty_i32, "%n") e_cc2: mlirlite.BasicBlock* = mcore.CreateBlock(f_cc2, "entry") mlirlite.block_append_text(pool, e_cc2, "%a, %b = cmpxchg !llvm.ptr %p, i32 %n, i32 %n acq_rel monotonic") - # %b = 成功位 [1];%a = 旧值 [0] + # %b = success bit [1]; %a = old value [0] mlirlite.block_append_text(pool, e_cc2, "%r = zext i1 %b to i32") mlirlite.block_append_text(pool, e_cc2, "ret i32 %a") - # ---- ⑤ 全局属性字典:section/alignment 在**类型之前**;unnamed_addr 作关键字 ---- + # ---- (5) global attr dict: section/alignment precede the type; unnamed_addr is a keyword ---- ty_arr3: mlirlite.LLVMType* = core.Array(ty_i8, 3) init_s: str = pool.alloc(32) string.strcpy(init_s, "c\"ab\\00\"") @@ -1099,7 +1036,7 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): testcheck.info(buf) dump_mlir(pool, "T14_vararg_vaarg_cmpxchg.mlir", buf) - # ① 变参函数声明:参数表尾 `...` + # (1) vararg declaration: parameter list ends with ... testcheck.check(string.strstr(buf, "llvm.func @printf(%p: !llvm.ptr, ...) -> i32") is not None, "变参声明 'llvm.func @printf(%p: !llvm.ptr, ...) -> i32'", "missing vararg function declaration") @@ -1107,7 +1044,7 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): "参数表尾 '..., ...)' 形态(', ...)')", "missing vararg ellipsis in declaration") - # ② 变参调用:vararg(完整 MLIR 函数类型) + # (2) vararg call: vararg(full MLIR function type) testcheck.check(string.strstr(buf, "vararg(!llvm.func<") is not None, "变参调用 'vararg(!llvm.func<'", "missing vararg(...) attribute") testcheck.check(string.strstr(buf, @@ -1115,13 +1052,13 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): "vararg 完整函数类型 'vararg(!llvm.func) : (!llvm.ptr, i32) -> i32'", "missing vararg function type") - # ③ va_arg:generic 形态(刻意选择,不透明指针下自定义汇编无法表达) + # (3) va_arg: generic form (deliberate; custom asm cannot express opaque pointers) testcheck.check(string.strstr(buf, "\"llvm.va_arg\"(") is not None, "va_arg generic 形态 '\"llvm.va_arg\"('", "missing generic llvm.va_arg") testcheck.check(string.strstr(buf, ") : (!llvm.ptr) -> i32") is not None, "va_arg 类型串 ') : (!llvm.ptr) -> i32'", "missing va_arg type list") - # ④ cmpxchg:单结果 + 两条 extractvalue([0]=旧值、[1]=i1 成功位) + # (4) cmpxchg: single result + two extractvalue ([0]=old value, [1]=i1 success bit) testcheck.check(string.strstr(buf, "llvm.cmpxchg") is not None, "contains 'llvm.cmpxchg'", "missing llvm.cmpxchg") testcheck.check(string.strstr(buf, "llvm.extractvalue ") is not None, @@ -1130,9 +1067,8 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): "旧值抽取 '[0] : !llvm.struct<(i32, i1)>'", "missing extractvalue [0]") testcheck.check(string.strstr(buf, "[1] : !llvm.struct<(i32, i1)>") is not None, "成功位抽取 '[1] : !llvm.struct<(i32, i1)>'", "missing extractvalue [1]") - # extractvalue 结果名由 struct 结果名**确定性派生**(不再用计数器 ⇒ 两遍必然同名) - # `%0` → `%_0_v`(旧值 [0])/ `%_0_ok`(成功位 [1]);`%a` → `%_a_v`/`%_a_ok` - # (`_` 前缀是必需的:MLIR 裸 SSA 名首字符须为字母或 `_`,`%0_v` 被 mlir-opt 拒绝) + # extractvalue result names derive deterministically from the struct result name + # (%0 -> %_0_v/%_0_ok, %a -> %_a_v/%_a_ok; MLIR requires the _ name prefix) testcheck.check(string.strstr(buf, "%_0_v = llvm.extractvalue %0[0] : !llvm.struct<(i32, i1)>") is not None, "旧值定义 '%_0_v = llvm.extractvalue %0[0] …'", "cmpxchg single result not deterministically named") @@ -1145,7 +1081,7 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "%_a_ok = llvm.extractvalue %a[1] : !llvm.struct<(i32, i1)>") is not None, "双结果次名定义 '%_a_ok = llvm.extractvalue %a[1] …'", "cmpxchg double-result ok bit not deterministically named") - # 引用侧:别名把 %0 / %a / %b 改写成上述确定性新名(定义与引用同名 ⇒ 不悬空) + # Reference side: aliases rewrite %0/%a/%b to those names (def and use match) testcheck.check(string.strstr(buf, "llvm.return %_0_v : i32") is not None, "单结果引用改写 'llvm.return %_0_v : i32'", "cmpxchg result not bound to old value") @@ -1156,7 +1092,7 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): "双结果首名引用改写 'llvm.return %_a_v : i32'", "cmpxchg first name not bound to old value") - # ⑤ 属性字典在**类型之前**(整串断言);unnamed_addr 作关键字、不进字典 + # (5) attr dict precedes the type (whole-string assert); unnamed_addr is not in the dict testcheck.check(string.strstr(buf, "(\"ab\\00\") {section = \"data\", alignment = 16 : i64} : !llvm.array<3 x i8>") is not None, "属性字典在类型之前 '(\"ab\\00\") {section = \"data\", alignment = 16 : i64} : !llvm.array<3 x i8>'", @@ -1172,23 +1108,8 @@ def test_vararg_vaarg_cmpxchg(pool: memhub.MemBuddy*): "unnamed_addr leaked into attribute dict") -# ============================================================ -# 测试 15: 具名结构体(%"name" = type {…}) -# -# TPV 侧对每个类都调 module_add_named_type 登记具名结构体(mlirlite 由此输出 -# `%"sha1.Cls" = type {…}` 定义行)。MLIR(llvm 方言) **没有**独立类型定义语法, -# 也**不允许无体前向声明**(实测 mlir-opt 22.1.8:`!llvm.struct<"x">` 报 -# "struct without a body only allowed in a recursive struct"),故: -# ① 定义行**整体丢弃**(NamedTypeHead 只作模型保留 + 打印期查表); -# ② 按值使用处内联为 !llvm.struct<"名字", (字段…)>(名字直接作字符串字面量, -# 含数字/`.`/`[`/`]` 均不额外转义);嵌套具名同理递归; -# ③ 指向具名结构体的指针仍是 !llvm.ptr(不透明指针,既有路径不变); -# ④ 中间文本里"只有名字"的形态 `%"name"` 由打印期登记表回查完整定义后展开 -# 为 ②(查不到 / 仍是 opaque ⇒ 响亮报错,绝不静默输出空体错误布局)。 -# 本用例的期望整模块已用 mlir-opt / mlir-translate 22.1.8 实测 exit 0, -# 降级(--mlir-to-llvmir)可得 MLIR 自动生成的定义行: -# %aa11bb22cc33dd44.Cls = type { i32, ptr } -# ============================================================ +# Test 15: named struct types (LLVM %"name" = type) in MLIR +# MLIR has no type defs: drop def lines, inline by value, keep pointers opaque !llvm.ptr def test_named_struct(pool: memhub.MemBuddy*): testcheck.section("Test 15: named struct type") @@ -1198,7 +1119,7 @@ def test_named_struct(pool: memhub.MemBuddy*): ty_i8: mlirlite.LLVMType* = core.Int8() ty_i8ptr: mlirlite.LLVMType* = core.Ptr(ty_i8) - # 具名结构体 %"aa11bb22cc33dd44.Cls" = type { i32, i8* }(sha1 风格前缀 + '.') + # Named struct %"aa11bb22cc33dd44.Cls" = type { i32, i8* } (sha1-style prefix with '.') ns1: mlirlite.ParamNode* = core.NewParamNode(ty_i32) ns2: mlirlite.ParamNode* = core.NewParamNode(ty_i8ptr) ns_head: mlirlite.ParamNode* = core.ParamListAppend(None, None, ns1) @@ -1206,23 +1127,22 @@ def test_named_struct(pool: memhub.MemBuddy*): ty_named: mlirlite.LLVMType* = core.Struct(ns_head, 2, "aa11bb22cc33dd44.Cls") ty_named_ptr: mlirlite.LLVMType* = core.Ptr(ty_named) - # packed 具名结构体 %"aa11bb22cc33dd44.Packed" = type <{ i32, i8 }> - # MLIR 侧(实测 mlir-opt / mlir-translate 22.1.8): - # !llvm.struct<"aa11bb22cc33dd44.Packed", packed (i32, i8)> → 降级 type <{ i32, i8 }> + # Packed named struct %"aa11bb22cc33dd44.Packed" = type <{ i32, i8 }> + # MLIR: !llvm.struct<"aa11bb22cc33dd44.Packed", packed (i32, i8)> pk1: mlirlite.ParamNode* = core.NewParamNode(ty_i32) pk2: mlirlite.ParamNode* = core.NewParamNode(ty_i8) pk_head: mlirlite.ParamNode* = core.ParamListAppend(None, None, pk1) core.ParamListAppend(pk_head, pk1, pk2) ty_packed: mlirlite.LLVMType* = core.Struct(pk_head, 2, "aa11bb22cc33dd44.Packed") - # ---- 类型文本:按值 = 内联具名形态;指针 = 不透明 !llvm.ptr ---- + # ---- type text: by value = inline named form; pointer = opaque !llvm.ptr ---- tbuf: str = pool.alloc(256) tbuf[0] = 0 core.PrintType(tbuf, 256, ty_named) testcheck.check(string.strstr(tbuf, "!llvm.struct<\"aa11bb22cc33dd44.Cls\", (i32, !llvm.ptr)>") is not None, "具名结构体按值形态 '!llvm.struct<\"aa11bb22cc33dd44.Cls\", (i32, !llvm.ptr)>'", "named struct by-value form missing") - # 名字里的 '.' / 数字开头不需要额外转义或引号(实测 mlir-opt 22.1.8) + # A '.' / digit-leading name needs no extra escaping or quotes (verified) testcheck.check(string.strstr(tbuf, "<\"aa11bb22cc33dd44.Cls\",") is not None, "名字直接作字符串字面量(不额外转义)", "named struct name literal form missing") @@ -1233,19 +1153,19 @@ def test_named_struct(pool: memhub.MemBuddy*): "named struct pointer must stay opaque !llvm.ptr") mod: mlirlite.LLVMModule* = mcore.NewModule("test_named_struct") - # 真实流程:具名结构体经 module_add_named_type 登记(打印期查表用) + # Real flow: register named structs via module_add_named_type for the print-time table mlirlite.module_add_named_type(mod, pool, ty_named) - # packed 标记唯一设置点(须在 add_named_type 之后设;打印期由登记表携带) + # Only place the packed flag is set (after add_named_type; carried by the table) mlirlite.module_add_named_type(mod, pool, ty_packed) mlirlite.module_set_named_type_packed(mod, pool, ty_packed, 1) - # ---- ① 按值全局(类型使用处内联具名体)+ ② 指向它的指针全局 ---- + # ---- (1) by-value global (inlines the named body) + (2) pointer global to it ---- gv_v: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "g_cls", ty_named) gv_p: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "g_cls_p", ty_named_ptr) - # ③ packed 按值全局 + # (3) packed by-value global gv_pk: mlirlite.GlobalVariable* = mcore.NewGlobal(mod, "g_packed", ty_packed) - # ---- ① 按值形参 + ② 指针形参 ---- + # ---- (1) by-value parameter + (2) pointer parameter ---- fn: mlirlite.Function* = mcore.CreateFunction(mod, "use_named", ty_i32) mcore.AddParam(fn, ty_named, "%v") mcore.AddParam(fn, ty_named_ptr, "%p") @@ -1253,16 +1173,16 @@ def test_named_struct(pool: memhub.MemBuddy*): b: mlirlite.IRBuilder* = mcore.NewBuilder(fn) mlirlite.position_at_end(b, entry) - # ---- ④ 中间文本里的"只有名字"形态(手工 / TPV 注入)---- - # 打印期由登记表回查完整定义展开;指针形态 %"name"* 仍走 !llvm.ptr + # ---- (4) bare-name form in mid text (hand-written / TPV-injected) ---- + # Print time expands it via the table; pointer form %"name"* stays !llvm.ptr mlirlite.block_append_text(pool, entry, "%0 = alloca %\"aa11bb22cc33dd44.Cls\"") mlirlite.block_append_text(pool, entry, "%1 = load i32, %\"aa11bb22cc33dd44.Cls\"* %0") - # ⑤ packed 具名结构体的文本形态(同一登记表槽位带 packed 标记) + # (5) packed named struct text form (same table slot carries the packed flag) mlirlite.block_append_text(pool, entry, "%2 = alloca %\"aa11bb22cc33dd44.Packed\"") v_1: mlirlite.Value* = mcore.SSAValue(ty_i32, "%1") mlirlite.build_ret(b, v_1) - # ---- ⑥ 按值 packed 形参:独立声明函数,不改动 use_named 的既有断言 ---- + # ---- (6) by-value packed parameter: separate declare, keeping use_named asserts ---- fn_pk: mlirlite.Function* = mcore.CreateDeclare(mod, "use_packed", ty_i32) mcore.AddParam(fn_pk, ty_packed, "%pk") @@ -1272,14 +1192,14 @@ def test_named_struct(pool: memhub.MemBuddy*): testcheck.info(buf) dump_mlir(pool, "T15_named_struct.mlir", buf) - # ① 按值形参 / 全局:使用处内联具名体 + # (1) by-value parameter / global: inline the named body at the use site testcheck.check(string.strstr(buf, "llvm.func @use_named(%v: !llvm.struct<\"aa11bb22cc33dd44.Cls\", (i32, !llvm.ptr)>, %p: !llvm.ptr) -> i32") is not None, "按值形参 'llvm.func @use_named(%v: !llvm.struct<\"aa11bb22cc33dd44.Cls\", (i32, !llvm.ptr)>, %p: !llvm.ptr) -> i32'", "missing inline named struct parameter") testcheck.check(string.strstr(buf, "@g_cls() : !llvm.struct<\"aa11bb22cc33dd44.Cls\", (i32, !llvm.ptr)>") is not None, "按值全局 '@g_cls() : !llvm.struct<\"aa11bb22cc33dd44.Cls\", (i32, !llvm.ptr)>'", "missing inline named struct global") - # ② 指针:仍是不透明 !llvm.ptr + # (2) pointer: remains opaque !llvm.ptr testcheck.check(string.strstr(buf, "@g_cls_p() : !llvm.ptr") is not None, "指针全局 '@g_cls_p() : !llvm.ptr'", "named struct pointer global must be !llvm.ptr") @@ -1287,7 +1207,7 @@ def test_named_struct(pool: memhub.MemBuddy*): "不得出现指向具名结构体的指针类型(MLIR 不透明指针)", "pointer-to-named-struct type leaked") - # ④ 文本形态 %"name" 展开(alloca 元素类型 / load 的指针类型);定义行不输出 + # (4) %"name" text expands (alloca element / load pointer type); no def line emitted testcheck.check(string.strstr(buf, "%0 = llvm.alloca %c0 x !llvm.struct<\"aa11bb22cc33dd44.Cls\", (i32, !llvm.ptr)> : (i32) -> !llvm.ptr") is not None, "文本 %\"name\" 展开为内联具名体(alloca 元素类型)", "named struct type text not expanded in alloca") @@ -1297,12 +1217,12 @@ def test_named_struct(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "%\"aa11bb22cc33dd44.Cls\"") is None, "LLVM 口径的 %\"name\" 形态不再出现(已全部转写)", "raw LLVM named type text leaked") - # ③ 定义行整体丢弃:MLIR 无独立类型定义语法(由 mlir-translate 在使用处自动生成) + # (3) def lines dropped: MLIR has no type-def syntax (mlir-translate emits at use) testcheck.check(string.strstr(buf, "\"aa11bb22cc33dd44.Cls\" = type") is None, "模块不输出 '\"name\" = type {…}' 定义行", "named type definition line should be dropped") - # ⑦ packed 具名结构体:登记表携带 NamedTypeNode.IsPacked,按值形态加 'packed ' 关键字 + # (7) packed named struct: the table carries IsPacked and adds the 'packed ' keyword testcheck.check(string.strstr(buf, "@g_packed() : !llvm.struct<\"aa11bb22cc33dd44.Packed\", packed (i32, i8)>") is not None, "packed 按值全局 '@g_packed() : !llvm.struct<\"aa11bb22cc33dd44.Packed\", packed (i32, i8)>'", "missing packed inline named struct global") @@ -1312,38 +1232,18 @@ def test_named_struct(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, "x !llvm.struct<\"aa11bb22cc33dd44.Packed\", packed (i32, i8)> : (i32) -> !llvm.ptr") is not None, "文本 %\"name\" 展开为 packed 内联具名体(alloca 元素类型)", "packed named struct type text not expanded with packed") - # 负向:非 packed 的具名结构体类型串里不得出现 packed + # Negative: a non-packed named struct type string must not contain 'packed' testcheck.check(string.strstr(buf, "!llvm.struct<\"aa11bb22cc33dd44.Cls\", packed") is None, "非 packed 具名结构体类型串不含 'packed'", "packed keyword leaked into non-packed named struct") - # 负向:packed 具名结构体不得漏掉 packed 关键字(按值渲染为无 packed 形态) + # Negative: a packed named struct must not render without the packed keyword testcheck.check(string.strstr(buf, "!llvm.struct<\"aa11bb22cc33dd44.Packed\", (i32, i8)>") is None, "packed 具名结构体不得渲染为无 packed 的形态", "packed named struct rendered without packed keyword") -# ============================================================ -# 测试 16: extractvalue(多结果内联汇编的结果抽取) -# -# 依据真实语料(Test/DefaultArgTest/output/*.ll 等 4163 份 TPV 产物): -# %asm_result = call {i32, i32} asm inteldialect "rdrand $1", "=r,=r,~{cc}"() -# %asm_out_0 = extractvalue {i32, i32} %asm_result, 0 -# %asm_out_1 = extractvalue {i32, i32} %asm_result, 1 -# 即"多结果内联汇编"是 extractvalue 的唯一来源(另有 {i64, i64} / -# {i32, i32, i32, i32} / {i64, i32, i64, i32} 等多字段结构体结果)。 -# -# MLIR 形态(mlir-opt / mlir-translate 22.1.8 实测 exit 0): -# ① 多结果内联汇编 = **单结果 + 结构体类型**: -# %0 = llvm.inline_asm has_side_effects "…", "=r,r" : () -> !llvm.struct<(i32, i32)> -# ② extractvalue 的索引列表写在 `[]` 内、逗号分隔(LLVM 词法的 `<聚合>, i0, i1` -# 被拒绝): -# %a = llvm.extractvalue %0[0] : !llvm.struct<(i32, i32)> -# ③ 多级索引合法(`%v[1, 0]` 于嵌套结构体,实测 exit 0) -# 降级(--mlir-to-llvmir)可得: -# %1 = call { i32, i32 } asm sideeffect "…", "=r,r"() -# %2 = extractvalue { i32, i32 } %1, 0 -# %3 = extractvalue { i32, i32 } %1, 1 -# ============================================================ +# Test 16: extractvalue for multi-result inline asm +# MLIR uses a single struct-typed result plus extractvalue with [idx] index lists def test_extractvalue_multi_asm(pool: memhub.MemBuddy*): testcheck.section("Test 16: extractvalue (multi-result inline asm)") @@ -1355,19 +1255,19 @@ def test_extractvalue_multi_asm(pool: memhub.MemBuddy*): func: mlirlite.Function* = mcore.CreateFunction(mod, "multi_asm", ty_i32) entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") - # ① TPV 真实形态:多结果内联汇编 + 两条 extractvalue(单索引) + # (1) TPV real form: multi-result inline asm + two extractvalue (single index) mlirlite.block_append_text(pool, entry, "%2 = call {i32, i32} asm sideeffect \"mov $0, $1; mov $1, $1\", \"=r,r\"()") mlirlite.block_append_text(pool, entry, "%a = extractvalue {i32, i32} %2, 0") mlirlite.block_append_text(pool, entry, "%b = extractvalue {i32, i32} %2, 1") - # ② 多级索引(嵌套结构体结果的 [1, 0],mlir-opt 22.1.8 实测合法) + # (2) multi-level index [1, 0] into a nested struct result (verified legal) mlirlite.block_append_text(pool, entry, "%3 = call {i32, {i32, i32}} asm sideeffect \"mov $0, $1\", \"=r,r\"()") mlirlite.block_append_text(pool, entry, "%d = extractvalue {i32, {i32, i32}} %3, 1, 0") - # 引用 %a(保证 extractvalue 结果被真实使用) + # Reference %a so the extractvalue result is actually used mlirlite.block_append_text(pool, entry, "ret i32 %a") buf: str = pool.alloc(65536) @@ -1376,14 +1276,14 @@ def test_extractvalue_multi_asm(pool: memhub.MemBuddy*): testcheck.info(buf) dump_mlir(pool, "T16_extractvalue.mlir", buf) - # ① 多结果内联汇编 → 单结果结构体类型 + # (1) multi-result inline asm -> single struct-typed result testcheck.check(string.strstr(buf, ": () -> !llvm.struct<(i32, i32)>") is not None, "多结果内联汇编 '… : () -> !llvm.struct<(i32, i32)>'", "multi-result inline_asm struct result missing") testcheck.check(string.strstr(buf, "llvm.inline_asm has_side_effects") is not None, "contains 'llvm.inline_asm has_side_effects'", "missing llvm.inline_asm") - # ② extractvalue:索引在 `[]` 内、聚合类型为 MLIR 形态 + # (2) extractvalue: index inside [], aggregate type in MLIR form testcheck.check(string.strstr(buf, "llvm.extractvalue ") is not None, "contains 'llvm.extractvalue '", "missing llvm.extractvalue") testcheck.check(string.strstr(buf, "[0] : !llvm.struct<(i32, i32)>") is not None, @@ -1395,29 +1295,24 @@ def test_extractvalue_multi_asm(pool: memhub.MemBuddy*): testcheck.check(string.strstr(buf, ": !llvm.struct<(i32, i32)>") is not None, "聚合类型为 MLIR 结构体 ': !llvm.struct<(i32, i32)>'", "aggregate type not rendered as MLIR struct") - # ③ 多级索引:`[1, 0]`(MLIR 内逗号分隔,实测合法) + # (3) multi-level index [1, 0] (comma-separated in MLIR, verified legal) testcheck.check(string.strstr(buf, "[1, 0] : !llvm.struct<(i32, !llvm.struct<(i32, i32)>)>") is not None, "多级索引 '[1, 0] : !llvm.struct<(i32, !llvm.struct<(i32, i32)>)>'", "multi-level extractvalue index missing") - # 负向:LLVM 词法的 `<聚合类型> <值>, <索引>` 不再出现(类型文本必须已转写) + # Negative: LLVM , must not appear (type text rewritten) testcheck.check(string.strstr(buf, "{i32, i32} %") is None, "LLVM 词法聚合类型文本不再出现('{i32, i32} %' 不出现)", "raw LLVM aggregate type text leaked") - # 引用侧:extractvalue 结果名原样被 return 引用 + # Reference side: the extractvalue result name is returned as-is testcheck.check(string.strstr(buf, "llvm.return %a : i32") is not None, "extractvalue 结果被引用 'llvm.return %a : i32'", "extractvalue result not referenced") def _sub_arena(main_pool: memhub.MemBuddy*) -> rawptr: - """从主池切一块子池 arena(返回**裸指针**,由调用方在自己帧内构造 MemBuddy) + """Carve a sub-pool arena from the main pool and return its raw pointer. - 为什么只返回裸指针、不返回构造好的 MemBuddy*:Viper 中无 __new__ 的类实例是 - 值语义,`MemBuddy(...)` 被降级为栈 alloca;"返回指向本帧局部对象"的指针会 - 悬空(IR 物证:助手函数内 `alloca %MemBuddy` … `ret %MemBuddy*`,随后第一次 - alloc 读 max_order 即落到复用的栈垃圾 → memhub 报"字段被写穿")。 - arena 分配失败必须在这里 fail-fast,否则 `MemBuddy(None, size)` 会在 - `self.free_lists[i] = 0` 处写空指针(现场 0xC0000005 av_addr=0x0)。 + MemBuddy is a stack value here, so returning one would dangle; fail fast if alloc fails. """ mem: rawptr = main_pool.alloc(SUB_POOL_SIZE) if mem is None: @@ -1429,7 +1324,7 @@ def _sub_arena(main_pool: memhub.MemBuddy*) -> rawptr: def main() -> int: testcheck.begin("MLIRLiteTest: mlirlite 库(MLIR llvm 方言文本生成)") - # 初始化主池:仅用于给每个测试切子池(测试内分配一律走各自的子池) + # Init main pool: used only to carve a sub-pool per test (allocs use their sub-pool) pool_mem: bytes = stdlib.malloc(POOL_SIZE) if pool_mem is None: stdio.printf("FAIL: malloc for pool failed\n") @@ -1439,8 +1334,8 @@ def main() -> int: stdio.printf("FAIL: memhub.MemBuddy init failed\n") return 1 - # 子池必须在 **main 的帧内** 构造:见 _sub_arena 注释(MemBuddy 实例是栈值, - # 其指针不能跨函数返回)。每个测试一块,互不叠加。 + # Sub-pools must be built in main's frame (see _sub_arena): MemBuddy is a stack + # value, so its pointer cannot cross functions. One per test, not overlapping. sub: memhub.MemBuddy* = memhub.MemBuddy(_sub_arena(pool), SUB_POOL_SIZE) test_type_print(sub) diff --git a/MemhubTest/App/main.vp b/MemhubTest/App/main.vp index efe5772..9667b01 100644 --- a/MemhubTest/App/main.vp +++ b/MemhubTest/App/main.vp @@ -6,7 +6,7 @@ import testcheck import memhub -# 多态测试: 通过 MemManager 基类指针调用, 验证 vtable 分派到正确子类 +# Polymorphism test: call through a MemManager base pointer, verify vtable dispatch def test_polymorphic(mgr: memhub.MemManager*, size: sizet) -> int: p: t.CPtr = mgr.alloc(size) if p is None: @@ -15,12 +15,12 @@ def test_polymorphic(mgr: memhub.MemManager*, size: sizet) -> int: return 1 -# 测试 calloc 多态: calloc 是 MemManager 具体方法, 内部调 self.alloc (虚函数) +# Test calloc polymorphism: calloc is concrete but calls the virtual self.alloc def test_calloc_polymorphic(mgr: memhub.MemManager*) -> int: p: t.CPtr = mgr.calloc(4, 8) if p is None: return 0 - # 验证清零: 读第一个字节应为 0 + # Verify zero-fill: the first byte should be 0 first_byte: uint8 = uint8(*uint64(p, t.CPtr)) if first_byte != 0: return 0 @@ -72,11 +72,11 @@ def main() -> int: buddy.free(b1) b3: t.CPtr = buddy.alloc(100) testcheck.check(b3 is not None, "MemBuddy alloc after free", "FAIL") - # realloc 增长 + # Grow via realloc b4: t.CPtr = buddy.realloc(b2, 400) testcheck.check(b4 is not None, "MemBuddy realloc 200->400", "FAIL") - # ========== 多态分派 (核心测试) ========== + # ========== Polymorphic dispatch (core test) ========== testcheck.section("polymorphic dispatch") r1: int = test_polymorphic(pool, 50) testcheck.check(r1 == 1, "vtable: MemPool.alloc/free via MemManager", "FAIL") @@ -85,7 +85,7 @@ def main() -> int: r3: int = test_polymorphic(buddy, 50) testcheck.check(r3 == 1, "vtable: MemBuddy.alloc/free via MemManager", "FAIL") - # calloc 多态 (具体方法调虚函数) + # calloc polymorphism (concrete method calls a virtual one) rc1: int = test_calloc_polymorphic(pool) testcheck.check(rc1 == 1, "vtable: calloc dispatches MemPool.alloc", "FAIL") rc2: int = test_calloc_polymorphic(buddy) diff --git a/MultiInheritTest/App/main.vp b/MultiInheritTest/App/main.vp index 88f1897..63e612b 100644 --- a/MultiInheritTest/App/main.vp +++ b/MultiInheritTest/App/main.vp @@ -7,7 +7,7 @@ import stdlib import testcheck -# === 1. 多继承字段合并 === +# === 1. multiple inheritance field merging === class A: a: CInt @@ -29,7 +29,7 @@ class B: return self.b -# 多继承:C(A, B),字段展平 a+b+c,布局 [a, b, c] +# Multiple inheritance C(A, B): fields flatten to layout [a, b, c]. class C(A, B): c: CInt @@ -42,7 +42,7 @@ class C(A, B): return self.c -# === 2. 菱形去重 + 最左优先 === +# === 2. diamond dedup + leftmost priority === class Base: shared: CInt @@ -64,14 +64,14 @@ class Right(Base): return 3 -# 菱形:Diamond(Left, Right),Left/Right 共享 Base, -# Base.shared 字段只展平一次,who() 用 Left(先声明优先) +# Diamond(Left, Right) shares Base: Base.shared flattens once, +# and who() resolves to Left (leftmost priority). class Diamond(Left, Right): def __init__(self, s: CInt): self.shared = s -# === 3. 虚方法多继承 vtable === +# === 3. virtual method multiple-inheritance vtable === @t.CVTable class ShapeM: @@ -102,7 +102,7 @@ class ColoredCircle(ShapeM, ColorM): return 3.14159265 * self.r * self.r -# === 4. 运算符重载 + 方法继承链(MRO) === +# === 4. operator overloading + method inheritance chain (MRO) === class Vec2M: x: CFloat64T @@ -120,14 +120,14 @@ class Vec2M: class Vec2Extra: - # 注意:方法体字段访问基于"定义类字段"(TPV 模型), - # 不引用 Vec2M 的 x/y(跨父类字段引用是更深层语义,暂不验证)。 + # Field access uses the defining class's fields (TPV model); does not + # reference Vec2M's x/y (cross-parent field access is out of scope here). def extra_val(self) -> CInt: return 7 -# 多继承:__add__ 继承自 Vec2M(运算符重载 MRO 链), -# extra_val 继承自 Vec2Extra(方法查找 MRO 链) +# Multiple inheritance: __add__ comes from Vec2M (operator-overload MRO), +# extra_val from Vec2Extra (method lookup MRO). class Vec2Both(Vec2M, Vec2Extra): def __new__() -> 'Vec2Both' | CPtr: return stdlib.malloc(16) @@ -145,7 +145,7 @@ def main() -> CInt | CExport: buf: CChar | CPtr = CPtr(stdlib.malloc(256)) - # === 1. 字段合并 + 属性访问 + 方法调用 === + # === 1. field merge + attribute access + method calls === testcheck.section("多继承字段合并") obj_c = C(1, 2, 3) viperlib.snprintf(buf, 256, "C: a=%d b=%d c=%d", obj_c.a, obj_c.b, obj_c.c) @@ -158,7 +158,7 @@ def main() -> CInt | CExport: testcheck.check(obj_c.get_c() == 3, "C.get_c 自身 OK", "C.get_c 自身 FAILED") testcheck.ok("字段合并测试完成") - # === 2. 菱形去重 + 最左优先 === + # === 2. diamond dedup + leftmost priority === testcheck.section("菱形去重 + 最左优先") dm = Diamond(5) viperlib.snprintf(buf, 256, "Diamond: shared=%d who=%d base=%d", dm.shared, dm.who(), dm.base_method()) @@ -168,7 +168,7 @@ def main() -> CInt | CExport: testcheck.check(dm.base_method() == 100, "Base 方法继承 OK", "Base 方法继承 FAILED") testcheck.ok("菱形去重测试完成") - # === 3. 虚方法多继承 vtable === + # === 3. virtual method multiple-inheritance vtable === testcheck.section("虚方法多继承 vtable") cc = ColoredCircle(3.0, 7) area: CFloat64T = cc.area() @@ -180,7 +180,7 @@ def main() -> CInt | CExport: testcheck.check(area > 28.0 and area < 28.5, "area 虚方法覆盖 OK", "area 虚方法覆盖 FAILED") testcheck.ok("虚方法多继承测试完成") - # === 4. 运算符重载 + 方法继承链 === + # === 4. operator overloading + method inheritance chain === testcheck.section("运算符重载 + 方法继承链") v1 = Vec2Both(3.0, 4.0) v2 = Vec2Both(1.0, 2.0) diff --git a/NegativeTest/App/cases/import_stale_path.vp b/NegativeTest/App/cases/import_stale_path.vp index 5715cd7..4a6ad98 100644 --- a/NegativeTest/App/cases/import_stale_path.vp +++ b/NegativeTest/App/cases/import_stale_path.vp @@ -1,5 +1,5 @@ import t, c -# f8bca62 移动前的旧路径(文件在 lib/Stub/StubMerger/ 下) +# Stale pre-move path; the import is expected to fail. import lib.Stub.StubMergerStore as StubMergerStore def main() -> int: diff --git a/NewAstTest/App/main.vp b/NewAstTest/App/main.vp index 1627780..8ac3f95 100644 --- a/NewAstTest/App/main.vp +++ b/NewAstTest/App/main.vp @@ -21,7 +21,7 @@ ARENA_SIZE: CInt = 16777216 def main() -> CInt | CExport: printf("=== NewAstTest Start ===\n") - # 初始化分配器 + # Initialize allocator arena: bytes = stdlib.malloc(ARENA_SIZE) if arena is None: printf("FAIL: arena alloc failed\n") @@ -34,7 +34,7 @@ def main() -> CInt | CExport: passed: CInt = 0 failed: CInt = 0 - # --- 分配 dump 缓冲区(用于 AST 反向输出测试) --- + # --- Allocate dump buffer for AST round-trip output tests --- DUMP_BUF_SIZE: sizet = 8192 dump_buf: char | CPtr = stdlib.malloc(DUMP_BUF_SIZE) if dump_buf is None: @@ -42,7 +42,7 @@ def main() -> CInt | CExport: stdlib.free(arena) return 1 - # --- Test 0: Match 语句 --- + # --- Test 0: Match statement --- match_src: str = """match x: case 1: pass @@ -57,7 +57,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: parse match with cases failed\n") - # --- Test 1: Name 节点创建 --- + # --- Test 1: Name node creation --- name_x: Name | CPtr = Name(pool, "x", ASTCtx.Load) if name_x is None: printf("FAIL: Name creation\n") @@ -66,7 +66,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: Name('x'), kind=%d\n", name_x.kind()) - # --- Test 2: ConstantInt 节点 --- + # --- Test 2: ConstantInt node --- int_42: Constant | CPtr = Constant(pool, CONST_INT, 42, 0.0, None, 1, 0) if int_42 is None: printf("FAIL: ConstantInt creation\n") @@ -76,7 +76,7 @@ def main() -> CInt | CExport: printf("PASS: ConstantInt(42), kind=%d, val=%lld\n", int_42.kind(), int_42.int_val) - # --- Test 3: ConstantStr 节点 --- + # --- Test 3: ConstantStr node --- str_hello: Constant | CPtr = Constant(pool, CONST_STR, 0, 0.0, "hello", 2, 0) if str_hello is None: printf("FAIL: ConstantStr creation\n") @@ -85,7 +85,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: ConstantStr('hello'), kind=%d\n", str_hello.kind()) - # --- Test 4: ConstantNone 节点 --- + # --- Test 4: ConstantNone node --- const_none: Constant | CPtr = Constant(pool, CONST_NONE, 0, 0.0, None, 3, 0) if const_none is None: printf("FAIL: ConstantNone creation\n") @@ -94,7 +94,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: ConstantNone, kind=%d\n", const_none.kind()) - # --- Test 5: BinOp 节点 (x + 42) --- + # --- Test 5: BinOp node (x + 42) --- binop: BinOp | CPtr = BinOp(pool, name_x, OpKind.Add, int_42) if binop is None: printf("FAIL: BinOp creation\n") @@ -103,7 +103,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: BinOp(Add), kind=%d\n", binop.kind()) - # --- Test 6: UnaryOp 节点 (-x) --- + # --- Test 6: UnaryOp node (-x) --- unary: UnaryOp | CPtr = UnaryOp(pool, OpKind.USub, name_x) if unary is None: printf("FAIL: UnaryOp creation\n") @@ -112,7 +112,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: UnaryOp(USub), kind=%d\n", unary.kind()) - # --- Test 7: list[AST | CPtr] 容器 --- + # --- Test 7: list[AST | CPtr] container --- body: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8) if body is None: printf("FAIL: list creation\n") @@ -128,7 +128,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: list count=%zu (expected 2)\n", cnt) - # --- Test 8: list get + kind 分派 --- + # --- Test 8: list get + kind dispatch --- if body is not None: item0: AST | CPtr = body.get(0) if item0 is not None: @@ -143,7 +143,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: list get(0) returned None\n") - # --- Test 9: Module 节点 (新签名:Module(pool) + append) --- + # --- Test 9: Module node (Module(pool) + append) --- mod: Module | CPtr = Module(pool) if mod is None: printf("FAIL: Module creation\n") @@ -154,7 +154,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: Module, kind=%d\n", mod.kind()) - # --- Test 10: 多态分派 — 通过 AST 基类指针调用 kind() --- + # --- Test 10: polymorphic dispatch via AST base pointer kind() --- ast_ptr: AST | CPtr = mod poly_kind: CInt = ast_ptr.kind() if poly_kind == ASTKind.Module: @@ -164,7 +164,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: polymorphic kind()=%d (expected %d)\n", poly_kind, ASTKind.Module) - # --- Test 11: 多态分派 — list 中的节点 --- + # --- Test 11: polymorphic dispatch on list elements --- if body is not None: ast_item: AST | CPtr = body.get(1) if ast_item is not None: @@ -179,7 +179,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: list get(1) returned None\n") - # --- Test 12: Return 节点 --- + # --- Test 12: Return node --- ret: Return | CPtr = Return(pool, binop) if ret is None: printf("FAIL: Return creation\n") @@ -188,7 +188,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: Return, kind=%d\n", ret.kind()) - # --- Test 13: Expr 语句节点 --- + # --- Test 13: Expr statement node --- expr_stmt: Expr | CPtr = Expr(pool, binop) if expr_stmt is None: printf("FAIL: Expr creation\n") @@ -197,7 +197,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: Expr, kind=%d\n", expr_stmt.kind()) - # --- Test 14: If 节点 (新签名:If(pool, test, orelse),body=children) --- + # --- Test 14: If node (If(pool, test, orelse), body = children) --- empty_else: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8) if_stmt: If | CPtr = If(pool, binop, empty_else) if if_stmt is None: @@ -209,7 +209,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: If, kind=%d\n", if_stmt.kind()) - # --- Test 15: Compare 节点 --- + # --- Test 15: Compare node --- cmp_ops: list[int] | CPtr = list[int](pool) cmp_ops.append(OpKind.Lt) cmp_comparators: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8) @@ -222,7 +222,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: Compare, kind=%d\n", cmp_node.kind()) - # --- Test 16: Assign 节点 --- + # --- Test 16: Assign node --- assign_targets: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8) assign_targets.append(name_x) assign_node: Assign | CPtr = Assign(pool, assign_targets, int_42) @@ -233,7 +233,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: Assign, kind=%d\n", assign_node.kind()) - # --- Test 17: Call 节点 --- + # --- Test 17: Call node --- call_args: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8) call_args.append(int_42) call_kwargs: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8) @@ -245,7 +245,7 @@ def main() -> CInt | CExport: passed += 1 printf("PASS: Call, kind=%d\n", call_node.kind()) - # --- Test 18: 字段访问验证 --- + # --- Test 18: field access check --- if name_x is not None: nm: str = name_x.id if nm is not None: @@ -259,7 +259,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: Name.id is None\n") - # --- Test 19: parent 指针验证 (binop 被 append 到 mod) --- + # --- Test 19: parent pointer check (binop appended to mod) --- if binop is not None and binop.parent is mod: passed += 1 printf("PASS: BinOp.parent == Module (via append)\n") @@ -267,7 +267,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: BinOp.parent != Module\n") - # --- Test 20: Module.children 遍历 --- + # --- Test 20: Module.children traversal --- if mod is not None and mod.children is not None: mod_cnt: sizet = mod.children.__len__() if mod_cnt == 2: @@ -280,7 +280,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: Module.children is None\n") - # --- Test 21: Module.children 多态分派 --- + # --- Test 21: Module.children polymorphic dispatch --- if mod is not None and mod.children is not None: c0: AST | CPtr = mod.children.get(0) c1: AST | CPtr = mod.children.get(1) @@ -300,7 +300,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: Module.children unavailable\n") - # --- Test 22: If.children 遍历 (ret + expr_stmt) --- + # --- Test 22: If.children traversal (ret + expr_stmt) --- if if_stmt is not None and if_stmt.children is not None: if_cnt: sizet = if_stmt.children.__len__() if if_cnt == 2: @@ -313,7 +313,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: If.children is None\n") - # --- Test 23: parent 向上遍历 (if_stmt.children[0].parent == if_stmt) --- + # --- Test 23: parent upward traversal (child.parent == if_stmt) --- if if_stmt is not None and if_stmt.children is not None: first_child: AST | CPtr = if_stmt.children.get(0) if first_child is not None and first_child.parent is if_stmt: @@ -326,7 +326,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: If.children unavailable for parent test\n") - # --- Test 24: parse_expression 解析 "x + 42" --- + # --- Test 24: parse_expression on "x + 42" --- expr_src: str = "x + 42" expr_tree: AST | CPtr = parse_expression(expr_src, pool) if expr_tree is not None: @@ -336,7 +336,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: parse_expression returned None\n") - # --- Test 25: parse 解析简单模块 "x = 42\n" --- + # --- Test 25: parse simple module "x = 42" --- mod_src: str = "x = 42\n" parsed_mod: Module | CPtr = parse(mod_src, pool) if parsed_mod is not None and parsed_mod.kind() == ASTKind.Module: @@ -346,7 +346,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: parse('x = 42') failed\n") - # --- Test 26: parse 模块的 children 验证 --- + # --- Test 26: parsed module children check --- if parsed_mod is not None and parsed_mod.children is not None: pmod_cnt: sizet = parsed_mod.children.__len__() if pmod_cnt == 1: @@ -359,7 +359,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: parsed Module.children is None\n") - # --- Test 27: parse 模块子节点类型验证 (Assign) --- + # --- Test 27: parsed module child kind check (Assign) --- if parsed_mod is not None and parsed_mod.children is not None: pmod_child: AST | CPtr = parsed_mod.children.get(0) if pmod_child is not None: @@ -378,7 +378,7 @@ def main() -> CInt | CExport: failed += 1 printf("FAIL: parsed Module.children unavailable for kind test\n") - # --- Test 28: parse 多语句模块 --- + # --- Test 28: parse multi-statement module --- multi_src: str = """a = 1 b = 2 c = a + b @@ -396,7 +396,7 @@ c = a + b failed += 1 printf("FAIL: parse multi-stmt failed\n") - # --- Test 29: parse if 语句 --- + # --- Test 29: parse if statement --- if_src: str = """if x > 0: y = 1 """ @@ -414,7 +414,7 @@ c = a + b failed += 1 printf("FAIL: parse if failed\n") - # --- Test 30: parse for 循环 --- + # --- Test 30: parse for loop --- for_src: str = """for i in range(10): pass """ @@ -432,7 +432,7 @@ c = a + b failed += 1 printf("FAIL: parse for failed\n") - # --- Test 31: parse while 循环 --- + # --- Test 31: parse while loop --- while_src: str = """while x < 100: x = x + 1 """ @@ -450,7 +450,7 @@ c = a + b failed += 1 printf("FAIL: parse while failed\n") - # --- Test 32: parse 函数定义 --- + # --- Test 32: parse function definition --- def_src: str = """def foo(a, b): return a + b """ @@ -468,7 +468,7 @@ c = a + b failed += 1 printf("FAIL: parse def failed\n") - # --- Test 33: parse 复杂表达式 (a + b * c - 1) --- + # --- Test 33: parse complex expression (a + b * c - 1) --- complex_expr_src: str = "a + b * c - 1" complex_expr: AST | CPtr = parse_expression(complex_expr_src, pool) if complex_expr is not None: @@ -483,7 +483,7 @@ c = a + b failed += 1 printf("FAIL: parse complex expr failed\n") - # --- Test 34: parse 嵌套语句 (for 内 if) --- + # --- Test 34: parse nested statement (if inside for) --- nested_src: str = """for i in range(10): if i > 5: x = 1 @@ -502,7 +502,7 @@ c = a + b failed += 1 printf("FAIL: parse nested for-if failed\n") - # --- Test 35: parse 混合多语句模块 --- + # --- Test 35: parse mixed multi-statement module --- mixed_src: str = """x = 1 y = 2 if x < y: @@ -524,7 +524,7 @@ w = z * 2 failed += 1 printf("FAIL: parse mixed module failed\n") - # --- Test 36: dump 反向 - parse("x = 42") → dump → strstr 验证 --- + # --- Test 36: dump round-trip - parse("x = 42") then strstr check --- if parsed_mod is not None: dump(parsed_mod, dump_buf, DUMP_BUF_SIZE) has_assign: str = string.strstr(dump_buf, "Assign") @@ -539,7 +539,7 @@ w = z * 2 failed += 1 printf("FAIL: parsed_mod unavailable for dump test\n") - # --- Test 37: dump 反向 - parse_expression("x + 42 * 2") → dump → strstr BinOp --- + # --- Test 37: dump round-trip - complex expr then strstr BinOp --- if complex_expr is not None: dump(complex_expr, dump_buf, DUMP_BUF_SIZE) has_binop: str = string.strstr(dump_buf, "BinOp") @@ -553,7 +553,7 @@ w = z * 2 failed += 1 printf("FAIL: complex_expr unavailable for dump test\n") - # --- Test 38: dump 反向 - parse if → dump → strstr "If" + "Compare" --- + # --- Test 38: dump round-trip - parse if then strstr If/Compare --- if if_mod is not None: dump(if_mod, dump_buf, DUMP_BUF_SIZE) has_if: str = string.strstr(dump_buf, "If(") @@ -568,7 +568,7 @@ w = z * 2 failed += 1 printf("FAIL: if_mod unavailable for dump test\n") - # --- Test 39: dump 反向 - parse def → dump → strstr "FunctionDef" --- + # --- Test 39: dump round-trip - parse def then strstr FunctionDef --- if def_mod is not None: dump(def_mod, dump_buf, DUMP_BUF_SIZE) has_fdef: str = string.strstr(dump_buf, "FunctionDef") @@ -582,11 +582,11 @@ w = z * 2 failed += 1 printf("FAIL: def_mod unavailable for dump test\n") - # --- Test 40: AST 结构化输出 - dump 多语句模块完整输出 --- + # --- Test 40: structured dump of multi-statement module --- if mixed_mod is not None: dump(mixed_mod, dump_buf, DUMP_BUF_SIZE) printf("--- AST dump of mixed module ---\n%s\n--- end dump ---\n", dump_buf) - # 验证包含多种节点 + # Check multiple node kinds present has_m_assign: str = string.strstr(dump_buf, "Assign") has_m_if: str = string.strstr(dump_buf, "If(") if has_m_assign is not None and has_m_if is not None: @@ -599,7 +599,7 @@ w = z * 2 failed += 1 printf("FAIL: mixed_mod unavailable for structured dump\n") - # --- Test 41: AST 结构化输出 - dump for 循环完整输出 --- + # --- Test 41: structured dump of for loop --- if for_mod is not None: dump(for_mod, dump_buf, DUMP_BUF_SIZE) printf("--- AST dump of for loop ---\n%s\n--- end dump ---\n", dump_buf) @@ -614,7 +614,7 @@ w = z * 2 failed += 1 printf("FAIL: for_mod unavailable for structured dump\n") - # --- Test 42: type_name 多态分派验证 --- + # --- Test 42: type_name polymorphic dispatch check --- if parsed_mod is not None and parsed_mod.children is not None: tn_node: AST | CPtr = parsed_mod.children.get(0) if tn_node is not None: @@ -632,7 +632,7 @@ w = z * 2 failed += 1 printf("FAIL: parsed_mod unavailable for type_name test\n") - # --- Test 43: parse 类定义 --- + # --- Test 43: parse class definition --- class_src: str = """class Foo(Base): x = 1 def bar(self): @@ -672,7 +672,7 @@ except: failed += 1 printf("FAIL: parse try/except failed\n") - # --- Test 45: parse import 语句 --- + # --- Test 45: parse import statement --- import_src: str = """import os from sys import path """ @@ -710,7 +710,7 @@ x += 1 failed += 1 printf("FAIL: parse AugAssign failed\n") - # --- Test 47: parse 条件表达式 (x if y else z) --- + # --- Test 47: parse conditional expression (x if y else z) --- ifexp_src: str = "x if y else z" ifexp_tree: AST | CPtr = parse_expression(ifexp_src, pool) ifexp_expr: Expression | CPtr = (Expression | CPtr)(ifexp_tree) @@ -726,7 +726,7 @@ x += 1 failed += 1 printf("FAIL: parse IfExp failed\n") - # --- Test 48: parse 嵌套函数定义 --- + # --- Test 48: parse nested function definition --- nested_def_src: str = """def outer(): x = 1 def inner(): @@ -747,7 +747,7 @@ x += 1 failed += 1 printf("FAIL: parse nested def failed\n") - # --- Test 49: dump 复杂代码 (类 + try + 嵌套函数) --- + # --- Test 49: dump complex code (class + try + nested def) --- complex_src: str = """class Foo(Base): x = 1 try: @@ -774,7 +774,7 @@ def bar(): failed += 1 printf("FAIL: parse complex module failed\n") - # --- Test 50: 复杂 mixed_src - 综合语法实例 --- + # --- Test 50: complex mixed_src - combined syntax sample --- complex_mixed_src: str = """def gcd(a, b): while b: t = b @@ -819,7 +819,7 @@ else: failed += 1 printf("FAIL: complex mixed_src parse failed\n") - # --- Test 51: Lambda 表达式 --- + # --- Test 51: Lambda expression --- lambda_src: str = "f = lambda x: x + 1" lambda_mod: Module | CPtr = parse(lambda_src, pool) if lambda_mod is not None: @@ -887,7 +887,7 @@ else: failed += 1 printf("FAIL: SetComp parse returned None\n") - # --- Test 55: With 语句 --- + # --- Test 55: With statement --- with_src: str = """with open('f') as f: data = f.read() """ @@ -907,7 +907,7 @@ else: failed += 1 printf("FAIL: With parse returned None\n") - # --- Test 56: Raise 语句 --- + # --- Test 56: Raise statement --- raise_src: str = "raise ValueError('bad')" raise_mod: Module | CPtr = parse(raise_src, pool) if raise_mod is not None: @@ -923,7 +923,7 @@ else: failed += 1 printf("FAIL: Raise parse returned None\n") - # --- Test 57: Assert 语句 --- + # --- Test 57: Assert statement --- assert_src: str = "assert x > 0, 'x must be positive'" assert_mod: Module | CPtr = parse(assert_src, pool) if assert_mod is not None: @@ -939,7 +939,7 @@ else: failed += 1 printf("FAIL: Assert parse returned None\n") - # --- Test 58: Del 语句 --- + # --- Test 58: Del statement --- del_src: str = "del x" del_mod: Module | CPtr = parse(del_src, pool) if del_mod is not None: @@ -973,7 +973,7 @@ else: failed += 1 printf("FAIL: Slice parse returned None\n") - # --- Test 60: Tuple 解包 --- + # --- Test 60: Tuple unpacking --- tuple_src: str = "a, b = 1, 2" tuple_mod: Module | CPtr = parse(tuple_src, pool) if tuple_mod is not None: @@ -989,7 +989,7 @@ else: failed += 1 printf("FAIL: Tuple parse returned None\n") - # --- Test 61: 默认参数 + 关键字参数签名 --- + # --- Test 61: default args + keyword args signature --- defdef_src: str = "def f(a, b=10): return a + b" defdef_mod: Module | CPtr = parse(defdef_src, pool) if defdef_mod is not None: @@ -1007,7 +1007,7 @@ else: failed += 1 printf("FAIL: defdef parse returned None\n") - # --- Test 62: 装饰器 --- + # --- Test 62: decorator --- deco_src: str = """@my_dec def f(): pass @@ -1026,7 +1026,7 @@ def f(): failed += 1 printf("FAIL: Decorator parse returned None\n") - # --- Test 63: 链式赋值 --- + # --- Test 63: chained assignment --- chain_src: str = "a = b = c = 42" chain_mod: Module | CPtr = parse(chain_src, pool) if chain_mod is not None: @@ -1045,7 +1045,7 @@ def f(): failed += 1 printf("FAIL: Chain parse returned None\n") - # --- Test 64: 位运算 --- + # --- Test 64: bitwise ops --- bit_src: str = "y = (a | b) & c ^ d << 2" bit_mod: Module | CPtr = parse(bit_src, pool) if bit_mod is not None: @@ -1064,7 +1064,7 @@ def f(): failed += 1 printf("FAIL: Bit ops parse returned None\n") - # --- Test 65: 多继承 + 多装饰器 --- + # --- Test 65: multiple inheritance + decorators --- multi_src: str = """@dec1 @dec2 class C(Base1, Base2): @@ -1126,7 +1126,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: fstring parse returned None\n") - # --- Test 68: 嵌套函数 + 闭包 --- + # --- Test 68: nested function + closure --- nested_src: str = """def outer(): x = 10 def inner(): @@ -1149,7 +1149,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: nested parse returned None\n") - # --- Test 69: Match 字面量整数模式 --- + # --- Test 69: Match literal int pattern --- m_lit_src: str = """match x: case 1: pass @@ -1168,7 +1168,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match literal int parse returned None\n") - # --- Test 70: Match 字面量字符串模式 --- + # --- Test 70: Match literal string pattern --- m_str_src: str = """match x: case "hello": pass @@ -1187,7 +1187,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match literal str parse returned None\n") - # --- Test 71: Match 负数字面量模式 --- + # --- Test 71: Match negative literal pattern --- m_neg_src: str = """match x: case -1: pass @@ -1206,7 +1206,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match negative literal parse returned None\n") - # --- Test 72: Match None 单例模式 --- + # --- Test 72: Match None singleton pattern --- m_none_src: str = """match x: case None: pass @@ -1225,7 +1225,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match None parse returned None\n") - # --- Test 73: Match True 单例模式 --- + # --- Test 73: Match True singleton pattern --- m_true_src: str = """match x: case True: pass @@ -1244,7 +1244,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match True parse returned None\n") - # --- Test 74: Match False 单例模式 --- + # --- Test 74: Match False singleton pattern --- m_false_src: str = """match x: case False: pass @@ -1263,7 +1263,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match False parse returned None\n") - # --- Test 75: Match 通配符 _ 模式 --- + # --- Test 75: Match wildcard _ pattern --- m_wild_src: str = """match x: case _: pass @@ -1282,7 +1282,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match wildcard parse returned None\n") - # --- Test 76: Match 捕获变量模式 --- + # --- Test 76: Match capture variable pattern --- m_cap_src: str = """match x: case y: pass @@ -1301,7 +1301,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match capture parse returned None\n") - # --- Test 77: Match 值模式 (dotted name Color.RED) --- + # --- Test 77: Match value pattern (dotted name Color.RED) --- m_val_src: str = """match x: case Color.RED: pass @@ -1322,7 +1322,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match value parse returned None\n") - # --- Test 78: Match 序列模式 [1, 2] --- + # --- Test 78: Match sequence pattern [1, 2] --- m_seq_src: str = """match x: case [1, 2]: pass @@ -1341,7 +1341,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match sequence parse returned None\n") - # --- Test 79: Match 序列带星号 [a, *rest] --- + # --- Test 79: Match starred sequence [a, *rest] --- m_star_src: str = """match x: case [a, *rest]: pass @@ -1360,7 +1360,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match star parse returned None\n") - # --- Test 80: Match 类模式 Point(x, y) --- + # --- Test 80: Match class pattern Point(x, y) --- m_cls_src: str = """match p: case Point(x, y): pass @@ -1379,7 +1379,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match class parse returned None\n") - # --- Test 81: Match 类模式带关键字 Point(x=0, y=0) --- + # --- Test 81: Match keyword class pattern Point(x=0, y=0) --- m_kwcls_src: str = """match p: case Point(x=0, y=0): pass @@ -1398,7 +1398,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match class kwd parse returned None\n") - # --- Test 82: Match OR 模式 1 | 2 --- + # --- Test 82: Match OR pattern 1 | 2 --- m_or_src: str = """match x: case 1 | 2: pass @@ -1417,7 +1417,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match OR parse returned None\n") - # --- Test 83: Match AS 模式 [x] as p --- + # --- Test 83: Match AS pattern [x] as p --- m_as_src: str = """match x: case [x] as p: pass @@ -1438,7 +1438,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match AS parse returned None\n") - # --- Test 84: Match guard 模式 case x if x > 0 --- + # --- Test 84: Match guard pattern case x if x > 0 --- m_guard_src: str = """match x: case x if x > 0: pass @@ -1457,7 +1457,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match guard parse returned None\n") - # --- Test 85: Match 映射模式 {"k": v} --- + # --- Test 85: Match mapping pattern {"k": v} --- m_map_src: str = """match x: case {"k": v}: pass @@ -1476,7 +1476,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match mapping parse returned None\n") - # --- Test 86: Match 映射带 rest {"k": v, **rest} --- + # --- Test 86: Match mapping with rest {"k": v, **rest} --- m_map2_src: str = """match x: case {"k": v, **rest}: pass @@ -1497,7 +1497,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match mapping rest parse returned None\n") - # --- Test 87: Match 组合模式 (1 | 2) as p --- + # --- Test 87: Match combined pattern (1 | 2) as p --- m_combo_src: str = """match x: case (1 | 2) as p: pass @@ -1634,7 +1634,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: async with parse returned None\n") - # --- Test 91: Match 复合语句 (多 case + 多类型模式) --- + # --- Test 91: Match compound statement (multi-case, multi-pattern) --- m_complex_src: str = """match cmd: case "quit": pass @@ -1665,7 +1665,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: Match complex parse returned None\n") - # --- Test 92: async def + async for + async with 组合 --- + # --- Test 92: async def + async for + async with combo --- acombo_src: str = """async def f(): async with ctx: async for x in y: @@ -1695,7 +1695,7 @@ class C(Base1, Base2): failed += 1 printf("FAIL: async combo parse returned None\n") - # --- 结果汇总 --- + # --- Result summary --- printf("\n=== Results: %d passed, %d failed ===\n", passed, failed) stdlib.free(dump_buf) diff --git a/NoVTableCrossMixinTest/App/main.vp b/NoVTableCrossMixinTest/App/main.vp index a84e349..9984a3a 100644 --- a/NoVTableCrossMixinTest/App/main.vp +++ b/NoVTableCrossMixinTest/App/main.vp @@ -5,14 +5,8 @@ import testcheck # ============================================================ -# 复现:NoVTable 多继承下跨 Mixin self. 方法调用 -# -# 缺陷:BaseB.caller 内 `self.helper()`(helper 定义在兄弟 Mixin BaseA, -# 经 Combined 多继承组合)被 mangle 成 `.BaseB.helper` -# (用调用者自身/直接父类做前缀),而定义符号是 `.BaseA.helper` -# → ld.lld undefined symbol(TPV 侧 StmtGenMixin.translate_stmt 调 -# self.translate_return 同根因,符号成 StmtGenDeclMixin.translate_return)。 -# 期望:按实际定义类(BaseA)做前缀,或按最终组合类(Combined)。 +# NoVTable multiple inheritance: a sibling-mixin self.helper() call (BaseB +# calling helper defined in BaseA) must resolve the symbol to BaseA/Combined. # ============================================================ novirtual class BaseA: a: int @@ -43,13 +37,8 @@ def test_cross_mixin_call(): # ============================================================ -# 扩展 Test 2:多级 Mixin 链(父类继承 + 兄弟)+ 字段写 -# -# 覆盖 Handles 去壳核心要求: -# MixinB2 继承 MixinA2(1 级父类);Combined2(MixinB2, MixinC2) 多继承。 -# MixinC2.outer2 调兄弟 MixinB2.mid2(this_adjust 到 MixinB2 字段区), -# MixinB2.mid2 调父类 MixinA2.inner2(this_adjust 到 MixinA2 字段区), -# inner2 内写 self.a2(this_adjust 精确到组合类中 a2 字段)。 +# Test 2: multilevel mixin chain (parent inheritance + sibling) with field +# writes, exercising this_adjust across sibling and parent field regions. # ============================================================ novirtual class MixinA2: a2: int @@ -83,18 +72,15 @@ def test_multilevel_chain(): c.a2 = 1 c.b2 = 2 c.c2 = 3 - # outer2 -> mid2 -> inner2:inner2 写 a2(1->11),mid2=11+2=13,outer2=13+3=16 + # outer2 -> mid2 -> inner2: inner2 writes a2 (1->11), mid2=13, outer2=16 testcheck.check(c.outer2() == 16, "outer2()==16 (C->B->A chain + field write)", "multilevel chain fail") # ============================================================ -# 扩展 Test 3:第二父类字段区偏移(this_adjust 非 0)+ 指针字段 -# -# Combined3(PtrMixin, DataMixin):PtrMixin 第一父类(字段区偏移 0), -# DataMixin 第二父类(字段区偏移 = sizeof(PtrMixin),非 0)。 -# DataMixin.get_val 内 self.val 需 this_adjust 到第二父类字段区。 +# Test 3: second-parent field offset (nonzero this_adjust) plus a pointer +# field; self.val must adjust into DataMixin's field region. # ============================================================ novirtual class PtrMixin: name: char* diff --git a/NoVTableTest/App/main.vp b/NoVTableTest/App/main.vp index 9d658be..d916558 100644 --- a/NoVTableTest/App/main.vp +++ b/NoVTableTest/App/main.vp @@ -7,19 +7,13 @@ import viperlib import stdlib -# ============================================================ -# 子类继承 linkedlist.LinkedNode:启用链表/树形能力 -# 字段展平,无 vtable;OOP 方法通过 _generate_inherited_method_wrappers -# 自动生成子类包装(self bitcast 为父类指针后调用父类方法)。 -# 从 LinkedNode* 取回 Node* 需显式向下转型:(Node | t.CPtr)(ptr) -# ============================================================ +# Subclass of linkedlist.LinkedNode: flattened fields, no vtable; OOP wrappers are auto-generated. +# Cast LinkedNode* back to Node* explicitly: (Node | t.CPtr)(ptr) class Node(linkedlist.LinkedNode): value: int -# ============================================================ -# 测试 1:append + child_count -# ============================================================ +# --- Test 1: append + child_count --- def test_append(): testcheck.section("Test 1: append") root: Node = Node() @@ -35,7 +29,7 @@ def test_append(): testcheck.check(root.child_count == 3, "append count=3", "append count fail") - # 验证顺序(LinkedNode* → Node* 显式向下转型) + # verify order (explicit downcast LinkedNode* -> Node*) c1: Node* = (Node*)(root.child) c2: Node* = (Node*)(c1.next) c3: Node* = (Node*)(c2.next) @@ -44,9 +38,7 @@ def test_append(): "order fail") -# ============================================================ -# 测试 2:双向链表 prev 指针 -# ============================================================ +# --- Test 2: doubly linked prev --- def test_prev_link(): testcheck.section("Test 2: prev pointer (doubly linked)") root: Node = Node() @@ -56,20 +48,18 @@ def test_prev_link(): b.value = 2 root.append(a) root.append(b) - # b.prev 应指向 a + # b.prev should point to a bp: Node* = (Node*)(b.prev) testcheck.check(bp is not None and bp.value == 1, "b.prev.value=1", "prev link fail") - # a.prev 应为 None(第一个子节点) + # a.prev should be None (first child) testcheck.check(a.prev is None, "a.prev=None", "first prev fail") -# ============================================================ -# 测试 3:last_child 指针(O(1) 追加验证) -# ============================================================ +# --- Test 3: last_child pointer --- def test_last_child(): testcheck.section("Test 3: last_child pointer") root: Node = Node() @@ -89,9 +79,7 @@ def test_last_child(): "last_child fail 2") -# ============================================================ -# 测试 4:detach(O(1) 摘除) -# ============================================================ +# --- Test 4: detach (O(1) unlink) --- def test_remove(): testcheck.section("Test 4: detach (O(1) unlink)") root: Node = Node() @@ -104,30 +92,28 @@ def test_remove(): root.append(a) root.append(b) root.append(c) - # 摘除中间的 b + # detach middle node b b.detach() testcheck.check(root.child_count == 2, "count=2 after detach", "detach count fail") - # a.next 应直接指向 c + # a.next should point directly to c an: Node* = (Node*)(a.next) testcheck.check(an is not None and an.value == 3, "a.next.value=3", "detach link fail") - # c.prev 应指向 a + # c.prev should point to a cp: Node* = (Node*)(c.prev) testcheck.check(cp is not None and cp.value == 1, "c.prev.value=1", "detach prev fail") - # b 的链接应清空 + # b links should be cleared testcheck.check(b.parent is None and b.next is None and b.prev is None, "b cleared", "b not cleared") -# ============================================================ -# 测试 5:remove_child -# ============================================================ +# --- Test 5: remove_child --- def test_remove_child(): testcheck.section("Test 5: remove_child") root: Node = Node() @@ -147,9 +133,7 @@ def test_remove_child(): "remove_child first fail") -# ============================================================ -# 测试 6:prepend + insert_before + insert_after -# ============================================================ +# --- Test 6: prepend/insert_before/insert_after --- def test_insert_ops(): testcheck.section("Test 6: prepend/insert_before/insert_after") root: Node = Node() @@ -163,9 +147,9 @@ def test_insert_ops(): d.value = 4 root.append(a) # [1] root.append(c) # [1, 3] - root.insert_before(c, b) # [1, 2, 3] 在 c 前插入 b - root.insert_after(a, d) # [1, 4, 2, 3] 在 a 后插入 d - # 遍历验证顺序 + root.insert_before(c, b) # [1, 2, 3] insert b before c + root.insert_after(a, d) # [1, 4, 2, 3] insert d after a + # traverse to verify order cur: Node* = (Node*)(root.child) v0: int = cur.value cur = (Node*)(cur.next) @@ -182,11 +166,8 @@ def test_insert_ops(): "insert count fail") -# ============================================================ -# 测试 7:child_at + count_children -# 注意:Viper 中 Node() 是栈分配,循环内 n 会被复用(同一地址), -# 导致所有子节点指向同一内存。必须用独立变量保证各节点地址不同。 -# ============================================================ +# --- Test 7: child_at + count_children --- +# Node() is stack-allocated; use distinct variables so each node has a unique address. def test_index_access(): testcheck.section("Test 7: child_at + count_children") root: Node = Node() @@ -229,9 +210,7 @@ def test_index_access(): "count_children fail") -# ============================================================ -# 测试 8:has_children + first_sibling/last_sibling -# ============================================================ +# --- Test 8: has_children + sibling traverse --- def test_sibling_traverse(): testcheck.section("Test 8: has_children + sibling traverse") root: Node = Node() @@ -250,7 +229,7 @@ def test_sibling_traverse(): testcheck.check(root.has_children() == 1, "has_children=1", "has_children fail") - # 从 b 出发找头尾兄弟 + # find first/last sibling starting from b fs: Node* = (Node*)(b.first_sibling()) ls: Node* = (Node*)(b.last_sibling()) testcheck.check(fs is not None and fs.value == 1, @@ -261,9 +240,7 @@ def test_sibling_traverse(): "last_sibling fail") -# ============================================================ -# 测试 9:unlink(断开所有连接) -# ============================================================ +# --- Test 9: unlink --- def test_unlink(): testcheck.section("Test 9: unlink") root: Node = Node() @@ -273,7 +250,7 @@ def test_unlink(): b.value = 2 root.append(a) root.append(b) - # unlink a:从兄弟链摘除 + 断开父子链接 + # unlink a: remove from sibling chain and clear parent/child links a.unlink() testcheck.check(a.next is None and a.prev is None and a.parent is None, "a links cleared", @@ -281,15 +258,13 @@ def test_unlink(): testcheck.check(a.child is None and a.last_child is None and a.child_count == 0, "a child cleared", "a child not cleared") - # root 应只剩 b + # root should keep only b testcheck.check(root.child_count == 1, "root count=1 after unlink", "root count fail") -# ============================================================ -# 测试 10:SListNode 单向链表(OOP 方法) -# ============================================================ +# --- Test 10: SListNode (singly linked, OOP) --- class SNode(linkedlist.SListNode): value: int @@ -302,7 +277,7 @@ def test_slist(): n0.value = 100 n1.value = 200 n2.value = 300 - # append (O(n)) — 直接用 n0 作为 head + # append (O(n)); use n0 as head head: linkedlist.SListNode* = n0 head = head.append(n1) head = head.append(n2) @@ -327,7 +302,7 @@ def test_slist(): testcheck.check(a3 is None, "at(3)=None", "at 3 fail") - # remove (移除中间节点 n1) + # remove (drop middle node n1) head = head.remove(n1) testcheck.check(head.count() == 2, "after remove count=2", @@ -335,7 +310,7 @@ def test_slist(): testcheck.check(n1.Next is None, "n1.Next cleared", "n1.Next not cleared") - # 移除后 a0.Next 应指向 n2 + # after removal a0.Next should point to n2 a0b: SNode* = (SNode*)(a0.Next) testcheck.check(a0b is not None and a0b.value == 300, "after remove a0.Next=300", @@ -352,12 +327,10 @@ def test_slist(): "append count fail") -# ============================================================ -# 测试 11:viperlib.sprintf *args 转发 -# ============================================================ +# --- Test 11: viperlib.sprintf *args forwarding --- def test_sprintf_vararg(): testcheck.section("Test 11: viperlib.sprintf *args forwarding") - # 测试 %d 单参数 + # single %d argument buf: char* = stdlib.malloc(32) if buf is None: return buf[0] = 0 @@ -365,7 +338,7 @@ def test_sprintf_vararg(): testcheck.check(string.strcmp(buf, "key42") == 0, "sprintf key42", "sprintf key%d fail") - # 测试无参数 + # no argument buf2: char* = stdlib.malloc(32) if buf2 is None: return buf2[0] = 0 @@ -373,7 +346,7 @@ def test_sprintf_vararg(): testcheck.check(string.strcmp(buf2, "hello") == 0, "sprintf hello", "sprintf no-arg fail") - # 测试多参数 + # multiple arguments buf3: char* = stdlib.malloc(32) if buf3 is None: return buf3[0] = 0 @@ -383,18 +356,8 @@ def test_sprintf_vararg(): "sprintf multi-arg fail") -# ============================================================ -# 测试 12:泛型 GSListNode[T] + GSList[T] -# -# 验证 4 个技术点(为 mlirlite 简化铺路): -# 1. 递归泛型 class GNode(GSListNode[GNode]): -# 2. novirtual class + 泛型组合(GNode 无 vptr,字段展平) -# 3. 泛型类作字段类型 lst: GSList[GNode] -# 4. 泛型方法继承 lst.append(n) / lst.count() / lst.at(i) -# (GSList[T] 的方法在特化 GSList[GNode] 后可用) -# -# 注:编译器暂不支持 模块.泛型类[T]() 跨模块构造,故本地定义。 -# ============================================================ +# --- Test 12: generic GSListNode[T] + GSList[T] --- +# Recursive generic, novirtual flattened fields, generic as field type; local def (no cross-module generic support yet). novirtual class GSListNode[T]: Next: T* @@ -438,10 +401,10 @@ class GNode(GSListNode[GNode]): def test_generic_slist(): testcheck.section("Test 12: Generic GSListNode[T] + GSList[T]") - # 技术点 3: 泛型类作字段类型 + 构造 + # generic class as field type + construction lst: GSList[GNode]* = GSList[GNode]() - # 技术点 1+2: 递归泛型 + NoVTable 组合(GNode 定义在上方) + # recursive generic + NoVTable combo (GNode defined above) n0: GNode = GNode() n1: GNode = GNode() n2: GNode = GNode() @@ -449,7 +412,7 @@ def test_generic_slist(): n1.Value = 20 n2.Value = 30 - # 技术点 4: 泛型方法继承 + # generic method inheritance lst.append(n0) lst.append(n1) lst.append(n2) @@ -459,7 +422,7 @@ def test_generic_slist(): "GSList.count()=3", "GSList count fail") - # at (O(n)) — 返回 GNode|CPtr,无需向下转型 + # at (O(n)) returns GNode|CPtr, no downcast needed a0: GNode* = lst.at(0) a1: GNode* = lst.at(1) a2: GNode* = lst.at(2) @@ -477,7 +440,7 @@ def test_generic_slist(): "GSList.at(3)=None", "GSList at 3 fail") - # Next 字段强类型(a0.Next 直接是 GNode|CPtr,无需转型) + # Next is strongly typed (a0.Next is GNode|CPtr, no cast) testcheck.check(a0.Next is a1, "a0.Next is a1 (strong type)", "a0.Next fail") diff --git a/NumpyTest/App/test_numpy.vp b/NumpyTest/App/test_numpy.vp index 0ecec19..ba4d002 100644 --- a/NumpyTest/App/test_numpy.vp +++ b/NumpyTest/App/test_numpy.vp @@ -68,8 +68,7 @@ def section_footer(): # ============================================================ -# Timer: 单调时钟(GetTickCount64 毫秒 → 秒) -# 原 c.Timer() 无编译器支持(TPC/TPV 均无),改用 Win32 API +# Timer: monotonic clock (GetTickCount64 ms -> s) via Win32 API. # ============================================================ def timer_sec() -> double: return double(w32.win32base.GetTickCount64()) / double(1000.0) diff --git a/OopInheritTest/App/main.vp b/OopInheritTest/App/main.vp index d7d0d0d..81f71a8 100644 --- a/OopInheritTest/App/main.vp +++ b/OopInheritTest/App/main.vp @@ -7,7 +7,7 @@ import stdlib import testcheck -# === OOP 继承 + 虚方法 === +# === OOP inheritance + virtual methods === @t.CVTable class Shape: @@ -64,7 +64,7 @@ class Rect(Shape): return self -# === 运算符重载 + 链式调用(堆分配) === +# === operator overloading + chained calls (heap allocated) === class Vec2: x: CFloat64T @@ -133,7 +133,7 @@ class Vec3: return self.dot(self) -# === 独立类(非继承) === +# === standalone classes (no inheritance) === @t.CVTable class Dog: @@ -180,7 +180,7 @@ class Cat: return 0 -# === 嵌套对象组合(堆分配) === +# === nested object composition (heap allocated) === class Transform: px: CFloat64T @@ -211,7 +211,7 @@ class Transform: return Vec3(self.px * self.scale_x, self.py * self.scale_y, self.pz * self.scale_z) -# === 多层继承(子类只重写需要的方法) === +# === multilevel inheritance (subclasses override only what they need) === @t.CVTable class Vehicle: @@ -264,7 +264,7 @@ def main() -> CInt | CExport: buf: CChar | CPtr = CPtr(stdlib.malloc(256)) - # === OOP 继承测试 === + # === OOP inheritance test === testcheck.section("OOP 继承测试") c1 = Circle(0.0, 0.0, 5.0) viperlib.snprintf(buf, 256, "Circle area=%.2f perim=%.2f", c1.area(), c1.perimeter()) @@ -274,7 +274,7 @@ def main() -> CInt | CExport: viperlib.snprintf(buf, 256, "Rect area=%.2f perim=%.2f", r1.area(), r1.perimeter()) print(buf) - # 链式调用: scale -> move + # chained calls: scale -> move c2 = Circle(1.0, 2.0, 3.0) c2.scale(2.0).move(10.0, 20.0) viperlib.snprintf(buf, 256, "Circle after scale+move: x=%.1f y=%.1f r=%.1f area=%.2f", @@ -288,7 +288,7 @@ def main() -> CInt | CExport: print(buf) testcheck.ok("OOP 继承测试完成") - # === Vec2 运算符重载 + 链式调用(堆分配) === + # === Vec2 operator overloading + chained calls (heap) === testcheck.section("Vec2 运算符重载 + 链式调用") v1 = Vec2(3.0, 4.0) v2 = Vec2(1.0, 2.0) @@ -312,13 +312,13 @@ def main() -> CInt | CExport: viperlib.snprintf(buf, 256, "Vec2 dot: %.1f", d) print(buf) - # 链式运算: (v1 + v2) * 3.0 + # chained op: (v1 + v2) * 3.0 v_chain = (v1 + v2) * 3.0 viperlib.snprintf(buf, 256, "Vec2 chain (v1+v2)*3: (%.1f, %.1f)", v_chain.x, v_chain.y) print(buf) testcheck.ok("Vec2 运算符重载测试完成") - # === Vec3 运算符重载 + 链式调用(堆分配) === + # === Vec3 operator overloading + chained calls (heap) === testcheck.section("Vec3 运算符重载 + 链式调用") a1 = Vec3(1.0, 0.0, 0.0) a2 = Vec3(0.0, 1.0, 0.0) @@ -330,7 +330,7 @@ def main() -> CInt | CExport: viperlib.snprintf(buf, 256, "Vec3 dot: %.1f", dot_v) print(buf) - # 链式: (a + b).dot(c) + # chained: (a + b).dot(c) a3 = Vec3(1.0, 2.0, 3.0) a4 = Vec3(4.0, 5.0, 6.0) a5 = Vec3(7.0, 8.0, 9.0) @@ -338,18 +338,18 @@ def main() -> CInt | CExport: viperlib.snprintf(buf, 256, "Vec3 chain dot: %.1f", chain_dot) print(buf) - # 链式: (a * 2.0 - b).cross(c) + # chained: (a * 2.0 - b).cross(c) chain_cross = (a3 * 2.0 - a4).cross(a5) viperlib.snprintf(buf, 256, "Vec3 chain cross: (%.1f, %.1f, %.1f)", chain_cross.x, chain_cross.y, chain_cross.z) print(buf) - # len_sq 链式 + # chained len_sq lsq = a3.len_sq() viperlib.snprintf(buf, 256, "Vec3 len_sq: %.1f", lsq) print(buf) testcheck.ok("Vec3 运算符重载测试完成") - # === Dog/Cat 虚方法 === + # === Dog/Cat virtual methods === testcheck.section("Dog/Cat 虚方法") dog = Dog(1, CInt32T(30)) cat = Cat(2, CInt32T(9)) @@ -368,7 +368,7 @@ def main() -> CInt | CExport: print(buf) testcheck.ok("Dog/Cat 虚方法测试完成") - # === Transform 嵌套组合(堆分配,链式调用) === + # === Transform nested composition (heap, chained calls) === testcheck.section("Transform 嵌套组合") tr = Transform(10.0, 20.0, 30.0) tr.apply_scale(2.0, 3.0, 4.0) @@ -383,7 +383,7 @@ def main() -> CInt | CExport: print(buf) testcheck.ok("Transform 嵌套组合测试完成") - # === 多层继承 === + # === multilevel inheritance === testcheck.section("多层继承") ec = ElectricCar(CInt32T(120), CInt32T(4), CInt32T(80)) viperlib.snprintf(buf, 256, "ECar speed=%d doors=%d battery=%d", ec.speed, ec.doors, ec.battery) diff --git a/PointerTest/App/main.vp b/PointerTest/App/main.vp index b9b7632..78f9f4e 100644 --- a/PointerTest/App/main.vp +++ b/PointerTest/App/main.vp @@ -6,27 +6,23 @@ import w32.win32console import w32.win32memory import testcheck -# ============================================================ -# PointerTest - 测试指针操作、global声明、数组退化、指针算术 -# ============================================================ +# PointerTest: pointer operations, global declarations, array decay, pointer arithmetic -# --- Test 1: global 声明对模块级变量的影响 --- +# --- Test 1: global declaration effects on module-level variables --- _g_val: int = 0 _g_ptr: uint32* = None def test_global_write(): - """测试:缺少 global 声明时,赋值是否修改模块级变量""" + """Write to module-level _g_val through the global declaration.""" global _g_val _g_val = 42 def test_global_write_no_decl(): - """测试:没有 global 声明时,函数内局部赋值不修改模块级变量 + """Local assignment without global leaves the module-level variable unchanged. - 新规则:模块级已有 `_g_val` 时,函数内再写 `_g_val: int = ...`(注解同名) - 一律判为"重复声明"并终止编译(TypeError)——**不管**注解类型是否与全局相同。 - 因此这里改用**不重名**的局部变量验证"函数内局部赋值不影响全局"。 + Uses a non-conflicting local name; same-name annotated redeclaration is a compile error. """ - local_val: int = 99 # 独立局部变量,与全局 _g_val 无关 + local_val: int = 99 # standalone local, unrelated to global _g_val def test_global_ptr(): global _g_ptr @@ -39,31 +35,27 @@ def test_global_ptr(): p[1] = 0x11223344 def test_global_ptr_no_decl(): - """测试:没有 global 声明时,同名注解声明是编译期错误(此处演示合法写法) + """Same-name annotated redeclaration of a module variable is a compile error. - 新规则:模块级已有 `_g_ptr` 时,函数内写 `_g_ptr: t.CUInt32T* = None` - (无 global)或 `global _g_ptr` 之后仍带类型注解声明,都判为"重复声明"并终止 - 编译(TypeError)——不管注解类型是否与全局相同。合法写法只有两种: - - 修改全局:`global _g_ptr` + **无注解**赋值(见 test_global_ptr) - - 独立局部:换成不与全局重名的变量名(本函数) + Legal forms: global + unannotated assignment, or a non-conflicting local name. """ - local_ptr: uint32* = None # 独立局部变量,不触碰全局 _g_ptr + local_ptr: uint32* = None # standalone local, does not touch global _g_ptr -# --- Test 2: 指针算术和数组索引 --- +# --- Test 2: pointer arithmetic and array indexing --- def test_pointer_arithmetic(): - """测试指针算术:偏移计算是否正确""" + """Verify pointer arithmetic computes offsets correctly.""" buf: uint32* = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04) if not buf: testcheck.fail("pointer arithmetic: VirtualAlloc returned NULL") return string.memset(buf, 0, 256) - # 写入值 + # Write values for i in range(8): buf[i] = uint32(i * 100) - # 读取并验证 + # Read back and verify ok: int = 1 for i in range(8): v: uint32 = buf[i] @@ -74,38 +66,38 @@ def test_pointer_arithmetic(): testcheck.check(ok, "pointer arithmetic (buf[i] = i*100)", "pointer arithmetic mismatch") -# --- Test 3: 数组退化为指针 --- +# --- Test 3: array decay to pointer --- def test_array_decay(): - """测试 list[t.CChar, N] 传递给 t.CConst | str 参数""" + """Pass list[t.CChar, N] to a t.CConst | str parameter.""" arr: t.CArray[char, 32] string.memset(&arr, 0, 32) - # 手动写入字符串 + # Write string manually src: str = "Hello" for i in range(5): arr[i] = char(ord(src[i])) arr[5] = 0 - # 传递给 print (接受 t.CConst | str) + # Pass to print (accepts t.CConst | str) stdio.printf("array decay -> %s\n", &arr) testcheck.ok("array decay (Hello)") -# --- Test 4: 指针类型转换 (CVoid/CPtr) --- +# --- Test 4: pointer type casts (CVoid/CPtr) --- def test_pointer_cast(): - """测试指针与整数之间的类型转换""" + """Cast between pointers and integers.""" buf: uint32* = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04) if not buf: testcheck.fail("pointer cast: VirtualAlloc returned NULL") return string.memset(buf, 0, 256) - # 通过 CVoid 指针写入 + # Write through CVoid pointer raw: t.CPtr = t.CPtr(uint64(buf)) - # 将 CVoid 指针转回 CUInt32T 指针 + # Cast CVoid pointer back to CUInt32T pointer p32: uint32* = (uint32*)(raw) p32[0] = 0xDEADBEEF - # 通过原始指针读取 + # Read through raw pointer if buf[0] == 0xDEADBEEF: testcheck.ok("pointer cast CVoid -> CUInt32T*") else: @@ -113,22 +105,22 @@ def test_pointer_cast(): testcheck.fail("pointer cast failed") -# --- Test 5: 指针偏移计算 (byte offset vs element offset) --- +# --- Test 5: pointer offset (byte offset vs element offset) --- def test_pointer_offset(): - """测试指针偏移:CUInt8T* + N 应该偏移 N 字节,CUInt32T* + N 应该偏移 N*4 字节""" + """CUInt8T* + N advances N bytes; CUInt32T* + N advances N*4 bytes.""" buf: uint8* = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04) if not buf: testcheck.fail("pointer offset: VirtualAlloc returned NULL") return string.memset(buf, 0, 256) - # 写入 4 字节 + # Write 4 bytes buf[0] = 0x41 # 'A' buf[1] = 0x42 # 'B' buf[2] = 0x43 # 'C' buf[3] = 0x44 # 'D' - # 通过 CUInt32T* 读取(应该读到 0x44434241 on little-endian) + # Read via CUInt32T* (0x44434241 on little-endian) p32: uint32* = (uint32*)(t.CPtr(uint64(buf))) val: uint32 = p32[0] @@ -140,14 +132,14 @@ def test_pointer_offset(): testcheck.fail("byte offset vs element offset") -# --- Test 6: 结构体指针访问 --- +# --- Test 6: struct pointer access --- class TestStruct(): a: int b: int c: uint64 def test_struct_pointer(): - """测试结构体指针的成员访问""" + """Access struct members through a pointer.""" s: TestStruct s.a = 10 s.b = 20 @@ -158,23 +150,23 @@ def test_struct_pointer(): testcheck.check(p.a == 10 and p.b == 20 and p.c == 0x123456789ABCDEF0, "struct pointer access", "struct pointer access mismatch") -# --- Test 7: memcpy/memset 通过指针 --- +# --- Test 7: memcpy/memset through pointers --- def test_memcpy_pointers(): - """测试 memcpy 在指针之间的数据复制""" + """Copy data between pointers with memcpy.""" src_buf: uint32* = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04) dst_buf: uint32* = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04) if not src_buf or not dst_buf: testcheck.fail("memcpy: VirtualAlloc returned NULL") return - # 初始化 src + # Initialize src for i in range(8): src_buf[i] = uint32(i + 1000) - # 复制 + # Copy string.memcpy(t.CPtr(uint64(dst_buf)), t.CPtr(uint64(src_buf)), 32) - # 验证 + # Verify ok: int = 1 for i in range(8): if dst_buf[i] != uint32(i + 1000): @@ -183,13 +175,13 @@ def test_memcpy_pointers(): testcheck.check(ok, "memcpy between pointers", "memcpy between pointers failed") -# --- Test 8: 指针作为函数参数 --- +# --- Test 8: pointer as function parameter --- def fill_array(arr: uint32*, count: int, val: uint32): for i in range(count): arr[i] = val def test_pointer_param(): - """测试指针作为函数参数传递""" + """Pass a pointer as a function parameter.""" buf: uint32* = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04) if not buf: testcheck.fail("pointer param: VirtualAlloc returned NULL") @@ -225,7 +217,7 @@ def main() -> int | t.CExport: testcheck.begin("PointerTest: 指针操作基准测试") - # Test 1: global 声明 + # Test 1: global declaration testcheck.section("Test 1: global declaration") global _g_val _g_val = 0 diff --git a/ProbeGen/App/main.vp b/ProbeGen/App/main.vp index a153ec4..0d74021 100644 --- a/ProbeGen/App/main.vp +++ b/ProbeGen/App/main.vp @@ -1,109 +1,43 @@ -# ============================================================ -# main.vp — ProbeGen:代际不稳定性最小探针(勿当普通功能测试改动) -# -# 背景:同一份源码在 TPC→TPV1→TPV2→TPV3 逐代自举出的编译器二进制下 -# 产出的 IR 不一致,部分甚至非法。本工程把已定位的 5+1 个"代际 -# 不稳定构造"各用一段最小代码覆盖,用两代编译器各编一次,即可在 -# 同一份产物里一次性暴露全部差异点,并作为后续修复的回归用例。 -# -# 运行(两条命令,各用独立 build_dir,互不覆盖): -# 第 1 代(TPC 产出): -# TransPyV\output\TransPyV.exe --project Test\ProbeGen\project.vpj --clean --run --build-dir Test\ProbeGen\.tpv_build_g1 -# 第 2 代(TPV1 产出): -# TransPyV\.tpv_build\output\TransPyV.exe --project Test\ProbeGen\project.vpj --clean --run --build-dir Test\ProbeGen\.tpv_build_g2 -# --build-dir 依据:TransPyV\App\main.vp:163 注册该参数,:299-304 在 -# resolve_paths 之前覆盖 Config.BuildDir(相对路径基于工程目录解析, -# 注释见 main.vp:300-301);产物 = \temp + \output -# (TransPyV\App\lib\Projectrans\Config.vp:432-443)。 -# 注意 TPC 的 Projectrans.py 没有 --build-dir,只有 -# --project/--src/--temp/--output(TransPyC\lib\Projectrans\Config.py:139-146); -# 本探针由 Viper 编译器 TransPyV.exe 驱动,故 --build-dir 可用。 -# -# 判定:两棵树 -# Test\ProbeGen\.tpv_build_g1\temp\\.{stub,text}.ll -# Test\ProbeGen\.tpv_build_g2\temp\<同上> -# 探针自身模块文件名两侧相同(module_name = 源码 SHA1,与编译器代际无关), -# 可逐 P 点直接 diff;includes 模块若被译为本地产物亦同名可比对。 -# -# ⚠ [P6] 在第二代及以后会直接把编译打断(App\lib\core\Gen\AssignGenMixin.vp:2213 -# "SyntaxError: subscript ptr is None")。若要单独拿到 P1..P5 的第二代 IR, -# 需临时注释掉 [P6] 段;P6 自身的证据就是那条报错。 -# ============================================================ +# ProbeGen: minimal probe for cross-generation IR instability. Do not treat as a normal feature test. + +# Translate the same source with two compiler generations, then diff the emitted IR per module +# (module file name = source SHA1, so both sides are comparable). + +# Gen 1: TransPyV\output\TransPyV.exe --project Test\ProbeGen\project.vpj --clean --run --build-dir Test\ProbeGen\.tpv_build_g1 +# Gen 2: TransPyV\.tpv_build\output\TransPyV.exe --project Test\ProbeGen\project.vpj --clean --run --build-dir Test\ProbeGen\.tpv_build_g2 + +# WARNING [P6] breaks compilation from generation 2 onward; comment out [P6] to get Gen-2 IR for P1..P5. import t from stdint import * import w32.win32console as w32console -# ============================================================ -# [P1] 嵌套联合形参 -# VOIDPTR 本身是 typedef 联合 t.CPtr(includes/stdint.vp:40), -# 再与 t.CPtr 联合 ⇒ 一侧 i8**、另一侧 i8*。 -# 先例(同形):includes/w32/win32sync.vp:65 -# extern def InitOnceExecuteOnce(InitOnce: INIT_ONCE | t.CPtr, InitFn: VOIDPTR, -# Parameter: VOIDPTR, Context: VOIDPTR | t.CPtr) -> BOOL -# VOIDPTR 引入方式先例:includes/w32/win32sync.vp:2(from stdint import *) -# extern def 写法先例(语言推荐写法):wiki/08-c-operations.md:238-249 -# 只声明不调用:extern 声明未调用不产生链接引用,不影响链接 -# 先例:Test/Extern2Test/App/main.vp:18-35(三个仅声明不调用的外部声明) -# ============================================================ +# [P1] Nested union parameter: VOIDPTR (typedef of t.CPtr) unioned with t.CPtr gives i8** on one side, i8* on the other. +# Declared but never called, so no link reference is produced. extern def ProbeNestedUnion(Context: VOIDPTR*) -> BOOL -# ============================================================ -# [P2] 结构体按值形参 -# 形参是既有 Win32 结构体 COORD(includes/w32/win32console.vp:35-37,X/Y: SHORT), -# 不带 | t.CPtr ⇒ 一侧按值 %COORD、另一侧 %COORD*。 -# 先例(同形):includes/w32/win32console.vp:86 -# extern def SetConsoleScreenBufferSize(hConsoleOutput: HANDLE, dwSize: COORD) -> BOOL -# 限定名类类型标注先例:TransPyV/App/main.vp:142(argparse.ArgumentParser) -# Test/ArgparseTest/App/main.vp:12(memhub.MemBuddy) -# 模块别名导入先例:TransPyV/App/main.vp:20(import w32.win32console as w32cmd) -# ============================================================ +# [P2] Struct by-value parameter: COORD without | t.CPtr gives %COORD on one side, %COORD* on the other. extern def ProbeCoordByVal(dwSize: w32console.COORD) -> BOOL -# ============================================================ -# [P5] 局部 t.CUInt8T = 1 的字面量"蓄池": -# 把局部值写进全局,避免整段被当成死代码/被窥孔吞掉。 -# 全局小整型先例:ViperApps/ViperOS/VKernel/Kernel/services/desktop.vp:62 -# (_cursor_buttons: uint8 = 0) -# ============================================================ +# [P5] Sink for the local uint8 = 1 literal: store it into a global so the code is not dead-code eliminated. U8Sink: uint8 = 0 -# ============================================================ -# [P3] CChar → int 提升:参数 t.CChar、返回 int,直接 return -# 一侧应生成 zext i8 %s to i32,另一侧若退化成 ret i8 即丢提升(缺陷)。 -# 先例(同形):includes/builtins.vp:12-13 -# def ord(s: t.CChar) -> int: -# return s -# ============================================================ +# [P3] char -> int promotion: param char, int return. One side must emit zext i8 to i32, not ret i8. def ProbeOrd(s: char) -> int: return s -# ============================================================ -# [P4] double 比较:参数/返回 double,含 if a < b -# 一侧 fcmp olt double,另一侧若成 icmp slt double(非法)即缺陷。 -# 先例(同形):includes/builtins.vp:18-21 -# def min(a: double, b: double) -> double: -# if a < b: -# return a -# return b -# ============================================================ +# [P4] double comparison: params/return double. One side must emit fcmp olt double, not icmp slt double. def ProbeMin(a: double, b: double) -> double: if a < b: return a return b -# ============================================================ -# [P5] 局部 t.CUInt8T = 1 字面量赋值(字面量定型:一侧 store i8 1, i8*; -# 另一侧 store i32 1, i8*(非法)或 trunc + store) -# 局部声明先例:includes/atom.vp:13(result: t.CUInt8T = 1) -# 局部值落全局(global 声明 + 赋值)先例: -# Test/ArgparseTest/App/main.vp:17(global _mbuddy)→ :26(_mbuddy = ...) -# ============================================================ +# [P5] Local uint8 = 1 assignment: literal typing must emit store i8 1, not store i32 1 or trunc+store. def ProbeU8Literal() -> uint8: global U8Sink result: uint8 = 1 @@ -111,22 +45,8 @@ def ProbeU8Literal() -> uint8: return result -# ============================================================ -# [P6] 类字段联合 + 下标写 -# 字段为 t.CChar | t.CPtr 联合,必须先判空再按下标写; -# 第二/三代在 App\lib\core\Gen\AssignGenMixin.vp:2213 抛 -# "SyntaxError: subscript ptr is None"。 -# 先例(同形):includes/viperio.vp:5-20 -# class Buf: -# data: t.CChar | t.CPtr -# def clear(self): -# if self.data != None and self.capacity > 0: -# self.data[0] = 0 -# 联合类型字段/变量初始化 None 先例:Test/SimdTest/App/main.vp:13 -# (arena: t.CUInt8T | t.CPtr = None) -# 无参构造 __init__(self) 先例:TransPyV/App/lib/core/Gen/Translator.vp:75/252-255 -# (class Translator: def __init__(self): ...;实例化 TransPyV/App/main.vp:471) -# ============================================================ +# [P6] Class field union + subscript write: field is char | t.CPtr, must null-check before indexed write. +# Generations 2+ fail here with "SyntaxError: subscript ptr is None". class Box: p: char* @@ -139,16 +59,8 @@ class Box: pass -# ============================================================ -# 入口:main 保持最小(引用到上面各构造,保证它们真的被翻译;返回 0) -# @t.CExport + main() -> int 先例:ViperApps/ViperTemplateProject/App/main.vp:7-8 -# ViperApps/ViperCPW/App/main.vp:181-184 -# 字符字面量先例:Test/CharTest/App/main.vp:24(lit: char = 'Z') -# 类实例化先例:Test/StructTest/App/main.vp:21(p: Point = Point()) -# double 字面量先例:Test/G7/App/main.vp:39(node.FloatVal = 3.14) -# P1/P2 是 extern 声明,不调用(调用会产生未解析符号,见各自注释); -# 其差异体现在本模块的 declare 上。 -# ============================================================ +# Entry: keep main minimal, referencing each construct above so it is really translated; return 0. +# P1/P2 are extern declarations and are not called, so their difference shows in this module's declares. @t.CExport def main() -> int: Ch: char = 'A' diff --git a/PtrOpProbe/App/main.vp b/PtrOpProbe/App/main.vp index 4237e4c..2ca5896 100644 --- a/PtrOpProbe/App/main.vp +++ b/PtrOpProbe/App/main.vp @@ -4,15 +4,8 @@ import stdio import stdlib -# ============================================================ -# 指针操作符全形态自检(TPC 侧) -# -# 解析实况(vast_c.c ParseSimpleStmt → ParseExprList + SetStoreContext): -# `*p` 由 ParseFactor 产出 UnaryOp(op=Deref),SetStoreContext **不改 UnaryOp** -# ⇒ `*p = v` 的赋值目标就是 UnaryOp(Deref)(ctx 仍是 Load),与读侧同形。 -# 若编译器目标分派没有 UnaryOp 分支,整条语句会被静默丢弃(不落盘、不报错), -# 本程序即用于钉死这一点:每个形态都必须真的写进内存。 -# ============================================================ +# ===== Pointer operator full-form self-check (TPC side) ===== +# `*p = v` targets UnaryOp(Deref); without a dispatch branch it is silently dropped. def MakePair() -> tuple[int, int]: return 1, 2 @@ -25,13 +18,13 @@ def main() -> int: stdio.printf("FAIL: malloc\n") return 9 - # 形态 A:*p = v + # Form A: *p = v *buf = 7 if buf[0] != 7: stdio.printf("FAIL A *p = v : buf[0]=%llu(期望 7)\n", buf[0]) fails += 1 - # 形态 B:*p = *q + # Form B: *p = *q q: uint64* = buf + 1 *q = 99 *buf = *q @@ -39,7 +32,7 @@ def main() -> int: stdio.printf("FAIL B *p = *q : buf[0]=%llu(期望 99)\n", buf[0]) fails += 1 - # 形态 C:&x 取址,*px = v + # Form C: &x address-of, *px = v x: uint64 = 0 y: uint64 = 5 px: uint64* = &x @@ -48,25 +41,25 @@ def main() -> int: stdio.printf("FAIL C *px = v : x=%llu(期望 11)\n", x) fails += 1 - # 形态 D:*&x = *&y + # Form D: *&x = *&y *&x = *&y if x != 5: stdio.printf("FAIL D *&x = *&y : x=%llu(期望 5)\n", x) fails += 1 - # 形态 E(对照):下标写 p[i] = v + # Form E (control): subscript write p[i] = v buf[0] = 123 if buf[0] != 123: stdio.printf("FAIL E p[0] = v : buf[0]=%llu(期望 123)\n", buf[0]) fails += 1 - # 形态 F:AugAssign 目标 *p += v + # Form F: AugAssign target *p += v *buf += 5 if buf[0] != 128: stdio.printf("FAIL F *p += v : buf[0]=%llu(期望 128)\n", buf[0]) fails += 1 - # 形态 G1(对照):Tuple 目标 a, b = f() + # Form G1 (control): tuple target a, b = f() a: int = 0 b: int = 0 a, b = MakePair() @@ -74,7 +67,7 @@ def main() -> int: stdio.printf("FAIL G1 a, b = f() : a=%d b=%d(期望 1/2)\n", a, b) fails += 1 - # 形态 G2:List 目标 [c, d] = f() + # Form G2: list target [c, d] = f() cc: int = 0 dd: int = 0 [cc, dd] = MakePair() @@ -82,18 +75,14 @@ def main() -> int: stdio.printf("FAIL G2 [c, d] = f() : c=%d d=%d(期望 1/2)\n", cc, dd) fails += 1 - # 形态 H:值位置的 *p(调用实参 f(*p))——Starred(Load) + # Form H: *p in value position (call arg f(*p)) -- Starred(Load) got: int = stdio.printf("INFO H f(*p) : %llu(期望 128)\n", *buf) if got < 0: stdio.printf("FAIL H f(*p) : printf 返回 %d\n", got) fails += 1 - # 形态 I:memhub 实际用的「两步式读块头」(关键回归点) - # hd1 = *((uint64*)(blk)) —— 直接读 - # hd2 = uint64(t.CPtr(*((uint64*)(blk)))) —— 两步式;注意 `*((...))` 位于 - # t.CPtr( ) 的**实参位置** ⇒ 解析为 Starred(Load),旧 TPC 在这一形态落到 - # 末尾兜底 `return i32 0` ⇒ t.CPtr(0)=NULL ⇒ hd2==0(内存里明明是 0x1234) - # 这正是 OOM 报告里 `hdr=0x9 / hdr2=0x0` 的成因。 + # Form I: the two-step block-header read memhub uses (key regression point). + # `*((...))` inside t.CPtr() args parses as Starred(Load); old TPC returned 0. w: uint64 = 0 pw: uint64* = &w *pw = 0x1234 diff --git a/RawArrayTest/App/main.vp b/RawArrayTest/App/main.vp index 350b411..e627838 100644 --- a/RawArrayTest/App/main.vp +++ b/RawArrayTest/App/main.vp @@ -3,26 +3,26 @@ from stdint import * import stdio -# 模块级全局定长数组(rawarray 复刻 t.CArray) +# Module-level global fixed-size array (rawarray mirrors t.CArray) g_arr: rawarray[int, 4] = [10, 20, 30, 40] -# struct 内嵌定长数组字段 +# Struct with embedded fixed-size array fields class Ctx: state: rawarray[uint32, 5] buf: rawarray[uint8, 64] def main() -> int | t.CExport: - # 1) 全局数组读取 + # 1) Read global array stdio.printf("1 g_arr[0]=%d g_arr[3]=%d (expect 10 40)\n", g_arr[0], g_arr[3]) - # 2) 局部定长数组(写 + 读) + # 2) Local fixed-size array (write + read) loc: rawarray[uint32, 3] = [0, 0, 0] loc[1] = 7 stdio.printf("2 loc[1]=%d (expect 7)\n", loc[1]) - # 3) struct 内嵌数组字段 + # 3) Struct embedded array fields ctx: Ctx ctx.state[0] = 100 ctx.state[4] = 400 @@ -30,7 +30,7 @@ def main() -> int | t.CExport: stdio.printf("3 ctx.state[0]=%d ctx.state[4]=%d ctx.buf[0]=%d (expect 100 400 65)\n", ctx.state[0], ctx.state[4], int(ctx.buf[0])) - # 4) 参数数组衰减(CArray 形参 → 元素指针)+ sizeof + # 4) Parameter array decay (CArray param to element pointer) + sizeof total: int = sum_arr(loc, 3) stdio.printf("4 sum=%d (expect 7)\n", total) diff --git a/ShortCircuitTest/App/main.vp b/ShortCircuitTest/App/main.vp index 925866b..55a36d0 100644 --- a/ShortCircuitTest/App/main.vp +++ b/ShortCircuitTest/App/main.vp @@ -8,13 +8,13 @@ import string import testcheck -# 副作用函数:将 buf[0] 置为 1,返回 True +# side-effect helper: set buf[0] = 1 and return True def bump_true(buf: bytes) -> bool: buf[0] = 1 return True -# 副作用函数:将 buf[0] 置为 1,返回 False +# side-effect helper: set buf[0] = 1 and return False def bump_false(buf: bytes) -> bool: buf[0] = 1 return False @@ -28,31 +28,31 @@ def main() -> CInt | CExport: buf: bytes = stdlib.malloc(1) - # === Test 1: False and bump_true() - bump 不应被调用 === + # === Test 1: False and bump_true() - bump must not be called === testcheck.section("Test 1: False and bump_true()") buf[0] = 0 r1: bool = False and bump_true(buf) testcheck.check(buf[0] == 0, "and short-circuit OK (bump not called)", "and short-circuit FAILED (bump called)") - # === Test 2: True or bump_true() - bump 不应被调用 === + # === Test 2: True or bump_true() - bump must not be called === testcheck.section("Test 2: True or bump_true()") buf[0] = 0 r2: bool = True or bump_true(buf) testcheck.check(buf[0] == 0, "or short-circuit OK (bump not called)", "or short-circuit FAILED (bump called)") - # === Test 3: True and bump_true() - bump 应被调用 === + # === Test 3: True and bump_true() - bump must be called === testcheck.section("Test 3: True and bump_true()") buf[0] = 0 r3: bool = True and bump_true(buf) testcheck.check(buf[0] == 1, "and eval OK (bump called)", "and eval FAILED (bump not called)") - # === Test 4: False or bump_true() - bump 应被调用 === + # === Test 4: False or bump_true() - bump must be called === testcheck.section("Test 4: False or bump_true()") buf[0] = 0 r4: bool = False or bump_true(buf) testcheck.check(buf[0] == 1, "or eval OK (bump called)", "or eval FAILED (bump not called)") - # === Test 5: if 语句中的短路 === + # === Test 5: short-circuit in if statement === testcheck.section("Test 5: if 语句中的短路") buf[0] = 0 if False and bump_true(buf): @@ -66,7 +66,7 @@ def main() -> CInt | CExport: testcheck.check(False, "should enter if", "if True or else") testcheck.check(buf[0] == 0, "if or short-circuit OK", "if or short-circuit FAILED") - # === Test 6: 嵌套短路 === + # === Test 6: nested short-circuit === testcheck.section("Test 6: 嵌套短路") buf[0] = 0 r6: bool = False and (True or bump_true(buf)) @@ -76,7 +76,7 @@ def main() -> CInt | CExport: r7: bool = True or (False and bump_true(buf)) testcheck.check(buf[0] == 0, "nested or short-circuit OK", "nested or short-circuit FAILED") - # === Test 7: not 与短路 === + # === Test 7: not with short-circuit === testcheck.section("Test 7: not 与短路") buf[0] = 0 r8: bool = not False and bump_true(buf) @@ -86,19 +86,19 @@ def main() -> CInt | CExport: r9: bool = not True or bump_true(buf) testcheck.check(buf[0] == 1, "not or eval OK (bump called)", "not or eval FAILED (bump not called)") - # === Test 8: and 链中第一个为 False,后续不评估 === + # === Test 8: and chain, first False stops later evaluation === testcheck.section("Test 8: and 链短路") buf[0] = 0 r10: bool = False and bump_true(buf) and bump_true(buf) testcheck.check(buf[0] == 0, "and chain short-circuit OK", "and chain short-circuit FAILED") - # === Test 9: or 链中第一个为 True,后续不评估 === + # === Test 9: or chain, first True stops later evaluation === testcheck.section("Test 9: or 链短路") buf[0] = 0 r11: bool = True or bump_true(buf) or bump_true(buf) testcheck.check(buf[0] == 0, "or chain short-circuit OK", "or chain short-circuit FAILED") - # === Test 10: and 返回值正确性 === + # === Test 10: and return value correctness === testcheck.section("Test 10: and 返回值正确性") buf[0] = 0 r12: bool = True and bump_true(buf) @@ -108,7 +108,7 @@ def main() -> CInt | CExport: r13: bool = True and bump_false(buf) testcheck.check(not r13, "and return False OK", "and return False FAILED") - # === Test 11: or 返回值正确性 === + # === Test 11: or return value correctness === testcheck.section("Test 11: or 返回值正确性") buf[0] = 0 r14: bool = False or bump_true(buf) diff --git a/SimdTest/App/main.vp b/SimdTest/App/main.vp index 605b97f..f22ea14 100644 --- a/SimdTest/App/main.vp +++ b/SimdTest/App/main.vp @@ -9,19 +9,17 @@ import memhub import testcheck -# 全局内存池 +# Global memory pool arena: uint8* = None pool: memhub.MemPool* = None -# 外部函数: clock() 用于性能计时 +# External function: clock() for performance timing def clock() -> t.CLong | t.CExtern: pass define CLOCK_PER_SEC = 1000 -# ============================================================ -# 1. AVX2 double4 正确性测试 -# ============================================================ +# 1. AVX2 double4 correctness tests def test_avx2_add_sub_mul_div(): testcheck.section("AVX2 add/sub/mul/div 4d") @@ -220,9 +218,7 @@ def test_avx2_fma(): out.delete() -# ============================================================ -# 2. 批量数组运算正确性测试 -# ============================================================ +# 2. Batch array operation correctness tests def test_batch_array_ops(): testcheck.section("Batch array operations") @@ -285,9 +281,7 @@ def test_batch_array_ops(): out1.delete() -# ============================================================ -# 3. LLVMIR 精确标量运算测试 -# ============================================================ +# 3. LLVMIR precise scalar operation tests def test_llvmir_scalar(): testcheck.section("LLVMIR precise scalar ops") @@ -357,9 +351,7 @@ def test_llvmir_scalar(): testcheck.check(r == double(1024.0), "pow(2,10)==1024", "pow(2,10)==1024") -# ============================================================ -# 4. 性能基准测试: SIMD vs 标量 -# ============================================================ +# 4. Benchmark: SIMD vs scalar define N_ELEM = 40000 define N_ITER = 50000 @@ -451,7 +443,7 @@ def benchmark_simd_vs_scalar(): else: printf(" speedup=N/A\n") - # 验证结果正确性 + # Verify result correctness testcheck.check(out.data[0] > double(0.0), "bench result[0] valid", "bench result[0] valid") a.delete() diff --git a/SlotsBugTest/App/main.vp b/SlotsBugTest/App/main.vp index 17a83de..1ee48ed 100644 --- a/SlotsBugTest/App/main.vp +++ b/SlotsBugTest/App/main.vp @@ -3,9 +3,9 @@ import ast # ============================================================ -# 回归测试:__slots__ + ast.AST 字段类型 -# 验证 TPC 修复:无法识别的类型注解应报错终止,而非 VoidType alloca 崩溃 -# 对照:使用 ast.expr(无效)会报错;使用 ast.AST(有效)应编译成功 +# Regression test: __slots__ with ast.AST field types. +# An unrecognized type annotation must error out instead of crashing in +# VoidType alloca; ast.expr (invalid) errors, ast.AST (valid) compiles. # ============================================================ class Result: __slots__ = ('elem_type_node', 'count_node', 'is_pointer') diff --git a/SprintfTest/App/main.vp b/SprintfTest/App/main.vp index 3358236..910ae42 100644 --- a/SprintfTest/App/main.vp +++ b/SprintfTest/App/main.vp @@ -7,16 +7,13 @@ import viperlib import string -# ============================================================ -# SprintfTest - viperlib.snprintf %a/%A 运行时验证 -# 预期输出对照 glibc printf("%a", ...) 行为 -# ============================================================ +# SprintfTest: runtime verification of viperlib.snprintf %a/%A against glibc printf @t.CExport def main() -> int: testcheck.begin("SprintfTest: %a/%A runtime verification") buf: bytes = stdlib.malloc(256) - # ---------- 默认精度(核心正确性) ---------- + # ---------- default precision (core correctness) ---------- testcheck.section("default precision") v1: double = 1.0 @@ -54,25 +51,25 @@ def main() -> int: testcheck.info(buf) testcheck.check(string.strcmp(buf, "-0x1p+0") == 0, "%a -1.0 -> -0x1p+0", "FAIL -1.0") - # ---------- 大写 %A ---------- + # ---------- uppercase %A ---------- testcheck.section("uppercase %A") viperlib.snprintf(buf, 64, "%A", v_pi) testcheck.info(buf) testcheck.check(string.strcmp(buf, "0X1.91EB851EB851FP+1") == 0, "%A 3.14 -> 0X1...P+1", "FAIL %A") - # ---------- # flag 强制小数点 ---------- + # ---------- # flag forces radix point ---------- testcheck.section("# flag") viperlib.snprintf(buf, 64, "%#a", v1) testcheck.info(buf) testcheck.check(string.strcmp(buf, "0x1.p+0") == 0, "%#a 1.0 -> 0x1.p+0", "FAIL %#a") - # ---------- 显式精度 13(不裁剪) ---------- + # ---------- explicit precision 13 (no trimming) ---------- testcheck.section("precision 13") viperlib.snprintf(buf, 64, "%.13a", v1) testcheck.info(buf) testcheck.check(string.strcmp(buf, "0x1.0000000000000p+0") == 0, "%.13a 1.0 -> 0x1.0000000000000p+0", "FAIL %.13a") - # ---------- 宽度/对齐 ---------- + # ---------- width/alignment ---------- testcheck.section("width/align") viperlib.snprintf(buf, 64, "%10a", v1) testcheck.info(buf) @@ -91,7 +88,7 @@ def main() -> int: # ---------- inf / nan ---------- testcheck.section("inf/nan") - # 构造 +inf: bit pattern 0x7FF0000000000000 + # Build +inf from bit pattern 0x7FF0000000000000 inf_bits: uint64 = 0x7FF0000000000000 inf_val: double = 0.0 *(&inf_val) = *(&inf_bits) @@ -99,7 +96,7 @@ def main() -> int: testcheck.info(buf) testcheck.check(string.strcmp(buf, "inf") == 0, "%a +inf -> inf", "FAIL +inf") - # 构造 -inf: bit pattern 0xFFF0000000000000 + # Build -inf from bit pattern 0xFFF0000000000000 ninf_bits: uint64 = 0xFFF0000000000000 ninf_val: double = 0.0 *(&ninf_val) = *(&ninf_bits) @@ -107,7 +104,7 @@ def main() -> int: testcheck.info(buf) testcheck.check(string.strcmp(buf, "-inf") == 0, "%a -inf -> -inf", "FAIL -inf") - # 构造 nan: bit pattern 0x7FF8000000000000 + # Build nan from bit pattern 0x7FF8000000000000 nan_bits: uint64 = 0x7FF8000000000000 nan_val: double = 0.0 *(&nan_val) = *(&nan_bits) @@ -115,34 +112,31 @@ def main() -> int: testcheck.info(buf) testcheck.check(string.strcmp(buf, "nan") == 0, "%a nan -> nan", "FAIL nan") - # 大写 INF/NAN + # Uppercase INF/NAN viperlib.snprintf(buf, 64, "%A", inf_val) testcheck.info(buf) testcheck.check(string.strcmp(buf, "INF") == 0, "%A +inf -> INF", "FAIL INF") - # ============================================================ - # viperlib %g/%f/%e 浮点格式化诊断(定位 SimdTest 浮点 CDefine 值错) - # 已知现象: %a 正确, %.17g 输出 3.1397985356295141 (应为 3.1415926535897931) - # 同一 va_list 连续读同一 double, %.17g 错而 %a 对 → 定位是算法还是传参/读取 - # ============================================================ + # viperlib %g/%f/%e diagnosis: %a is correct but %.17g prints a wrong value. + # Same double read twice from one va_list: %.17g wrong, %a right. testcheck.section("viperlib %g bug diagnosis") v_pi17: double = 3.1415926535897931 v_e17: double = 2.7182818284590455 - # T1: 同一参数 %.17g vs %a(复现;%a 对则说明值本身正确) + # T1: same arg via %.17g vs %a (repro; %a correct means value is fine) viperlib.snprintf(buf, 128, "T1 %.17g|%a", v_pi17, v_pi17) testcheck.info(buf) - # T2: 两个 %.17g 不同值 + # T2: two different doubles with %.17g viperlib.snprintf(buf, 128, "T2 %.17g|%.17g", v_pi17, v_e17) testcheck.info(buf) - # T3: CRT 对照 + # T3: CRT reference stdio.snprintf(buf, 128, "T3 %.17g|%a", v_pi17, v_pi17) testcheck.info(buf) - # T4: 不同精度 + # T4: different precisions viperlib.snprintf(buf, 128, "T4 %.17g|%.10g|%.6g|%g", v_pi17, v_pi17, v_pi17, v_pi17) testcheck.info(buf) @@ -150,38 +144,34 @@ def main() -> int: viperlib.snprintf(buf, 128, "T5 %.17f|%.17e", v_pi17, v_pi17) testcheck.info(buf) - # T6: 简单精确值(1.0/0.5 二进制精确, 若这些也错则算术层坏) + # T6: exact values (1.0/0.5); wrong here means arithmetic layer broken viperlib.snprintf(buf, 128, "T6 %.17g|%.17g|%.17g", 1.0, 0.5, 123.456) testcheck.info(buf) - # T7/T8: double 在变参不同位置(va_list 读取位置相关性) + # T7/T8: double at different vararg positions (va_list slot dependence) viperlib.snprintf(buf, 128, "T7 %d|%.17g|%d", 100, v_pi17, 200) testcheck.info(buf) viperlib.snprintf(buf, 128, "T8 %d|%d|%.17g", 100, 200, v_pi17) testcheck.info(buf) - # T9: 字面量直接传(非常量折叠则看传递路径) + # T9: literals passed directly (checks passing path) viperlib.snprintf(buf, 128, "T9 %.17g|%a", 3.1415926535897931, 3.1415926535897931) testcheck.info(buf) - # T10: 顺序反转, %a 在前 %.17g 在后 + # T10: reversed order, %a before %.17g viperlib.snprintf(buf, 128, "T10 %a|%.17g", v_pi17, v_pi17) testcheck.info(buf) - # ============================================================ - # 多整数变参复现(DefineTest test_define_string PAGE= 遗留 bug): - # viperlib.snprintf 3+ 个 int 变参时, 第 2 个 %d 读到垃圾 - # (va_arg 游标从寄存器区切到溢出区推进错误, 非本次 CIf 引入) - # 预期: R1-R3 目前 FAIL, 修复后应全部 PASS - # ============================================================ + # Multi-int varargs repro: with 3+ int args, viperlib.snprintf reads garbage + # at the 2nd %d (va_arg cursor advances wrong past the register area). testcheck.section("multi-int varargs repro") - # R1: 3 个常量 int(复现 DefineTest "MAX_SIZE=%d PAGE=%d MASK=0x%x" 模式) + # R1: 3 const ints (reproduces DefineTest MAX_SIZE/PAGE/MASK pattern) viperlib.snprintf(buf, 128, "R1 %d|%d|%d", 1024, 4096, 255) testcheck.info(buf) testcheck.check(string.strcmp(buf, "R1 1024|4096|255") == 0, "R1 3-const-int (1024|4096|255)", "R1 FAIL (第2变参被误读)") - # R2: 3 个运行时变量 int(排除常量折叠差异) + # R2: 3 runtime int vars (rules out constant folding) ia: int = 1024 ib: int = 4096 ic: int = 255 @@ -189,12 +179,12 @@ def main() -> int: testcheck.info(buf) testcheck.check(string.strcmp(buf, "R2 1024|4096|255") == 0, "R2 3-var-int (1024|4096|255)", "R2 FAIL (第2变参被误读)") - # R3: 4 个变参(游标推进进一步暴露) + # R3: 4 varargs (further exposes cursor advance) viperlib.snprintf(buf, 128, "R3 %d|%d|%d|%d", 1, 2, 3, 4) testcheck.info(buf) testcheck.check(string.strcmp(buf, "R3 1|2|3|4") == 0, "R3 4-int (1|2|3|4)", "R3 FAIL (变参游标推进错误)") - # R4: 第 2 个变参为 0(值 0 若被截断读也会暴露) + # R4: 2nd vararg is 0 (exposes truncated reads) viperlib.snprintf(buf, 128, "R4 %d|%d|%d", 100, 0, 200) testcheck.info(buf) testcheck.check(string.strcmp(buf, "R4 100|0|200") == 0, "R4 middle-zero (100|0|200)", "R4 FAIL (第2变参被误读)") diff --git a/StringIterTest/App/main.vp b/StringIterTest/App/main.vp index 25d65ce..a0a48f3 100644 --- a/StringIterTest/App/main.vp +++ b/StringIterTest/App/main.vp @@ -6,7 +6,7 @@ import testcheck import inline_test # ============================================================ -# Test 1: 字符串指针迭代 - 逐字符直到\0 +# Test 1: string pointer iteration, char by char until NUL # ============================================================ def test_string_ptr_iter(): testcheck.section("Test 1: string pointer iteration") @@ -19,7 +19,7 @@ def test_string_ptr_iter(): testcheck.check(count == 5, "ptr iter (count=5)", "ptr iter (count expect 5)") # ============================================================ -# Test 2: 字符串指针求和ASCII值 +# Test 2: sum ASCII values via string pointer # ============================================================ def test_string_ascii_sum(): testcheck.section("Test 2: string ASCII sum") @@ -33,7 +33,7 @@ def test_string_ascii_sum(): testcheck.check(total == 198, "ASCII sum (total=198)", "ASCII sum (total expect 198)") # ============================================================ -# Test 3: 手动strcpy - 指针复制 +# Test 3: manual strcpy via pointers # ============================================================ def test_manual_strcpy(): testcheck.section("Test 3: manual strcpy via pointers") @@ -49,7 +49,7 @@ def test_manual_strcpy(): testcheck.check(dst[0] == 84 and dst[1] == 101 and dst[2] == 115 and dst[3] == 116, "manual strcpy (T=84 e=101 s=115 t=116)", "manual strcpy (expect T=84 e=101 s=115 t=116)") # ============================================================ -# Test 4: 指针比较和偏移 +# Test 4: pointer comparison and offset # ============================================================ def test_ptr_offset_compare(): testcheck.section("Test 4: pointer offset and compare") @@ -65,7 +65,7 @@ def test_ptr_offset_compare(): testcheck.check(total == 100, "ptr offset (total=100)", "ptr offset (total expect 100)") # ============================================================ -# Test 5: 字符串长度手动计算 +# Test 5: manual string length # ============================================================ def test_manual_strlen(): testcheck.section("Test 5: manual strlen") @@ -78,7 +78,7 @@ def test_manual_strlen(): testcheck.check(length == 12, "manual strlen (len=12)", "manual strlen (len expect 12)") # ============================================================ -# Test 6: 指针反向遍历字符串 +# Test 6: reverse string via pointer # ============================================================ def test_reverse_string_ptr(): testcheck.section("Test 6: reverse string via pointer") @@ -102,7 +102,7 @@ def test_reverse_string_ptr(): testcheck.check(dst[0] == 100 and dst[1] == 99 and dst[2] == 98 and dst[3] == 97, "reverse string (d=100 c=99 b=98 a=97)", "reverse string (expect d=100 c=99 b=98 a=97)") # ============================================================ -# Test 7: 多级指针 - 指向指针的指针 +# Test 7: multi-level pointer (pointer to pointer) # ============================================================ def test_double_pointer(): testcheck.section("Test 7: double pointer") @@ -114,7 +114,7 @@ def test_double_pointer(): testcheck.check(val == 42, "double pointer (val=42)", "double pointer (val expect 42)") # ============================================================ -# Test 8: 指针算术 - 数组元素访问 +# Test 8: pointer arithmetic, array element access # ============================================================ def test_ptr_arithmetic(): testcheck.section("Test 8: pointer arithmetic") @@ -128,7 +128,7 @@ def test_ptr_arithmetic(): testcheck.check(val == 16, "ptr arithmetic (arr[3]=16)", "ptr arithmetic (arr[3] expect 16)") # ============================================================ -# Test 9: 字符串比较 - 逐字符指针 +# Test 9: manual string compare via char pointers # ============================================================ def test_manual_strcmp(): testcheck.section("Test 9: manual strcmp via pointers") @@ -148,7 +148,7 @@ def test_manual_strcmp(): testcheck.check(equal == 1, "manual strcmp (equal=1)", "manual strcmp (equal expect 1)") # ============================================================ -# Test 10: 结构体指针访问 +# Test 10: struct pointer access # ============================================================ class Vec2: x: int diff --git a/StringTest/App/main.vp b/StringTest/App/main.vp index f055a3f..131d2f3 100644 --- a/StringTest/App/main.vp +++ b/StringTest/App/main.vp @@ -28,7 +28,7 @@ def test_strcat(): stdio.printf("SKIP: VirtualAlloc returned NULL\n") return string.memset(buf, 0, 64) - # 手动拼接: 先拷贝 "Hello",再拷贝 " World" + # Manual concat: copy "Hello" then " World". hello: char* = "Hello" world: char* = " World" string.memcpy(buf, hello, 5) diff --git a/StructTest/App/main.vp b/StructTest/App/main.vp index 55a753f..712884b 100644 --- a/StructTest/App/main.vp +++ b/StructTest/App/main.vp @@ -3,7 +3,7 @@ import stdio import string import testcheck -# 定义结构体 +# Define structs class Point(): x: int y: int @@ -14,7 +14,7 @@ class Rect(): class Node(): value: int - next: t.CPtr # Node* 类型 + next: t.CPtr # Node* type def test_struct_basic(): testcheck.section("Test 1: struct basic") @@ -37,12 +37,12 @@ def test_struct_pointer(): p: Point = Point() p.x = 42 p.y = 84 - # 取结构体指针 + # Take a struct pointer pp: Point* = t.CPtr(uint64(p)) - # 通过指针修改 + # Modify through the pointer pp.x = 100 pp.y = 200 - # 检查原始结构体是否被修改 + # Check whether the original struct changed testcheck.check(p.x == 100 and p.y == 200, "struct pointer (x=100 y=200)", "struct pointer (x y expect 100 200)") def test_struct_param(): @@ -58,13 +58,13 @@ def point_sum(p: Point) -> int: def test_struct_array(): testcheck.section("Test 5: struct array") - # 分配结构体数组 + # Allocate a struct array buf: uint8* = w32.win32memory.VirtualAlloc(None, 256, 12288, 4) if uint64(buf) == 0: stdio.printf("SKIP: VirtualAlloc returned NULL\n") return string.memset(buf, 0, 256) - # 将缓冲区转为 Point 数组 + # Reinterpret the buffer as a Point array pts: Point* = (Point*)(buf) pts[0].x = 1 pts[0].y = 2 diff --git a/SuperTest/App/main.vp b/SuperTest/App/main.vp index 8c746e9..e4a57e2 100644 --- a/SuperTest/App/main.vp +++ b/SuperTest/App/main.vp @@ -4,20 +4,11 @@ from t import CPtr, CInt, CExport import testcheck -# ============================================================ -# super() 语义专项测试(由 TransPyV.exe 编译) -# -# 覆盖场景: -# 1. super().__init__(args) — 子类构造调父类构造(字段由父类设置) -# 2. super().method() 静态绑定父类实现(不触发子类 override / 虚分派) -# 3. super() 调未覆盖的父类方法(父类字段区前缀对齐,this 无需调整) -# 4. 三层继承链 super().__init__(Leaf → Mid → Grand 逐层传递, -# 每个中间类的 super() 沿各自 CurClassName 的 MRO 跳自身找父类) -# 5. super().method 沿 MRO 找实际定义类(Mid 未定义 Base → 找到 Grand.Base) -# ============================================================ +# ===== super() semantics test ===== +# Covers super().__init__ chaining, static method binding, MRO lookup, 3-level chains. -# ========== 单继承:super().__init__ + super().method ========== +# ========== Single inheritance: super().__init__ + super().method ========== @t.CVTable class Animal: @@ -38,21 +29,21 @@ class Dog(Animal): Breed: CInt def __init__(self, tag: CInt, breed: CInt): - super().__init__(tag) # 调 Animal.__init__ 设置 Tag + super().__init__(tag) # Call Animal.__init__ to set Tag self.Breed = breed def Speak(self) -> CInt: return 1 def ParentSpeak(self) -> CInt: - return super().Speak() # 静态绑定 Animal.Speak → 0(不走虚分派) + return super().Speak() # Statically bind Animal.Speak -> 0 (no virtual dispatch) def FullGreet(self) -> CInt: - # super() 调父类 Greet(Dog 未覆盖),再加自身字段 + # Call parent Greet (not overridden by Dog), then add own field return super().Greet() + self.Breed -# ========== 三层继承链:Grand → Mid → Leaf ========== +# ========== Three-level chain: Grand -> Mid -> Leaf ========== @t.CVTable class Grand: @@ -70,7 +61,7 @@ class Mid(Grand): M: CInt def __init__(self, v: CInt): - super().__init__(v + 1) # 调 Grand.__init__ + super().__init__(v + 1) # Call Grand.__init__ self.M = v def MidOnly(self) -> CInt: @@ -80,39 +71,39 @@ class Mid(Grand): @t.CVTable class Leaf(Mid): def __init__(self, v: CInt): - super().__init__(v + 2) # 调 Mid.__init__(Mid 内部再 super 到 Grand) + super().__init__(v + 2) # Call Mid.__init__ (which supers to Grand) def GetBase(self) -> CInt: - return super().Base() # Mid 未定义 Base → 沿 MRO 找 Grand.Base + return super().Base() # Mid has no Base -> find Grand.Base along MRO def CallMidOnly(self) -> CInt: - return super().MidOnly() # 调 Mid.MidOnly + return super().MidOnly() # Call Mid.MidOnly def main() -> CInt | CExport: testcheck.begin("SuperTest: super() 语义测试") - # --- 1. super().__init__ 设置父类字段 --- + # --- 1. super().__init__ sets parent fields --- d: Dog | CPtr = Dog(42, 7) testcheck.check(d.Tag == 42, "super().__init__ 设置父类字段 OK", "super().__init__ FAILED") testcheck.check(d.Breed == 7, "子类字段 OK", "子类字段 FAILED") - # --- 2. super().method 静态绑定(不虚分派到子类 override) --- + # --- 2. super().method static binding (no dispatch to child override) --- testcheck.check(d.ParentSpeak() == 0, "super().Speak() 静态绑定父类 OK", "super().Speak() FAILED") testcheck.check(d.Speak() == 1, "子类 Speak() override OK", "Speak() FAILED") - # --- 3. super() 调未覆盖的父类方法(42+1000+7 = 1049) --- + # --- 3. super() calls uncovered parent method (42+1000+7 = 1049) --- testcheck.check(d.FullGreet() == 1049, "super() 调未覆盖父类方法 OK", "FullGreet() FAILED") - # --- 4. 三层继承链 super().__init__(Leaf(10) → Mid(12) → Grand(13)) --- + # --- 4. three-level super().__init__ chain (Leaf(10) -> Mid(12) -> Grand(13)) --- lf: Leaf | CPtr = Leaf(10) testcheck.check(lf.G == 13, "三层 super().__init__ 链 G OK", "三层 G FAILED") testcheck.check(lf.M == 12, "中间类 M OK", "中间类 M FAILED") - # --- 5. super().method 沿 MRO 找实际定义类 --- + # --- 5. super().method finds the defining class along MRO --- testcheck.check(lf.GetBase() == 13, "super().Base() 沿 MRO OK", "GetBase() FAILED") testcheck.check(lf.CallMidOnly() == 12, "super().MidOnly() OK", "CallMidOnly() FAILED") diff --git a/SysLibTest/App/main.vp b/SysLibTest/App/main.vp index 6d712ff..004c5cd 100644 --- a/SysLibTest/App/main.vp +++ b/SysLibTest/App/main.vp @@ -14,7 +14,7 @@ import subprocess import syslibtest_impl -# MBuddy arena 大小:1MB +# MBuddy arena size: 1 MB. define ARENA_SIZE = 1048576 @@ -22,11 +22,11 @@ def main() -> CInt | CExport: w32.win32console.SetConsoleCP(65001) w32.win32console.SetConsoleOutputCP(65001) - # 初始化全局 MBuddy 内存分配器 + # Initialize the global MBuddy allocator. arena: bytes = stdlib.malloc(ARENA_SIZE) mbuddy_obj: memhub.MemBuddy* = memhub.MemBuddy(arena, ARENA_SIZE) - # 将 MBuddy 对象赋值给所有需要内存分配的模块 + # Assign the MBuddy object to every module that allocates. sys._mbuddy = mbuddy_obj os._mbuddy = mbuddy_obj os._win32._mbuddy = mbuddy_obj diff --git a/SysLibTest/App/os_backend.vp b/SysLibTest/App/os_backend.vp index 4271bb8..3549546 100644 --- a/SysLibTest/App/os_backend.vp +++ b/SysLibTest/App/os_backend.vp @@ -6,34 +6,33 @@ import os._posix # ============================================================================= -# Workaround: TransPyC 无法正确解析 os.xxx() 包级函数调用 -# (os.path.xxx() 子模块调用正常,但 os.xxx() 包级调用解析为本地模块) -# 此文件单独导入 os._win32 / os._posix 子模块,避免污染调用方的 os.rmdir() 等解析。 +# Workaround: TransPyC mis-resolves package-level os.xxx() calls as a local +# module. Import os._win32 / os._posix here so caller code stays intact. # ============================================================================= def os_exists(path: str) -> bool: - """检查文件/目录是否存在(跨平台)""" + """Return whether the file/dir exists.""" if platmacro.IS_WINDOWS: return os._win32.exists(path) return os._posix.exists(path) def os_remove(path: str) -> int: - """删除文件(跨平台)。成功返回 0,失败返回 -1。""" + """Remove a file. Returns 0 on success, -1 on failure.""" if platmacro.IS_WINDOWS: return os._win32.remove(path) return os._posix.remove(path) def os_isdir(path: str) -> bool: - """检查路径是否为目录(跨平台)""" + """Return whether the path is a directory.""" if platmacro.IS_WINDOWS: return os._win32.isdir(path) return os._posix.isdir(path) def os_getsize(path: str) -> int64: - """返回文件大小(字节,跨平台)。失败返回 -1。""" + """Return file size in bytes, or -1 on failure.""" if platmacro.IS_WINDOWS: return os._win32.getsize(path) return os._posix.getsize(path) diff --git a/SysLibTest/App/syslibtest_impl.vp b/SysLibTest/App/syslibtest_impl.vp index 232eaa6..a7c22a4 100644 --- a/SysLibTest/App/syslibtest_impl.vp +++ b/SysLibTest/App/syslibtest_impl.vp @@ -18,7 +18,7 @@ import w32.win32base import w32.win32process -# 测试用临时文件/目录名前缀 +# Temp file/dir name prefixes used by tests define TEST_DIR = "__sylibtest_dir__" define TEST_FILE = "__sylibtest_file.txt" define TEST_COPY = "__sylibtest_copy.txt" @@ -26,14 +26,11 @@ define TEST_TREE = "__sylibtest_tree__" define TEST_MOVE = "__sylibtest_moved.txt" -# ============================================================================= -# Workaround: TransPyC 无法正确解析 os.xxx() 包级函数调用 -# (os.path.xxx() 子模块调用正常,但 os.xxx() 包级调用解析为本地模块) -# 通过 os_backend 模块(单独导入 os._win32 / os._posix)绕过此问题 -# ============================================================================= +# ===== Workaround: TransPyC cannot resolve package-level os.xxx() calls ===== +# Use os_backend (imports os._win32 / os._posix) to bypass it. def _cleanup(): - """清理可能残留的测试文件/目录""" + """Remove leftover test files/dirs.""" if os_backend.os_exists(TEST_DIR): os.rmdir(TEST_DIR) if os_backend.os_exists(TEST_FILE): @@ -51,12 +48,10 @@ def run() -> CInt: testcheck.begin("SysLibTest: 系统兼容层库测试") - # 清理残留 + # Clean leftover _cleanup() - # ============================================================================= - # 全局 MBuddy 初始化验证(在 main 中已初始化) - # ============================================================================= + # ===== Global MBuddy init check (initialized in main) ===== testcheck.section("全局 MBuddy 初始化验证") testcheck.check(os._mbuddy != None, "os._mbuddy initialized OK", "os._mbuddy NOT initialized") @@ -64,13 +59,11 @@ def run() -> CInt: testcheck.check(shutil._mbuddy != None, "shutil._mbuddy initialized OK", "shutil._mbuddy NOT initialized") testcheck.check(subprocess._mbuddy != None, "subprocess._mbuddy initialized OK", "subprocess._mbuddy NOT initialized") - # 所有模块应共享同一个 MBuddy 对象 + # All modules must share the same MBuddy object testcheck.check(os._mbuddy == sys._mbuddy, "os==sys same MBuddy OK", "os!=sys different MBuddy") testcheck.check(shutil._mbuddy == os._mbuddy, "shutil==os same MBuddy OK", "shutil!=os different MBuddy") - # ============================================================================= - # MBuddy alloc/free/calloc/realloc(通过 os._mbuddy 测试) - # ============================================================================= + # ===== MBuddy alloc/free/calloc/realloc (via os._mbuddy) ===== testcheck.section("MBuddy alloc/free") p1: bytes = os._mbuddy.alloc(64) @@ -87,7 +80,7 @@ def run() -> CInt: os._mbuddy.free(p2) testcheck.ok("free OK") - # calloc 清零测试 + # calloc zeroing test testcheck.section("MBuddy calloc/realloc") cp: bytes = os._mbuddy.calloc(4, 16) @@ -104,7 +97,7 @@ def run() -> CInt: else: testcheck.fail("calloc FAILED") - # realloc 数据保留测试 + # realloc data preservation test rp: bytes = os._mbuddy.alloc(32) rp_c: CUInt8T | CPtr = CPtr(rp) for i in range(32): @@ -122,9 +115,7 @@ def run() -> CInt: else: testcheck.fail("realloc FAILED") - # ============================================================================= - # os.path 路径操作 - # ============================================================================= + # ===== os.path path operations ===== testcheck.section("os.path 路径操作") # sep @@ -151,9 +142,7 @@ def run() -> CInt: testcheck.check(os.path.isabs("/usr/local"), "isabs(/usr/local) OK", "isabs FAILED") testcheck.check(not os.path.isabs("relative/path"), "isabs(relative)=False OK", "isabs(relative) should be False") - # ============================================================================= - # os 文件/目录操作 - # ============================================================================= + # ===== os file/dir operations ===== testcheck.section("os 文件/目录操作") # getcwd @@ -181,12 +170,10 @@ def run() -> CInt: testcheck.check(os_backend.os_exists(TEST_TREE) and not os_backend.os_exists(TEST_DIR), "rename: swapped OK", "rename: swap FAILED") testcheck.check(os.rmdir(TEST_TREE) == 0, "rmdir renamed OK", "rmdir renamed FAILED") - # ============================================================================= - # shutil 高级文件操作 - # ============================================================================= + # ===== shutil high-level file operations ===== testcheck.section("shutil 高级文件操作") - # 创建测试文件 + # Create test file f: w32.fileio.File | CPtr = w32.fileio.File(TEST_FILE, w32.fileio.MODE.W) testcheck.check(not f.closed, "create test file OK", "create test file FAILED") f.write_str("hello shutil") @@ -197,7 +184,7 @@ def run() -> CInt: testcheck.check(shutil.copyfile(TEST_FILE, TEST_COPY) == 0, "copyfile OK", "copyfile FAILED") testcheck.check(os_backend.os_exists(TEST_COPY), "copyfile: dst exists OK", "copyfile: dst not exists") - # 验证拷贝内容一致(检查文件大小) + # Verify copied content matches (compare size) src_size: int64 = os_backend.os_getsize(TEST_FILE) dst_size: int64 = os_backend.os_getsize(TEST_COPY) viperlib.snprintf(buf, 512, "src_size=%lld dst_size=%lld", src_size, dst_size) @@ -209,12 +196,12 @@ def run() -> CInt: testcheck.check(os_backend.os_exists(TEST_MOVE), "move: dst exists OK", "move: dst not exists") os_backend.os_remove(TEST_MOVE) - # rmtree(递归删除目录树) + # rmtree (recursive tree delete) testcheck.check(os.mkdir(TEST_TREE) == 0, "mkdir tree OK", "mkdir tree FAILED") - # 在树中创建子目录 + # Create subdir inside the tree subdir: str = os.path.join(TEST_TREE, "sub") testcheck.check(os.mkdir(subdir) == 0, "mkdir subdir OK", "mkdir subdir FAILED") - # 在子目录中创建文件 + # Create a file inside the subdir subfile: str = os.path.join(subdir, "leaf.txt") sf: w32.fileio.File | CPtr = w32.fileio.File(subfile, w32.fileio.MODE.W) sf.write_str("leaf") @@ -225,15 +212,13 @@ def run() -> CInt: testcheck.check(shutil.rmtree(TEST_TREE) == 0, "rmtree OK", "rmtree FAILED") testcheck.check(not os_backend.os_exists(TEST_TREE), "rmtree: gone OK", "rmtree: still exists") - # 清理剩余文件 + # Clean remaining files if os_backend.os_exists(TEST_FILE): os_backend.os_remove(TEST_FILE) if os_backend.os_exists(TEST_COPY): os_backend.os_remove(TEST_COPY) - # ============================================================================= - # sys 系统信息 - # ============================================================================= + # ===== sys system info ===== testcheck.section("sys 系统信息") # platform @@ -262,12 +247,10 @@ def run() -> CInt: testcheck.check(argv0 != None, "argv(0) OK", "argv(0) FAILED") testcheck.info(argv0) - # 越界访问 + # Out-of-range access testcheck.check(sys.argv(9999) == None, "argv(out-of-range)=None OK", "argv(out-of-range) should be None") - # ============================================================================= - # subprocess 子进程 - # ============================================================================= + # ===== subprocess ===== testcheck.section("subprocess 子进程") # Windows: cmd /c echo hello @@ -279,7 +262,7 @@ def run() -> CInt: testcheck.check(result.returncode == 0, "returncode == 0 OK", "returncode != 0") if result.stdout != None: testcheck.info(result.stdout) - # 验证输出包含 "hello" + # Verify output contains "hello" testcheck.check(string.strstr(result.stdout, "hello") != None, "stdout contains 'hello' OK", "stdout missing 'hello'") else: @@ -287,9 +270,7 @@ def run() -> CInt: else: testcheck.fail("run returned None") - # ============================================================================= - # 清理 - # ============================================================================= + # ===== Cleanup ===== _cleanup() stdlib.free(buf) diff --git a/ThreadingTest/App/main.vp b/ThreadingTest/App/main.vp index d677b35..5c4801e 100644 --- a/ThreadingTest/App/main.vp +++ b/ThreadingTest/App/main.vp @@ -1,13 +1,5 @@ -# ThreadingTest - vthreading 专项测试 -# -# 覆盖范围: -# Thread : start/join/is_alive/get_exit_code/close、线程传参 -# Lock : 多线程持锁互斥自增共享计数器 -# Event : 线程等待事件被唤醒 -# Condition : 生产者/消费者模式 -# RWLock : 多读单写(SRWLock) -# local : TLS 线程局部存储 set/get 自校验 -# get_current_thread_id / sleep_ms +# ThreadingTest - vthreading coverage +# Thread/Lock/Event/Condition/RWLock/local/id/sleep_ms/args import t, c from stdint import * from w32.win32base import NULL, FALSE, TRUE @@ -16,16 +8,14 @@ import testcheck import vthreading -# ============================================================ -# 共享状态(模块级全局,跨线程读写) -# ============================================================ -_shared_count: int = 0 # Lock 并发测试共享计数器 -_evt_done: int = 0 # Event 测试完成标志 -_cond_ready: int = 0 # Condition 测试就绪标志 -_rw_value: int = 0 # RWLock 测试共享值 -_main_tid: uint32 = 0 # 主线程 ID +# ===== Shared state: module globals read/written across threads ===== +_shared_count: int = 0 # Lock test shared counter +_evt_done: int = 0 # Event test done flag +_cond_ready: int = 0 # Condition test ready flag +_rw_value: int = 0 # RWLock test shared value +_main_tid: uint32 = 0 # Main thread ID -# 并发规模常量 +# Concurrency scale constants THREAD_NUM: int = 4 LOCK_ITER: int = 1000 RW_ITER: int = 100 @@ -33,17 +23,15 @@ TLS_NUM: int = 4 SYS_ITER: int = 10 -# ============================================================ -# 线程回调(签名: def worker(arg: t.CPtr) -> t.CPtr) -# ============================================================ +# ===== Thread callbacks (signature: def worker(arg: t.CPtr) -> t.CPtr) ===== -# Thread 基础: 短暂睡眠后退出,保证 start 后 is_alive 观测窗口 +# Thread basic: brief sleep then exit, keeps an is_alive window after start def _basic_worker(arg: t.CPtr) -> t.CPtr: vthreading.sleep_ms(100) return NULL -# 传参: 通过 arg 指针自增 100 次(c.Deref/c.DerefAs 读写) +# Arg passing: increment through arg pointer 100 times (c.Deref/c.DerefAs) def _increment_worker(arg: t.CPtr) -> t.CPtr: ip: int* = (int*)(arg) i: int @@ -52,7 +40,7 @@ def _increment_worker(arg: t.CPtr) -> t.CPtr: return NULL -# Lock: 持锁自增全局计数器 +# Lock: increment a global counter while holding the lock def _lock_worker(arg: t.CPtr) -> t.CPtr: lk: vthreading.Lock* = (vthreading.Lock*)(arg) global _shared_count @@ -63,7 +51,7 @@ def _lock_worker(arg: t.CPtr) -> t.CPtr: return NULL -# Event: 等待事件被唤醒后置位完成标志 +# Event: wait to be woken, then set the done flag def _event_worker(arg: t.CPtr) -> t.CPtr: ev: vthreading.Event* = (vthreading.Event*)(arg) global _evt_done @@ -73,7 +61,7 @@ def _event_worker(arg: t.CPtr) -> t.CPtr: return NULL -# Condition 消费者: 循环等待 _cond_ready 就绪(限次防挂起) +# Condition consumer: wait for _cond_ready, bounded retries to avoid hanging def _cond_consumer(arg: t.CPtr) -> t.CPtr: cond: vthreading.Condition* = (vthreading.Condition*)(arg) global _cond_ready @@ -86,7 +74,7 @@ def _cond_consumer(arg: t.CPtr) -> t.CPtr: return NULL -# Condition 生产者: 延迟后置位 _cond_ready 并 notify +# Condition producer: delay, set _cond_ready, then notify def _cond_producer(arg: t.CPtr) -> t.CPtr: cond: vthreading.Condition* = (vthreading.Condition*)(arg) global _cond_ready @@ -98,7 +86,7 @@ def _cond_producer(arg: t.CPtr) -> t.CPtr: return NULL -# RWLock 读者: 持读锁反复读共享值 +# RWLock reader: read the shared value repeatedly under the read lock def _rw_reader(arg: t.CPtr) -> t.CPtr: rwl: vthreading.RWLock* = (vthreading.RWLock*)(arg) global _rw_value @@ -110,7 +98,7 @@ def _rw_reader(arg: t.CPtr) -> t.CPtr: return NULL -# RWLock 写者: 持写锁自增共享值 +# RWLock writer: increment the shared value under the write lock def _rw_writer(arg: t.CPtr) -> t.CPtr: rwl: vthreading.RWLock* = (vthreading.RWLock*)(arg) global _rw_value @@ -122,7 +110,7 @@ def _rw_writer(arg: t.CPtr) -> t.CPtr: return NULL -# TLS: 每线程 set/get 自校验(存入自身线程 ID 再读回比对) +# TLS: per-thread set/get self-check (store own thread ID, then read back) def _tls_worker(arg: t.CPtr) -> t.CPtr: tls: vthreading.local = vthreading.local() tls.set(t.CPtr(uint64(vthreading.get_current_thread_id()))) @@ -134,7 +122,7 @@ def _tls_worker(arg: t.CPtr) -> t.CPtr: return t.CPtr(uint64(ok)) -# 线程 ID 隔离: 工作线程 ID 必须与主线程不同 +# Thread ID isolation: worker ID must differ from the main thread ID def _tid_worker(arg: t.CPtr) -> t.CPtr: global _main_tid if vthreading.get_current_thread_id() == _main_tid: @@ -142,7 +130,7 @@ def _tid_worker(arg: t.CPtr) -> t.CPtr: return t.CPtr(uint64(1)) -# stdlib.system 多线程并发: 每线程循环调 C 运行时 system(),统计失败次数 +# stdlib.system concurrency: each thread calls C system(), count failures def _system_worker(arg: t.CPtr) -> t.CPtr: i: int fails: int = 0 @@ -153,9 +141,7 @@ def _system_worker(arg: t.CPtr) -> t.CPtr: return t.CPtr(uint64(fails)) -# ============================================================ -# main -# ============================================================ +# ===== main ===== def main() -> int | t.CExport: testcheck.begin("ThreadingTest: vthreading 专项测试") @@ -170,7 +156,7 @@ def main() -> int | t.CExport: testcheck.check(th1.get_exit_code() == 0, "退出码 == 0", "退出码 != 0") th1.close() - # ========== Thread: 通过 arg 传参 ========== + # ========== Thread: pass arg ========== testcheck.section("Thread: arg 传参") cnt: int = 0 th2: vthreading.Thread = vthreading.Thread(_increment_worker, &cnt) @@ -179,7 +165,7 @@ def main() -> int | t.CExport: th2.close() testcheck.check(cnt == 100, "worker 经 arg 自增 100 次", "cnt != 100") - # ========== Lock: 多线程互斥自增 ========== + # ========== Lock: mutex increment ========== testcheck.section("Lock: 多线程互斥自增") lock: vthreading.Lock = vthreading.Lock() t0: vthreading.Thread = vthreading.Thread(_lock_worker, t.CPtr(lock)) @@ -201,7 +187,7 @@ def main() -> int | t.CExport: testcheck.check(j0 != 0 and j1 != 0 and j2 != 0 and j3 != 0, "4 线程全部 join 成功", "有线程 join 超时") testcheck.check(_shared_count == THREAD_NUM * LOCK_ITER, "互斥自增计数正确", "计数丢失") - # ========== Event: 线程等待唤醒 ========== + # ========== Event: thread waits for wakeup ========== testcheck.section("Event: 线程等待唤醒") ev: vthreading.Event = vthreading.Event(FALSE, FALSE) th4: vthreading.Thread = vthreading.Thread(_event_worker, t.CPtr(ev)) @@ -215,7 +201,7 @@ def main() -> int | t.CExport: ev.close() testcheck.check(_evt_done == 1, "worker 收到事件并置位", "worker 未收到事件") - # ========== Condition: 生产者/消费者 ========== + # ========== Condition: producer/consumer ========== testcheck.section("Condition: 生产者/消费者") cond: vthreading.Condition = vthreading.Condition() tc: vthreading.Thread = vthreading.Thread(_cond_consumer, t.CPtr(cond)) @@ -229,7 +215,7 @@ def main() -> int | t.CExport: testcheck.check(_cond_ready == 1, "条件变量值已置位", "条件变量值未置位") cond.delete() - # ========== RWLock: 多读单写 ========== + # ========== RWLock: multi-reader single-writer ========== testcheck.section("RWLock: 多读单写") rwl: vthreading.RWLock = vthreading.RWLock() r1: vthreading.Thread = vthreading.Thread(_rw_reader, t.CPtr(rwl)) @@ -245,7 +231,7 @@ def main() -> int | t.CExport: w1.close() testcheck.check(_rw_value == RW_ITER, "写锁自增计数正确", "写锁计数丢失") - # ========== local: TLS 线程局部存储 ========== + # ========== local: TLS thread-local storage ========== testcheck.section("local: TLS 线程局部存储") i_t: int for i_t in range(TLS_NUM): @@ -255,7 +241,7 @@ def main() -> int | t.CExport: testcheck.check(th_t.get_exit_code() == 1, "TLS set/get 自校验通过", "TLS 自校验失败") th_t.close() - # ========== get_current_thread_id: 线程 ID 隔离 ========== + # ========== get_current_thread_id: thread ID isolation ========== testcheck.section("get_current_thread_id: 线程 ID 隔离") global _main_tid _main_tid = vthreading.get_current_thread_id() @@ -271,7 +257,7 @@ def main() -> int | t.CExport: vthreading.sleep_ms(20) testcheck.ok("sleep_ms(20) 正常返回") - # ========== stdlib.system 多线程并发 ========== + # ========== stdlib.system concurrency ========== testcheck.section("stdlib.system 多线程并发") s0: vthreading.Thread = vthreading.Thread(_system_worker, NULL) s1: vthreading.Thread = vthreading.Thread(_system_worker, NULL) diff --git a/TypeCastTest/App/main.vp b/TypeCastTest/App/main.vp index ba12b7e..6b6d5d6 100644 --- a/TypeCastTest/App/main.vp +++ b/TypeCastTest/App/main.vp @@ -6,65 +6,62 @@ import w32.win32console import w32.win32memory import testcheck -# ============================================================ -# TypeCastTest - 测试类型转换、zext/sext/trunc 行为、 -# 有符号/无符号混合运算、CDefine 常量 -# ============================================================ +# TypeCastTest: type casts, zext/sext/trunc behavior, +# mixed signed/unsigned arithmetic and CDefine constants -# --- Test 1: CUInt8T -> CUInt32T 零扩展 (zext) --- +# --- Test 1: CUInt8T -> CUInt32T zero extension (zext) --- def test_zext_u8_u32(): - v: uint8 = 200 # 0xC8, 如果 sign-extend 会变成 0xFFFFFFC8 + v: uint8 = 200 # 0xC8; sign-extension would yield 0xFFFFFFC8 wide: uint32 = uint32(v) testcheck.check(wide == 200, "zext u8->u32 (200)", "zext u8->u32 (expected 200)") -# --- Test 2: CInt8T -> CInt32T 符号扩展 (sext) --- +# --- Test 2: CInt8T -> CInt32T sign extension (sext) --- def test_sext_i8_i32(): v: int8 = -50 # 0xCE wide: int32 = int32(v) testcheck.check(wide == -50, "sext i8->i32 (-50)", "sext i8->i32 (expected -50)") -# --- Test 3: CUInt32T -> CUInt64T 零扩展 --- +# --- Test 3: CUInt32T -> CUInt64T zero extension --- def test_zext_u32_u64(): - v: uint32 = 0x80000000 # 最高位为1 + v: uint32 = 0x80000000 # top bit set wide: uint64 = uint64(v) testcheck.check(wide == 0x80000000, "zext u32->u64 (0x80000000)", "zext u32->u64 (expected 0x80000000)") -# --- Test 4: CInt32T -> CInt64T 符号扩展 --- +# --- Test 4: CInt32T -> CInt64T sign extension --- def test_sext_i32_i64(): v: int32 = -1 # 0xFFFFFFFF wide: int64 = int64(v) testcheck.check(wide == -1, "sext i32->i64 (-1)", "sext i32->i64 (expected -1)") -# --- Test 5: CUInt64T -> CUInt32T 截断 (trunc) --- +# --- Test 5: CUInt64T -> CUInt32T truncation (trunc) --- def test_trunc_u64_u32(): v: uint64 = 0x123456789ABCDEF0 narrow: uint32 = uint32(v) testcheck.check(narrow == 0x9ABCDEF0, "trunc u64->u32 (0x9ABCDEF0)", "trunc u64->u32 (expected 0x9ABCDEF0)") -# --- Test 6: 有符号/无符号混合运算 --- +# --- Test 6: mixed signed/unsigned arithmetic --- def test_mixed_signed_unsigned(): a: int = -10 b: uint32 = 20 - # C 中有符号/无符号混合运算,有符号会转为无符号 - # -10 作为 unsigned 是 0xFFFFFFF6 = 4294967286 - # 4294967286 + 20 = 4294967306 (overflow to 10 on u32) + # In C mixed signed/unsigned ops convert the signed value to unsigned. + # -10 as u32 is 0xFFFFFFF6; +20 overflows to 10. result: uint32 = uint32(a) + b stdio.printf(" mixed signed+unsigned: %u (C behavior: %u)\n", result, uint32(-10) + 20) testcheck.ok("mixed signed+unsigned (C behavior)") -# --- Test 7: CDefine 常量在运算中的行为 --- +# --- Test 7: CDefine constants in operations --- define VAL_32BIT = 0x80000000 define VAL_NEG = -1 define VAL_BIG = 0xFFFFFFFF def test_cdefine_values(): - """测试 CDefine 常量值是否正确""" + """Verify CDefine constant values.""" v1: uint32 = uint32(VAL_32BIT) v2: int = VAL_NEG v3: uint32 = uint32(VAL_BIG) @@ -72,20 +69,20 @@ def test_cdefine_values(): testcheck.ok("CDefine constants") -# --- Test 8: 位运算与类型宽度 --- +# --- Test 8: bit operations and type width --- def test_bitops_width(): - """测试位运算是否保持正确类型宽度""" - # 左移 + """Verify bit operations keep the correct type width.""" + # Left shift v: uint32 = 1 - shifted: uint32 = v << 31 # 应该是 0x80000000 + shifted: uint32 = v << 31 # should be 0x80000000 testcheck.check(shifted == 0x80000000, "bit shift (1<<31 = 0x80000000)", "bit shift (expected 0x80000000)") - # 右移 - back: uint32 = shifted >> 31 # 应该是 1 + # Right shift + back: uint32 = shifted >> 31 # should be 1 testcheck.check(back == 1, "bit shift (0x80000000>>31 = 1)", "bit shift (expected 1)") -# --- Test 9: 整数除法与取模 (无符号) --- +# --- Test 9: integer div/mod (unsigned) --- def test_unsigned_divmod(): a: uint32 = 100 b: uint32 = 7 @@ -94,20 +91,19 @@ def test_unsigned_divmod(): testcheck.check(q == 14 and r == 2, "unsigned div/mod (100//7=14, 100%7=2)", "unsigned div/mod (expected 14,2)") -# --- Test 10: 整数除法与取模 (有符号负数) --- +# --- Test 10: integer div/mod (signed negative) --- def test_signed_divmod_neg(): a: int = -100 b: int = 7 q: int = a // b r: int = a % b - # C 语言: -100/7 = -14, -100%7 = -2 - # Python: -100//7 = -15, -100%7 = 5 - # TransPyC 应该遵循 C 语义 + # C: -100/7 = -14, -100%7 = -2; Python: -15 and 5. + # TransPyC follows C semantics. stdio.printf(" signed div/mod: -100//7=%d, -100%%7=%d (C: -14,-2)\n", q, r) testcheck.ok("signed div/mod (C semantics)") -# --- Test 11: 比较运算返回值 --- +# --- Test 11: comparison operation results --- def test_comparison_types(): a: int = 10 b: int = 20 @@ -118,22 +114,22 @@ def test_comparison_types(): testcheck.check(lt == 1 and eq == 1 and gt == 1, "comparison operations", "comparison operations failed") -# --- Test 12: 指针与整数互转 --- +# --- Test 12: pointer/integer casts --- def test_ptr_int_cast(): buf: uint32* = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04) if not buf: testcheck.fail("VirtualAlloc returned NULL") return - # 指针转整数 + # Pointer to integer addr: uint64 = uint64(buf) stdio.printf(" ptr->int: addr=0x%lx\n", addr) - # 整数转指针 + # Integer to pointer p2: uint32* = (uint32*)(addr) p2[0] = 0x12345678 testcheck.check(buf[0] == 0x12345678, "ptr<->int roundtrip", "ptr<->int roundtrip failed") -# --- Test 13: CUInt64T 乘法溢出行为 --- +# --- Test 13: CUInt64T multiplication --- def test_u64_mul(): a: uint64 = 1000 b: uint64 = 1000 @@ -141,19 +137,19 @@ def test_u64_mul(): testcheck.check(c_val == 1000000, "u64 mul (1000*1000=1000000)", "u64 mul (expected 1000000)") -# --- Test 14: bool 运算 (and/or) --- +# --- Test 14: bool operations (and/or) --- def test_bool_ops(): a: int = 5 b: int = 0 c_val: int = 3 - # Python `and`/`or` 是短路求值 - r1: int = a and c_val # 5 and 3 -> 在 C 中应该是 (5 && 3) = 1 - r2: int = b or c_val # 0 or 3 -> 在 C 中应该是 (0 || 3) = 1 + # Python and/or are short-circuiting + r1: int = a and c_val # 5 and 3 -> (5 && 3) = 1 in C + r2: int = b or c_val # 0 or 3 -> (0 || 3) = 1 in C stdio.printf(" bool: 5 and 3 = %d, 0 or 3 = %d (expect 1,1 in C)\n", r1, r2) testcheck.ok("bool ops (C semantics)") -# --- Test 15: 条件表达式 (三元运算符) --- +# --- Test 15: conditional expression (ternary) --- def test_ternary(): a: int = 10 b: int = 20 diff --git a/VRandomTest/App/main.vp b/VRandomTest/App/main.vp index b745dab..680bc01 100644 --- a/VRandomTest/App/main.vp +++ b/VRandomTest/App/main.vp @@ -6,7 +6,7 @@ import testcheck # ============================================================ -# VRandomTest - 硬件随机数生成 + 标准分布函数测试 +# VRandomTest: hardware RNG and standard distribution functions. # ============================================================ def main() -> int: diff --git a/VariadicTest/App/main.vp b/VariadicTest/App/main.vp index 753729c..5f83169 100644 --- a/VariadicTest/App/main.vp +++ b/VariadicTest/App/main.vp @@ -7,12 +7,12 @@ import viperlib import w32.win32console # ============================================================ -# VariadicTest - 测试 snprintf/printf variadic 参数传递 +# VariadicTest - check snprintf/printf variadic argument passing # ============================================================ -# --- Test 1: %u 格式化小整数 (CUInt8T -> CUnsignedInt) --- +# --- Test 1: %u formats small int (CUInt8T -> CUnsignedInt) --- def test_snprintf_u8(): - """测试 CUInt8T 值通过 t.CUnsignedInt() 传递给 %u""" + """Check a CUInt8T value passed to %u via t.CUnsignedInt().""" testcheck.section("Test 1: %u 格式化小整数 (CUInt8T -> CUnsignedInt)") hr: uint8 = 14 mn: uint8 = 30 @@ -24,9 +24,9 @@ def test_snprintf_u8(): testcheck.ok("CUInt8T -> %u (expect 14:30:59)") -# --- Test 2: %u 格式化 CUInt16T --- +# --- Test 2: %u formats CUInt16T --- def test_snprintf_u16(): - """测试 CUInt16T 值通过 t.CUnsignedInt() 传递给 %u""" + """Check a CUInt16T value passed to %u via t.CUnsignedInt().""" testcheck.section("Test 2: %u 格式化 CUInt16T") yr: uint16 = 2026 buf: t.CArray[char, 64] @@ -36,9 +36,9 @@ def test_snprintf_u16(): testcheck.ok("CUInt16T -> %u (expect 2026)") -# --- Test 3: %lu 格式化 CUInt64T --- +# --- Test 3: %lu formats CUInt64T --- def test_snprintf_u64(): - """测试 CUInt64T 值传递给 %lu""" + """Check a CUInt64T value passed to %lu.""" testcheck.section("Test 3: %lu 格式化 CUInt64T") val: uint64 = 1234567890123 buf: t.CArray[char, 64] @@ -48,9 +48,9 @@ def test_snprintf_u64(): testcheck.ok("CUInt64T -> %lu (expect 1234567890123)") -# --- Test 4: %d 格式化负数 --- +# --- Test 4: %d formats negative int --- def test_snprintf_d_neg(): - """测试 %d 格式化负整数""" + """Check %d formatting of a negative int.""" testcheck.section("Test 4: %d 格式化负数") val: int = -42 buf: t.CArray[char, 64] @@ -60,7 +60,7 @@ def test_snprintf_d_neg(): testcheck.ok("CInt -> %d neg (expect -42)") -# --- Test 5: %d 格式化正数 --- +# --- Test 5: %d formats positive int --- def test_snprintf_d_pos(): testcheck.section("Test 5: %d 格式化正数") val: int = 42 @@ -71,7 +71,7 @@ def test_snprintf_d_pos(): testcheck.ok("CInt -> %d pos (expect 42)") -# --- Test 6: %x 格式化十六进制 --- +# --- Test 6: %x formats hex --- def test_snprintf_x(): testcheck.section("Test 6: %x 格式化十六进制") val: uint32 = 0xDEADBEEF @@ -82,9 +82,9 @@ def test_snprintf_x(): testcheck.ok("%x hex (expect 0xdeadbeef)") -# --- Test 7: 混合格式化 (模拟 desktop.py 时间格式) --- +# --- Test 7: mixed formatting (desktop.py time format) --- def test_snprintf_mixed(): - """模拟 desktop.py 的时间格式化""" + """Mimic desktop.py time formatting.""" testcheck.section("Test 7: 混合格式化 (模拟 desktop.py 时间格式)") hr: uint8 = 14 mn: uint8 = 5 @@ -101,18 +101,18 @@ def test_snprintf_mixed(): testcheck.ok("time format (expect 2026-06-14 14:05:09)") -# --- Test 8: printf 直接输出 variadic --- +# --- Test 8: printf direct variadic output --- def test_printf_variadic(): - """测试 printf 直接输出 variadic 参数""" + """Check printf direct variadic output.""" testcheck.section("Test 8: printf 直接输出 variadic") stdio.printf("Test8 (printf direct): %u %d %lu 0x%x (expect 100 -50 999999999 0xcafe)\n", uint(100), -50, uint64(999999999), 0xCAFE) testcheck.ok("printf direct variadic (expect 100 -50 999999999 0xcafe)") -# --- Test 9: 多个 %lu 连续 --- +# --- Test 9: several consecutive %lu --- def test_snprintf_multi_lu(): - """测试多个 %lu 连续(模拟 perf 日志格式)""" + """Check several consecutive %lu (mimics perf log format).""" testcheck.section("Test 9: 多个 %lu 连续") v1: uint64 = 16 v2: uint64 = 2 @@ -124,7 +124,7 @@ def test_snprintf_multi_lu(): testcheck.ok("multi %lu (expect wall=16 work=2 render=11)") -# --- Test 10: %u 格式化 0 --- +# --- Test 10: %u formats zero --- def test_snprintf_zero(): testcheck.section("Test 10: %u 格式化 0") val: uint32 = 0 @@ -135,7 +135,7 @@ def test_snprintf_zero(): testcheck.ok("%u zero (expect 0)") -# --- Test 11: %u 格式化大值 --- +# --- Test 11: %u formats a large value --- def test_snprintf_large(): testcheck.section("Test 11: %u 格式化大值") val: uint32 = 4294967295 # 0xFFFFFFFF @@ -148,7 +148,7 @@ def test_snprintf_large(): # --- Test 12: CUnsignedInt cast from CUInt8T edge values --- def test_snprintf_u8_edge(): - """测试 CUInt8T 边界值""" + """Check CUInt8T edge values.""" testcheck.section("Test 12: CUnsignedInt cast from CUInt8T edge values") v0: uint8 = 0 v127: uint8 = 127 diff --git a/WebTest/App/main.vp b/WebTest/App/main.vp index b79e6cb..b63a399 100644 --- a/WebTest/App/main.vp +++ b/WebTest/App/main.vp @@ -7,7 +7,7 @@ import memhub import requests -# 全局 MBuddy 指针 +# Global MBuddy pointer _mbuddy: memhub.MemBuddy* @@ -16,7 +16,7 @@ def main() -> int: global _mbuddy stdio.printf("WebTest: HTTP client library test\n") - # 初始化内存管理器(16MB arena) + # Initialize the memory manager (16MB arena) arena: bytes = stdlib.malloc(16 * 1024 * 1024) if arena is None: stdio.printf("FATAL: malloc arena failed\n") @@ -25,11 +25,11 @@ def main() -> int: _mbuddy = memhub.MemBuddy(arena, 16 * 1024 * 1024) requests._mbuddy = _mbuddy - # 初始化 Socket 库 + # Initialize the socket library result: INT = socket.SocketInit() stdio.printf("SocketInit: %d\n", result) - # 测试 Socket OOP API + # Test the Socket OOP API sock = socket.Socket(socket.AF_INET, socket.SOCK_STREAM) if sock.fd != socket.INVALID_SOCKET: stdio.printf("Socket: OK (fd=%d)\n", sock.fd) @@ -38,7 +38,7 @@ def main() -> int: else: stdio.printf("Socket: FAIL\n") - # 测试 DNS 解析 — 通过 Socket.connect 间接测试(内部调用 _MakeAddr) + # Test DNS resolution indirectly via Socket.connect (calls _MakeAddr internally) stdio.printf("\n--- DNS test ---\n") dns_sock = socket.Socket(socket.AF_INET, socket.SOCK_STREAM) if dns_sock.fd != socket.INVALID_SOCKET: @@ -50,7 +50,7 @@ def main() -> int: stdio.printf("DNS: cn.bing.com resolved but connect failed (err in _MakeAddr debug above)\n") dns_sock.close() - # 测试 HTTP GET — 使用 DNS 解析 cn.bing.com(example.com 在部分网络下不可达) + # Test HTTP GET via cn.bing.com (example.com is unreachable on some networks) stdio.printf("\n--- HTTP GET test (cn.bing.com) ---\n") resp = requests.get("http://cn.bing.com/") if resp is not None: @@ -74,7 +74,7 @@ def main() -> int: else: stdio.printf("requests.get: FAIL (network unavailable)\n") - # 清理 + # Cleanup socket.SocketCleanup() stdio.printf("\nSocketCleanup: OK\n") stdio.printf("WebTest: ALL PASSED\n") diff --git a/ZlibDbg/App/main.vp b/ZlibDbg/App/main.vp index 90e73ae..03dea6b 100644 --- a/ZlibDbg/App/main.vp +++ b/ZlibDbg/App/main.vp @@ -20,14 +20,8 @@ def fill_data(data: BYTEPTR, size: sizet, seed: sizet, repeating: int): def huffman_probe(seed: sizet, size: sizet, repeating: int): - """对 roundtrip 的同一份数据直接用 zhuff 复算字面量码表并打印分布。 - - 背景:随机数据的 comp 远小于其字面量熵下限(250 字节数据熵下限约 221 字节, - 实测 comp=132),说明码表/码长分配异常。本探针打印: - - active:拿到码位(bits>0)的符号数 - - no_code:有频率却拿不到码位的符号数(编码期会被 encode_symbol 静默丢弃) - - sum15:Σ hist[b]*2^(15-b),合法完整码表必须恰为 32768(=2^15) - 再逐位宽打印码字数直方图。 + """Recompute the literal code table with zhuff for one dataset and print its + distribution (active/no_code/sum15 and code-count histogram per bit width). """ data: BYTEPTR = BYTEPTR(stdlib.malloc(size)) fill_data(data, size, seed, repeating) @@ -67,15 +61,8 @@ def huffman_probe(seed: sizet, size: sizet, repeating: int): def count_freqs_probe(seed: sizet, size: sizet, repeating: int): - """调用真实的 zdeflate_count_freqs,与朴素直方图对照。 - - 上面 huffman_probe 证明码表层正确,则 comp 远小于熵下限只能来自 - "频率统计与编码遍历不一致":count 阶段漏计某些位置 ⇒ 那些字节值 freq=0 ⇒ - 码表里 bits=0 ⇒ encode_block_data 仍会写出这些字面量,被 encode_symbol - 静默丢弃 ⇒ 码流偏短(dec < size)。本探针打印: - - sum_lit:Σlit_freqs,正常应恰为 size+1(每个字节一次 + EOB) - - active:真实统计下 freq>0 的字面量符号数 - - hlit / hdist / Σdist_freqs(>0 说明 count 阶段找到了 LZ77 匹配) + """Call the real zdeflate_count_freqs and compare it with a naive histogram + (prints sum_lit/active/hlit/hdist; sum_lit should equal size+1). """ data: BYTEPTR = BYTEPTR(stdlib.malloc(size)) fill_data(data, size, seed, repeating) @@ -90,9 +77,8 @@ def count_freqs_probe(seed: sizet, size: sizet, repeating: int): zdeflate.zdeflate_count_freqs(lit, dist, s, data, size) s.destroy() - # 元素符号性对拍:UINT8PTR 若被当作**有符号 i8**,则字节 ≥128 读成负数 - # (-56 >= 128 恒假),既导致 count 阶段 lit_freqs[负数] 写到数组之前(漏计), - # 也让 encode_symbol(data[pos]) 收到负 symbol 被静默丢弃 ⇒ 码流截断。 + # Signedness cross-check: if UINT8PTR were treated as signed i8, bytes >=128 + # would read negative, undercounting freqs and dropping symbols -> truncated stream. up: UINT8PTR = UINT8PTR(data) ge8_up: int = 0 ge8_bp: int = 0 @@ -165,13 +151,13 @@ def roundtrip(seed: sizet, size: sizet, repeating: int, wbits: int) -> int: def main() -> int: testcheck.begin("ZlibDbg: zlib 多 seed/size/wbits 往返") - # 先跑码表探针:定位 comp 远小于熵下限的根因(码表异常 / 还是别处) + # Run the code-table probe first to locate the cause of comp below entropy floor testcheck.section("字面量码表探针") huffman_probe(0, 250, 0) huffman_probe(9, 20000, 0) huffman_probe(0, 256, 1) - # 真实频率统计 vs 朴素直方图对照 + # Real frequency stats vs naive histogram comparison testcheck.section("频率统计探针 (zdeflate_count_freqs)") count_freqs_probe(0, 250, 0) count_freqs_probe(9, 20000, 0) diff --git a/ZlibTest/App/main.vp b/ZlibTest/App/main.vp index 36708cb..732d037 100644 --- a/ZlibTest/App/main.vp +++ b/ZlibTest/App/main.vp @@ -12,7 +12,7 @@ def main() -> int: tpz.main123456() testcheck.ok("zlib test_pyzlib completed") - # 标准 zlib 库(includes/zlib) + # Standard zlib library (includes/zlib) testcheck.section("标准 zlib 库 (zlib.pyzlib)") print(stdzp.runtime_version()) testcheck.ok("zlib runtime version printed") diff --git a/ZlibTest/App/test_pyzlib.vp b/ZlibTest/App/test_pyzlib.vp index 13d6a1e..ad00361 100644 --- a/ZlibTest/App/test_pyzlib.vp +++ b/ZlibTest/App/test_pyzlib.vp @@ -176,7 +176,7 @@ def test_compressobj(): printf(" Flush result : %zu bytes -> ", out_length) print_hex_test(c3, out_length, 16) if out_length > 0 and c3: - new_all: BYTEPTR = stdlib.realloc(all, total + out_length) # 隐式转换 + new_all: BYTEPTR = stdlib.realloc(all, total + out_length) # implicit cast if new_all: all = new_all string.memcpy(all + total, c3, out_length) @@ -643,7 +643,7 @@ def test_huffman_tree(): printf(" Active codes: %d, max code lengthgth: %d\n", total_codes, max_length_found) printf(" Code assignments:\n") - names: t.CArray[str, None] = ["A","B","C","D","E","F"] # 一个都æ˜?char* 的数ç»? + names: t.CArray[str, None] = ["A","B","C","D","E","F"] # all char* array syms: t.CArray[int, None] = ['A','B','C','D','E','F'] for i in range(6): printf(" '%s' (freq=%3d): code=0x%04X, bits=%d\n", @@ -761,9 +761,8 @@ def test_huffman_tree(): stdlib.free(w.buf) - # 全量 257 符号往返:ZlibDbg 随机数据的失败只在"多符号码表"场景出现, - # 上面 4 符号抽样覆盖不到——这里把 0..256 全部编码再解码逐一比对, - # 与 ZlibDbg 的失败形态(码表把部分符号编成无码位/错码位)直接对齐。 + # Full 257-symbol roundtrip: encode and decode every symbol 0..256. + # The 4-symbol sample above misses failures that only appear with many symbols. w2 = zdef.zbit_writer(None) for i in range(257): of_tree.encode_symbol(i, &w2) @@ -874,10 +873,8 @@ def main123456() -> int: printf(" Python zlib - C Implementation Tests\n") printf("==============================================\n") - # Huffman 树/码表构建前置:此前以 "skip: heap corruption from earlier tests" - # 跳过——排在其它用例之后时,前面用例造成的堆破坏会让本用例崩溃,从而掩盖 - # 它自己的结论。前置后可在干净堆上独立复现(ZlibDbg 随机数据 roundtrip 失败 - # 已定位到"多符号码表构建"这一层,本用例是当前最小复现入口)。 + # Run Huffman tree / code-table construction first, on a clean heap. + # After other tests, earlier heap corruption crashes this case and hides its result. test_huffman_tree() test_constants() test_version() @@ -895,7 +892,7 @@ def main123456() -> int: test_gzip_format() test_raw_deflate() test_zdict() - # test_huffman_tree() # 已前置到 main123456 开头(理由见该处注释) + # test_huffman_tree() # moved to the start of main123456 (see note there) test_error_handling() printf("\n==============================================\n")