自举实验失败,C1 编译 Test 成功,暂未达到自举收敛点

This commit is contained in:
2026-07-30 15:44:32 +08:00
parent 68481a5a7f
commit 32af3f93fa
22 changed files with 2158 additions and 442 deletions

View File

@@ -17,6 +17,109 @@ import viperlib
# ============================================================
# ============================================================
# _eval_binop_int / _eval_binop_valid - 递归计算 BinOp 常量值
#
# 用于 .pyi 存根文件生成时计算 BinOp 表达式(如 A | B, A + B的整数值。
# 支持 BitOr/BitAnd/Add/Sub 以及嵌套的 Name引用已注册的 CDefine 常量)。
# ============================================================
def _eval_binop_valid(node: ast.AST | t.CPtr) -> int:
"""检查 BinOp 节点是否可计算(所有叶子节点都是常量或已注册的 CDefine"""
if node is None:
return 0
k: int = node.kind()
if k == ast.ASTKind.Constant:
cn: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(node)
if cn.const_kind == ast.CONST_INT:
return 1
return 0
if k == ast.ASTKind.UnaryOp:
uop: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(node)
if uop.operand is not None:
return _eval_binop_valid(uop.operand)
return 0
if k == ast.ASTKind.BinOp:
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
if bop.left is not None and bop.right is not None:
if _eval_binop_valid(bop.left) != 0:
if _eval_binop_valid(bop.right) != 0:
return 1
return 0
if k == ast.ASTKind.Name:
# Name 引用:检查是否是已注册的 CDefine 常量
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
if nm.id is not None:
# 从本地 CDefine 表查找
val: int = _lookup_cdefine_for_pyi(nm.id)
if _pyi_cdefine_found() != 0:
return 1
return 0
return 0
def _eval_binop_int(node: ast.AST | t.CPtr) -> int:
"""递归计算 BinOp 节点的整数值"""
if node is None:
return 0
k: int = node.kind()
if k == ast.ASTKind.Constant:
cn: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(node)
if cn.const_kind == ast.CONST_INT:
return cn.int_val
return 0
if k == ast.ASTKind.UnaryOp:
uop: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(node)
if uop.op == ast.OpKind.USub and uop.operand is not None:
return -_eval_binop_int(uop.operand)
if uop.op == ast.OpKind.UAdd and uop.operand is not None:
return _eval_binop_int(uop.operand)
if uop.op == ast.OpKind.Invert and uop.operand is not None:
return ~_eval_binop_int(uop.operand)
return 0
if k == ast.ASTKind.BinOp:
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
if bop.left is None or bop.right is None:
return 0
lv: int = _eval_binop_int(bop.left)
rv: int = _eval_binop_int(bop.right)
if bop.op == ast.OpKind.BitOr:
return lv | rv
if bop.op == ast.OpKind.BitAnd:
return lv & rv
if bop.op == ast.OpKind.Add:
return lv + rv
if bop.op == ast.OpKind.Sub:
return lv - rv
return 0
if k == ast.ASTKind.Name:
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
if nm.id is not None:
return _lookup_cdefine_for_pyi(nm.id)
return 0
return 0
# CDefine 查找的前向声明(实际实现在 HandlesType
# 避免循环依赖,使用弱引用
_g_pyi_cdefine_found: int = 0
def _lookup_cdefine_for_pyi(name: str) -> int:
"""从本地 CDefine 表查找常量值(用于 .pyi 生成时的 BinOp 计算)"""
import lib.core.Handles.HandlesType as HandlesType
val: int = HandlesType.lookup_cdefine_constant(name)
if HandlesType.is_cdefine_found() != 0:
_g_pyi_cdefine_found = 1
return val
_g_pyi_cdefine_found = 0
return 0
def _pyi_cdefine_found() -> int:
"""返回上次 _lookup_cdefine_for_pyi 的查找结果状态"""
return _g_pyi_cdefine_found
# ============================================================
# _PyiEmit - 追加字符串到缓冲区
#
@@ -525,6 +628,72 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy | t.CPtr, tree: ast.AST | t.CPtr,
pos = _PyiEmit(buf, buf_size, pos, " = False")
elif cv.const_kind == ast.CONST_NONE:
pos = _PyiEmit(buf, buf_size, pos, " = None")
elif aa.value is not None and aa.value.kind() == ast.ASTKind.UnaryOp:
# 处理负值常量(如 INVALID_HANDLE_VALUE = -1
# UnaryOp(USub, Constant(1)) → -1
uop_cv: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(aa.value)
if uop_cv.op == ast.OpKind.USub and uop_cv.operand is not None:
if uop_cv.operand.kind() == ast.ASTKind.Constant:
uop_const: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(uop_cv.operand)
if uop_const.const_kind == ast.CONST_INT:
neg_val: int = -uop_const.int_val
num_buf_u: bytes = mb.alloc(32)
if num_buf_u is not None:
viperlib.snprintf(num_buf_u, 32, " = %d", neg_val)
pos = _PyiEmit(buf, buf_size, pos, num_buf_u)
elif aa.value is not None and aa.value.kind() == ast.ASTKind.Call:
# 处理类型构造函数常量(如 t.CUnsignedLong(-11)
# 提取第一个参数的整数值并输出
call_cv: ast.Call | t.CPtr = (ast.Call | t.CPtr)(aa.value)
if call_cv.args is not None:
call_args_cv: list[ast.AST | t.CPtr] | t.CPtr = call_cv.args
if call_args_cv.__len__() > 0:
first_arg: ast.AST | t.CPtr = call_args_cv.get(0)
if first_arg is not None:
arg_kind: int = first_arg.kind()
if arg_kind == ast.ASTKind.Constant:
ca_cv: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(first_arg)
if ca_cv.const_kind == ast.CONST_INT:
num_buf_c: bytes = mb.alloc(32)
if num_buf_c is not None:
viperlib.snprintf(num_buf_c, 32, " = %d", ca_cv.int_val)
pos = _PyiEmit(buf, buf_size, pos, num_buf_c)
elif arg_kind == ast.ASTKind.UnaryOp:
uop_ca: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(first_arg)
if uop_ca.op == ast.OpKind.USub and uop_ca.operand is not None:
if uop_ca.operand.kind() == ast.ASTKind.Constant:
uoc: ast.Constant | t.CPtr = (ast.Constant | t.CPtr)(uop_ca.operand)
if uoc.const_kind == ast.CONST_INT:
neg_c_val: int = -uoc.int_val
num_buf_cu: bytes = mb.alloc(32)
if num_buf_cu is not None:
viperlib.snprintf(num_buf_cu, 32, " = %d", neg_c_val)
pos = _PyiEmit(buf, buf_size, pos, num_buf_cu)
elif arg_kind == ast.ASTKind.BinOp:
# Call 内部的 BinOp如 t.CUnsignedLong(A | B)
# 递归计算 BinOp 值
binop_val_bo: int = _eval_binop_int(first_arg)
if binop_val_bo != 0 or _eval_binop_valid(first_arg) != 0:
num_buf_bo: bytes = mb.alloc(32)
if num_buf_bo is not None:
viperlib.snprintf(num_buf_bo, 32, " = %d", binop_val_bo)
pos = _PyiEmit(buf, buf_size, pos, num_buf_bo)
elif aa.value is not None and aa.value.kind() == ast.ASTKind.BinOp:
# 处理 BinOp 常量(如 FOREGROUND_COMBO = FOREGROUND_RED | FOREGROUND_GREEN
# 递归计算 BinOp 值并输出
binop_val_av: int = _eval_binop_int(aa.value)
if binop_val_av != 0 or _eval_binop_valid(aa.value) != 0:
num_buf_b: bytes = mb.alloc(32)
if num_buf_b is not None:
viperlib.snprintf(num_buf_b, 32, " = %d", binop_val_av)
pos = _PyiEmit(buf, buf_size, pos, num_buf_b)
elif aa.value is not None and aa.value.kind() == ast.ASTKind.Name:
# 处理 Name 引用常量(如 ALIAS = OTHER_CONST
# 输出引用的名字,让消费方在本地查找
name_val: ast.Name | t.CPtr = (ast.Name | t.CPtr)(aa.value)
if name_val.id is not None:
pos = _PyiEmit(buf, buf_size, pos, " = ")
pos = _PyiEmit(buf, buf_size, pos, name_val.id)
pos = _PyiEmit(buf, buf_size, pos, "\n")
# 全局赋值(无注解)— 从 Constant value 推断类型