Files
Viper_RegressionTesting/AstTest/App/main.vp
T
TermiNexus 3c6fb1d246 chore(test): 初始化回归测试仓(新增 .gitignore,TestsOverview.md 改为 README.md)
把 Test/ 纳入 https://git.gvsds.com/GVSDS/Viper_RegressionTesting 。

1) 新增 .gitignore —— 只保留测试源码,剔除全部构建产物:
   目录   **/output*/(output / output_opt / output_orig / output_verify / output_dbg)、
          **/temp*/(temp / temp_opt)、**/.tpv_build/
   二进制 *.exe *.obj *.o *.out *.a *.lib *.dll
   中间物 *.ll *.vpi *.pyi *.deps.txt *.deps.json *.doc.json *_sha1_map.txt
          _pyi_cache_v1.pkl _pyi_cache_v1.sig.json _shared_sym.json _phase1_manifest.json
   其它   build_all.txt(构建日志)、*.log、__pycache__/、*.bak、IDE 目录
   保留   App/*.vp、project.json / project_opt.json / project.vpj、README.md、两个 .py
   实测 `git add -A --dry-run`:196 个文件,无任何构建产物混入。

2) TestsOverview.md → README.md(作为仓库首页文档)。

3) SequentialRegressionTest.py:7 处 TestsOverview.md 引用同步改为 README.md
   (文档串、OVERVIEW 路径、read_test_order 文档与报错文案、argparse description、
   启动横幅);同时修正入口路径 PROJECTRANS —— 旧值 <root>/Projectrans.py 已不存在,
   改为 <root>/TransPyC/Projectrans.py(与 regression_test.py:45-48 记录一致),
   否则本脚本会以 "can't open file" 全量失败。
   regression_test.py 无需改动:它按目录扫描 project.json 找项目,不引用该文档。
2026-09-29 15:14:59 +08:00

257 lines
8.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from stdint import *
import t, c
from t import CInt, CExport
from stdio import printf
import memhub
import stdlib
import sys
import string
import ast
import w32.win32console
# MBuddy arena 大小:1MB
ARENA_SIZE: t.CDefine = 1048576
# mpool 内存大小:512KB
POOL_SIZE: t.CDefine = 524288
# dump 缓冲区大小:256KB
DUMP_SIZE: t.CDefine = 262144
def classify_list(lst: list[ast.AST | t.CPtr] | t.CPtr, depth: t.CInt):
"""递归遍历 list[AST | t.CPtr] 容器,逐元素分类(orelse/args/comparators 等)"""
if lst is None:
return
n: t.CSizeT = lst.__len__()
i: t.CSizeT = 0
while i < n:
classify_print(lst.get(i), depth + 1)
i += 1
def classify_print(node: ast.AST | t.CPtr, depth: t.CInt):
"""递归遍历 parse 树,用 isinstance 运行时判定每个节点的类别并打印。
依赖 TPV isinstance 的 vtable 子类集合比较:
- isinstance(node, ast.Stmt) → 语句节点(Assign/If/For/While/...)
- isinstance(node, ast.ExprNode) → 表达式节点(Name/Constant/BinOp/...)
- 两者皆非 → 其他(Module/Expression/...)
验证运行时(非编译期静态)正确区分 Stmt 与 ExprNode。
"""
if node is None:
return
sp: t.CInt = 0
while sp < depth:
printf(" ")
sp += 1
if isinstance(node, ast.Stmt) != 0:
printf("STMT %s\n", node.type_name())
elif isinstance(node, ast.ExprNode) != 0:
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(按需过滤原则)。
k: t.CInt = node.kind()
if k == ast.ASTKind.Assign:
asg: ast.Assign | t.CPtr = (ast.Assign | t.CPtr)(node)
classify_print(asg.value, depth + 1)
elif k == ast.ASTKind.If:
ifn: ast.If | t.CPtr = (ast.If | t.CPtr)(node)
classify_print(ifn.test, depth + 1)
classify_list(ifn.orelse, depth + 1)
elif k == ast.ASTKind.While:
whl: ast.While | t.CPtr = (ast.While | t.CPtr)(node)
classify_print(whl.test, depth + 1)
classify_list(whl.orelse, depth + 1)
elif k == ast.ASTKind.For:
for_nd: ast.For | t.CPtr = (ast.For | t.CPtr)(node)
classify_print(for_nd.iter, depth + 1)
classify_print(for_nd.target, depth + 1)
classify_list(for_nd.orelse, depth + 1)
elif k == ast.ASTKind.Return:
ret_nd: ast.Return | t.CPtr = (ast.Return | t.CPtr)(node)
classify_print(ret_nd.value, depth + 1)
elif k == ast.ASTKind.Expr:
expr_nd: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(node)
classify_print(expr_nd.value, depth + 1)
elif k == ast.ASTKind.BinOp:
bin_nd: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
classify_print(bin_nd.left, depth + 1)
classify_print(bin_nd.right, depth + 1)
elif k == ast.ASTKind.UnaryOp:
una_nd: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(node)
classify_print(una_nd.operand, depth + 1)
elif k == ast.ASTKind.Compare:
cmp_nd: ast.Compare | t.CPtr = (ast.Compare | t.CPtr)(node)
classify_print(cmp_nd.left, depth + 1)
classify_list(cmp_nd.comparators, depth + 1)
elif k == ast.ASTKind.BoolOp:
bool_nd: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
classify_list(bool_nd.values, depth + 1)
elif k == ast.ASTKind.Call:
call_nd: ast.Call | t.CPtr = (ast.Call | t.CPtr)(node)
classify_print(call_nd.func, depth + 1)
classify_list(call_nd.args, depth + 1)
else:
pass
# children(语句 body 块)
if node.children is not None:
n: t.CSizeT = node.children.__len__()
i: t.CSizeT = 0
while i < n:
classify_print(node.children.get(i), depth + 1)
i += 1
def main() -> CInt | CExport:
w32.win32console.SetConsoleCP(65001)
w32.win32console.SetConsoleOutputCP(65001)
printf("AST Comprehensive Test Start\n")
# 初始化全局 MBuddy 内存分配器
arena: bytes = stdlib.malloc(ARENA_SIZE)
if arena == None:
printf("FAIL: arena alloc failed\n")
return 1
mbuddy_obj: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, ARENA_SIZE)
if mbuddy_obj == None:
printf("FAIL: mbuddy init failed\n")
return 1
sys._mbuddy = mbuddy_obj
ast._mbuddy = mbuddy_obj
# 为 ast 解析器创建 mpool
pool_mem: bytes = stdlib.malloc(POOL_SIZE)
if pool_mem == None:
printf("FAIL: malloc for pool failed\n")
return 1
pool: memhub.MemPool | t.CPtr = memhub.MemPool(pool_mem, POOL_SIZE)
if pool == None:
printf("FAIL: memhub.MemPool init failed\n")
return 1
# dump 缓冲区(独立分配)
dump_mem: bytes = stdlib.malloc(DUMP_SIZE)
if dump_mem == None:
printf("FAIL: malloc for dump failed\n")
return 1
dump_buf: t.CChar | t.CPtr = t.CChar(dump_mem, t.CPtr)
# 综合测试源码:覆盖 CPython 主要语法
src: str = """x = 1
y = 2
z = x + y
a = x - y
b = x * y
c = x / y
d = x == y
e = x < y
f = x > y
g = x and y
h = x or y
i = not x
def foo(a, b):
return a + b
result = foo(x, y)
if x > 0:
print(x)
else:
print(y)
for i in range(10):
print(i)
while x > 0:
x = x - 1
class Point:
pass
"""
printf("Parsing comprehensive source...\n")
# 解析
ast._init_tables(pool)
lx_dbg: t.CPtr = ast.new_lexer(pool)
if lx_dbg == None:
printf("FAIL: new_lexer returned None\n")
stdlib.free(pool_mem)
stdlib.free(dump_mem)
return 1
ast._lexer_init(lx_dbg, src, pool)
tokens_dbg: t.CPtr = ast.tokenize(lx_dbg)
if tokens_dbg == None:
printf("FAIL: tokenize returned None\n")
stdlib.free(pool_mem)
stdlib.free(dump_mem)
return 1
tree: ast.AST | t.CPtr = ast.parse_tokens(pool, tokens_dbg)
if tree == None:
printf("FAIL: parse returned None\n")
stdlib.free(pool_mem)
stdlib.free(dump_mem)
return 1
printf("PASS: parse succeeded\n")
# dump AST
printf("Calling ast.dump...\n")
ast.dump(tree, dump_buf, DUMP_SIZE)
printf("ast.dump returned, now printing buffer...\n")
printf("=== AST DUMP ===\n%s\n=== END ===\n", dump_buf)
# ============================================================
# Stmt/Expr 运行时区分测试(isinstance vtable 子类集合比较)
# ============================================================
printf("=== STMT/EXPR RUNTIME DISTINGUISH TEST ===\n")
classify_print(tree, 0)
# 断言 1: Module 既非 Stmt 亦非 ExprNode(顶层容器)
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
top_ok: t.CInt = 1
top_n: t.CSizeT = tree.children.__len__()
i2: t.CSizeT = 0
while i2 < top_n:
top_node: ast.AST | t.CPtr = tree.children.get(i2)
if isinstance(top_node, ast.Stmt) == 0:
top_ok = 0
printf("FAIL: top-level node not Stmt: %s\n", top_node.type_name())
i2 += 1
if top_ok != 0:
printf("PASS: all %lld top-level nodes are Stmt\n", top_n)
# 断言 3: Assign 是 Stmt 且不是 ExprNode
first_assign: ast.Assign | t.CPtr = (ast.Assign | t.CPtr)(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
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 语义)
if top_n >= 15:
if_node: ast.If | t.CPtr = (ast.If | t.CPtr)(tree.children.get(14))
if if_node.children is not None and if_node.children.__len__() > 0:
expr_stmt: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(if_node.children.get(0))
if isinstance(expr_stmt, ast.Stmt) != 0 and isinstance(expr_stmt, ast.ExprNode) == 0:
printf("PASS: Expr(stmt) is Stmt, not ExprNode (%s)\n", expr_stmt.type_name())
else:
printf("FAIL: Expr(stmt) classification wrong\n")
printf("=== END RUNTIME TEST ===\n")
stdlib.free(pool_mem)
stdlib.free(dump_mem)
return 0