119 Commits
Author SHA1 Message Date
TermiNexus 65e03c823f feat(obs): reject nullable call arguments for non-nullable parameters
Compiled callees register a per-parameter nullable mask (self included for methods, specializations included); cross-module callees fall back to their vpi param annotations. A nullable binding/field argument now fails instead of silently narrowing.
2026-11-03 18:12:20 +08:00
TermiNexus 1911f70818 feat(option): reject direct dot access on nullable values
A field annotated `own T?` / `T?` (and a local declared nullable) now fails fast on `base.field`: it may be None. Use `base?.field` or check against None first. FieldEntry carries a Nullable flag (appended), populated from the annotation during struct registration and inherited by flattened parent fields; both read and write attribute paths check it.
2026-11-03 15:30:16 +08:00
TermiNexus c81ebaa7d4 feat(option): builtin Option uses the Nil variant
The lazily registered builtin template now declares Nil = 0 instead of None_.
2026-11-02 22:15:15 +08:00
TermiNexus 1f491c6dba feat(renum): generic Option[T] and Option pattern matching
- Generic renum specialization: `Option[int].Some(42)` / `Option[int].None_()`
  are intercepted before method dispatch (which would translate the
  subscript type argument as a value), specialize the renum template and
  construct the variant. `_ctor_call_agg_ty` recognizes the generic
  qualifier so construction materializes the renum value.
- Builtin Option: the generator registers `renum Option[T]` (None_ |
  Some(T)) lazily on first `Option[...]` use, with a reserved synthetic
  module id. The copy in includes/builtins.vp is skipped during Phase1
  template/variant registration so a user-defined `renum Option` (EnumTest)
  keeps precedence; constructor/annotation lookup prefers the current
  module's Option.
- Match: the renum class is derived from the concrete subject struct
  (authoritative for `Option[int]`) instead of only the annotation name.
  Both `case Option[int].Some(v)` and `case Some(v)` bind the payload;
  `None_()` works qualified or bare.

LSP: pattern captures (`case Some(v)`) are declared as variables.

Probe: builtin Option without importing builtins prints 42 for Some and
hits the None_ arm; EnumTest (user renum Option) passes; self-host
110/110; full regression set passes.
2026-11-02 22:05:09 +08:00
TermiNexus 634321a12b refactor: consolidate duplicate ViperC helpers
Merge repeated list lowering, directory scanning, SHA1-store writes, VPI lookup keys, type-parameter splitting, DefineT width normalization, and LSP helpers. Source-only change: 235 added, 793 deleted (net -558 lines).
2026-11-02 13:08:50 +08:00
TermiNexus 5b68732a94 refactor: remove dead ViperC compiler code
Drop unreachable struct/type helpers, the legacy wrapper-main and build pipeline paths, debug-only scaffolding, unused logging helpers/constants, and the no-op LSP signature map. Add the audit report for the remaining duplication and logging work.
2026-11-02 12:46:53 +08:00
TermiNexus f57a7d962c feat(gen): generic calls with explicit args and pointer-parameter inference
Three gaps kept `mod.f[T](x)` from compiling:

- get_func_name now unwraps a Subscript callee to its base name, so an
  expression statement like `f[int](x)` / `mod.f[int](x)` reaches the
  normal call path instead of failing name resolution. Generic class
  constructors and type subscripts still return None, keeping their
  dedicated paths.
- the generic-call dispatcher resolves `Attribute` bases inside the
  subscript (`temp.array2list[int]`) to the defining module's SHA1, and
  treats it as a module-qualified template lookup.
- inference understands pointer/array annotations around the type
  parameter: `_annotation_refers_type_param` walks PtrT/ArrayT wrappers
  and tuple slices, and inference peels as many pointer/array layers off
  the argument as the parameter annotation wraps around T, so
  `array2list(l, ...)` with `array: T*` and `l: []int` infers int.

Self-host: 110/110 with the new compiler building itself; GenericTest,
GenericTest3, GenericTest4, VectorGenericTest and ListTest pass.
2026-11-02 09:07:32 +08:00
TermiNexus eda8e4465f refactor(codegen): one body pipeline for module functions and class methods
Module-level functions and class methods each carried their own copy of "resolve the
return type", "create the parameter allocas" and "emit the implicit epilogue". The copies
drifted: an unannotated method was still typed i32 by the class-method body path while its
declaration said void, so the epilogue emitted `llvm.return 0 : i32` inside a void function
and the MLIR verifier rejected it ("'llvm.return' op expected no operands", Scheduler._yield).

- FuncGenBase.resolve_func_ret_ty: the single return-type policy (annotation -> storage
  marker -> __init__/__new__ hooks -> unannotated = procedure void -> fail-fast). Used by
  the forward-declare pass, the body pass, class methods and generic specializations
- FuncGenBase.param_llvm_ty: the single parameter mapping (CVoid skipped, bare class ->
  Ptr(struct), ArrayT -> element pointer), used by every signature and alloca site
- FuncGenBase.emit_func_epilogue: the single implicit-return implementation (procedure ->
  ret void, unreachable merge, fail-fast for an annotated fall-through), shared by module
  functions, methods and nested functions
- FuncGenBase.translate_func_body: the shared body pipeline (scope entry, self/parameter
  storage, *args va_list, try/except out-params, pre-scan, capture preparation, slife,
  statements, epilogue, state restore). ClassGenVTable._translate_method now only handles
  method naming, vtable/overload registration and add_param
- the same policy reaches cross-module and generic declares: unannotated vpi functions and
  methods declare void, generic specialization declares use the shared resolver, and the
  list.append call sites emit a void call
- method parameters now carry the const / volatile / pointee-volatile / pure markers that
  the module-level path always had
- FuncGenMixin: the two dry-run helpers that return ints are annotated, as the language
  now requires (an unannotated def is a procedure)

Verified: 41 Test projects pass (MethodProcTest, CrossModuleSigTest, RawPtrParamTest,
AstTest, ListTest, OopInheritTest, ...), ViperC self-hosts with the new compiler, and the
6 tests that still fail reproduce identically with the previous compiler.
2026-10-29 19:37:55 +08:00
TermiNexus 19f9c53a5f fix(codegen): zero-extend unsigned 16-bit widening in every coercion path
A uint16 value that is widened to int/uint32/uint64 must be zero-extended
(movzwl), and an int16 value must be sign-extended (movswl). coerce_to_type
picks the direction from the source AST node's declared signedness, which
requires the translator; several call sites omitted it and therefore fell
back to sext, so a big-endian uint16 such as 0xDCBC became 0xFFFF...DCBC
(numGlyphs 56508 read as -9028 and every glyph range collapsed to zero).

- pass trans at the assignment, annotated-assignment, augmented-assignment,
  global-array initializer, index, element-store, constructor-argument,
  conditional-expression and return coercion sites
- printf argument promotion now receives the argument expression and trans,
  so uint16/uint8 promote with zext like any other widening
- print selects the format token and extension from the source signedness
  (%u/%llu + zext for unsigned, %d/%lld + sext for signed) instead of a
  hardcoded %d + sext for 8/16-bit values
2026-10-28 23:06:17 +08:00
TermiNexus 7cbe4e93dc fix(codegen): widen calls by the declared return signedness 2026-10-27 19:51:46 +08:00
TermiNexus 645e193729 feat(gen): []T 值类型按初始化器推断定长数组
声明位置(全局/局部/字段)的 []T 依据初始化器推断为 [N x T]:字符串按 strlen+1、列表按元素个数;函数参数仍保持 T* ABI。全局与字段的 .vpi 类型写入推断长度,跨模块声明与定义布局一致;字段默认值支持字符串/列表数组的逐字节/逐元素初始化。V_VPC_VERSION 改为定长数组,使 .PRVERSN 内联真实版本号。
2026-10-27 13:59:28 +08:00
TermiNexus 782b4d63ff feat(build): 增加 --build-self 与 copyself
- 新增 copyself:延迟后删除目标并复制文件/目录
- ViperC 新增 --build-self:自举到 __vpcbuild_2__ 后由 copyself 替换 __vpcbuild__
- 同步当前 ViperC 工作区已有的 Gen/Diag/Stub 改动
- .gitignore 忽略 __vpcbuild_* 与 _sha1_map.txt
2026-10-26 02:09:45 +08:00
TermiNexus a20bc312ab docs(classgen): 声明前置注释示例 FileW -> File
FileW 已在 includes/win32/fileio.vp 中删除,示例改用 File.__init__(同样在 self.seek 之前定义)。
2026-10-25 12:07:59 +08:00
TermiNexus af445058b4 fix(overload): _translate_method 补传 ClassDef,修复 undefined name cd
方法重载需要在类体内统计同名 def 才能决定是否追加 _v{hash},但 _translate_method 之前没有 ClassDef 参数。改为从 _translate_oop_methods 把 cd 传下去(两处调用点:sig_only 预扫描与正式翻译),未传时 _method_slot_name 退回原方法名,保持非重载路径行为不变。
2026-10-24 19:34:22 +08:00
TermiNexus faea680116 feat(overload): 类方法与虚函数重载(符号/函数表键/vtable 槽名一致)
类内同名方法 >=2 时,方法短名追加 _v{参数签名hash}(跳过 self,static 不跳):LLVM 符号 {sha1}.Class.m_v{hash}、函数表键 Class.m_v{hash}、vtable 槽名 m_v{hash} 三者一致。vtable 收集改为先用 _method_slot_name 建槽名表:继承槽的覆盖判定按槽名比较(只有签名相同的同名方法才算覆盖),本类槽按槽名去重(重载各占一槽);__init__/__before_init__/__new__ 仍按原始名排除。实例方法调用与 Class.m(obj,...) 两条路径在候选 >=2 时用同一套决议(prefix 模式 + param_base=1),并把 method_name 换成带后缀的短名,使虚调用取到正确槽位。注:本提交含此前未提交的既有改动。
2026-10-24 17:02:33 +08:00
TermiNexus 82a735c367 refactor(viperc): 完全删除 T1 | T2 类型组合,语法糖改用标记下标 2026-10-18 13:39:38 +08:00
TermiNexus 42b094a575 refactor(viperc): 退役 t/c 模块标记,内建类型改由编译器直接识别 2026-10-18 12:56:57 +08:00
TermiNexus 3242560d02 支持 tls 关键字,全面准备清退 t, c 2026-10-17 23:40:06 +08:00
TermiNexus 6e17716a69 revert(vtable): 恢复按类实际规模动态分配
bf0bbcc 已经把固定上限去掉:收集前按「各父类 VTableMethodCount 之和 + 本类 FunctionDef 数 + 1」一次性分配三张表,越界检查保留为 InternalCompilerError。eff88dd 在并行开发中误把这段覆盖回固定 1024,这里恢复 bf0bbcc 的实现——无任意上限,且符合「能动态就动态」的既定规则。
2026-10-17 19:22:50 +08:00
TermiNexus eff88dd591 fix(vtable): VTBL_METHOD_MAX 32 -> 1024
memhub.MemBuddy 这类工具类的虚方法数远超 32,上一轮加的 fail-fast 直接把它拦下了。三张槽位表由 PermPool 分配(各 8*VTBL_METHOD_MAX),1024 时每类 24 KiB,可接受。
2026-10-17 19:21:44 +08:00
TermiNexus bf0bbcc89b fix(vtable): 虚方法表按类实际规模动态分配,去掉 32 上限
MemBuddy 继承 MemManager 后虚方法约 60+ 个,VTBL_METHOD_MAX=32 会触发 fail-fast(此前静默只收前 32 个,之后的调用点找不到槽位、退化成静态直调)。现在收集前先算容量上界:各父类已收集的 VTableMethodCount 之和 + 本类 FunctionDef 数量 + 1,三个 PermPool 数组按此一次性分配;两处越界检查保留为 InternalCompilerError(理论不可达)。删除 VTBL_METHOD_MAX。注:本次提交同时带上了该文件既有的 t.CPtr → rawptr 迁移与 _generate_default_init 删除等未提交改动。
2026-10-17 19:20:03 +08:00
TermiNexus 3e1e1fc1b3 fix(gen): 消除 ViperC 侧 P0 级静默截断
match:case 数超过 MAX_MATCH_CASES 时 fail-fast(原先 break 会静默少分支,need_case 检查也发现不了)。vtable:初始化串按真实方法表动态分配,_vtable_strcat 溢出改 fatal;VTBL_METHOD_MAX 超限不再 break(原先子类 override 静默失效)。符号名:coro_pool_/__tls_init_done_/__decor_rec_/闭包 fn_ptr 的定义与引用改为按实际长度分配,消除 96 vs 128、64 vs 128 的不对称。Stub:_PyiEmit 溢出改 VLogger.error(半截 .vpi 会被当完整文件解析);VpiReader 参数段/返回注解缓存槽放不下时 fail-fast,不再丢段导致形参注解错位。Includes:文件超过 1MiB 拒绝哈希(SHA1 冲突会让两个模块共用缓存);add_file_entry 失败不再被忽略。f-string:格式串按字面量/转换符实际长度分配,字面量与 format_spec 溢出 fail-fast。
2026-10-17 18:46:18 +08:00
TermiNexus dc24970af2 fix(gen): 修 __before_init__ 字段默认值写入的参数次序(build_store 缺 builder/file 顺序颠倒),修编译期参数缺失报错 2026-10-13 21:46:20 +08:00
TermiNexus ea54d5685d feat(gen): virtual(HasVTable)类豁免「无 def => struct」规则,必须合成 __before_init__/__init__ 且必发 vtable;非泛型构造路径按符号存在性判定调用 2026-10-13 21:29:24 +08:00
TermiNexus 99a021ad67 fix(gen): 类合成默认构造——有方法但无显式 __init__ 的类合成空 __init__(补 undefined 符号);完全无 def 的类按 struct 处理,不合成 __init__/__before_init__ 2026-10-13 20:59:41 +08:00
TermiNexus 5d15d01e21 feat(gen): 支持 t.BigEndian / t.LittleEndian 字节序描述符(注解识别 X|marker 并把字节序登记到 FieldEntry.ByteOrder,暂不生成 bswap) 2026-10-13 12:17:02 +08:00
TermiNexus d206abf3e1 chore: 全仓同步 w32→win32 模块改名与 range(int(...)) 显式收窄适配 2026-10-12 20:59:11 +08:00
TermiNexus ae12ae8581 Revert "feat(gen): 裸类形参按值物化(值语义),调用方 ABI 不变"
This reverts commit 87914b0a51.
2026-10-12 19:56:02 +08:00
TermiNexus 87914b0a51 feat(gen): 裸类形参按值物化(值语义),调用方 ABI 不变 2026-10-12 18:25:04 +08:00
TermiNexus 4e46a25ab1 fix(gen): define 位宽/整数提升/移位/AugAssign 规则收敛,修 va_list 与 traceback 卡死
- define 位宽:cdefine_decl_bits 单一裁决(注解 → 右侧强转 → 值最小可存宽度),定义方与 VpiReader 两处跨模块注册共用;lookup_cdefine_bits 取最后一条非零记录;存储即截断;使用侧改按声明位宽;通用求值器加编译期除零/移位越界 fail-fast
- 消除对无符号强转加宽方向的依赖:define_min_width 改 (value>>32)==0,截断改左移+算术右移,修 TPC/TPV 判定不一致导致 0x80000000 误判 64 位
- 整数提升:算术/移位、比较、一元 +/-/~ 提升到 i32;位运算保持同宽不提升
- AugAssign:y 有效宽度须 <= x、禁 y 显式有符号而 x 无符号;移位计数静态范围检查
- 函数入口复位 va_list 状态与 willFree 失效槽表(FuncGenDef/FuncGenMixin/VarGenMixin 等)
- BuildPipeline:traceback 逐行扫描改 span 判定,去掉对全文 strlen 的 O(n^2)
2026-10-12 12:37:48 +08:00
TermiNexus 985983391b fix(narrow): ClassGenBase 方法元数据指针声明 int* 而非 t.CPtr
flags_ptr/flags_ptr2 被显式 (int*)(...) 赋值但声明为 t.CPtr,下标元素被判为 i8,与 i*4 的 32 位步长及位标志语义不符(且 >127 的值会读出符号错误);声明改为 int*
2026-10-11 10:04:19 +08:00
TermiNexus 3b9deb08d8 fix(narrow): ClassGenEnum RenumClassVariantCounts 元素读取改用 int(...)
n_first_v(1029) 与 vcount(1010/1055) 承接 sizet* 元素,原先 64->32 隐式窄化;改用显式 int(...) 保持原截断语义
2026-10-11 10:00:05 +08:00
TermiNexus 7468b007f7 fix(narrow): ClassGenEnum pos_max 加宽为 sizet
pos_max 承接 variant_field_sizes 的 sizet 元素,仅与 sizet 比较并流入 sizet();原 int 触发 64->32 隐式窄化
2026-10-11 09:54:18 +08:00
TermiNexus 3c0d3d13b5 fix(narrow): 清理注解式整数窄化(Converter/TypeGenCType/CallGenLeafKit/ClassGenEnum)
CDefine 查询返回 int64 处按下游用法定型:回传给 int 的用显式 int(...),流入 int64 目标的加宽为 int64;sizet 数组元素赋给 int 的用 int(...)
2026-10-11 09:51:08 +08:00
TermiNexus 82ad5da7c7 fix(narrow): len() 结果赋给 int 的形参/默认值计数改用显式 int(...)
FuncGenDef 的 fd_param_count/fd_default_count/tfd_param_count/tfd_default_count 与 ClassGenVTable 的 md_param_count/md_default_count 原本直接接收 len()(sizet),触发隐式窄化;改 int(len(...)) 保持原有截断语义
2026-10-11 09:34:43 +08:00
TermiNexus d0ffb094c2 feat(lifetime): §13 NLL——默认生命期的 new heap 证明帧内封闭时降级为帧对象
StructGenMixin: 新增 NllFrameConfined 及遍历器(_NllStmts/_NllExprUnsafe/_NllMentions/_NllInSet/_NllAdd/_NllCalleeEscMask)+
has_param_escapes(区分"有记录=权威不逃逸"与"无记录=判不定");别名集只增不减故单遍即可,if/while/for 全走、
不进嵌套 def/class;认不出的语句"不提及别名才放行";取址/实参位逃逸/return/长命目标一律按外泄拒绝。

CallGenCtor._new_is_nll_demotable:只降级"堆且未显式指定生命期"的 new;AssignGenMixin.propagate_life
判据成立则 life=FRAME(于是调用点同命裁剪放过 g(l,h)),_slife_note_assign 接 target_name、判据成立按托管堆
对象登记 → 复用 slife 的作用域出口释放(手动 free/del 也会被既有检查挡住)。

三条函数体翻译入口记录 NllCurFunc(谓词要遍历当前函数体),与 traceback 推帧同一处。

注:谓词按 §13.2 保守优先,判不定一律维持 HEAP;本提交未编译验证。
2026-10-09 20:49:21 +08:00
TermiNexus 6769cf0335 refactor(diag): 编译期 traceback 抽为 Diag 模块,单条诊断携带完整调用链
- 新增 Diag.DiagEntry 与 new_entry/begin/set_current/add_frame/emit/free_entry,方向由 DIAG_DIR_* 决定

- TypeGenErr.fatal_error 改走 DiagEntry:填调用链 + 当前帧,emit(UP) 后 free + finish

- 顶层函数体/嵌套函数体/方法体三处翻译入口各 push/pop 一帧(def 位置),报错可回溯所在函数
2026-10-09 18:45:06 +08:00
TermiNexus 2178970ff7 feat(gen): slife 释放前调度析构 __del__,并禁止手动 del(§3.6 落地)
- 释放统一入口 _SlifeEmitGuardedFree 改为「先析构、再 free」;析构名定案 __del__(对齐 TPC LLVMCG/MemoryOps._emit_local_heap_frees 的释放路径;del obj 那条语句走的仍是 __delete__)。

- 查表沿 MRO / 跨模块 stub 回退(复用 ExprGenOps._resolve_dunder_by_class);类未定义 __del__ 时**不加任何分支**,常见路径零开销。

- 析构用条件分支而不是 select:未拥有的路径必须完全不进析构体(析构体里会解引用 self,传 null 进去会踩空);块标签走 trans._label_counter,避免同函数内重名。

- §2.4 判据5 扩展:对 slife 对象手动 del obj → LifetimeError(否则析构跑两次)。hlife 路径不受影响。

- 为把 trans 传进析构查找,_SlifeEmitFrees / _SlifeEmitGuardedFree / _SlifeDropOwned 加 trans 形参,9 处调用点同步。
2026-10-08 20:34:11 +08:00
TermiNexus 78b2052445 feat(gen): 接线 M3 owned slife 的 RAII 出口释放(函数级 scope guard)
- 所有权影子标志(i8,登记时入口块置 0)+ free(select(影子!=0, load 槽, null)) 保护式释放:赋值在分支/循环里而未执行 → free(NULL);槽里写入外来指针或别名 → 清影子,绝不 free 外来指针;循环反复 new → 赋值前覆盖释放上一轮,不累积。

- 三条函数体转译路径(FuncGenDef 主路径 / FuncGenMixin 嵌套函数提升为 __closure_* / ClassGenVTable 方法体)各自抬升与弹回登记区间;修两处漏 reset 导致内层出口 free 外层对象再被外层 free 一次 = double free(Windows STATUS_HEAP_CORRUPTION)。出口按槽去重做兜底。

- free 由模块前言统一声明(Translator.vp,紧挨 malloc);释放点只查表 + fail-fast,绝不吐指向未声明符号的 llvm.call。

- 赋值处记账:new heap slife → 登记 + 覆盖释放 + 影子置 1;其它 RHS(new stack / hlife / 别名 / 外来指针 / None)→ 已登记则交还所有权。手动 free slife 对象 → LifetimeError。
2026-10-08 20:03:54 +08:00
TermiNexus 2fb648d68a feat(lang): 新增 cif/celif/celse 条件编译与值引用注解 &T/&temp T,assert 改译 testcheck.check
cif 三件套:StmtGenCifMixin 负责常量求值(含 defined(模块宏) 的 Attribute 形式),链式错配与含运行时变量一律 fail-fast;删掉 c.CIf 家族。值引用:TypeGenResolve 让 CRef/CTempRef 与 t.CPtr 走同一解析路径(&void 折叠为 i8*,删除 t.CNeedPtr),CallGenBase 在调用点按形参模式自动取址(ref 只接受左值,右值 fail-fast;temp 物化临时栈),跨模块经 VpiReader/StubMergerBuild 传递模式。assert:StmtGenMixin 合成 testcheck.check(cond, None, msg),Translator 检测到 assert 时自动注入 testcheck 导入(带去重与防环),深递归守卫改用 stdio.printf + stdlib.exit(Translator 无 Gen 成员)。
2026-10-07 19:03:16 +08:00
TermiNexus edca6c3760 chore(detsite): 类型文本 4096 缓冲补插桩
19 处 TypePrint(..., 4096, ...) 对应的 pool.alloc(4096) 全部改用 alloc_tagged
(AssignGenMixin/ClassGenVTable/FuncGenDef/ExprGenBase/ExprGenCdef/CallGenLeafKit/
TypeGenCType/TypeGenResolve/CallGenCBuiltin/ExprGenOps),tag 33..51 见 memhub.vp。
detection==0 时 alloc_tagged 直接转发,无布局与性能变化。
2026-10-07 15:16:52 +08:00
TermiNexus 848dc0ab38 fix(compiler): 跨模块调用补全 int→ptr 转换与别名默认参数;类型文本缓冲 512→4096
1) CallGenMixin.vp(跨模块 extern 实参提升):指针目标形参改为无条件走 coerce_to_type——原守卫按整数位宽比较,而指针类型的 bits 恒为 0,整段提升被跳过,致 VirtualAlloc(0,...) 以 i32 传入指针形参、mlir-opt 报 operand type mismatch(ViperAIChat 失败)。

2) CallGenMixin.vp(默认参数限定键):改用 StructGen._resolve_module_sha1 解析模块 SHA——原只精确匹配模块名,import x as y 这类别名取不到真实 SHA,默认值表落空、跨模块调用实参数目不符(ViperRequestsTest 失败)。

3) 11 个文件的 TypePrint 类型文本缓冲 512→4096(分配与传入 size 成对修改):48 字段类(如 MNIST 的 Net)的 MLIR 结构体类型文本超过 512 被截断并 fail-fast。
2026-10-07 08:48:09 +08:00
TermiNexus 7a9bc5ae75 chore(messages): TransPyV 运行时中文字符串英文化
把 TransPyV/App 下 57 个文件的运行时中文字符串(编译器报错/告警/日志、CLI 帮助与横幅、REPL 提示、Phase1/Phase2 流程日志、Codegen 各 Mixin 的类型与调用报错、Stub/Vpi 诊断等)共 1091 行译为英文。

口径:只改字符串字面量内部文字,行数零变化(+1092/-1092);printf 格式符与转义序列多重集合校验不变(_strcheck 异常 0);译文不引入撇号以免干扰单引号字面量解析。验证:三重重编 SUCCESS(136.20s)+ 全量 77/77 顺序回归通过 + VET 编译 SUCCESS / --search-paths 7 条 exit 0;新产物 help/日志输出已为英文。
2026-10-07 00:03:58 +08:00
TermiNexus cd55a7e214 refactor: rawptr[T] -> T*(R14)+ 修 REnum 前向占位未就地填充
R14:rawptr[X] -> X*(56 文件 / 834 行改动);保留 6 处 rawptr[t.CPtr](存纯裸指针的规范例外)。 修复:class X(t.REnum) 的变体字段写成自引用 X* 时,字段解析在变体扫描期经 ensure_forward_class 建了一个 opaque 前向占位;末尾 register_struct 按 Ty 指针去重会再建第二个同名 entry,而 find_struct 取首个(占位,0 字段)→ X.__sizeof__() == 0,报「已注册但大小为 0(字段链表未填充)」。改为注册前若命中同模块前向占位则就地填充(与 ensure_forward_class 文档口径一致)。TPC 无此问题,属 TPV 侧缺口。 验证:自举三重重编 SUCCESS;全量 77/77 顺序回归通过(修复前卡在 LLvmLiteTest)。
2026-10-05 17:38:28 +08:00
TermiNexus aeb4e8e54c refactor(gen): R12 收尾同步——12 处计数 while 循环改 for range
与 includes 同步:<= 条件转 range(expr + 1),并放宽初始化行的紧贴要求(同块内最近一次写即为初始化即可)。其余保守守卫不变。

验证:bootstrap 三重重编 SUCCESS;全量 77/77 顺序回归通过。
2026-10-05 16:36:36 +08:00
TermiNexus 0f4aeeceff docs(tpv): R11 注释与 docstring 英文化并压缩到 2 行内
按 wiki/新规范:注释只讲作用、不掺杂历史原因、避免超长、尽可能英文(含三引号 __doc__)。全文 79 个 .vp:# 注释 16269 行(中文 13808)与 docstring(中文 1381 处)全部改英文;超 2 行的注释块(2093)与 docstring(397)全部压到 2 行。运行时可见文本未动(fatal_error/VLogger 的中文报错文案、stdio.printf 的横幅格式串)。校验:屏蔽注释与三引号后逐行比对各文件代码骨架,0 漂移。验证:自举重建 153.48s 通过(跨模块内联完成);TPV 顺序回归 77/77 全通过。
2026-10-05 13:38:22 +08:00
TermiNexus f2ef1bb240 refactor(tpv): 新语法 R10 括号内隐式续行并一行(1140 处 / 67 文件) 2026-10-05 07:14:14 +08:00
TermiNexus 4a685d478f refactor(tpv): 新语法 R10 单语句块并一行(7722 处 if/for/while 单语句体) 2026-10-05 03:10:55 +08:00
TermiNexus 30a3da4cd4 refactor(tpv): 新语法 R10(反斜杠续行合并)+ 回退 R5(语义不等价)
- 反斜杠续行合并为单行(304 处),呼应"尽可能不换行"。
- 回退 c.DerefAs(p, v) → *p = v 两处(StructGenMixin):原写法是 bitcast 后
  store 指针位,新写法按 pointee 值类型赋值,类型不符(i8* → List 值),
  语义不等价,保留 c.DerefAs。

种子自举通过。
2026-10-04 22:56:27 +08:00
TermiNexus 185a2196ca refactor(tpv): 迁移新语法 R1/R2/R7/R8/R3/R4/R5(指针 T*、短别名、define、&/*、__asm__)
按 wiki/新规范:
- T | t.CPtr → T*(无 | 标准)
- t.CInt/t.CUInt64T/t.CChar/t.CDouble 等 → int/uint64/char/double 等短别名
- X: t.CDefine = Y → define X = Y
- c.Asm → __asm__,c.AsmInp/c.AsmOut → asminp/asmout,t.ASM_DESCR. → ASM_DESCR.
- c.Addr(x) → &x,c.Deref(p) → *p,c.DerefAs(p, v) → *p = v

种子自举通过(96s)。
2026-10-04 22:49:01 +08:00