TermiNexus
|
f19d25782f
|
refactor(tpc): 退役 t/c 模块并将定宽类型升级为内建
删除 lib/includes/t.py、c.py,类型模型迁入 lib/core/TypeSystem.py;移除 IsTModule/_T_MODULE_NAMES 等名称判据,语法糖与内部标记统一为裸名;builtins 的 sizet/intN/uintN/fast/least/uchar/short/long 等改为编译器内建短名。
|
2026-10-18 13:00:58 +08:00 |
|
TermiNexus
|
8d27747c7c
|
支持 tls 关键字,全面准备清退 t, c
|
2026-10-17 23:39:41 +08:00 |
|
TermiNexus
|
2b4679073e
|
维护基线
|
2026-10-17 23:27:00 +08:00 |
|
TermiNexus
|
b51faef1cb
|
fix(tpc): 带注解重声明冲突不再静默丢 store,改为 fail-fast 报错
原有变量分支整段包在 try/except Exception 里,隐式窄化抛出的 FailFastError 被吞成一条 strict 警告 ⇒ alloca 已建、store 整条丢失 ⇒ 之后 load 读到未初始化栈槽(运行期随机崩溃,且无任何编译期提示)。现场:ViperC 由 TPC 引导时 Converter.vp 'di: sizet = ai - (an - dn)'(di 已由 for 循环绑定为 int/i32)→ 生成的 viperc.exe 在 list[AST*].get 处 ASan 越界读(READ 0x1296f00c1808)。现改为捕获后重抛带变量名/两侧类型的清晰错误。
|
2026-10-14 21:12:56 +08:00 |
|
TermiNexus
|
5f1d2c3300
|
fix(tpc): 显式强转加宽用 sext、窄化用 trunc,不再被隐式窄化禁令拦下
上一轮把显式强转也统一走 _coerce_value 后,显式窄化(如 ViperC 里 LONG(BUF_B),Windows LLP64 下 sizeof(long)==4,即 sizet/u64 -> int32)被当成隐式窄化而触发 FailFastError,导致 TPC 重编 ViperC 中断。'隐式窄化禁止' 只约束隐式路径,显式转换必须允许 trunc;同时加宽保持 sext 以免 int64(int32(-1)) 变成 4294967295。Test/IntWidthTest 新增 Test 7 覆盖该形态(12/12 PASS)。
|
2026-10-14 20:57:47 +08:00 |
|
TermiNexus
|
6b87a78239
|
fix(tpc): 全局注解赋值的一元负号常量按位宽还原带符号真值
_eval_global_const 对负常量直接用无符号读回值取负,负数被物化成 2 的位宽次方减绝对值,例如 -196608 变成 4294770688。改为先按常量自身位宽还原带符号真值再取负,最后按目标类型发射。
与 aaf9330b 同族,覆盖全局路径。
|
2026-10-14 20:49:52 +08:00 |
|
TermiNexus
|
aaf9330b3b
|
fix(tpc): 负数常量与负值整型加宽改为保符号,sext 与常量折叠,不再零扩展
根因:多处手写 zext 做整型加宽,把有符号为负的常量当无符号处理。涉及 HandlesAnnAssign 局部标量初始化两处、HandlesExprCall 的 typedef 与 builtins 强转两处。
一元负号对常量无条件发运行期 neg,常量 -1 变成 neg i32 指令后再被零扩展成 4294967295。
_eval_global_const 用无符号读回值取负,-196608 被物化成 4294770688 即 0x00000000FFFD0000。
现场:b 为 int64 等于 -196608 后,b 右移 1 呈逻辑右移假象,负数右移循环不收敛,见 IntWidthTest Test 5 与 Test 6。
改法:统一收敛到 _coerce_value,加宽用 sext,窄化按其规则 fail-fast;一元负号对常量直接折叠为有符号常量;_eval_global_const 先按位宽还原带符号真值。
另修右移符号性:去掉 emit_binary_op 里按 self._last_var_name 的残留变量名重判,调用方改按 _check_node_unsigned 判定。
验收:Test/IntWidthTest 10 项全 PASS,此前 TPC 侧 5 项通过 2 项失败。
|
2026-10-14 20:49:35 +08:00 |
|
TermiNexus
|
55a6856c4e
|
fix(tpc): >> 符号性只按左操作数判定,去掉“残留变量名”误判(负数右移发成 lshr)
- 现场:`b: int64 = -196608; b >> 1` 发成 lshr ⇒ 负数变大正数;而同样注解的 `c: int64 = 0 - 196608; c >> 1` 却正确 ⇒ 与 RHS/位置相关(IntWidthTest Test 5/6)
- 根因:emit_binary_op 在 i32/i64 分支又用 self._last_var_name 重判符号性,而它只是“最近见过的变量名”,可能是上一条表达式残留的别的(无符号)变量 ⇒ 误判无符号
- 改动:① ExprGen.emit_binary_op 删除 i32/i64 的 _last_var_name 分支(符号性只信调用方;i8/i16 仍按宽度定无符号);② HandlesExprOps 的 `>>` 改用 _check_node_unsigned(Node.left),覆盖 Name 之外的形态
- 验收:Test/IntWidthTest(Test 5/6),目标 TPC 侧 9/9 PASS
|
2026-10-14 20:18:26 +08:00 |
|
TermiNexus
|
23b47053d9
|
chore: 同步 TransPyV→ViperC 改名、new 表达式支持与定宽字面量/窄化适配
|
2026-10-12 20:59:39 +08:00 |
|
TermiNexus
|
15f77da9d3
|
chore: 改名同步 TransPyV -> ViperC(源码/配置内的纯替换)
|
2026-10-12 15:06:48 +08:00 |
|
TermiNexus
|
f6447ad594
|
chore: 改名同步 TransPyV -> ViperC(.gitignore/文档/脚本)
|
2026-10-12 15:02:19 +08:00 |
|
TermiNexus
|
ddf40e02c5
|
feat(deref): 解引用写入 *p = v 采用 DerefAs 安全语义(方案1)
当 v 是指针且 pointee(p) != typeof(v)(原会因'指针<->非基本类型不匹配'fail-fast)时,把指针 p bitcast 成 typeof(v)* 再按值存 v,即 *(T*(p)) = v(DerefAs 期望写法;旧 DerefAs 的 *(intptr_t*(p))=(intptr_t)v 是错实现)。标量宽度等其余情形维持 pointee(p) 语义不变
|
2026-10-11 12:22:23 +08:00 |
|
TermiNexus
|
3122793139
|
fix(define): _try_resolve_nested_cdefine 复用 _make_define_constant,消除模块属性 CDefine 的位宽误判
模块属性访问(win32.win32file.GENERIC_READ)走的是 _try_resolve_nested_cdefine,其内部三处常量物化仍用 val > 0x7FFFFFFF 判 i64,绕过 _make_define_constant 的按值推断;导致 0x80000000 等无符号 32 位 define 变 i64、与 32 位使用点组合时报「64→32 隐式窄化」。改为委托 _make_define_constant(带声明类型按声明位宽,否则按值推断)
|
2026-10-11 11:51:31 +08:00 |
|
TermiNexus
|
7a061d4d49
|
fix(define): CDefine 常量位宽按值推断(含无符号 32 位高半区)
_make_define_constant 原用 abs(val) > 2^31-1 判定,把 [2^31, 2^32-1] 的无符号位模式(如 GENERIC_READ=0x80000000、SHARED 掩码)误判为 i64,导致 X | DEFINE 结果为 i64、赋回 32 位使用点时触发「64→32 隐式窄化」。改为按值推断:落进 [-2^31, 2^32-1] 即 i32,与 TPV 的 define_min_width/ExprGenCdef 同口径
|
2026-10-11 11:46:33 +08:00 |
|
TermiNexus
|
815a6245a5
|
fix(narrow): HandlesAnnAssign._StoreWithCoerce 补注解式整数窄化 fail-fast
此前该路径对整数窄化静默 trunc,导致 x: <32位> = <64位> 注解声明绕过规则;现与 MemoryOps._coerce_value 同口径:豁免 i1 归一化与落进目标位宽的编译期常量,其余抛 FailFastError
|
2026-10-11 09:51:03 +08:00 |
|
TermiNexus
|
3b16334f5d
|
feat(types): 禁止隐式窄化(整数 高→低)——_coerce_value 与 pointee 判据同步
与 TransPyV 同口径:_coerce_value 的 int→int 窄化分支改为 fail-fast(隐式窄化禁止),仅豁免 ① 目标 i1 真值归一化 ② 编译期常量且值落进目标位宽;_ScalarConvertLossless 的 int↔int 改为 Dst.width>=Src.width。
|
2026-10-10 21:57:25 +08:00 |
|
TermiNexus
|
4f9c234ea8
|
fix(cdef): external 声明不再遮蔽同名 CDefine 常量;补 t 类名别名解析
两处:① 现场证据(_shared_sym_includes.pickle)显示 all_dc 已含 STD_*-10/-11/-12,但模块 IR 仍 load @STD_ERROR_HANDLE —— 因为 stub 注入的 @X = external global(无初值)让 _lookup_cdefine 的遮蔽判据 AttrName in Gen.module.globals 成立,直接跳过了 CDefine 回退。新增 SymbolUtils.GlobalDeclShadowsDefine:只有**带初值**(本模块真正定义)的全局才遮蔽;仅 external 声明不算。裸名路径同判据改用同一 helper。② all_decl_types 为空的根因:DWORD 的 BaseType 为 None,底层类型存在 OriginalType 字符串 'CUInt32T'(t 类名),原解析只认内层 CTypeInfo。补:按 getattr(t, 类名) 解析该串。离线校验 DWORD|t.CDefine → (32, False)。
|
2026-10-10 21:25:33 +08:00 |
|
TermiNexus
|
d5b4e9a8b9
|
feat(cdef): define 常量带类型注册——按声明类型物化(DWORD(-11) → i32 位型)
方案 C:CDefine 不再只存无类型 int,而是把**声明整数类型**(位宽 + 符号性)一并登记,使用点按该类型物化,而不是按数值大小猜 i32/i64。链路:① SymbolUtils 新增 DefineIntSignednessOf / DefineDeclIntTypeFromAnnotation(由 T | t.CDefine 注解经符号表 typedef 链解析宽度与符号性)/ DefineDeclTypeValue(按声明类型把值归一成 (位宽, 位型值));② 同模块注册(LlvmGenerator._register_cdefine_constant)与跨模块提取(Phase2Translator._ExtractCDefineConstantsFromPyi,含 _shared_all_decl_types 的 pickle 传递)分别写 Gen._define_decl_types / translator._define_decl_types;③ 物化处(HandlesExpr 裸名两处、HandlesExprAttr._make_define_constant,及 from-import 注册)优先按声明类型出常量。这样 win32file 的 STD_*_HANDLE(DWORD(-10/-11/-12))解析为 i32 位型 0xFFFFFFF5 等,与 GetStdHandle(ULONG) 使用点一致。
|
2026-10-10 21:20:30 +08:00 |
|
TermiNexus
|
e1a0fbf9c0
|
fix(cdef): 裸类型别名构造的 CDefine(如 DWORD(-11))也能提取进 _all_define_constants
根因:ConstEvaluator 只认 t.X(...) / from t import X 的类型构造,裸 typedef 别名(DWORD(-11))既不在 _t_module 也不在 mock ctx 的 _t_type_symbols → eval_full 返回 None → _ExtractCDefineConstantsFromPyi 整条丢弃该常量。win32file.vp 的 STD_INPUT/OUTPUT/ERROR_HANDLE 是全仓唯一用别名构造写的 define,正对应链接期三个 undefined symbol(模块属性访问 wf.STD_*_HANDLE 解析落空后退化成未定义全局)。补:eval_full 失败且值为单参 Call 时,回退求值其实参(CDefine 只要常量值,位型一致)。
|
2026-10-10 20:57:26 +08:00 |
|
TermiNexus
|
936a43f543
|
fix(attr): 模块属性访问的 CDefine 查询补 _all_define_constants 回退
上一提交只补了 3 级路径 _try_resolve_nested_cdefine,而 win32file.STD_OUTPUT_HANDLE 是 2 级访问 → 走 _handle_attr_name → _lookup_cdefine,该函数只查 SymbolTable/_define_constants,没有裸名路径已有的 _all_define_constants 回退。includes 的 vpi 模块不会在 SymbolTable 里登记 IsDefine,于是解析落空 → _lookup_module_global 现造一个无定义的 @STD_OUTPUT_HANDLE → 链接期 undefined symbol。补回退(仅在无同名变量/全局时),覆盖 STD_INPUT/OUTPUT/ERROR_HANDLE。
|
2026-10-10 20:46:52 +08:00 |
|
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
|
18d753999d
|
feat(preprocess): ExpandSoftKeywords 增加 new 生命周期软关键字展开
TPV 的 new [描述符...] T(args) 出现在共享 includes(w32/fileio.vp 的 return new File(...))后会打断 TPC 引导编译(TPC 把它当普通名字 → NameError)。新增第 10 种展开 _ExpandNewExprs:把 new + [stack|heap|hlife|slife|memgr(...)] + 类型名 + ( 删成等价裸构造 T(args),TPC 无需理解生命周期语义;new = 1 / new.x / new(1) / for new in 仍作标识符,跨行不处理。
|
2026-10-10 15:24:09 +08:00 |
|
TermiNexus
|
04acaa3dd5
|
fix(funcdef): @life/@willFree 从自定义行为装饰器检测中排除
P2 的编译期生命期标注没有运行时装饰器函数;不排除会生成 wrapper 去调用不存在的 @life/@willFree,并把被装饰的 extern def(stdlib.free)变成本模块 internal 声明。与 TPV 侧 FuncGenDef 同口径。
|
2026-10-08 21:44:02 +08:00 |
|
TermiNexus
|
5a0eecc22f
|
feat(core): 栈地址逃逸检查(LifetimeError)与标量→聚合 fail-fast
- MemoryOps._IsFrameStackAddr 判据 + HandlesReturn/HandlesAssign 汇点挂钩:禁止栈地址逃逸(&local 与数组退让);新增 LifetimeError(FailFastError) 承载该错误类。 - MemoryOps._coerce_value:标量(整数/浮点)不得初始化/赋值给聚合类型,改为 FailFastError(旧行为让 _store 抛 TypeError,非 strict 下被静默吞掉,聚合未初始化)。
|
2026-10-08 12:10:24 +08:00 |
|
TermiNexus
|
75aae26881
|
fix(codegen): arg 糖支持 vprintf 式转发的 va_list,补 stdarg 模块限定分派
_HandleArgLlvm 的回退分支原先把 Gen.variables 里的形参 alloca 直接当 va_list 用,转发形态(vsnprintf(buf,size,fmt,args))因此多一层间接、读错内存;现改为先 load 出槽里的 va_list 指针(自身变参形态仍走 _direct_values 缓冲地址、不 load)。另新增 ModulePath == 'stdarg' 分派,使 stdarg.arg/va_arg/va_start/va_end 命中与裸名相同的内建(点号形式此前会落到外部调用产生未定义符号 @arg)。同时删除 ExprCallHandle 里重复且无调用者的 _HandleArgLlvm 死代码。
|
2026-10-07 20:15:32 +08:00 |
|
TermiNexus
|
9656bb161a
|
feat(codegen): 值引用自动取址收口到 _adjust_args,补齐 vtable/方法/构造等路径
查表键统一为真实发射出的函数名:FuncGen._adjust_args 开头以 func.name 调用 _apply_auto_addr,于是 direct/vtable 虚分派/构造/静态/__call__/下标赋值/c.Addr 构造/闭包/泛型/方法兜底全部自动取址,不再依赖每个调用点手写;同时删除 16 处冗余显式取址(t.CAutoPtr 的 always 模式不幂等,重复应用会多包一层指针)。登记侧:HandlesImports 把模式登记提前到 FuncName-in-Gen.functions 早退之前并按 func.name 主键写表,_TryLoadStructFromStub 改为无条件调用;HandlesFunctions 在函数对象就绪后按真实名登记,并在 _EmitFunctionForwardDeclLlvm 把逻辑名下的模式播种到 MangledName,覆盖同模块先调用后定义的场景。
|
2026-10-07 19:59:36 +08:00 |
|
TermiNexus
|
b49b5c3ba6
|
chore(parse): 已删除的 CIf 家族名字表补齐 CElif/CElse/CEndif
ExprParser 的 _REMOVED_CIF_NAMES 与 vast_c.c 的 Interesting/Removed 名字表原本只认 CIf/CIfdef/CIfndef,现补齐三件套六个拼写(含 c. 前缀形式),使 parser 阶段即可给出指向 cif/celif/celse 的 FailFast;_parser.pyd 同步重编。
|
2026-10-07 19:59:28 +08:00 |
|
TermiNexus
|
6a7b27e14f
|
chore(c): 清理已删除的 c.CIf 家族残留
c.py 删除 CElif/CElse/CEndif 三个类及其 Library_C 登记;HandlesSpecialCall 删除无人调用的 _HandleCIfLlvm;_REMOVED_CIF_CALL_MSG 的报文补齐 CElif/CElse/CEndif 六个拼写。Converter.py 去掉已无意义的注释掉守卫与 c.CIfndef/c.CEndif 时代注释,示例改为仍在用的 c.CUndef/c.CPragma;ExprParser/ConstEvaluator/HandlesIf 的注释把内部标记统一写成 c.@CIfdef 与 cif 标记。
|
2026-10-07 19:09: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
|
64f3d79b64
|
refactor(asan): ASan 运行库目录改为按 PATH 自动探测,去除本机硬编码路径
- _FindAsanRuntimeDir() 重写为 _FindAsanRuntime():遍历 PATH 定位
- clang64/bin 由前置改为追加到 PATH,避免裸名 clang++/llc/opt 被解析到 clang64 的 libc++ 版本
- 缺失 ASan 运行库时的报错文案改用占位符路径
|
2026-10-07 11:25:37 +08:00 |
|
TermiNexus
|
305242aa8a
|
feat(parse): typedef 右值纳入类型位,支持 const T / T*
X: t.CTypedef = const str / = const uint16* 现按类型位解析(含 typedef X = T 语法糖):
- 文本层:_ExpandTypeDescriptors 新增 _IsTypedefAnnotationRhs(= 右侧且语句含 CTypedef);
- 解析层:vast.Parser._TryParseAnnAssign 对 CTypedef 注解的右值走 _ParseTypeAnnotation,vast_c.c 同步并重建 _parser.pyd;
- 文本回退:TypeAnnotationResolver._NormalizeTypedefRhsText 把 const T / T* 归一为 | 联合;
- 值解析:LLVMTypeMapper.resolve_typedef_value_type 把 CConst/CVolatile 限定符标记视为无类型(_TYPEDEF_VALUE_QUALIFIERS),修 const str 被误解析成 CConst * 导致 LPCSTR 登记失败。
|
2026-10-05 20:36:29 +08:00 |
|
TermiNexus
|
59378e6a2a
|
fix(codegen): 内建标量别名双参指针包装 + 解引用赋值按 c.Load 原样拷贝
HandlesExprBuiltin: int/char/bool/float/double(v, t.CPtr) 不再被标量分支吞掉第二参,改由 TSpecialCallHandle._HandleTPtrCastLlvm 处理(等价 t.CInt(v, t.CPtr));此前退化为 ptrtoint+trunc,includes/argparse.vp get_bool 因此恒真,--version/--project 一律打印帮助。
HandlesAssign: 目标与右值同为解引用(*a = *b)时按 c.Load 语义做原样字节拷贝,抽出 CSpecialCallHandle.EmitRawCopyLlvm 复用;此前按 fptosi/trunc 转换,mlirlite ConstFloat 的位双关 *&fv_bits = *&val 会把 double 位模式截断为整数,浮点字面量全部错误。
|
2026-10-05 14:14:25 +08:00 |
|
TermiNexus
|
397bab1360
|
chore(vast_c): 同步 C 解析器二进制产物 _parser.pyd
重新编译 vast_c 源码后的 .pyd 产物(217027 -> 220943 字节)。
|
2026-10-05 09:26:26 +08:00 |
|
TermiNexus
|
9fe88831f3
|
fix(codegen): 修复模块级 str 字面量全局的初始化器缺失
模块级 `X: str = "字面量"` 有两条路径都没写出正确初始化器:
1) 新建全局分支在创建 GlobalVar 之后又查 `VarName not in Gen.module.globals`
(此时刚登记,条件恒假),于是永远走 else 分支、从不写初始化器:全局退化成
无初值的声明,第二遍再被升级成 `common global i8* null`,字符串常量沦为无人
引用的 @NAME_str。只读常量(如 BuildPipeline.MLIR_OPT_CMD)在 mlir 后端
strlen(NULL) 直接崩(ASan 0x0)。
2) 把既有 external 声明升级为本模块定义的分支一律设 common,但 LLVM 要求
common 全局的初始化器必须是零值,字符串字面量会触发 verifier 报错。
新增 _BuildStringPtrInitializer 统一产出「指向 @{Name}_str 常量数组首元素的
GEP」,两处改用它。
验证:TransPyV 自举通过;TPV 顺序回归 77/77 全通过。
|
2026-10-05 09:26:26 +08:00 |
|
TermiNexus
|
07ba7a4fe5
|
fix(codegen): 新规范迁移暴露的 4 类解析/代码生成缺陷
1) HandlesExpr._HandleConstantLlvm 引号判定用 AST lineno 直查磁盘行,漏了 _inject_auto_imports 注入行的偏移 N,取到错行;改用 _DiskLineno 还原,并把 col_offset(UTF-8 字节偏移)转字符偏移后再切片。2) Phase2Translator 新增 _DedupComdatDecls:_dso.ll 由各依赖片段拼接,每片段各带同名 comdat 声明,llc 报 redefinition of comdat;在 _AddWeakComdat 入口与两处落盘点去重。3) LLVMTypeMapper._resolve_name 补存储类/类型限定符标记分支(CExport/CExtern/CConst… 返回空串,由 _resolve_bitor 取另一侧真实类型),与 _resolve_attribute 同口径。4) 短别名(int/int64/sizet/char…)在 typedef 右值与类型转换调用处解析不到:SymbolTypeResolver._resolve_typedef_from_value 与 LLVMTypeMapper.resolve_typedef_value_type 的 ast.Name 分支补 builtins typedef / BuiltinTypeMap 兜底(BaseType 可能是 CType 实例,须取 type(x).__name__),HandlesExprCall 的类型转换求值补 _lookup_builtins_typedef 回退并保留双参数 CPtr 指针包装。验证:TransPyV 自举 includes 52/52 + App 76/76 全通过;TPV 顺序回归 77/77。
|
2026-10-05 09:25:02 +08:00 |
|
TermiNexus
|
65f0e87193
|
feat(dunder): 补齐 __bool__ 条件真值调度与反向运算符/位运算增量重载
- BaseHandle 新增 _CoerceCondToBool:if/while/and/or/not/三元条件统一归一到 i1,类实例定义了 __bool__ 时优先调度(此前仅 if 支持)
- HandlesExprOps:新增反向运算符重载(__radd__/__rsub__/... 共 12 个),左操作数无普通 dunder 时调度右操作数 __rX__
- HandlesAugAssign:_AUGOP_MAP/_AUGOP_FALLBACK 补齐位运算与移位增量(__iand__/__ior__/__ixor__/__ilshift__/__irshift__)
|
2026-10-03 00:39:53 +08:00 |
|
TermiNexus
|
2f70bd2733
|
feat(switch): switch 允许重复 case 标签(match 仍禁止)
- HandlesMatch / MatchGenMixin:值标签去重仅对 match 生效;switch 允许重复 case
标签(按书写顺序,先出现者生效);通配臂多个(default / case _)仍 fail-fast
- wiki/07-control-flow.md 同步该语义
|
2026-10-03 00:18:54 +08:00 |
|
TermiNexus
|
d6eefcbece
|
fix(switch): case 标签支持裸名(按值引用)并给出常量标签 fail-fast
- 裸名在 match 里是捕获模式(MatchAs),switch 里对齐 C 的 `case NAME:` 语义,
三端解析均归一为 MatchValue(Name);`_` 仍作通配(等价 default)
- includes/ast/parser.vp、lib/vast/Parser.py、lib/vast_c/vast_c.c 同步实现
- HandlesMatch:case 标签求值非编译期常量时 fail-fast(原先会因取 .constant 崩成
AttributeError),报文明确“case 标签必须是编译期常量”
|
2026-10-03 00:14:51 +08:00 |
|
TermiNexus
|
61df58334f
|
fix(match): 补齐 TPC 侧 MatchHandle._CaseLabelKey
- 上一轮重名 case 检测引用了 _CaseLabelKey,但该方法未真正落盘,运行期报
AttributeError: type object 'MatchHandle' has no attribute '_CaseLabelKey'
- 新增 _CaseLabelKey / _ValueLabelKey:MatchValue(Constant/Name/Attribute 链)、
MatchSingleton、MatchClass(变体名)、MatchOr(子键拼接);MatchAs/序列返回 None
|
2026-10-02 23:35:58 +08:00 |
|
TermiNexus
|
5de9cb6527
|
fix(vast_c): C 解析器补齐 match 的 is_switch,并实现 switch / fallthrough
- ParseMatch:Match 由 2 字段改为 3 字段(subject, cases, is_switch=False),
修运行期 AttributeError: 'Match' object has no attribute 'is_switch'
- 新增 ParseSwitch:switch 脱糖为 is_switch=True 的 Match,支持 case 常量/枚举
变体/多值或模式与 default:(标签非法或不支持 if 守卫时 fail-fast)
- 新增 ParseFallThrough:fallthrough 脱糖为 c.NoBreak() 标记调用
- 语句分派:match / struct 改为硬关键字,新增 switch / fallthrough 分派
|
2026-10-02 23:34:33 +08:00 |
|
TermiNexus
|
74cfaeb917
|
feat(switch): 新增 switch 语句并禁止 match 内 fallthrough
- vast/Nodes.py:Match 增加 is_switch 字段(含默认值)
- vast/Parser.py:新增 _ParseSwitch(case <常量|枚举变体> / default:,desugar 为 Match(is_switch=True));match / struct / fallthrough 改为硬关键字
- vast/Unparser.py:round-trip 忠实还原 switch 与 default:
- HandlesMatch / HandlesBody:新增 in_switch_case 门控,fallthrough 只允许出现在 switch 的 case 体内
- HandlesFor:补齐嵌套函数的 saved_loop_break/continue_targets 定义(修 NameError),并隔离 in_switch_case
- LLVMCG/BaseGen:新增 in_switch_case 状态
|
2026-10-02 23:15:42 +08:00 |
|
TermiNexus
|
8b6c36d24f
|
feat(match): 重名 case 标签 fail-fast
HandlesMatch._HandleMatchLlvm 新增前置检查(在产出任何 IR 之前):新增
_CaseLabelKey 提取 case 的 switch 标签(MatchValue 值 / MatchSingleton(None) /
MatchClass 变体名 / MatchOr 组合),标签重复或出现多个 `case _` 时报 FailFastError,
并给出重复的 case 序号与标签键(C switch 不允许重复 case 标签)。
|
2026-10-02 22:44:34 +08:00 |
|
TermiNexus
|
4353efd8ff
|
fix(flow): 嵌套/协程函数体独立 break/continue 目标,越界即 fail-fast
- HandlesFor._HandleNestedFunctionLlvm:进入嵌套函数体前清空 loop_break_targets /
loop_continue_targets,退出恢复——原实现会让嵌套函数体内的 break/continue 继承
外层函数的跳转目标(生成跨函数 br,非法 IR)
- HandlesAsyncFunctions:协程体内循环之外的 break/continue 改为 FailFastError,
不再静默不生成跳转
|
2026-10-02 22:40:04 +08:00 |
|
TermiNexus
|
34c4eeff02
|
fix(flow): 循环/match 外的 break/continue 改为 fail-fast
HandlesBody:loop_break_targets / loop_continue_targets 为空时不再静默不生成跳转,
直接 FailFastError 暴露——原实现会让 break/continue 无声无效果(不兜底原则)。
|
2026-10-02 22:35:26 +08:00 |
|
TermiNexus
|
cc0615e519
|
feat(match): fallthrough 软关键字 + case 内 break 跳出 match
- vast/Parser:语句位置识别裸 `fallthrough`(仅整条语句命中),脱糖为 c.NoBreak()
标记调用;作标识符的写法不受影响
- HandlesBody:`c.NoBreak()` 标记语句不产出 IR(语义由 HandlesMatch 消费)
- HandlesMatch:新增 _HandleMatchCaseBody(case 内 break 目标 = match 的 AfterBB,
经 loop_break_targets 压栈/出栈,不影响外层循环)与 _FallThroughTarget;
9 处 fallthrough 由"只留无终结符块"改为显式 br 下一个 case body
|
2026-10-02 22:33:26 +08:00 |
|
TermiNexus
|
9ff301d747
|
refactor(types): 移除 list[T, N] 的定长数组遗留判据,统一走 _list.vp
- SymbolUtils.IsListAnnotation 不再把双参 list[type, count] 判为栈上定长数组:
list 是 includes/_list.vp 的堆上 STL 容器泛型类,list[T] / list[T, N] 都走泛型特化
- ParseListAnnotation / ListAnnotationParseResult / ExtractListFromBinOp 相应收窄为
只处理 t.CArray / rawarray / array,并同步文档串
- HandlesAnnAssign / HandlesBase / HandlesFunctions / HandlesImports / SymbolUtils 的
注释改按 CArray 形态表述
|
2026-10-02 22:16:30 +08:00 |
|
TermiNexus
|
0efdc9e111
|
fix(expr): 整型与 None 比较统一按 == 0 / != 0 处理
- HandlesExprOps.py:is / is not / == / != 遇整型与 None 比较时直接与 0 比较,
避免把 i8 当作空指针 load;检查置于类型对齐与指针分支之前
- README.md:同步引用 wiki 第 12 章(12-compilation-system.md)
|
2026-10-02 22:07:06 +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
|
a8f6ca006d
|
feat(struct): TPC 前端支持 struct 关键字(含 C 加速解析器)
与 TransPyV/includes 侧(c27ebc1)逐点对齐:`struct X:` / `struct X(Base):` 脱糖为
`@t.NoVTable class X(t.CStruct):`,禁止 virtual/novirtual 修饰、禁止类体内 def。
- lib/vast/Parser.py:软关键字分派(语句起始 + 后随标识符;`struct = 5` 不受影响)、
_ParseStructDef(复用 _ParseClassDef 全路径 + 合成 @t.NoVTable + 追加 t.CStruct
标记基类 + 类体禁 def 校验)、_StructSyntaxError 报文、_ParseVirtualModified
显式拦截 `virtual/novirtual struct`;@deco 前缀同样支持。
- lib/vast_c/vast_c.c:同构实现(ParseStatement / ParseDecorated 分派、
ParseStructDef、ParseVirtualModified 拦截)。
- lib/vast_c/_parser.pyd:按 README §4.3 的命令重建(gcc 15.2.0)。
验证(两条路径逐一对照):bases=[t.CStruct] / [Base, t.CStruct]、
decos=[t.NoVTable];`virtual struct` 与 `struct 内 def` 均 fail-fast;
`struct = 5` 仍解析为普通赋值。
|
2026-10-01 23:07:49 +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 |
|