Commit Graph
21 Commits
Author SHA1 Message Date
TermiNexus 1050e5a23a fix(decl): stub 跳过联合形态 CDefine + 模块属性访问回退 _all_define_constants
链接报 undefined symbol: STD_INPUT/OUTPUT/ERROR_HANDLE。根因两处:① DeclarationGenerator._generate_global_decl 的 CDefine 跳过判据只认裸 t.CDefine,而 define X: T = V 展开为注解 T | t.CDefine,于是 stub 里写出 @STD_OUTPUT_HANDLE = external global i32(该符号无人定义);② 模块属性访问 win32file.STD_OUTPUT_HANDLE 的 _try_resolve_nested_cdefine 只查 SymbolTable/_define_constants,缺裸名路径已有的 _all_define_constants 回退,解析落空后转去加载那条错误的 stub 全局 → 链接期未定义符号。改为 AnnotationContainsName 判据 + 补 _all_define_constants 回退(仅在本模块无同名全局时,避免遮蔽真实模块全局)。
2026-10-10 20:29:59 +08:00
TermiNexus 2514cee4c9 feat(lang): 同步 cif/celif/celse、值引用注解与 assert 改译 testcheck.check
vast 双路径(Python Parser/ExprParser 与 C 扩展 vast_c.c)新增 cif-celif-celse 语句族与 &T / &temp T 参数注解解析,_parser.pyd 已同步重编。HandlesIf 改认 @CIf 标记并做编译期常量求值,含运行时变量一律 fail-fast,同时删除 c.CIf 家族(c.py)。HandlesAssert 合成 testcheck.check(cond, None, msg) 调用,非字符串字面量消息报 TypeError。FuncGen 调用点按形参模式自动取址(ref 仅接受左值,右值 fail-fast;temp 物化临时栈),SymbolUtils/TypeAnnotationResolver 提供模式识别;t.py 删除 CNeedPtr。
2026-10-07 19:03:29 +08:00
TermiNexus 5eef845e5b feat(struct): 嵌套 class/struct 发射为独立结构体 {外类}_{内类}
用户 2026-10-01 定:struct 内允许叠加 struct(与 class 内写 class 同口径)。
此前类体里的嵌套 ClassDef 在两个编译器里都被**静默丢弃**(字段遍历只认 AnnAssign、
方法遍历只认 FunctionDef),现按既有 REnum/union 嵌套命名先例发射为独立结构体。

命名与引用口径(双端同源):内层结构体 = {外类}_{内类}(多层递归 A_B_C);
引用两种写法都可用 —— 限定名 `外类.内类`、扁平名 `外类_内类`。

- HandlesClassDef.py:新增 _EmitNestedClassDefs(deepcopy + 改名后递归
  _EmitClassLlvm,deepcopy 避免污染源码 AST)+ _RegisterNestedClassName
  (SymbolTable 登记裸名/点号名/扁平名,对齐 REnum 变体的三键先例)。
- TypeAnnotationResolver.py:_from_node_attribute 增加嵌套分支 —— 限定名按**扁平名**
  取条目并让 Name/BaseType 都是扁平名(否则会拼出 t.CStruct(name='内类'),
  与声明端 `%"{sha}.外类_内类"` 不同源 ⇒ 布局分叉)。
- DeclarationGenerator.py:_get_type_str 支持 `外类.内类` → `%"{sha}.外类_内类"`;
  _generate_class_decl 递归产出嵌套类型的完整声明(否则跨模块只拿到 opaque,
  指针可用但字段偏移全失效)。
- Phase1Generator.py / Phase2Translator.py:跨模块注册表按扁平名登记嵌套类。
  Phase2Translator 原先用 ast.walk 把嵌套类按**短名**登记(占住平坦命名空间、
  与定义端不同源),改为递归扁平名。

实测(TPC 侧):嵌套类名字登记 {A_B, A_C, A_C_D};`x: A.B` → CTypeInfo(A_B);
声明端 `%"cafe.A" = type { i32, %"cafe.A_B" }` + `%"cafe.A_B" = type { i32 }`
+ 多层 `%"cafe.A_C_D" = type { i32 }`。

已知缺口(下一步):TransPyV 侧跨模块走 .vpi,VpiReader 只登记顶层类 ⇒ 跨模块引用
嵌套类型仍需在 VpiReader 侧补登记(同模块路径已通)。
2026-10-01 23:29:54 +08:00
TermiNexus 85d68e5913 fix(type): 支持内建裸名函数指针构造子 callable[[...], R]
TransPyV 侧 TypeGenResolve._IsCallableSubscriptValue 已把 t.Callable[...] 与内建裸名
callable[...] / Callable[...] 视为逐点等价,TPC 侧只有模块限定形态能识别:

- TypeAnnotationResolver._from_node_subscript 的 Callable 分支要求 IsTModule(parts[0]),
  裸名落进泛型特化兜底未命中 → 空 CTypeInfo;改为裸名同判并共用同一构造体。
- DeclarationGenerator._get_type_str 的 Subscript 分支缺 callable 判定,落到末尾
  兜底 'i32';补判返回 'i8*'(与 Attribute 分支的 t.Callable 一致)。

现场:Repl.vp:307 ReplFragFn: callable[[rawptr], int] 被声明成 i32 全局,
Repl.vp:2727 ReplFragFn = fp_addr(i8*)触发「指针隐式转整数已禁止」。
2026-10-01 21:53:43 +08:00
TermiNexus b18d57fa38 perf(全仓库/正则): 字面量正则全部改模块级预编译常量(15 文件 / 115 个调用点)
背景(prof 基线 PROF/20260930_224857,主进程 433.69s):正则这一族合计 ≈45s ——
`re.match`(未预编译入口)被调 1970 万次 / 自身 10.70s、它内部 `Pattern.match` 占 8.06s,
`re._compile`(缓存查找)1975 万次 / 7.19s,`re._make`(真正编译)274 万次 / 7.62s
(说明 re 的 512 条缓存已被打穿,每 7 次调用就有 1 次重新编译)。
每次 `re.match(字面量, s)` 都要做"模式串哈希 → 缓存查找";预编译后这层全省掉。

改动:把 15 个文件里 97 处"字面量当模式"的 `re.match/search/sub/subn/fullmatch/
findall/finditer/split(...)` 提升为模块级 `_RE_*: re.Pattern[str] = re.compile(...)`,
共 115 个调用点(含同字面量跨处共用)。模式串与 flags 一字未改(flags 从调用处
搬进 re.compile,含原先以**位置参数**传入的 flags)。4 处拼接型动态模式按设计不动
(FuncGen 2 处、HandlesImports 2 处)。

核验(不靠肉眼):写了 AST 指纹对拍脚本,对每个文件取 HEAD 版与新工作区版,把
"旧 re.<m>(字面量, 其余实参, 关键字) + flags" 与 "新 _RE_X.<m>(实参, 关键字) +
常量 (模式, flags)" 做多重集比对 —— 15 个文件、115 个调用点全部逐一等价(0 失败),
另查无重名常量、无遗留字面量调用、GetDiagnostics 全空。
对拍过程中查出一处子代理抄写错误:`_RE_GLOBAL_DSOLOCAL_MULTILINE` 丢了行首锚 `^`
(原文注释明确"使用 ^ + MULTILINE 避免匹配字符串常量内容中的 define/declare"),已修正。

同轮经查证后**未做改动**的两项(避免把假热点当真事修):
- VLogger 的 `re.sub` 6.43s:profile 当时的 VLogger 版本里根本没有 `import re`
  (`git show 3658ab06:lib/core/VLogger.py` 已确认),属 C 帧错挂,不做。
- tokenize 274 万次:那是 `_generate_tokens_from_c_tokenizer` 的 **token 产出次数**
  (≈350 个整文件的词法量),SymbolUtils 的 4 个 tokenize 调用点 nc 仅数百,且已有
  `_EXPAND_CACHE` 去重;再加一层 token 缓存无收益,不做。
2026-09-30 23:47:36 +08:00
TermiNexus c2f53852ee fix(Handles/PythonParser/DeclarationGenerator): 补齐 3 处"调用了不存在成员"的死路径 + 1 处被 hasattr 掩盖的静默降级
类别:a(编译器缺陷)

现场:翻译 TransPyV/App/lib/core/Gen/Call/CallGenLeafKit.vp 时终止编译
  RuntimeError: 翻译 ... 失败: 'ClassHandle' object has no attribute '_PreRegisterClassMembers'
  (FuncGen.py:965 有调用,方法全仓无定义)

按要求做了全仓静态扫描(ast:属性访问 vs 全仓属性定义;symtable:未定义全局名),共修 4 处:

1) HandlesClassDef.ClassHandle._PreRegisterClassMembers(缺失 → 实现)
   调用点:FuncGen._get_member_offset 的"struct body 已存在、class_members[类名] 为空"分支
   —— 该类的成员表在本次翻译里从未被收集,而按名定位字段槽位必须有表。
   实现与既有两处成员收集段同源(CollectAnnAssignMember → 追加 (名, 类型)),但**只做收集**:
     · 不展平继承前缀(调用方随后经 _member_base → EnsureClassMembersFlattened 补齐);
     · 不调用 _generate_structs(body 已存在,重入 set_body 会把残缺布局永久固化);
     · 只追加尚无同名的条目(幂等,重复命中不会把表撑长)。
   跳过 __provides__/__requires__/__require_must__(非布局槽位),并登记字段限定符。

2) HandlesExprAttr.ExprAttrHandle._load_bitfield_member(缺失 → 实现)
   读路径 7 处调用(位域分支)全部指向不存在的方法 ⇒ 任何位域字段读取都会 AttributeError。
   实现与 HandlesAssign._store_bitfield_member 严格对称:位域类 body 只有一个 storage 槽
   (elements[0]),字段位置由 class_member_bitoffsets/bitfields/signeds 表达,
   读取 = `(storage >> 位偏移) & ((1<<位宽)-1)`,有符号字段再做符号扩展;
   缺位偏移 / 位宽 ≤ 0 / struct 未具化 / storage 非整数一律 fail-fast(不返回 i32 兜底)。

3) PythonParserMixin 的 __set_default__ 分支(幽灵调用 → 明确报未支持)
   原调用 self._handle_set_default_in_parse(...) 全仓无定义。核实:该注解在 TransPyC/lib 内
   无任何消费端(只有 t.py 的定义与 StubGen/Converter 的"剥离该调用保留类型"),
   includes 全仓亦无源使用 ⇒ 不静默丢弃源码语义,改为 NotImplementedError 明确报"未支持"。

4) DeclarationGenerator._llvm_type_size_str 的数组分支(静默降级 → 修好)
   原写作 `self._ARR_TYPE_RE`(少一个 A)并以 hasattr 守卫 —— 该属性全仓从未定义 ⇒ 守卫恒假
   ⇒ 数组字段一律落到"未知类型 → 8",与 docstring 声明的"_EmitREnumLlvm 尺寸口径对齐"不符。
   改用本类已定义的 _ARRAY_TYPE_RE,并去掉守卫(属性再丢失应当响亮失败)。

核验:compileall 全 lib 通过;属性扫描剩余 26 条全为仓外对象(logging / vast AST /
llvmlite Value·Instruction·IRBuilder / 内置 Exception.args / __class__ / __dict__);
symtable 未定义全局名仅 __file__(运行时内置)。未新增/放宽任何 fail-fast。
2026-09-30 18:23:25 +08:00
TermiNexus de89fda73d fix(HandlesClassDef/DeclarationGenerator): 未声明字段不再静默兜底 i32,推不出类型即 fail-fast
类别:a 编译器缺陷(静默兜底推断)+ 隐患预防。

判据(为什么必须去掉 i32 兜底):成员类型是 struct 布局的唯一来源,静默把"没声明/
推不出"的字段当成 i32 会把错误推到下游——值域不匹配时表现为与真因无关的报文
(同族既有现场:`free_lists: uint64*` 被当成 i32 后,`self.free_lists = base`(i8*) 报
"指针隐式转整数已禁止")。项目约定:类型信息缺失立即终止(与同函数 `self.X: T` 分支
HandlesClassDef.py:1356-1386 已有 fail-fast 同口径)。

改动 1(定义端布局,权威侧)HandlesClassDef._scan_node_for_self_assign 的 Assign 分支:
  删除 `MemberType = ir.IntType(32)` 默认值,改为显式 `MemberType = None` + 白名单定型;
  推不出即 compile_error(含 文件:行:列、源码行、取值原文、建议写法,行号按 _line_offset
  还原)+ sys.exit(1)。
  采纳形态(逐条写进注释,必须与 stub 侧一致):
    整型/布尔字面量→i32;浮点字面量→double;字符串字面量→i8*;
    值为本方法带注解形参→该形参类型;白名单调用 float()/double()→double、char()→i8、
    int()/long()/short()→i32、`x.len()`→i32;其余(None 字面量/BinOp/任意调用…)→终止。

改动 2(stub 声明侧)DeclarationGenerator._CollectOwnMemberTypes 的 Assign 分支:
  删除 `InferredType = 'i32'` 默认值,改白名单 + 推不出即 raise `[FATAL] …拒绝静默写成
  i32`;同时纠正两处与定义端不一致的映射:浮点字面量 'float'(f32) → 'double'(f64),
  布尔字面量 'i8' → 'i32'(定义端 bool 走 int 分支),否则 stub 与定义端槽宽/类型分叉。

预检(确认不打断既有构建):用 TPC 自家解析器扫全工作区 .vp(678 类;口径 =
类体 AnnAssign + 任意位置 `self.X: T` + 祖先传递声明),"未声明字段 + 首次裸赋值"
实例数 = 0(曾疑似的 4 例 `self.Next = None` 均为继承字段:G4Node/Value 继承
GSListNode 已声明 Next)。

冒烟(合成样例,跑完删除):
  A `self.flag = None`(未声明、None 无类型信息)⇒ SystemExit(1) + 明确报文;
  B `self.n = 5`(可定型)⇒ 正常翻译;C `flag: int` 已声明后赋 None ⇒ 正常翻译。

已知残留(本次未动,已在代码注释里写明,避免下次盲修):stub 侧方法体内裸
`self.X = ...` 仍被 seen_member_names 过滤(该集合只含本类自有声明、不含继承字段);
若放行,继承字段(如 G4Node.Next)会被当成自有字段重复加槽 → 反而制造布局分叉。
要放行必须先在该处补"祖先字段名"判定。
2026-09-30 10:58:23 +08:00
TermiNexus 5d1620505e fix(decl): 声明端看穿「装饰器标记 + 裸类引用」联合,修 t.CExtern|X|t.CPtr 多外包一层指针
根因:vpi 记录的模块级全局是 `_mbuddy: t.CExtern | memhub.MemBuddy | t.CPtr` 形态,_get_type_str 把该联合展开为 %"sha1.MemBuddy"*(标记 t.CExtern 展开为空串,已被 BinOp 分支丢弃),但外层 | t.CPtr 走 _is_bare_class_ref_annotation 时对 ast.BinOp 一律 return False ⇒ 未吸收"裸类引用自身即指针"那一层 ⇒ 声明端 %X** 与定义端 %X* 差一层。

后果:Phase1 生成的 .stub.ll 声明 @_mbuddy = external global %X**,消费模块按下声明取值得到 %X**,赋给 %X* 字段(VLogger.vp:105 self.__mbuddy__ = _mbuddy)即报"指针隐式转换已禁止(层数不同)"。

修法:BinOp 分支内若恰一侧展开为空/void(纯装饰器标记 CExtern/CExport/State/CStatic...)则按另一侧递归判定,对齐 TPV TypeGenResolve.vp:2596 第 3 条语义「ActualType | DecoratorMarker → ActualType」(TPV 无此问题,故只改 TPC)。

探针验证:t.CExtern|X|t.CPtr / X|None|t.CPtr / t.State|X|t.CPtr → %X*(修正);X|t.CPtr、rawptr[X]|t.CPtr → %X**、bytes|t.CPtr → i8**、int|t.CPtr → i32*(均不变)。注意 .stub.ll 有全局缓存,需 --clear-cache 重编生效。
2026-09-28 16:35:53 +08:00
TermiNexus 35de6321f6 refactor(return): 移除 @c.CReturn 多返回值处理器,只保留 -> tuple[ty1, ty2, ...],遇到 CReturn 一律报错
DeclarationGenerator:tuple[...] 分支逐字保留(仅 CReturnTypes 机械改名 MultiRetTypes),装饰器分支改为 SyntaxError,报文含函数名与“请改用 -> tuple[ty1, ty2, ...]”提示

HandlesAssign(a, b = f() 解包路径):删除装饰器收集分支并改为报错;tuple[...] 恢复与逐个解包逻辑逐字不变

HandlesFunctions:新增 _CRETURN_REMOVED_HINT 与 _RejectCReturnDecorator,在函数定义入口(_GetFunctionSignatureLlvm / _EmitFunctionLlvm)fail-fast——即使只有装饰器、没有 -> 注解,也不会让返回类型静默退化成 i32

HandlesImports:外部函数声明处同样报错,并删除下游已失效的 CReturnTypes 参数拼接死代码

HandlesReturn / HandlesFor / BaseTranslator:CurrentCReturnTypes 等机械改名(读写端一致,无行为变化)

includes/c.py:保留 CReturn 名字作墓碑(删掉会让 @c.CReturn 变成未知属性、可能被静默忽略),docstring 写明已移除并指路 -> tuple[...];README 措辞同步
2026-09-28 13:57:04 +08:00
TermiNexus c83fc752c6 fix(sizeof,parse): 尺寸链去静默兜底,解析报错可定位,补 C 解析器缺口
StructGen: _get_struct_size/_get_align 去 opaque→8/ptr_size、未知→4 兜底并补 VectorType;LiteralStructType.fields→.elements(llvmlite 无 fields,必然 AttributeError)

HandlesClassDef: union 载荷尺寸经不存在的 ir.DataLayout 静默退化成 8 字节;HandlesExprCall/ExprBuiltin: sizeof 各静默 0 分支改 fail-fast,数组元素 sizeof 统一走 _get_struct_size

HandlesFor: nonlocal struct/array 堆分配不再退化成 malloc(8)

vast/vast_c: 补一元 * / & 解析,装饰器后 extern/export 分派修复,C 侧报错带 token 与行号;StubGen.Converter: 宏展开丢尾随空行修 .pyi 缩进非法

其余为 rawptr 迁移 / fail-fast 口径等历史改动一并入库
2026-09-26 19:27:22 +08:00
TermiNexus 2cc816ac13 修复了一些错误 2026-09-18 20:00:59 +08:00
TermiNexus 8d950f5d43 fix(declgen): 联合中 t.CPtr[T] 下标段按 Ptr^N 叠加,与 LLVMTypeMapper 口径对齐
_get_type_str 的 BinOp 段原先在右段非 i8* 时落到 星号在左值则直接返回左值 的启发式,左值已是指针(BYTEPTR=>i8*)时会吞掉右段层数(BYTEPTR | t.CPtr[t.CPtr] 得 i8*,Mapper 得 i8***,同份 stub 自相矛盾)

新增 t.CPtr[T] 分支(两侧对称,置于该启发式之前),复用文件内既有 _ptr_level_of 取层数并按定义侧 TypeGenResolve 口径改为纯外包 N 层(去掉原 struct 吸收半截语义);LLVM 聚合左值显式排除。A/B 实测 135 个 .pyi 输出逐字节相同,现有语料零影响
2026-09-16 07:11:23 +08:00
TermiNexus 45e78ad107 基线重置,修复了一些 bug 2026-09-07 14:46:02 +08:00
TermiNexus 2f0d52e736 fix(gentype): list[t.CPtr] 特化与 list[对象] elem_size 根本修复
两处根因:
1. list[t.CPtr] 报 Undefined method 'append':
   - _resolve_generic_slice_type 对 t.CPtr 返回裸名 'CPtr',type_map['T']='CPtr'
     替换进模板(item: CPtr)后 CPtr 不在顶层作用域 → append 声明注册失败
   - 改保留带前缀 't.CPtr'(可解析)
   - 查找端(SymbolUtils.FindStructNameInAnnotation)与声明端
     (DeclarationGenerator)的 CPtr 统一规范化为 'ptr',与特化端
     _mangle_generic_class_name 一致(list[CPtr]/list[i8*] vs list[ptr])
   - _specialize_generic_class 的 cptr_params/class_type_names 判定改 tn_bare
2. list[对象] elem_size=0(get(0)==get(1) 同槽根因):
   - T.__sizeof__() 特化后为 'X | t.CPtr'(BinOp 联合),_HandleSizeofLlvm
     对 BinOp 落到 else 返回 0 → list.__elem_size__=0 → 元素全写同槽
   - 改含 t.CPtr 的联合类型返回 8(指针大小)
2026-08-19 22:44:15 +08:00
TermiNexus 7c6a497111 fix(DeclarationGenerator): 按自有字段展平时补齐祖先 vtable 指针
_FlattenInheritedDecl 递归只取类自有字段,而原 _get_inherited_members 返回完整 struct 天然含 vtable。改造后 Module(AST CVTable) 等子类 struct 缺 vtable 指针 → 字段错位 → 编译报 'cannot store i8* to %AST**'(写 vtable 到 parent 槽位)。新增 _ShouldEmitOwnVtablePtr 判定,递归各祖先类时在自有字段前补齐 vtable。
2026-08-18 13:19:51 +08:00
TermiNexus 81ad712475 fix(Handles): 多继承字段展平按继承源去重,消除菱形重复
Generator 同时继承 ClassGenMixin/ClassGenEnum/ClassGenGeneric/ClassGenVTable/ClassGenDef/ClassGenBase,而前 5 个都继承 ClassGenBase → ClassGenBase 41 字段被重复展平 6 次(struct 707 元素),class_members 索引与 struct 布局错位 → 跨 Mixin 方法 this_adjust 失效 → is_exception_name 读错位内存 strcmp 越界(ASAN heap-buffer-overflow)。

修复:HandlesClassDef 与 DeclarationGenerator 的多继承展平改为递归按继承源去重(每类只展平一次,只取自有字段;同名字段如 TempDir 跨非继承 Mixin 仍各自保留,避免 2026-08-10 历史去重缺陷回归)。
2026-08-18 13:13:25 +08:00
TermiNexus 6fc9e19e24 feat(vast): 新增自研 Viper/Python 语法解析器取代标准库 ast
TPC 侧取缔对 Python 标准库 ast 模块的依赖,改用 lib/vast 包:
- Nodes: 与 CPython 3.12 ast 完全同构的 131 个节点类(含抽象基类继承)
- Tokenizer: 词法分析(缩进/字符串/f-string/数字/运算符/软关键字)
- ExprParser: 表达式递归下降解析(优先级/lambda/推导式/f-string/切片)
- Parser: 语句解析(def/class/if/for/try/with/match/import/注解)
- Utils/Unparser: walk/dump/unparse/copy_location/literal_eval 等辅助
- 软关键字 fn/fun/func/function 并入解析器, 废除 ExpandSoftKeywords 预处理
- lib/_bootstrap 将 lib 目录加入 sys.path, import vast as ast 零修改替换
- 52 个文件 import ast 替换为 import vast as ast; 94 文件差分测试 0 失败
2026-08-17 09:36:38 +08:00
TermiNexus ca7c2120b8 修正了种子编译器的错误 2026-07-22 21:55:36 +08:00
TermiNexus 135aa05485 尝试进行 Qt 测试,增加了 AI 人机调试工具 _console,以及 TransPyV 进行修正 2026-07-21 14:41:22 +08:00
TermiNexus 4e66207ba1 重置上传,新增了多个标准库,开始 TransPyV 自举实验 2026-07-19 11:38:15 +08:00
t 796222a300 snapshot before regression test 2026-07-18 19:25:40 +08:00