自举实验失败,C1 编译 Test 成功,暂未达到自举收敛点
This commit is contained in:
@@ -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 推断类型
|
||||
|
||||
Reference in New Issue
Block a user