冻结面
这一页说的是 Loment 的冻结面。它由 0.1.3.4 Alpha 立下、0.1.4 Pre2 沿用——语言面没有破坏性变更,语法、类型规则、诊断码 E001–E021(码只增不改,E018–E021 都是 0.1.3.4 之后新增的)、单元装载与发射符号约定与 0.1.3.4 相同。冻结不等于完备,也不等于发布——它说的是改动要付代价:任何触及下面那份清单的改动,必须同时改规范、改一致性套件、两个实现同一次提交改完,再走最后那套流程。清单之外的东西随便改。
为什么现在能冻结
冻结的前提不是「功能齐全」,而是规范有唯一的执行者,而且可测量。
-
63/63 规则等价
—— 自举 checker 与参考实现在 63 条规则上判定等价(
tools/loment_rule_parity.py)。门禁是棘轮:等价数 ≥ 预算,假阳性与码漂移必须为 0。 - 负例真的被拒 —— 63 条规则负例直接喂自举驱动,全部非零退出,而且无一因信号而死。
- 语料与定点 —— 40/40 语料单元零诊断、40/40 可发射目标两个后端逐字节一致、三阶段自举定点成立。
-
错误码是单一真源
—— 口径在
tools/loment_diag.RULES(E001–E021),checker 侧能发出的全部 81 条消息模板都被它分类(解析期的消息归 E019,不在这 81 条里)。
换句话说:从这一刻起「语言是什么」由规范加一致性套件定义,参考实现不再是唯一权威——它只是套件里的一员。
冻结了什么
| 面 | 内容 | 为什么冻结 |
|---|---|---|
| 语法与类型规则 | 词法(含「多字符运算符拆成单字符 token」这一条)、解析形状、类型系统、移动与借用规则 | 它们是用户程序与一致性套件的接口 |
| 诊断口径 | 错误码 E001–E021,以及「码按修法分」的分组原则 | 用户脚本与 CI 会按码匹配;码是最稳的那层 ABI |
| 单元装载规则 | use 递归装载、依赖按先序拼进单元、去重、预置枚举的注入点(单元末尾) |
它决定同名、顺序与枚举的可见性,跨文件程序的语义靠它 |
| 发射符号约定 | 顶层名字在单元内唯一(平名字空间,不做 mangling);入口名(_start、timer_isr 这类)由内核线按名查找;内核与驱动按名解析的符号不得私有化 |
这是跨线 ABI:内核与 C 夹具按名字找入口,改名就是破坏契约 |
| 两个后端的等价性 | 同一输入下,自举 codegen 与参考实现的 IR 必须逐字节相同;三阶段定点必须成立 | 它是「两个实现」能互相验证的前提,也是回归检测的主要手段 |
| 内建函数表 | 18 个内建的名字、元数、参数与返回类型 | 名字与签名被内核线直接调用 |
| 能力域语义 | capability / guard / excluded 的判定;字面量越界在编译期就拒 | 它是信任自适应能力域的输入 |
明确不冻结
- 实现内部 —— 两份编译器的内部表布局、缓冲尺寸、遍历顺序、临时名;自举侧的 arena 分段与类型表述。只要不动上面的等价性与容量闸门,随便改。
- 工具链内部 ——
tools/*.py的函数与结构,只要对外的命令行行为和上面的判据不变。 - 文档结构 —— 手册的产物随源变化,它本来就是生成的。
- 性能 —— 现在只有护栏(自编译 ≤ 30 秒,实测基线 12.8 秒)。优化不受冻结限制:索引化符号查找这类改动,只要不改变产物字节,随便做。
已知的开放项与刻意偏离
冻结不等于完备。这些是已知的口子,写在这里是为了让后来的人和审计者不必自己撞上去。
| # | 项 | 现状 | 影响 |
|---|---|---|---|
| 1 | 三处刻意偏离 | 下标与 & 在「类型未知」时不报;match 主体未知时不报;? 只在能确定不是 Result 时报 |
自举 checker 在这三种情形下可能少报,参考实现会报。方向是保守——不假阳性 |
| 2 | 同名 let 双 alloca |
参考实现复用槽位;自举 codegen 发两条,第二条遮蔽第一条 | 同一函数里重复声明同名变量时,两个实现语义不同 |
| 3 | 驱动器没有 parser | 驱动是 lex → check → emit;解析期错误它看不见 | 自举链单独使用时,解析期错误不会被报出来,只能靠参考实现兜底 |
| 4 | aarch64 目标 | 后端支持 elf64-littleaarch64,但没有在真机或模拟器上执行过 | 只保证发射,不保证运行 |
| 5 | 自举性能 | 自编译 12.8 秒(参考实现 1.2 秒),符号查找是线性扫 | 大单元编译偏慢;不影响正确性 |
| 6 | DWARF 变量信息 | 只有语句级行表,没有变量位置信息 | 调试器能按行断点,但看不到变量值 |
| 7 | 外部审计 | 尚未由第三方复核(M100) | 冻结面内的判据都是自证的——自证不全等于正确 |
改冻结面的流程
四条,缺一不可。
- 1 · 改规范 —— 先改手册(或对应的语言章节),把新规则写成可判定的句子。涉及诊断的话,先在
tools/loment_diag.RULES里给码:码只增不改,新规则从 E020 起(E018、E019 已经占用)。 - 2 · 改一致性套件 —— 在
tools/loment_rule_parity.py的用例表里加最小负例,并把预算上调。只调低预算是放松门禁,等于隐瞒缺口——门禁会因此变红。 - 3 · 两个实现同一次提交 —— 参考实现与自举 checker 必须一起改。规则对照、40/40 逐字节一致、三阶段定点全绿,才算完成。
- 4 · 过静态门禁 —— 静态门禁里 L0 / L1 的部分全绿。若改动触及内核线按名解析的符号,得先走内核线的交接约定。
一致性套件
说「冻结面成立」,指的就是这一套全绿——它们是判据,不是建议。
python tools/loment_rule_parity.py # 63/63 等价 + 假阳性/漂移 0(棘轮预算 63) python tools/loment_p8_test.py # 16/16:40/40 零诊断 + 40/40 逐字节 + 定点 + 4 条闸门 python tools/lomentc_test.py # 参考实现 91/91 python tools/loment_tools_test.py # 15/15:诊断分类 / 内建表 / 增量缓存 python tools/loment_ir_diff.py --all # 40 个目标逐字节一致(定位工具) python tools/loment_status.py --check # 状态矩阵与里程碑文档一致
判据优先于实现:
任何一处红灯都不许「改判据让它变绿」,只许改实现,或者按上面那四步走一遍。