豫言 / 技术规范

本篇描述 4cdeca1 的实现。版本与适用边界见基线说明

豫言独立实现技术规范

本规范供未参与豫言开发的实现者从零编写编译器,并与既有豫言对象文件及运行时互操作。它固定描述仓库提交 4cdeca11600fed16338793a494b6eecaae94485a,称为“本基线”;不是对未来版本的推测。阅读顺序如下,两种语言版本以相同章节和规则编号对应。

  1. 词法与语法:字符扫描、语法、结合与语法糖。
  2. 类型与模块:名称、类型判断、隐参求解、构造器及文件身份。
  3. 执行与编译:求值、异常、擦除、闭包、递归、控制流及代码生成。
  4. 原生二进制接口:值、堆、栈、调用、链接符号、GC 与 C 互操作。
  5. 网页汇编接口:WASI 与 WasmGC 的不同契约。
  6. 基线与实现依据:固定基线、源码索引、ABI 阅读示例与文档审阅准则。
  7. 规约关系表运行时接口表:完整数据附表。

总〇:兼容的含义

ABI 兼容指:同一目标平台、同一模块身份和定义序号下,新实现产生的函数、值与对象文件可供旧实现使用,旧实现产物也可供新实现使用;跨边界调用、返回、异常和回收后仍然正确。只打印相同结果或只通过自举,不足以证明这一点。

本规范划定三种检验,不能混为一谈:

层次 必须相同 不要求相同
源语言兼容 接受/拒绝边界、求值轨迹、结果、可观察失败类别 内部 AST 名称、诊断堆栈全文、编译速度
对象接口兼容 数据布局、调用协议、公开符号、定义身份、GC 根与存储约定 本地临时名、寄存器分配、优化算法、私有续延编号
逐字节产物复现 相同工具链、编译选项、路径、编号、优化及调试信息下的整个产物 不能由 ABI 兼容自动推出

本文件集的交付物是技术文档,目标是让陌生实现者不依赖原作者解释,即可理解语言算法及二进制接口。实现者可以采用不同前端、不同 IR 和不同优化器,但不可自行“修正”本基线的可观察兼容怪异处。

总一:约束用语

“必须”表示本基线兼容所需;“可”表示实现策略自由;“禁止”表示不能将其当作可互操作输入。“兼容缺陷”表示实现存在冲突或危险边界,需保留其事实并限定适用范围,不表示推荐语言设计。

没有稳定定义的行为,不以猜测填补。特别是原生 C 有符号溢出、越界、不安全转换、失效续延以及 ABI 不匹配调用,不在可承诺的稳定行为集合内。试图对这些行为实现“所有机器均完全相同”没有可实现的契约。

总二:实现边界

一个独立编译器至少具备:UTF-8 源文输入;模块解析与有序定义表;语法分析;静态检查;运行时值生成;程序及模块入口;C 外部调用;闭包与递归;异常/提前返回;GC 安全点;与平台工具链链接。

标准库是豫言源码库,可由新编译器编译;C 系统原语可链接基线运行时。此模式无需重写文件系统、套接字等整个操作系统封装,也不依赖原编译器参与代码生成。若还要替换运行时,则须实现接口表对应的实际 C 签名与行为,并通过原编译器产物调用新运行时的验收。

源码入口、模块接口与对象文件不是同一种输入:只拿到一个旧 .o,不足以恢复类型别名、隐参和构造器身份。独立前端必须同时获得依赖源码,或从本规范规定的接口记录重建等价的检查后接口。运行时标签不能替代编译期类型。

总三:最小数据模型

实现可以使用下列概念记录,字段顺序仅在明确写为 ABI 时才有二进制约束。

  • 类型:内建;刚性类型变量;名义构造器;构造器应用;连续显式箭头;连续隐式全称类型;元组类型。
  • 表达式:常量;局部引用;文件定义引用;显/隐函数;调用头及有序实参;局部绑定;递归;条件;顺序;元组及投影;模式匹配;类型标注;外调。
  • 文件接口项:原始文件身份、定义名、有序索引、类别、已检查类型、透明类型体或名义构造器身份;重导出保留来源。
  • 无类型中间值:单位、整数、小数、字节串、闭包、元组、构造器实例、引用;静态类型与隐参不占调用槽位。
  • 原生控制状态:当前豫言帧、分配指针、返回函数及续延编号、存活值、异常处理器。

局部绑定可用唯一 ID 或一基 de Bruijn 索引。所有替换须避免捕获;不能按名称做无作用域的文本替换。稳定符号由模块身份和定义索引决定,私有局部 ID 不得泄入公共接口。

总四:基线纪律

改变源路径、声明列表、构造器次序或目标平台,都可能改变 ABI。交付时附源提交、编译器可执行文件 SHA-256、运行时 SHA-256、目标三元组、工具链版本、优化选项、依赖解析结果及输出摘要。

文档维护时逐项核对源码、双语条件和接口表。已明确的实现事实写成具体规则;实现自相矛盾或尚无稳定语义的边界,明确标出其适用范围,不替语言作未经依据的承诺。