From c3b20281c143caaed8c05c2ac43817d18bf5a5b9 Mon Sep 17 00:00:00 2001 From: Manus AI Date: Wed, 26 Aug 2026 09:47:36 +0000 Subject: [PATCH] docs: Integrate Fer, FON, Next Web, and reference modules --- content/fer/attributes/zh-hans.md | 78 ++++++++ content/fer/backends/zh-hans.md | 63 +++++++ content/fer/expressions/zh-hans.md | 171 ++++++++++++++++++ content/fer/formatting/zh-hans.md | 103 +++++++++++ content/fer/functions/zh-hans.md | 108 +++++++++++ content/fer/memory-and-performance/zh-hans.md | 56 ++++++ content/fer/migration/zh-hans.md | 67 +++++++ content/fer/modules/zh-hans.md | 110 +++++++++++ content/fer/overview/zh-hans.md | 85 +++++++++ content/fer/strings/zh-hans.md | 75 ++++++++ content/fer/structure.json | 22 +++ content/fer/syntax/zh-hans.md | 118 ++++++++++++ content/fer/types/zh-hans.md | 147 +++++++++++++++ content/fon/frl/zh-hans.md | 82 +++++++++ content/fon/overview/zh-hans.md | 85 +++++++++ content/fon/schemes/zh-hans.md | 99 ++++++++++ content/fon/serialization/zh-hans.md | 89 +++++++++ content/fon/structure.json | 15 ++ content/fon/syntax/zh-hans.md | 133 ++++++++++++++ content/index.en.json | 20 ++ content/index.zh-hans.json | 20 ++ content/next-web/overview/zh-hans.md | 98 ++++++++++ content/next-web/structure.json | 11 ++ content/reference/markdown/zh-hans.md | 52 ++++++ content/reference/overview/zh-hans.md | 40 ++++ content/reference/structure-json/zh-hans.md | 83 +++++++++ content/reference/structure.json | 14 ++ content/reference/workflow/zh-hans.md | 54 ++++++ 28 files changed, 2098 insertions(+) create mode 100644 content/fer/attributes/zh-hans.md create mode 100644 content/fer/backends/zh-hans.md create mode 100644 content/fer/expressions/zh-hans.md create mode 100644 content/fer/formatting/zh-hans.md create mode 100644 content/fer/functions/zh-hans.md create mode 100644 content/fer/memory-and-performance/zh-hans.md create mode 100644 content/fer/migration/zh-hans.md create mode 100644 content/fer/modules/zh-hans.md create mode 100644 content/fer/overview/zh-hans.md create mode 100644 content/fer/strings/zh-hans.md create mode 100644 content/fer/structure.json create mode 100644 content/fer/syntax/zh-hans.md create mode 100644 content/fer/types/zh-hans.md create mode 100644 content/fon/frl/zh-hans.md create mode 100644 content/fon/overview/zh-hans.md create mode 100644 content/fon/schemes/zh-hans.md create mode 100644 content/fon/serialization/zh-hans.md create mode 100644 content/fon/structure.json create mode 100644 content/fon/syntax/zh-hans.md create mode 100644 content/next-web/overview/zh-hans.md create mode 100644 content/next-web/structure.json create mode 100644 content/reference/markdown/zh-hans.md create mode 100644 content/reference/overview/zh-hans.md create mode 100644 content/reference/structure-json/zh-hans.md create mode 100644 content/reference/structure.json create mode 100644 content/reference/workflow/zh-hans.md diff --git a/content/fer/attributes/zh-hans.md b/content/fer/attributes/zh-hans.md new file mode 100644 index 0000000..6d3a6a7 --- /dev/null +++ b/content/fer/attributes/zh-hans.md @@ -0,0 +1,78 @@ +# Fer 注解 + + +## 语法 + +使用 `#[...]` 定义注解: + +```fer +#[test] +check-username = () -> bool { + true +} +``` + +注解必须位于被注解项之前,并且每个注解占一行。注解参数使用 Fer/FON 的值语法: + +```fer +#[workgroup-size = [8, 8, 1]] +compute-main = (global-id: Vec3) -> void { + // GPU compute body +} +``` + +注解内容必须在编译期可解析。未知注解必须被报告为错误,除非模块通过显式扩展注册表声明它是可忽略的文档注解。 + +## 字段注解 + +注解可以附着到结构体字段: + +```fer +VertexInput: struct { + #[location = 0, interpolate = flat] + position: Vec3 + + #[location = 1] + color: Vec3 +} +``` + +字段注解的键和值必须由所属后端或类型 scheme 定义。GPU location、插值模式和布局规则不能通过字符串拼接或运行时反射替代。 + +## 测试注解 + +`#[test]` 标记测试函数: + +```fer +#[test] +check-username = () -> bool { + true +} +``` + +测试函数必须是无参数、可重复执行且具有明确结果的函数;测试失败时,工具应提供源文件、测试名和断言上下文。测试是否允许返回 `void`、如何隔离区域内存和如何表达参数化测试,仍待定。 + +## 后端注解 + +后端注解可以描述调用约定、GPU 工作组、外部接口或布局。后端注解必须只在目标后端启用时生效,并且在不支持该后端时给出明确诊断: + +```fer +#[workgroup-size = [8, 8, 1]] +compute-main = (global-id: Vec3) -> void { + // 待定:WebGPU 后端的主体语义 +} +``` + +实现不得把后端注解当作普通运行时数据;注解不应引入隐式全局状态。 + +## 注解参数 + +注解参数必须是布尔值、数值、字符串、数组、对象或已注册枚举值。动态表达式、函数调用、文件读取和网络请求不得出现在注解参数中。 + +注解键采用 kebab-case。相同注解是否可以重复、重复注解如何合并,以及未知参数是否允许,必须由注解定义明确声明;默认情况下重复注解和未知参数都是错误。 + +## 相关主题 + +- [类型系统](../types/zh-hans.md) +- [实现后端](../backends/zh-hans.md) +- [格式化规范](../formatting/zh-hans.md) diff --git a/content/fer/backends/zh-hans.md b/content/fer/backends/zh-hans.md new file mode 100644 index 0000000..20c644f --- /dev/null +++ b/content/fer/backends/zh-hans.md @@ -0,0 +1,63 @@ +# Fer 实现后端 + + +## 后端分层 + +编译器或运行时应按以下层次组织: + +| 层 | 责任 | +| --- | --- | +| 解析器 | 把 UTF-8 源文本转换为语法树,并报告词法/语法错误 | +| 语义分析 | 解析模块、名称、类型、scheme、Must-use 和迁移规则 | +| 中间表示 | 表达与目标架构无关的值、区域、调用和控制语义 | +| 后端 | 将中间表示映射到解释器、LLVM、JVM、BEAM 或 WebGPU | +| 运行时 | 提供 I/O、区域分配、并发、诊断和平台能力 | + +后端不得跳过语义分析来“尽力运行”不完整的 Fer 程序。开发模式可以提供恢复性诊断,但生产构建必须只接受通过规范检查的程序。 + +## 解释器 + +Fer Interpreter 用于快速反馈、工具链和 native fer browser 场景。解释器必须遵循与 AOT 相同的名称解析、类型检查、块返回值、Must-use、字符串视图和区域生命周期规则。解释器不得因为动态环境而引入隐式变量或动态字段。 + +## LLVM AOT + +LLVM 后端可以使用 LLVM IR 进行 AOT 编译。LLVM 的整数、指针、调用约定和布局只是实现细节;Fer 类型的可观察范围由 Fer 规范决定。任何平台特有的布局都必须通过 ABI 注解或后端接口显式声明。 + +AOT 构建必须记录目标三元组、优化级别、规范版本和运行时版本。相同输入和构建配置应当能够复现可审查的产物元信息。 + +## JVM 与 BEAM 字节码 + +JVM 和 BEAM 后端可以把 Fer 映射到各自的字节码与运行时,但不得将 Fer 变量、垃圾回收或异常模型直接暴露为语言语义。若目标运行时提供自动内存管理,适配层仍需维持 Fer 的区域和所有权边界,或明确标注尚未满足的实验性能力。 + +## WebGPU + +WebGPU 相关函数、结构体布局和工作组参数通过注解表达: + +```fer +#[workgroup-size = [8, 8, 1]] +compute-main = (global-id: Vec3) -> void { + // 具体 GPU 语义待定 +} +``` + +GPU 后端必须检查字段 location、对齐、可传输类型、工作组大小和资源绑定。不能映射到 WebGPU 的 Fer 能力必须在编译期拒绝,而不是生成隐式 CPU 回退。 + +## 后端一致性测试 + +每个后端应运行相同的规范测试集。测试至少覆盖: + +- 整数范围、浮点边界和字符串 UTF-8 行为。 +- 模块导入、导出、UFCS 和重命名。 +- 块返回值、match 穷尽性和 Must-use。 +- 结构体默认值、枚举变体、`Option` 和精炼类型。 +- 区域生命周期、越界、错误路径和资源释放。 +- FON 解析、scheme 验证和二进制序列化边界。 + +后端差异必须归因于明确的非规范化行为,并提供失败位置和最小复现输入。 + +## 相关主题 + +- [类型系统](../types/zh-hans.md) +- [注解](../attributes/zh-hans.md) +- [内存与性能](../memory-and-performance/zh-hans.md) +- [迁移机制](../migration/zh-hans.md) diff --git a/content/fer/expressions/zh-hans.md b/content/fer/expressions/zh-hans.md new file mode 100644 index 0000000..a760e8d --- /dev/null +++ b/content/fer/expressions/zh-hans.md @@ -0,0 +1,171 @@ +# Fer 表达式 + + +## 求值模型 + +表达式产生一个值,或产生无值结果。实现可以优化求值顺序,但不得改变可观察结果、错误诊断或资源安全边界。任何具有副作用的操作都必须在其所属库的接口中明确说明。 + +一个块的值严格等于其最后一行表达式的值: + +```fer +location = { + lat = 120 + lng = 30 + { lat = lat, lng = lng } +} +``` + +如果最后一行是绑定操作,则该块不返回实质性值: + +```fer +{ + temporary = create-resource() + close-resource(temporary) +} +``` + +## Must-use 规则 + +如果块产生了 `string`、整数、结构体、枚举或其他实质性值,该值必须被绑定、作为参数传递、作为返回值返回,或显式交给一个消费函数。表达式不得悬空: + +```fer +// 合法:值被绑定 +message = format-user(user) + +// 合法:值作为参数传递 +print(format-user(user)) + +// 非法:结果被丢弃 +format-user(user) +``` + +返回 `void` 的调用可以单独成行。实现不能仅凭函数名判断调用是否有值,必须根据函数签名和类型系统应用 Must-use 规则。 + +## Condition 表达式 + +condition 表达式返回 `bool`。比较词和符号是等价写法;项目应使用格式化工具的默认形式,不得在同一代码库中人为混用两套风格。 + +| 语义 | 词法形式 | 符号形式 | 适用类型 | +| --- | --- | --- | --- | +| 小于 | `less` | `<` | number | +| 大于 | `more` | `>` | number | +| 至少 | `least` | `>=` | number | +| 至多 | `most` | `<=` | number | +| 包含 | `contains` | 无 | string | +| 相等 | `equals` | 无 | string、number 或可比较类型 | +| 成员 | `in` | 无 | array 或集合 | +| 匹配 | `matches` | 无 | string 与 regex | +| 前缀 | `starts` | 无 | string | +| 后缀 | `ends` | 无 | string | +| 逻辑非 | `not` | `!` | bool | + +**Quantifier** 组合多个 condition expression: + +| 量词语法 | 数学含义 | 对应命令式 | 业务意图 | +| :--- | :--- | :--- | :--- | +| **`all ( ... )`** | 全部为真(∀) | `AND` / `&&` | 所有条件必须全部满足 | +| **`any ( ... )`** | 至少一个为真(∃ ≥ 1) | `OR` / `\|\|` | 命中任意一个即可 | +| **`one ( ... )`** | 恰好只有一个为真(∃ = 1) | `XOR` / 异或 | 排他互斥(有且仅有一个) | +| **`none ( ... )`** | 全部为假(∃ = 0) | `NOR` / `!any` | 所有条件绝不能命中 | + +`all`、`any`、`one` 和 `none` 统称为 **Quantifier**(量词)。Quantifier 的形式为 `quantifier ( condition-expression-list )`,其中 `quantifier` 必须是这四个名称之一。内部 condition expression 无需额外加括号;Quantifier 遵循与 FON 相同的通用元素分隔规则:逗号 `,` 与换行 `\n` 均为合法分隔符,单行、多行和逗号与换行混合的分组都具有相同语义。列表中的表达式可以继续嵌套 Quantifier。`all`、`any` 和 `none` 可以在确定结果后短路;`one` 在已经确认有两个满足条件的表达式后可以短路。condition 表达式应保持纯语义,因此实现不得让短路优化改变可观察结果或资源安全边界。 + +示例: + +```fer +/* All must match: */ +can-access = all ( + user.is-logged-in + + /* At least one: */ + any ( + user.role equals .admin + user.reputation >= 100 + ) + + /* Exactly one: */ + one ( + payment.is-credit-card + payment.is-crypto + ) + + /* None allowed: */ + none ( + user.is-banned + user.is-suspended + ) +) + +is-following = any ( + user.relationship equals .follower + user.relationship equals .friend +) + +/* Single-line Quantifier: */ +cond = all (x > 10, y < 10, not (z contains `123`)) + +/* Multi-line Quantifier: */ +cond = all ( + x > 10 + y < 10 + not (z contains `123`) +) + +/* Mixed separators are also valid: */ +cond = all (a > 1, b > 2 + c < 3) + +is-text = not (comment.content matches `\\btx(|et|t|.*)\\b`) +``` + +`and`、`or` 和 `xor` 不再是 Fer 关键字;组合多个 condition expression 时,必须使用 `all`、`any`、`one` 或 `none` Quantifier。逗号 `,` 与换行 `\n` 都是合法的通用元素分隔符,Parser 必须将单行纯逗号、多行纯换行以及逗号与换行混合的 Quantifier 解析为等价的条件序列。CST 必须保留原始物理排版,以支持无损还原。 + +## Match 表达式 + +match 以一个表达式作为输入,并按分支顺序返回第一个匹配分支的值。分支使用大括号表示: + +```fer +age = 20 +category = age { + < 18 { `minor` } + > 60 { `old` } + { `adult` } +} +``` + +最后一个没有模式的分支是默认分支。没有匹配分支且没有默认分支时,编译器必须报告非穷尽匹配;不得隐式返回空值。 + +condition 结果也可以作为 match 输入: + +```fer +label = any ( + comment.content matches `regex` + comment.content contains `xxx` +) { + true { `匹配或包含` } + { `未匹配到` } +} +``` + +模式分支的结果必须具有可统一的类型,或者显式声明为共同的枚举、结构体或 `Option`。分支内部同样遵循块返回值和 Must-use 规则。 + +## 成员访问和调用 + +成员访问使用点号。若成员后面是调用括号,则它可能触发 UFCS 解析;完整规则见 [函数与调用](../functions/zh-hans.md): + +```fer +io.stdout.writer().write(bytes = `Zero cost abstraction`) +``` + +成员访问不得动态创建字段。访问未知字段、访问私有字段或把函数当作值使用但缺少显式函数类型时,必须报告编译期错误。 + +## 条件与副作用 + +condition 和 match 的判断表达式应当是纯表达式。需要执行 I/O、锁、网络或资源释放时,应调用明确命名的函数,并让其返回值遵循 Must-use 规则。实现不得把条件分支的求值改写成会额外执行副作用的形式。 + +## 相关主题 + +- [函数与调用](../functions/zh-hans.md) +- [类型系统](../types/zh-hans.md) +- [字符串](../strings/zh-hans.md) +- [Fer 语法基础](../syntax/zh-hans.md) diff --git a/content/fer/formatting/zh-hans.md b/content/fer/formatting/zh-hans.md new file mode 100644 index 0000000..3a3ad4d --- /dev/null +++ b/content/fer/formatting/zh-hans.md @@ -0,0 +1,103 @@ +# Fer 格式化规范 + + +## 基本要求 + +格式化工具必须使用空格而不是制表符,不得生成行尾空白,并且必须在文件末尾保留一个换行。默认目标行宽为 100 个字符;字符串字面量、路径注释和不可拆分的标识符可以超出该宽度,但工具不得破坏其值。 + +格式化不得改变名称、字符串、注解参数、字段顺序所表达的语义,也不得自动添加可能产生副作用的表达式。无法安全解析的文件应原样保留并报告位置,不得输出部分格式化结果覆盖源文件。 + +## 文件布局 + +文件应按以下区域排列: + +1. 顶部路径文档注释。 +2. 外部包导入。 +3. 应用根目录导入。 +4. 当前目录导入。 +5. 公共接口声明与 `exports {}`。 +6. 公共类型、常量和函数。 +7. 私有类型、常量和函数。 + +顶部路径注释可以由 `ferfmt` 根据文件路径自动补全,因此不是强制手写项: + +```fer +/// @fer/std/src/io/mod.fer +``` + +应用模块使用 `@/`: + +```fer +/// @/modules/auth/repository.fer +/// 用户仓储:负责用户记录的读取与持久化。 +``` + +路径注释必须与真实文件路径一致。移动文件后,格式化工具应更新该注释或报告不一致。 + +## 导入排序 + +导入按来源从大到小分组,并在组内按稳定字典序排序: + +```fer +{ get, post } = @fer/http +{ User } = @/modules/user/model +{ create-user } = ./repository +``` + +排序组的顺序固定为:`@scope/package`、`@/project/path`、`./local/path`。导入项在同一语句中按名称排序;重命名项按原始导出名排序。重复导入、同名冲突和未使用导入由编译器或独立检查器报告。 + +## 导出与声明排序 + +`exports {}` 位于导入之后、实现声明之前,导出项按名称排序: + +```fer +{ io } = ./io +{ fs } = ./fs + +exports { fs, io } +``` + +公共类型、常量和函数按名称排序。私有项放在公共项之后,并在各自类别内按名称排序。公共函数不得因为私有实现重命名而改变排序结果。 + +## 函数调用与参数 + +单参数调用可以保持单行;两个或更多参数必须使用具名参数。参数超过目标行宽时,每个参数单独一行,并保留尾逗号: + +```fer +create-user( + username = `fuyeor`, + email = `user@example.com`, +) +``` + +尾逗号只用于同一结构被拆成多行的场景。单行结构不应被格式化为带多余尾逗号的形式。 + +## 块与结构体 + +块使用 2 个空格缩进,结构体字段和数组元素在多行时保持同一级缩进。格式化工具必须能区分多行局部作用域和多行结构值;无法区分时报告语法错误,而不是猜测。 + +```fer +User: struct { + id: Uuid4 + nickname = `guest` +} +``` + +## 注释和文档注释 + +普通注释优先使用 `//`,文档注释使用 `///`。注释与代码之间保留一个空格;独立注释应当是完整句子,并尽量不超过 80 个字符。格式化工具不得把文档注释移动到不相关的声明上。 + +## 稳定性 + +同一版本的 `ferfmt` 对同一输入必须产生相同输出。格式化版本应写入工具诊断或锁定文件,便于在迁移和持续集成中复现差异。升级格式化器时必须提供变更说明;纯布局变更不得被伪装成语义迁移。 + +## 与迁移的关系 + +格式化器只能做语法树保持不变的变换。名称重命名、参数重排、类型替换、模块路径变更和语义修复属于 [迁移机制](../migration/zh-hans.md),必须有迁移规则和审查结果。 + +## 相关主题 + +- [语法基础](../syntax/zh-hans.md) +- [模块系统](../modules/zh-hans.md) +- [注解](../attributes/zh-hans.md) +- [迁移机制](../migration/zh-hans.md) diff --git a/content/fer/functions/zh-hans.md b/content/fer/functions/zh-hans.md new file mode 100644 index 0000000..0cff7f5 --- /dev/null +++ b/content/fer/functions/zh-hans.md @@ -0,0 +1,108 @@ +# Fer 函数与调用 + + +## 定义 + +函数使用名称绑定、参数列表和返回类型定义: + +```fer +is-valid-user = (user: User) -> bool { + user.status equals .active +} + +get-location = () -> { lat: i64, lng: i64 } { + { lat = 120, lng = 30 } +} +``` + +参数类型和返回类型是接口的一部分,不得省略。编译器可以推断函数体内部表达式的中间类型,但不能把推断结果作为公共签名的替代品。 + +返回结构体的函数应当返回满足声明结构的对象: + +```fer +location = get-location() +``` + +函数体最后一个表达式是返回值。显式的 `return` 关键字不属于当前核心语法;需要提前分支时,使用 match 表达式返回不同结果。 + +## 参数调用 + +零个或一个参数可以使用直接形式: + +```fer +health-check() +print(`Hello, Fer!`) +``` + +两个或更多参数必须使用具名参数: + +```fer +function-name(arg1 = `字符串`, arg2 = 10) +``` + +以下形式非法,因为它依赖参数位置: + +```fer +function-name(`字符串`, 10) +``` + +具名参数名称必须与函数签名匹配。参数顺序由函数定义决定;调用方书写顺序可以由格式化工具归一化,但不得用重复名称覆盖参数。 + +## 默认值 + +函数参数默认值的语法和求值时机尚未冻结。当前草案不允许通过省略参数来触发未声明的默认行为;如果一个函数需要可选输入,应使用 `Option`、带默认值的结构体或显式重载设计。 + +## 返回类型与错误 + +函数的错误是返回类型的一部分。当前草案允许使用枚举或 `Option` 表达可预期的失败: + +```fer +find-user = (id: Uuid4) -> Option { + // 返回 .some 或 .none 的规则待定 +} +``` + +实现不得把未声明的异常、隐式空值或后端特有的错误对象当作稳定函数接口。错误传播操作符尚未进入冻结规范。 + +## UFCS + +UFCS(Uniform Function Call Syntax)允许把 `a.func(args)` 解释为 `func(a, args)`。它不是动态方法分派,而是受限的静态查找: + +1. 编译器先在当前文件和显式导入的上下文中查找 `func(a, args)`。 +2. 如果没有找到,编译器只在常量 `a` 的类型最初定义模块的 `exports` 列表中查找 `func`。 +3. 找到后,调用被视为合法的普通函数调用;找不到时必须产生编译期错误。 + +```fer +writer = io.stdout.writer() +writer.write(bytes = `Hello, Fer!`) +``` + +上例等价于: + +```fer +writer = writer(io.stdout) +write(writer, bytes = `Hello, Fer!`) +``` + +UFCS 查找不得扫描全局注册表、所有依赖包或运行时对象属性。这样可以保证名称解析可重复,并防止依赖包新增函数后意外改变已有程序的含义。 + +## 函数作为值 + +函数值、闭包、异步函数和高阶函数的完整语义尚未冻结。当前实现可以提供受限能力,但公共规范不得假设函数值具有隐式捕获、可变闭包或任意动态分派能力。 + +## 调用链 + +调用链必须保持每一步的类型可验证: + +```fer +io.stdout.writer().write(bytes = `Zero cost abstraction`) +``` + +如果中间结果为 `Option`、`never` 或其他不能直接访问成员的类型,编译器必须拒绝调用链,除非显式的解构或匹配规则已经规定了转换。 + +## 相关主题 + +- [表达式](../expressions/zh-hans.md) +- [模块系统](../modules/zh-hans.md) +- [类型系统](../types/zh-hans.md) +- [迁移机制](../migration/zh-hans.md) diff --git a/content/fer/memory-and-performance/zh-hans.md b/content/fer/memory-and-performance/zh-hans.md new file mode 100644 index 0000000..8c7da5e --- /dev/null +++ b/content/fer/memory-and-performance/zh-hans.md @@ -0,0 +1,56 @@ +# Fer 内存与性能 + + +## 目标 + +Fer 的实现应优先满足以下目标:执行效率高、网络传输和包体积可控、边界条件安全、长期维护成本低。编译器可以进行优化,但优化不得改变程序可观察行为、错误处理和资源释放契约。 + +Fer 核心不以追踪式垃圾回收为默认机制。当前方向是区域内存(arena allocator):对象分配到显式区域,区域具有清晰的生命周期,并在区域结束时批量释放。 + +## 区域模型方向 + +区域模型至少需要定义以下概念: + +| 概念 | 要求 | +| --- | --- | +| 区域创建 | 必须有明确的创建点和生命周期边界 | +| 分配 | 分配结果必须记录所属区域,不能脱离区域伪装为永久值 | +| 借用 | 短期引用不得超过被引用区域的生命周期 | +| 转移 | 将值传给更长生命周期区域时,必须显式复制或转移所有权 | +| 释放 | 区域释放必须是可预测的,不依赖隐藏线程或最终化器 | +| 跨后端 | 解释器、AOT、字节码和 WebGPU 必须保持同一生命周期语义 | + +区域的嵌套、共享引用、并发访问、异常路径和 FFI 所有权仍待定。实现不得在这些规则冻结前宣称完全兼容。 + +## 字符串和复合值 + +字符串逻辑上是 UTF-8 `(ptr, len)` 视图。结构体、数组和对象可以包含拥有值或借用视图,但其所有权必须可以从类型或函数契约推断。将局部区域内存中的字符串返回到外部区域时,编译器必须拒绝或插入经审计的复制操作;不得生成悬空指针。 + +## 性能边界 + +性能优化应遵循可测量、可复现和可回退原则: + +- 编译器不得为了优化而引入数据竞争、未定义行为或不受控的资源占用。 +- 包管理器和构建工具应避免重复下载和无必要的中间产物。 +- 网络协议实现应优先使用明确长度、流式处理和有界缓冲区。 +- 不可信输入必须设置大小、嵌套、并发和时间预算。 +- 任何零成本抽象声明都必须能通过后端生成代码或基准测试验证。 + +## 低认知维护 + +Fer 采用“三分钟法则”“昏睡测试”“时间推移推演”和“280 字符定理”作为设计评审启发式:一个原子性程序应能快速理解,代码库在规模增长和维护者变化后仍应保持可读。它们是工程准则,不是编译器可以自动证明的语言规则。 + +## 安全边界 + +内存错误、整数溢出、未对齐访问、越界访问、区域逃逸和资源耗尽应尽量在编译期拒绝;不能静态证明安全时,运行时必须采用有界检查或明确失败。`unsafe`、原始指针和自定义分配器接口尚未冻结,不能作为默认应用代码能力。 + +## 可观测性 + +实现应提供分配统计、区域使用量、峰值、释放延迟和后端差异的诊断接口。诊断输出不得泄露密钥、用户输入或未授权内存内容。性能基准必须记录规范版本、编译器版本、目标后端、输入规模和运行环境。 + +## 相关主题 + +- [类型系统](../types/zh-hans.md) +- [字符串](../strings/zh-hans.md) +- [实现后端](../backends/zh-hans.md) +- [迁移机制](../migration/zh-hans.md) diff --git a/content/fer/migration/zh-hans.md b/content/fer/migration/zh-hans.md new file mode 100644 index 0000000..d7f6c80 --- /dev/null +++ b/content/fer/migration/zh-hans.md @@ -0,0 +1,67 @@ +# Fer 迁移机制 + + +## 迁移文件 + +迁移文件命名为: + +```text +vXXX-vYYY.migrate.fer +``` + +其中 `vXXX` 是源版本,`vYYY` 是目标版本。迁移文件必须声明适用范围、前置条件、变更规则、无法自动迁移的情况和验证方式。 + +```text +migrations/ + v0.0.20-v0.0.21.migrate.fer + v0.0.21-v0.1.0.migrate.fer +``` + +版本号解析和多跳迁移策略尚未冻结。工具可以把连续迁移合并为一个计划,但必须保留每一步的诊断和可回滚源文件。 + +## 可自动迁移的变更 + +下列变更在满足类型和导出约束时可以自动迁移: + +- 模块路径重命名,并且旧路径只有一个明确的新路径。 +- 函数参数改名,调用点能够通过原始参数名唯一映射。 +- 公开名称从旧 kebab-case 名称迁移到新名称,并且没有冲突。 +- 语法格式变更,且语法树和类型完全不变。 +- 已声明默认值的结构体字段迁移。 + +迁移器不得把位置参数猜测成具名参数,不得把两个候选新名称中任意一个当作正确结果,也不得静默删除无法保留的字段。 + +## 迁移操作 + +迁移规则应以语法树和符号表为对象,而不是用无约束的文本替换。每条规则应能说明: + +| 项目 | 内容 | +| --- | --- | +| 匹配 | 需要匹配的模块、名称、类型或语法形状 | +| 变换 | 对语法树执行的确定性变换 | +| 约束 | 必须满足的导出、类型和生命周期条件 | +| 诊断 | 失败时显示给用户的原因和位置 | +| 验证 | 迁移后必须通过的解析、类型和测试检查 | + +## 破坏性变更 + +删除公共函数、改变返回类型、改变字符串索引语义、缩小整数范围、改变内存所有权或改变 FON wire format 都属于破坏性变更。迁移文件必须提供明确替代方案;不能自动证明安全时,迁移器必须停止并生成待人工处理清单。 + +## 迁移顺序 + +迁移顺序固定为:解析旧版本、建立符号索引、执行语法迁移、执行名称和模块迁移、重新类型检查、运行格式化器、运行测试和后端验证。任何一步失败都不得提交部分成功结果。 + +## 兼容窗口 + +库可以在一个有限版本窗口中保留旧名称,但必须通过注解或诊断标明弃用版本、替代名称和删除版本。兼容窗口结束后,旧名称应由迁移器转换或报告错误,而不是继续作为未记录的别名存在。 + +## 迁移与运行时 + +迁移规则不应被嵌入运行时。运行时只执行已经迁移并通过检查的目标版本代码。解释器可以在开发模式下提示可用迁移,但不得在生产环境静默修改源代码或加载不匹配的模块。 + +## 相关主题 + +- [模块系统](../modules/zh-hans.md) +- [函数与调用](../functions/zh-hans.md) +- [格式化规范](../formatting/zh-hans.md) +- [实现后端](../backends/zh-hans.md) diff --git a/content/fer/modules/zh-hans.md b/content/fer/modules/zh-hans.md new file mode 100644 index 0000000..c5e444e --- /dev/null +++ b/content/fer/modules/zh-hans.md @@ -0,0 +1,110 @@ +# Fer 模块系统 + + +## 目录与入口 + +一个目录可以作为模块,其入口文件按以下优先级确定: + +| 文件 | 用途 | +| --- | --- | +| `main.fer` | 可执行应用或命令入口 | +| `lib.fer` | 库的公开入口 | +| `mod.fer` | 普通目录模块的入口 | + +同一目录不得同时以多个入口文件表达不同公共模块。工具链发现多个候选入口时必须报告错误,而不能按实现顺序猜测。 + +示例目录: + +```text +modules/ + app/ + main.fer + auth/ + mod.fer + repository.fer + utils/ + username.fer +``` + +## 包名与 scope + +包名必须包含 `@scope`,scope 和包名都遵循 kebab-case: + +```text +@fer/std +@fer/http +@my-app/web-server +``` + +包名是依赖解析和迁移的稳定标识。目录重命名不得在没有迁移文件的情况下改变包的公共标识。 + +## 导入 + +导入使用解构形式,并且必须声明需要的名称: + +```fer +{ get, post } = @fer/http +{ check-username-availability } = @/utils/username +{ create-user } = ./repository +``` + +导入路径分为三类: + +| 形式 | 含义 | +| --- | --- | +| `@scope/package` | 外部包或标准库 | +| `@/path` | 当前应用根目录下的模块 | +| `./path` | 当前目录下的模块 | + +禁止使用 `../`。禁止通过父目录相对路径绕过应用根目录或包的显式边界;需要访问上层公共模块时,应通过根路径别名或包导出实现。 + +## 重命名 + +导入项可以使用 `->` 重命名: + +```fer +{ get, post, Http -> HttpClient } = @fer/http +``` + +重命名只影响当前文件中的名称,不改变源模块的导出名。导入解构中的名称必须存在于源模块的 `exports` 列表;否则必须在编译期报错。 + +## 导出 + +模块必须在显式 `exports {}` 块中声明公共名称: + +```fer +{ io } = ./io +{ fs } = ./fs + +exports { io, fs } +``` + +未导出的名称默认为私有。`exports` 应放在模块文件的最上方公共接口区域;导出项按格式化规范排序。循环导出必须在编译期检测,并给出完整模块路径链。 + +## 模块对象 + +将子模块作为名称导出后,调用方可以先访问模块对象,再访问其导出成员: + +```fer +{ io } = @fer/std + +writer = io.stdout.writer() +writer.write(bytes = `Hello, Fer!`) +``` + +模块对象不是可变哈希表。它只包含源模块声明的导出项,并且不能在运行时动态增加字段。 + +## 可见性与重构 + +公共接口由导出名、类型、参数名、返回类型和相关 scheme 共同组成。内部文件可以自由重构,但改变公共接口必须提供 `.migrate.fer` 迁移规则。编译器应当在迁移前后检查名称、类型和参数映射,不能把无法证明安全的改动自动应用。 + +## 解析错误 + +实现必须拒绝以下情况:入口文件不明确、导入使用 `../`、导入名称未导出、同名导入冲突、导出名称不存在、包缺少 scope、模块循环无法解析,以及私有成员从外部模块访问。 + +## 相关主题 + +- [语法基础](../syntax/zh-hans.md) +- [函数与调用](../functions/zh-hans.md) +- [迁移机制](../migration/zh-hans.md) +- [格式化规范](../formatting/zh-hans.md) diff --git a/content/fer/overview/zh-hans.md b/content/fer/overview/zh-hans.md new file mode 100644 index 0000000..0d9bb57 --- /dev/null +++ b/content/fer/overview/zh-hans.md @@ -0,0 +1,85 @@ +# Fer 语言规范概览 + +Fer 是一种面向系统软件、Web 前后端、Web 服务器、WAF 与 API 网关的意图编程语言。本规范描述 Fer 的可观察语义、源代码组织方式、类型与内存模型,以及对实现者和工具链的约束。 + +Fer 的首要目标不是提供尽可能多的表达方式,而是让同一意图在不同代码库、实现后端和维护者之间保持稳定。语言因此优先选择显式、可验证、可迁移的规则,并以编译期错误替代含糊的运行时行为。 + +## 本规范的阅读方式 + +本仓库将规范拆成主题页。概览页说明设计边界;主题页承载一组可以独立查阅的规则;示例页应当只展示已经在主题页中定义的语义。需要查找确切语法时,直接进入对应的参考主题,不要把概览页当作完整语法参考。 + +| 主题 | 内容 | 入口 | +| --- | --- | --- | +| 语法基础 | 词法边界、换行、标点和注释 | [语法基础](../syntax/zh-hans.md) | +| 模块 | 文件系统命名空间、入口文件、导入与导出 | [模块系统](../modules/zh-hans.md) | +| 表达式 | 块、条件、匹配、求值和 Must-use | [表达式](../expressions/zh-hans.md) | +| 函数 | 定义、调用、具名参数与 UFCS | [函数与调用](../functions/zh-hans.md) | +| 类型 | 基础类型、数组、结构体、枚举与泛型 | [类型系统](../types/zh-hans.md) | +| 字符串 | UTF-8 字符串、插值与意图明确的迭代 | [字符串](../strings/zh-hans.md) | +| 注解 | 编译器、测试和后端相关注解 | [注解](../attributes/zh-hans.md) | +| 格式化 | `ferfmt` 的确定性排序和布局规则 | [格式化规范](../formatting/zh-hans.md) | +| 迁移 | 跨版本的自动迁移文件和兼容策略 | [迁移机制](../migration/zh-hans.md) | +| 实现后端 | 解释器、AOT、字节码与 WebGPU 的共同约束 | [实现后端](../backends/zh-hans.md) | +| 内存与性能 | 区域内存方向、资源边界与性能约束 | [内存与性能](../memory-and-performance/zh-hans.md) | + +FON 是与 Fer 配套的对象表示格式,拥有独立的规范目录。FON 的语法可以脱离 Fer 源码使用,但其 scheme 校验可以由 Fer 类型系统提供。请参阅 [FON 概览](../../fon/overview/zh-hans.md)。 + +## 设计原则 + +### 意图优先 + +源代码表达的是逻辑意图,而不是目标机器的寄存器、调用约定或布局偶然性。例如,`i32` 表示能够安全容纳指定整数范围的逻辑单元;只有实现后端才负责把它映射到适合目标平台的表示。 + +### 声明优先 + +Fer 起源于服务端配置,因此配置、规则和表达式优先于命令式控制流。语言不提供 `if`、`switch`、`let`、`var` 或 `const` 作为核心关键字;条件和绑定使用 Fer 规定的表达式形式。 + +### 可验证优先 + +类型、函数参数、返回值、模块边界和导出接口必须足够明确,使编译器可以在重构前发现错误。对悬空值、非法导入、未导出成员、越界类型和不满足 scheme 的对象,应尽量给出编译期诊断。 + +### 资源可控 + +Fer 不以垃圾回收作为默认语义。当前设计方向是区域内存(arena)分配,并要求实现者明确记录区域的创建、借用、释放和跨后端映射规则。具体内存模型仍以 [内存与性能](../memory-and-performance/zh-hans.md) 中的状态标记为准。 + +### 时间安全 + +语言和库应当允许通过 `vXXX-vYYY.migrate.fer` 自动迁移到新版本。迁移规则属于可审查的源代码,不能依赖不可重复的人工操作。任何需要保留的兼容行为都必须声明其结束版本和替代写法。 + +## 规范性措辞 + +本仓库使用以下措辞表示要求强度: + +| 术语 | 含义 | +| --- | --- | +| **必须** | 不符合即不是有效的 Fer/FON 实现或文档示例。实现必须拒绝或报告错误。 | +| **不得** | 明确禁止的行为。实现不得把它静默解释为其他语义。 | +| **应** | 默认要求。只有在实现约束或兼容性理由明确记录时才能偏离。 | +| **可以** | 允许但不强制的能力。使用它不能破坏必须项和不得项。 | +| **待定** | 设计尚未冻结。本文中的示例不能作为稳定兼容承诺。 | + +## 版本与状态 + +本仓库当前描述的是草案规范。草案示例用于固定讨论方向,不代表已有解释器、编译器或编辑器已经全部实现。每个主题页的“状态”小节必须说明该主题是已冻结、草案还是待定。 + +实现者应当记录实现支持的规范版本,并在发现规范与实现不一致时优先提交可复现样例。规范变更必须说明受影响的源码形式、迁移方式和后端影响。 + +## 规范文档的组织依据 + +本目录采用“概览、概念、参考、工具与迁移”分层。这个选择借鉴了 Microsoft Learn 将学习内容拆成 learning path、module、unit,并把技术文档与培训内容区分开的做法。[1] C# 文档进一步将入门、概念、参考和应用生态分开,使读者能够按任务进入合适的层级。[2] Rust 官方文档则将 The Book、Reference、Style Guide 与工具书分工,并明确 Reference 不承担入门教程职责。[3] [4] + +因此,Fer 的概览页不重复每条语法;规范条文放在主题页;格式化、迁移和后端约束作为独立主题维护。 + +## 相关文档 + +- [Fer 语法基础](../syntax/zh-hans.md) +- [Fer 模块系统](../modules/zh-hans.md) +- [Fer 表达式](../expressions/zh-hans.md) +- [FON 概览](../../fon/overview/zh-hans.md) + +## 参考资料 + +[1]: https://learn.microsoft.com/en-us/training/support/learn-content-types "Microsoft Learn content and resource types" +[2]: https://learn.microsoft.com/en-us/dotnet/csharp/ "C# language documentation" +[3]: https://doc.rust-lang.org/ "Rust Documentation" +[4]: https://doc.rust-lang.org/reference/ "The Rust Reference" diff --git a/content/fer/strings/zh-hans.md b/content/fer/strings/zh-hans.md new file mode 100644 index 0000000..ea0c0cc --- /dev/null +++ b/content/fer/strings/zh-hans.md @@ -0,0 +1,75 @@ +# Fer 字符串 + + +## 字符串字面量 + +```fer +name = `Fuyeor` +message = `Hello, {name}!` +calculate-message = `1 + 1 = {1 + 1}` +``` + +字符串插值大括号内部是普通 Fer 表达式,表达式结果按字符串格式化规则转换。插值不能执行隐式 I/O 或改变外部状态。 + +反引号使用反斜杠转义: + +```fer +code = `here is a markdown inline code: \`code\`` +``` + +## 多行字符串 + +Fer 支持保留换行的多行字符串,也支持使用反斜杠连接物理行: + +```fer +multiple1 = ` + {message} + This is a string that spans multiple + lines easily. +` + +multiple2 = `This is a string \ + that spans multiple lines easily.` +``` + +格式化工具可以裁剪多行字符串公共缩进,但必须明确记录该行为,并保证转义后的字符串值可预测。字符串内容中有意义的前导空格、尾随空格和换行不得被静默删除。 + +## 禁止直接索引 + +对 `string` 使用 `str[i]` 是编译期错误。原因是 `i` 可能被误解为字节偏移、Unicode 标量索引或用户可见字符索引。调用方必须根据意图选择迭代视图。 + +| API | 元素 | 用途 | +| --- | --- | --- | +| `str.bytes()` | `byte` | 原始二进制数据、协议解析、哈希;速度和可控性优先 | +| `str.chars()` | `char` | Unicode 标量值;需要处理字符编码而不是用户字形时使用 | +| `str.graphemes()` | `string` | 用户看到的字形簇;处理输入、光标和显示文本时使用 | + +例如,组合字符 `e` 与重音符可能由多个 Unicode 标量组成,但用户可能把它们看作一个字形。需要按用户感知单位处理时,必须使用 `graphemes()`。 + +```fer +for-byte = (text: string) -> void { + text.bytes().each(byte = process-byte(byte)) +} + +for-character = (text: string) -> void { + text.chars().each(char = process-char(char)) +} +``` + +迭代器语法和 `each` 的完整定义尚未冻结;上例只说明意图,不构成当前完整控制流规范。 + +## 长度与切片 + +`length` 的语义必须与使用的视图一致:字节长度、标量长度和字形长度不是同一个值。实现不得提供无单位的 `str.length` 并让调用方猜测其含义。 + +字符串切片必须在明确边界上执行。以字节切片时,结果必须是合法的字节视图;以字符或字形切片时,结果必须保持合法 UTF-8。非法边界必须报告错误,不得返回损坏字符串。 + +## 字符串与内存 + +字符串的逻辑表示是 UTF-8 的 `(ptr, len)` 视图。视图是否拥有内存、是否借用区域以及是否需要复制,由类型或函数契约明确说明。将短生命周期区域中的字符串返回到长生命周期区域时,编译器必须拒绝或要求显式复制。 + +## 相关主题 + +- [类型系统](../types/zh-hans.md) +- [内存与性能](../memory-and-performance/zh-hans.md) +- [表达式](../expressions/zh-hans.md) diff --git a/content/fer/structure.json b/content/fer/structure.json new file mode 100644 index 0000000..914ff7e --- /dev/null +++ b/content/fer/structure.json @@ -0,0 +1,22 @@ +{ + "title": { + "zh-hans": "Fer 语言规范" + }, + "description": { + "zh-hans": "Fer 意图编程语言的语法、表达式、类型、模块、实现后端与工具链规范。" + }, + "navigation": [ + { "slug": "overview" }, + { "slug": "syntax" }, + { "slug": "expressions" }, + { "slug": "types" }, + { "slug": "functions" }, + { "slug": "modules" }, + { "slug": "attributes" }, + { "slug": "strings" }, + { "slug": "formatting" }, + { "slug": "migration" }, + { "slug": "backends" }, + { "slug": "memory-and-performance" } + ] +} diff --git a/content/fer/syntax/zh-hans.md b/content/fer/syntax/zh-hans.md new file mode 100644 index 0000000..6919d58 --- /dev/null +++ b/content/fer/syntax/zh-hans.md @@ -0,0 +1,118 @@ +# Fer 语法基础 + + +## 源文件与换行 + +Fer 源文件使用 UTF-8 编码。逗号 `,` 与换行符 `\n` 均为合法的通用元素分隔符;成员、参数、数组元素、对象字段以及其他可重复语法元素可以使用逗号、换行或两者混合进行分隔。Parser 必须将这些排版形式解析为等价的元素序列,CST 必须保留原始物理排版,以支持无损还原。格式化工具可以把等价形式规范化为稳定布局,但不得改变语义。 + +```fer +name = `Fuyeor` +version = 0.0.21 + +message = `Hello, {name}!` +``` + +语法解析器必须区分换行和字符串内容中的换行。反引号字符串内部的换行属于字符串值,除非它被字符串转义规则处理。 + +## 注释 + +Fer 支持三种注释: + +```fer +// 行注释,直到当前行结束 +/// 文档注释,可附着到后续模块、类型、函数或常量 +/* 多行注释 */ +``` + +`///` 应用于可以被工具发现的公共文档。文档注释不得改变程序语义。格式化工具应保留注释与其附着项的相对位置,并优先保留行注释而不是把多行注释重新排版为行注释。 + +## 名称与命名 + +函数名、常量名、字段名、包名和 scope 使用 kebab-case,只能包含小写 ASCII 字母、数字和连字符,并且必须以小写 ASCII 字母开头。名称不得包含连续的连字符,也不得以连字符结尾。 + +类型名、结构体名和枚举名使用 PascalCase。特殊协议或格式名称可以使用全大写,例如 `FON` 和 `FRL`。同一作用域内不得出现重复名称,也不得通过遮蔽复用外层名称。 + +| 名称种类 | 示例 | 规则 | +| --- | --- | --- | +| 函数 | `check-username` | kebab-case | +| 常量 | `default-timeout` | kebab-case | +| 字段 | `client-identity` | kebab-case | +| 类型 | `UserProfile` | PascalCase | +| 协议名称 | `FON`、`FRL` | 可全大写 | + +## 常量绑定 + +当前设计没有可变变量。使用名称绑定表达式声明常量,并由编译器推断或验证类型: + +```fer +name = `Fuyeor` +count = 0 +users: Array = [`Fuyeor`, `AI`] +``` + +绑定的生命周期与其作用域一致。顶层绑定默认贯穿模块生命周期;块内绑定在块的语义生命周期结束时失效。禁止通过重新绑定同名名称来模拟赋值,也禁止遮蔽外层名称。 + +当需要明确声明类型时,使用 `name: Type = value`。类型声明的完整规则见 [类型系统](../types/zh-hans.md)。 + +## 块边界 + +大括号 `{}` 具有两种由词法形状区分的用途: + +```fer +// 连续赋值表达式:局部作用域,最后一行是块结果 +result = { + left = 10 + right = 20 + left + right +} + +// 字段声明或字段初始化:结构值 +point = { lat = 100, lng = 100 } +``` + +多行块中的连续绑定表示局部作用域;字段之间使用逗号表示同一行结构;带字段名称的结构值与普通表达式必须由上下文区分。实现不得依赖不稳定的缩进猜测;需要歧义消解时,应要求显式类型或显式逗号。 + +## 字符串字面量 + +字符串只能使用反引号: + +```fer +plain = `hello` +quoted = `inline code: \`code\`` +interpolated = `Hello, {name}!` +``` + +插值大括号的内容是普通 Fer 表达式,表达式结果被格式化为字符串。多行字符串可以保留换行,也可以使用反斜杠连接相邻物理行。字符串的编码、索引和迭代规则见 [字符串](../strings/zh-hans.md)。 + +## 逗号与单行化 + +逗号可以用于同一行的函数参数、数组元素、对象字段和其他可重复语法元素;换行也可以承担相同的分隔作用,两者可以混合使用: + +```fer +config = { name = `fer`, version = 0.0.21, stable = false } +``` + +换行形式用于提高结构可读性;逗号和换行的混合形式同样合法: + +```fer +config = { + name = `fer` + version = 0.0.21 + stable = false +} +``` + +格式化工具必须把同一结构稳定地转换为多行或单行,不得因为输入使用逗号、换行或混合分隔而生成不同语义;CST 必须保留输入的原始物理排版,以支持无损还原。 + +## 语法错误 + +解析器至少应诊断以下错误:非法名称、未闭合字符串、未闭合注释、块边界不匹配、同一作用域重复绑定、元素之间缺少逗号或换行分隔、禁止的关键字和悬空的实质性表达式。 + +错误消息应包含源文件路径、起始位置、错误类别、简短原因和一个可执行的修复建议。错误类别的稳定编号属于后续诊断规范;当前实现不得把稳定编号写死为本页未定义的值。 + +## 相关主题 + +- [模块系统](../modules/zh-hans.md) +- [表达式](../expressions/zh-hans.md) +- [字符串](../strings/zh-hans.md) +- [格式化规范](../formatting/zh-hans.md) diff --git a/content/fer/types/zh-hans.md b/content/fer/types/zh-hans.md new file mode 100644 index 0000000..a0203b9 --- /dev/null +++ b/content/fer/types/zh-hans.md @@ -0,0 +1,147 @@ +# Fer 类型系统 + + +## 类型声明 + +类型名使用 PascalCase;字段名使用 kebab-case。使用 `Name: Type` 声明类型,使用 `name: Type = value` 声明带有类型约束的绑定: + +```fer +UserId: string + +user-id: UserId = `c7f7c5c7-2cdd-4fa8-9f61-8db9425a0f21` +``` + +结构体和枚举是类型定义,不得把未实例化的匿名 `struct` 当作普通常量: + +```fer +User: struct { + id: Uuid4 + nickname: string +} + +// 合法的具名实例 +user: User = { + id = `c7f7c5c7-2cdd-4fa8-9f61-8db9425a0f21` + nickname = `Fuyeor` +} +``` + +## 基础类型 + +Fer 提供面向日常业务的抽象类型和面向系统控制的精确类型: + +| 类别 | 类型 | 语义 | +| --- | --- | --- | +| 整数抽象 | `int` | `i64` 或平台原生字长 `isize` 的逻辑别名,用于 ID、计数和索引 | +| 浮点抽象 | `float` | `f64` 的逻辑别名,用于坐标和近似计算 | +| 文本 | `string` | UTF-8 字符串视图,逻辑上包含指针和长度 | +| 字符 | `char` | Unicode 标量值的逻辑别名,当前映射方向为 `u32` | +| 字节 | `byte` | `u8` 的别名,用于二进制流、哈希和协议 | +| 布尔 | `bool` | 二值逻辑,当前底层方向为 `i1` | +| 有符号整数 | `i8` 到 `i128` | 精确的有符号整数范围 | +| 无符号整数 | `u8` 到 `u128` | 精确的无符号整数范围 | +| 浮点数 | `f32`、`f64` | 精确的浮点表示宽度 | +| 单元 | `void` | 无有意义值的正常返回类型 | +| 空 | `never` | 不产生返回值的发散计算 | + +`int`、`float`、`string` 等抽象类型用于可移植业务代码;需要二进制布局、协议宽度或硬件接口时,使用精确类型。实现不得因为目标平台不同而改变 `i32` 的逻辑范围。 + +## 数组 + +数组是有序元素集合。元素类型写在 `Array` 中: + +```fer +users: Array = [`Fuyeor`, `AI`] +buffer: Array = [100, 255, 0] +``` + +数组索引的类型和越界行为尚未冻结。当前方向要求索引使用 `int` 或明确的无符号整数,并在可证明时由编译期消除边界检查;无法证明时必须执行安全检查,不能静默读取相邻内存。 + +## 泛型与 Option + +泛型类型使用尖括号: + +```fer +Option: enum { + some: T + none +} +``` + +`Option` 用于表示值存在或不存在。调用方必须通过匹配或规定的解构操作处理两种变体;不得把 `none` 当作任意类型的零值。 + +泛型约束、类型推断、协变/逆变和泛型函数的完整规则尚未冻结。实现可以内部支持这些能力,但公共语法必须在规则冻结前标记为实验性。 + +## 结构体 + +结构体字段是命名、类型和可选默认值组成的成员: + +```fer +User: struct { + id: Uuid4 + nickname = `guest` + score: i32 = 100 +} +``` + +只写类型的字段在实例化时必须提供;直接写值会推断字段类型并成为默认值;同时写类型和值时,值必须通过类型检查。字段重复定义是错误。 + +结构体值可以匿名或具名: + +```fer +point = { lat = 100, lng = 100 } +point: Location = { lat = 100, lng = 100 } +``` + +匿名值只在上下文能够唯一确定结构时可用。公共函数返回结构时应使用具名类型,避免匿名结构因字段增删而造成难以迁移的接口。 + +## 枚举 + +枚举类型和变体名称遵循类型命名规则;变体可以是无数据、基础类型或嵌套结构体: + +```fer +Gender: enum { ai, female, hide, male, nonbinary } + +Message: enum { + quit + move: struct { x: i32, y: i32 } + write: string +} +``` + +变体通过 `.variant` 简写或类型限定形式访问: + +```fer +gender: Option = .ai +status = Status.active +``` + +简写只能在上下文能够确定枚举类型时使用;否则必须写出类型或使用显式构造形式。枚举匹配必须覆盖所有变体,或提供默认分支。 + +## 精炼类型 + +精炼类型以基础类型为载体,并附加一个编译期可验证的条件: + +```fer +Uuid4: string { + (it matches `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$`) +} +``` + +精炼条件中的 `it` 代表待验证值。构造精炼类型时必须运行或证明该条件;从不可信输入解析时不得只做类型转换而跳过验证。正则引擎的语法、复杂度上限和拒绝服务防护属于后续规范。 + +## 默认值与初始化 + +默认值必须是无副作用的常量表达式,不能执行网络、文件、随机数、系统时间或用户代码。复杂默认值的生命周期和区域归属必须在 [内存与性能](../memory-and-performance/zh-hans.md) 中定义后,才能进入稳定规范。 + +## 类型错误 + +实现至少应诊断:值与声明类型不匹配、结构体缺少必填字段、出现未知字段、数组元素类型不满足 scheme、枚举变体不存在、精炼条件无法证明、把 `never` 当作普通值使用,以及未处理 `Option` 的缺失分支。 + +## 相关主题 + +- [表达式](../expressions/zh-hans.md) +- [函数与调用](../functions/zh-hans.md) +- [字符串](../strings/zh-hans.md) +- [注解](../attributes/zh-hans.md) +- [内存与性能](../memory-and-performance/zh-hans.md) diff --git a/content/fon/frl/zh-hans.md b/content/fon/frl/zh-hans.md new file mode 100644 index 0000000..766d7c2 --- /dev/null +++ b/content/fon/frl/zh-hans.md @@ -0,0 +1,82 @@ +# Fer Resource Locator(FRL) + + +## 结构 + +FRL 的基本字段如下: + +| 字段 | 类型方向 | 用途 | +| --- | --- | --- | +| `protocol` | `Protocol`,可选 | 传输协议,例如 `https` | +| `identifier` | `string` | 主资源标识,例如域名或服务名 | +| `path` | `Array`,可选 | 静态资源或层级路径 | +| `params` | object,可选 | 查询参数 | +| `fragment` | `string`,可选 | 文档或资源内的片段标识 | + +基础定位值: + +```fer +{ + identifier = `fuyeor.com` + params = { + q = `WebRoamer` + pagination = { page = 1, limit = 10 } + } + fragment = `search-results` +} +``` + +字段不是 URL 文本的任意字符串拼接。每个字段都必须经过适合其类型的编码,避免查询值、路径段或片段中的分隔符改变结构含义。 + +## 路径 + +静态文件或目录使用 `path`: + +```fer +{ + identifier = `fuyeor.com` + path = [`documents`, `introductions`, `file.pdf`] +} +``` + +上例表达的 URL 方向是 `fuyeor.com/documents/introductions/file.pdf`。路径数组中的每一项是一个独立段;`/`、`?` 和 `#` 不得在序列化时未经编码地改变层级。 + +## 具名 FRL 类型 + +在 Webroamer 或其他平台中,FRL 可以由 scheme 定义为具名结构: + +```fer +locator: FRL = { + protocol = Protocol.https + identifier = `fuyeor.com` + params = { + q = `WebRoamer` + pagination = { page = 1, limit = 10 } + } +} +``` + +`Protocol.https`、参数对象和路径规范由平台 scheme 定义。基础 FON 不应自动接受未知协议或把任意字符串转换为安全协议。 + +## 一维化 + +FRL 在地址栏、Markdown 或日志中以单行出现时,使用 FON 一维语法: + +```fer +{ identifier = `fuyeor.com`, params = { os = `WebRoamer`, type = `video` } } +``` + +一维化只改变表示,不改变字段结构。显示层可以进一步把 FRL 渲染为传统 URL,但渲染和解析必须是可逆的;无法无损表达的字段必须拒绝转换或保留原始 FON 形式。 + +## 安全规则 + +FRL 解析器必须限制标识长度、路径段数量、参数深度和整体大小。解析外部 FRL 时,必须拒绝控制字符、非法 Unicode、未编码分隔符和不允许的协议。解析器不得因为 `identifier` 看起来像域名就自动发起网络请求。 + +路径遍历、主机混淆、Unicode 同形异义字符和查询参数重复都必须有明确处理规则。当前草案要求默认拒绝不明确的重复参数和危险路径段;兼容策略待定。 + +## 相关主题 + +- [FON 概览](../overview/zh-hans.md) +- [FON 语法](../syntax/zh-hans.md) +- [FON 序列化](../serialization/zh-hans.md) +- [Next Web 规范](../../next-web/overview/zh-hans.md) diff --git a/content/fon/overview/zh-hans.md b/content/fon/overview/zh-hans.md new file mode 100644 index 0000000..d62e9e0 --- /dev/null +++ b/content/fon/overview/zh-hans.md @@ -0,0 +1,85 @@ +# FON 对象表示规范概览 + +FON(Fer Object Notation)是 Fer 生态中的结构表示格式。它用于表达配置、对象树、scheme 可验证值和跨平台传输对象,也可以在不运行完整 Fer 程序的场景中独立存在。 + +FON 的核心目标是让同一结构既适合人类阅读,也适合编译器、解释器、Web 平台和序列化工具处理。FON 不复制 HTML、XML 或 JSON 的全部语义;它只规定对象、数组、值、路径和 scheme 所需的结构规则。 + +## 规范范围 + +| 主题 | 责任 | 入口 | +| --- | --- | --- | +| 概览 | 定义 FON 的用途、模式和兼容边界 | 当前页面 | +| 语法 | 定义逗号、换行和混合分隔,以及对象、数组、原子值和注释 | [FON 语法](../syntax/zh-hans.md) | +| Scheme | 定义如何由 Fer 类型声明验证 FON 值 | [Scheme](../schemes/zh-hans.md) | +| 序列化 | 定义对象到传输表示的边界与要求 | [序列化](../serialization/zh-hans.md) | +| FRL | 定义 Fer Resource Locator 的结构表示 | [FRL](../frl/zh-hans.md) | + +## FON 与 Fer 的关系 + +Fer 是可执行的意图编程语言;FON 是表示结构的格式。Fer 可以构造、读取和验证 FON 对象,但 FON 文件不应隐式获得 Fer 函数调用、控制流或副作用。 + +在 Fer 中,FON 对象可以直接写成结构值: + +```fer +config = { + name = @fer/std + version = 0.1.0 + license = .mit + authors = [`Fuyeor`, `AI`] +} +``` + +在没有 scheme 的情况下,解析器识别结构和字面值,但不会凭字段名称猜测业务类型。在有 scheme 的情况下,字段的类型、默认值、枚举变体和约束由 scheme 决定;验证规则见 [Scheme](../schemes/zh-hans.md)。 + +## 通用元素分隔与排版表示 + +FON 中逗号 `,` 与换行 `\n` 均为合法的通用元素分隔符。对象字段、数组元素以及其他可重复结构元素可以使用单行纯逗号、多行纯换行,或逗号与换行混合的分组形式;缩进只用于人类阅读,不承载额外语义。Parser 必须将这些排版形式视为等价的分隔序列并构造等价结构,CST 必须保留原始物理排版,以支持无损还原。 + +```fon +name = @fer/std +version = 0.1.0 +license = .mit +authors = [`Fuyeor`, `AI`] +dependencies = { + @fer/common = ^0.1.0 +} +``` + +等价的单行形式如下: + +```fon +name=@fer/std,version=0.1.0,license=.mit,authors=[`Fuyeor`,`AI`],dependencies={@fer/common=^0.1.0} +``` + +排版转换不能改变结构语义或字段顺序。解析器不得把逗号、空白或换行误读为字符串内容;字符串内部的分隔符由字符串转义规则处理。 + +## 值的类别 + +FON 至少支持字符串、布尔值、整数、浮点数、数组、对象、路径、包引用、版本表达式、枚举简写和空值。具体实现可以提供扩展值,但扩展必须有明确的 scheme 或媒体类型,不能让同一字面量在不同实现中静默产生不同含义。 + +| 类别 | 示例 | 说明 | +| --- | --- | --- | +| 字符串 | `` `the standard library` `` | 使用反引号 | +| 布尔值 | `true`、`false` | 不加引号 | +| 数字 | `14`、`-100`、`2.4` | 由 scheme 或上下文确定精度 | +| 数组 | `` [`Fuyeor`, `AI`] `` | 元素按顺序排列 | +| 对象 | `{ mode = .dark }` | 字段由名称和值组成 | +| 路径 | `./docs/zh-hans.md` | 由所在文件解析 | +| 包引用 | `@fer/std` | 必须带 scope | +| 枚举简写 | `.mit`、`.dark` | 必须由 scheme 或已知类型解析 | + +## 安全与可移植性 + +FON 解析器默认是纯解析器,不得执行字段值中的函数、网络请求、文件写入或动态代码。路径、包引用和资源定位符只在调用方显式请求解析时才解析为资源;解析器必须限制输入大小、嵌套深度、字段数量和字符串长度,以防止资源耗尽攻击。 + +FON 的对象语义不依赖具体 CPU、字节序或指针宽度。二进制传输时使用 [序列化规范](../serialization/zh-hans.md) 规定的类型标签和长度规则;未冻结的 wire format 不能被标记为稳定协议。 + +## 文档状态 + + +## 相关文档 + +- [FON 语法](../syntax/zh-hans.md) +- [FON Scheme](../schemes/zh-hans.md) +- [FON 序列化](../serialization/zh-hans.md) +- [Fer 类型系统](../../fer/types/zh-hans.md) diff --git a/content/fon/schemes/zh-hans.md b/content/fon/schemes/zh-hans.md new file mode 100644 index 0000000..72f2b30 --- /dev/null +++ b/content/fon/schemes/zh-hans.md @@ -0,0 +1,99 @@ +# FON Scheme + + +## Scheme 的作用 + +没有 scheme 时,FON 解析器只验证基础结构:对象、数组、字符串、数字、布尔值和已定义的原子词法。导入 scheme 后,验证器可以确定字段类型、枚举变体、默认值、范围和精炼条件。 + +```fer +{ Hex } = @fer/web + +Appearance: struct { + mode: enum { dark, light, contrast, auto } + color: struct { + primary: Hex = #AEA4E4 + secondary: Hex = #ffe710 + } + font-size: u8 = 14 + enable-animations: bool = true +} + +exports { Appearance } +``` + +`Hex` 和 `#RRGGBB` 的完整语法由 `@fer/web` 的 scheme 定义;它们不是所有 FON 实现都必须支持的基础字面量。 + +## Scheme 的来源 + +Scheme 有三种来源: + +| 来源 | 说明 | +| --- | --- | +| Fer 具名类型 | 由 `struct`、`enum`、精炼类型和泛型组合定义 | +| 库导出 | 通过模块的 `exports {}` 公开给调用方 | +| 平台 prelude | Web、编译器或特定后端预加载的标准 scheme | + +平台 prelude 必须可查询、可锁定版本并可在不支持时给出诊断。实现不得把某个平台的 prelude 当作所有 Fer 后端都存在的全局类型。 + +## 使用 Scheme + +配置文件通过类型标注绑定到 scheme: + +```fer +{ Appearance } = @/config/app-appearance + +appconf: Appearance = { + mode = .dark + color = { primary = #2701ff } + font-size = 100 +} +``` + +如果字段不满足声明类型,验证必须失败。例如将负数赋给无符号类型必须在编译期或配置加载期被拒绝: + +```fer +appconf: Appearance = { + mode = .dark + font-size = -100 +} +// Error: -100 不满足 u8 的范围 +``` + +配置加载期失败必须包含 scheme 名称、字段路径、实际值类别、期望类型和修复建议。不得把非法配置静默替换为默认值。 + +## 默认值 + +具有默认值的字段可以在 FON 对象中省略;没有默认值的字段必须出现。显式提供的值必须经过验证,即使它与默认值相同。默认值必须是纯常量表达式,不能依赖当前时间、环境变量、网络或随机数。 + +## 枚举与简写 + +枚举变体可以使用 `.dark` 这样的简写。验证器必须从字段类型确定候选枚举;当多个枚举具有同名变体而上下文无法区分时,必须要求显式类型或报告歧义。 + +```fer +mode = .dark +``` + +枚举不应把任意字符串自动转换为变体。需要兼容外部字符串时,应定义显式解析函数或迁移规则。 + +## 精炼类型 + +精炼类型必须在构造点验证: + +```fer +Uuid4: string { + (it matches `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$`) +} +``` + +验证器必须限制正则和输入长度,避免恶意配置触发超时或内存耗尽。精炼条件失败时,错误必须指向字段路径而不是只报告整个文件无效。 + +## 兼容性 + +向 scheme 中添加带默认值的字段通常是向后兼容的;添加必填字段、删除字段、改变字段类型、缩小数值范围或改变枚举变体都可能是破坏性变更。每次 scheme 变更都应提供版本号和 FON 迁移规则。 + +## 相关主题 + +- [FON 概览](../overview/zh-hans.md) +- [FON 语法](../syntax/zh-hans.md) +- [Fer 类型系统](../../fer/types/zh-hans.md) +- [Fer 迁移机制](../../fer/migration/zh-hans.md) diff --git a/content/fon/serialization/zh-hans.md b/content/fon/serialization/zh-hans.md new file mode 100644 index 0000000..d390357 --- /dev/null +++ b/content/fon/serialization/zh-hans.md @@ -0,0 +1,89 @@ +# FON 序列化与传输 + + +## 文本与二进制的边界 + +文本 FON 适合配置、源代码、调试和版本控制。二进制 FON 适合已验证对象的传输,但二进制编码不得绕过 scheme 验证、大小限制和权限检查。 + +序列化流程应当是: + +1. 解析文本或构造 Fer 对象。 +2. 根据 scheme 验证字段、类型、范围和默认值。 +3. 将值转换为规范对象树。 +4. 编码类型标签、长度、字段和值。 +5. 在接收端验证媒体类型、协议版本、长度和对象限制。 + +## 稳定编码要求 + +二进制编码必须明确规定: + +| 项目 | 当前要求 | +| --- | --- | +| 类型标签 | 每个值类别必须有可扩展且不会冲突的标签 | +| 长度 | 长度编码必须有上限,并防止整数溢出 | +| 字节序 | 多字节数值必须规定字节序,不得使用主机默认值 | +| 字段 | 字段名和字段顺序的编码规则必须稳定 | +| 版本 | 编码必须携带格式版本或由外层协议明确协商 | +| 扩展 | 未知扩展必须有拒绝或安全跳过规则 | +| 校验 | 解码后的对象仍必须通过 scheme 和资源限制检查 | + +具体标签、字节序、哈希和压缩方式尚未冻结,因此当前草案的二进制结果不得被视为跨版本兼容协议。 + +## 对象顺序 + +基础对象语义按字段名寻址;序列化器必须选择稳定顺序,以便缓存、签名和调试输出可复现。默认顺序为 scheme 声明顺序;没有 scheme 时按稳定字典序。数组顺序始终保留。 + +如果应用依赖用户输入顺序、签名顺序或展示顺序,必须把对象声明为有序对象,并在 scheme 中明确该属性。序列化器不得自行排序有序对象。 + +## 安全边界 + +解码器必须限制输入总大小、对象深度、字段数量、数组长度、字符串长度和递归时间。长度字段必须在分配之前验证,不能把外部长度直接转换成内存分配请求。 + +解码器不得执行对象中的函数、路径访问、包安装、网络请求或动态加载。资源定位值只有在调用方显式请求解析时才能进入资源层,并且必须使用权限和沙箱策略。 + +## 请求头对象 + +Webroamer 方向把请求头建模为二进制 FON 对象: + +```fer +RequestHeader: struct { + method: HttpMethod + path: string + version: string + client-identity: ClientIdentity +} +``` + +客户端身份声明同样是结构化对象: + +```fer +client-identity = { + browser = { name = `Webroamer`, version = 1.0.0 } + capabilities = { gpu-acceleration = true, color-space = .p3 } + os = { name = `WebroamerOS`, version = 2.4, arch = `arch64` } + privacy-level = .strict +} +``` + +这些类型、字段和枚举只属于 Webroamer 草案,不是所有 FON 传输都必须携带的字段。 + +## HTTP/3 外层兼容 + +Webroamer 方向可以在 FON payload 外套用最小 HTTP/3 请求头: + +```http +:method = POST +:scheme = https +:authority = fuyeor.com +:path = /search +content-type = application/fon +``` + +HTTP/3 头部和 FON payload 是两个层次。外层协议负责路由、连接和传输协商;FON 负责结构化 payload。当前草案不规定必须使用 POST,也不规定所有 HTTP/3 实现都支持 `application/fon`。 + +## 相关主题 + +- [FON 概览](../overview/zh-hans.md) +- [FON Scheme](../schemes/zh-hans.md) +- [FRL](../frl/zh-hans.md) +- [Next Web 规范](../../next-web/overview/zh-hans.md) diff --git a/content/fon/structure.json b/content/fon/structure.json new file mode 100644 index 0000000..a90ffa4 --- /dev/null +++ b/content/fon/structure.json @@ -0,0 +1,15 @@ +{ + "title": { + "zh-hans": "FON 对象表示规范" + }, + "description": { + "zh-hans": "Fer Object Notation 的对象、数组、Scheme、序列化与资源定位规范。" + }, + "navigation": [ + { "slug": "overview" }, + { "slug": "syntax" }, + { "slug": "schemes", "title": { "zh-hans": "Scheme" } }, + { "slug": "serialization", "title": { "zh-hans": "序列化与传输" } }, + { "slug": "frl", "title": { "zh-hans": "Fer Resource Locator" } } + ] +} diff --git a/content/fon/syntax/zh-hans.md b/content/fon/syntax/zh-hans.md new file mode 100644 index 0000000..0409b19 --- /dev/null +++ b/content/fon/syntax/zh-hans.md @@ -0,0 +1,133 @@ +# FON 语法 + + +## 基本规则 + +FON 源文本使用 UTF-8 编码。逗号 `,` 与换行符 `\n` 均为合法的通用元素分隔符;对象字段、数组元素以及其他可重复结构元素可以使用逗号、换行或两者混合进行分隔。缩进只服务于可读性,不能改变对象的层级或字段值。Parser 必须将这些排版形式解析为等价的元素序列,CST 必须保留原始物理排版,以支持无损还原。 + +```fon +name = @fer/std +version = 0.1.0 +license = .mit +authors = [`Fuyeor`, `AI`] +description = `the standard library` +dependencies = { + @fer/common = ^0.1.0 +} +``` + +等价的一维形式如下: + +```fon +name=@fer/std,version=0.1.0,license=.mit,authors=[`Fuyeor`,`AI`],dependencies={@fer/common=^0.1.0} +``` + +解析器必须允许等号两侧出现空白,也必须允许逗号两侧出现空白。逗号和换行可以单独使用或混合使用;格式化工具应输出带空格的等号和稳定的布局,除非处于明确要求最小体积的序列化场景。 + +Fer/FON 共用 Parser 的分隔规则可以用以下抽象示例表示;示例中的 `enum` 和 `all` 分别属于上层结构或 Fer 表达式,不改变 FON 基础值的类型定义: + +```text +enum { en, es + zh-hans, zh-hant } + +all (a > 1, b > 2 + c < 3) +``` + +Parser 必须把上述逗号、换行和混合分隔视为等价的分隔序列;CST 必须保留其原始物理排版。 + +## 注释 + +FON 支持 Fer 的行注释和多行注释: + +```fon +// 这是一个行注释 +name = @fer/std /* 行内注释 */ +/* 这是一个 + 多行注释 */ +``` + +注释不是值的一部分。字符串中的 `//`、`/*` 和 `*/` 只有在字符串结束后才具有注释含义。 + +## 对象 + +对象由字段名、等号和值组成。对象字段可以由逗号、换行或两者混合分隔;多行对象可以让每个字段独占一行,一维对象也可以使用逗号分隔: + +```fon +readme = { + en = ./docs/en.md + fr = ./docs/fr.md +} +``` + +字段名使用 kebab-case,包依赖字段可以使用带 scope 的包名作为键: + +```fon +dependencies = { + @fer/common = ^0.1.0 + @fer/http = ~0.4.2 +} +``` + +同一对象中不得出现重复字段名。基础解析器应保留源顺序,语义层可以根据 scheme 声明字段的规范顺序。将对象转换为哈希结构时,重复字段必须报告错误,不得以后出现的值静默覆盖前一个值。 + +## 数组 + +数组使用方括号包围,元素可以由逗号、换行或两者混合分隔: + +```fon +authors = [`Fuyeor`, `AI`] +ports = [80, 443] +features = [.http2, .websocket] +mixed = [80, 443 + 8080, 8443] +``` + +数组保留元素顺序。基础语法允许混合字面值,但 scheme 可以要求所有元素具有相同类型。空数组的元素类型只能由 scheme 或显式上下文确定。 + +## 字符串 + +字符串只使用反引号。反引号可以用反斜杠转义: + +```fon +description = `a FON value` +markdown = `inline code: \`name\`` +``` + +FON 基础语法不执行 Fer 字符串插值。若需要动态生成字符串,必须在 Fer 中生成后再把结果作为 FON 值传递。多行字符串可以保留物理换行;一维化工具必须按照字符串语法进行转义,而不是直接删除换行。 + +## 原子值 + +以下原子形式是基础语法的一部分: + +```fon +stable = true +experimental = false +retry-count = 3 +timeout = 2.5 +license = .mit +package = @fer/std +version = 0.1.0 +range = ^0.1.0 +path = ./docs/index.md +``` + +原子值的业务类型由 scheme 或使用上下文确定。例如 `0.1.0` 在包清单中可以是版本值,在无 scheme 的对象中也可以作为未加引号的版本原子保存。实现不得仅凭数值形状把它强制转换成 `f64`。 + +## 空值与缺省值 + +空值的字面量、缺省字段的序列化行为和“字段存在但值为空”的区别尚未冻结。当前草案要求 scheme 显式声明默认值;基础语法不得擅自把缺失字段补成 `null`、空字符串或零。 + +## 语法错误 + +解析器必须拒绝未闭合字符串、未闭合注释、缺少等号、重复字段、数组或对象元素之间缺少逗号和换行以外的合法分隔符、对象中出现无法识别的字段键,以及不符合包引用或路径词法的值。错误消息应包含文件位置和建议修复方式。 + +## 规范化输出 + +FON 格式化工具应遵循以下顺序:先按 scheme 声明的字段顺序;没有 scheme 时按字段名的稳定字典序;依赖包按 scope 与包名排序;数组不排序。格式化不得改变对象字段的语义顺序,除非该对象已经声明为无序对象。 + +## 相关主题 + +- [FON 概览](../overview/zh-hans.md) +- [Scheme](../schemes/zh-hans.md) +- [序列化](../serialization/zh-hans.md) diff --git a/content/index.en.json b/content/index.en.json index 866ff24..fe8ac13 100644 --- a/content/index.en.json +++ b/content/index.en.json @@ -28,5 +28,25 @@ "module": "social", "title": "Ф social", "description": "Ф social help documentation, including usage instructions, feature descriptions, and frequently asked questions." + }, + { + "module": "fer", + "title": "fer", + "description": "" + }, + { + "module": "fon", + "title": "fon", + "description": "" + }, + { + "module": "next-web", + "title": "next-web", + "description": "" + }, + { + "module": "reference", + "title": "reference", + "description": "" } ] \ No newline at end of file diff --git a/content/index.zh-hans.json b/content/index.zh-hans.json index 4aefa1a..98d68a0 100644 --- a/content/index.zh-hans.json +++ b/content/index.zh-hans.json @@ -28,5 +28,25 @@ "module": "social", "title": "Ф 社交", "description": "Ф 社交媒体使用帮助文档,包含 Ф 社交应用的使用说明、功能介绍、常见问题解答等内容。" + }, + { + "module": "fer", + "title": "Fer 语言规范", + "description": "Fer 意图编程语言的语法、表达式、类型、模块、实现后端与工具链规范。" + }, + { + "module": "fon", + "title": "FON 对象表示规范", + "description": "Fer Object Notation 的对象、数组、Scheme、序列化与资源定位规范。" + }, + { + "module": "next-web", + "title": "Next Web 规范", + "description": "基于 FON 文档树与 Fer Interpreter 的 Web 方向概念规范,包含 Webroamer、FRL、请求头与兼容边界。" + }, + { + "module": "reference", + "title": "Reference 网站编辑指南", + "description": "Reference 文档网站的内容目录、structure.json、Markdown 写作、校验与 PR 发布指南。" } ] \ No newline at end of file diff --git a/content/next-web/overview/zh-hans.md b/content/next-web/overview/zh-hans.md new file mode 100644 index 0000000..2e2d110 --- /dev/null +++ b/content/next-web/overview/zh-hans.md @@ -0,0 +1,98 @@ +# Next Web 规范(草案) + + +## 文档树 + +页面文档树使用 FON 对象表达: + +```fer +header = { + title = `Welcome` + manifest = { url = ./manifest.json } +} + +body = { + content = `some text...` + button = { + style = { + padding = 10 + background = { color = #AEA4E4 } + } + on-click = noop + } +} + +noop = (event: Event) -> Style { + // 待定:事件到样式的完整语义 +} +``` + +页面对象、样式对象、事件处理器和资源对象应当通过 scheme 定义,而不是依赖浏览器对任意字段名的动态猜测。`#AEA4E4` 等颜色值属于 Web 平台 scheme 的候选扩展。 + +## Webroamer + +Webroamer 是该方向的浏览器或页面运行时名称。运行时需要完成以下工作:解析页面 FON、加载并验证 scheme、构造文档树、绑定事件、执行安全的 Fer 逻辑,并将结构映射到目标渲染后端。 + +运行时不得把不可信页面中的字段当作任意 Fer 代码执行。事件、样式、资源和网络访问都必须通过受限接口和权限模型进行。 + +## FRL + +Next Web 使用 [Fer Resource Locator(FRL)](../../fon/frl/zh-hans.md) 表达资源位置: + +```fer +locator: FRL = { + protocol = Protocol.https + identifier = `fuyeor.com` + params = { q = `WebRoamer` } +} +``` + +FRL 也可以在地址栏或 Markdown 中以一维 FON 形式出现。URL 文本和结构化 FRL 之间的转换必须进行正确编码,并且不得因为解析地址就自动发起请求。 + +## 请求头与身份 + +Webroamer 方向把应用层请求头建模为 FON 对象,并可以在 HTTP/3 传输层外使用最小兼容头: + +```fer +RequestHeader: struct { + method: HttpMethod + path: string + version: string + client-identity: ClientIdentity +} +``` + +```http +:method = POST +:scheme = https +:authority = fuyeor.com +:path = /search +content-type = application/fon +``` + +客户端身份声明可以包含浏览器、能力、操作系统和隐私等级: + +```fer +client-identity = { + browser = { name = `Webroamer`, version = 1.0.0 } + capabilities = { gpu-acceleration = true, color-space = .p3 } + os = { name = `WebroamerOS`, version = 2.4, arch = `arch64` } + privacy-level = .strict +} +``` + +身份声明必须遵循最小披露原则。浏览器不得把未获授权的硬件、系统或用户信息自动加入声明;能力枚举、隐私等级和用户同意流程待定。 + +## 兼容边界 + +Next Web 可以使用传统 HTTP/3 作为外层传输兼容层,但不应把 HTTP/3 的头部语义与 FON 对象语义混为一谈。`application/fon`、请求方法、二进制编码和响应协商都需要单独的协议规范。 + +本页不规定 HTML、CSS 或 JavaScript 的兼容实现,也不宣称 Webroamer、FON 二进制格式或 WebGPU 渲染后端已经实现。 + +## 相关主题 + +- [FON 概览](../../fon/overview/zh-hans.md) +- [FON Scheme](../../fon/schemes/zh-hans.md) +- [FON 序列化](../../fon/serialization/zh-hans.md) +- [FRL](../../fon/frl/zh-hans.md) +- [Fer 实现后端](../../fer/backends/zh-hans.md) diff --git a/content/next-web/structure.json b/content/next-web/structure.json new file mode 100644 index 0000000..9bf5739 --- /dev/null +++ b/content/next-web/structure.json @@ -0,0 +1,11 @@ +{ + "title": { + "zh-hans": "Next Web 规范" + }, + "description": { + "zh-hans": "基于 FON 文档树与 Fer Interpreter 的 Web 方向概念规范,包含 Webroamer、FRL、请求头与兼容边界。" + }, + "navigation": [ + { "slug": "overview" } + ] +} diff --git a/content/reference/markdown/zh-hans.md b/content/reference/markdown/zh-hans.md new file mode 100644 index 0000000..eb2c0f0 --- /dev/null +++ b/content/reference/markdown/zh-hans.md @@ -0,0 +1,52 @@ +# Markdown 编辑规范 + +Reference 文档使用 FFM Markdown 编写。页面应保持纯文本、结构清晰、链接稳定,并让读者能够从标题和示例直接理解页面责任。文档不应依赖 HTML、内联脚本或无法在站点渲染器中稳定工作的自定义标签。 + +## 文件和标题 + +文件名使用小写 kebab-case,例如 `memory-and-performance/zh-hans.md`。每个页面必须有一个 `#` 一级标题,并且标题应与页面主题一致。正文从一级标题之后开始,不在文件开头加入 ``、路径注释或“状态:草案 v...”形式的重复元信息;版本、稳定性和适用范围应写在正文的合适章节中。 + +页面标题与目录 slug 不必逐字相同,但 slug 必须稳定。除非页面已经重命名并同步所有链接,否则不要为了修正文案随意改变 slug。 + +## 规范性措辞 + +| 措辞 | 用法 | +| :--- | :--- | +| **必须** | 不满足时,输入、实现或文档示例不合规。 | +| **不得** | 明确禁止某种行为,不能静默转换成另一种语义。 | +| **应** | 默认要求;偏离时应记录原因、范围和影响。 | +| **可以** | 允许但不强制的能力。 | +| **待定** | 设计尚未冻结,不能作为稳定兼容承诺。 | + +规范页必须说明要求的对象,例如“解析器必须拒绝……”或“格式化工具不得……”,避免使用无法审查的空泛表达。涉及实现自由时,应区分可观察语义与内部算法。 + +## 示例 + +示例只使用当前页面或已链接主题定义的语法。示例应尽量短,并在示例后解释关键行为、错误边界和资源生命周期。对于不完整或概念性的 API,应明确标记为草案、伪代码或待定方向,不得让读者误以为已经实现。 + +```fer +config = { + name = `reference` + stable = true +} +``` + +代码块语言标记必须准确,例如 `fer`、`fon`、`json`、`http` 或 `text`。JSON 示例必须是合法 JSON;Fer 和 FON 示例则应遵守对应规范的分隔符、注释和结构规则。 + +## 链接 + +同一模块内优先使用相对链接,并指向实际存在的 `zh-hans.md` 页面目录,不要把源文件扩展名写进站点导航 URL: + +```markdown +[结构定义](../structure-json/zh-hans) +``` + +跨模块链接同样使用相对路径,并在移动文档时通过全文搜索同步更新。外部资料应链接到权威来源,例如规范原文、官方项目文档或官方工具页面;链接文字应说明目标,不要只写“点击这里”。 + +## 表格与列表 + +表格用于字段、选项、版本或规则的对照,不要把一整篇叙述拆成过多列表。连续步骤使用有序列表,独立要求使用短列表;复杂背景和规范解释优先使用完整段落。表格必须使用 Markdown pipe table,不使用 HTML 表格。 + +## 修改已有页面 + +修改已有页面时保留仍然有效的注释、示例和链接,不要为了减少差异而重排无关内容。若页面的规则发生变化,应同步更新受影响的示例、导航和交叉链接,并在 PR 描述中说明范围。 diff --git a/content/reference/overview/zh-hans.md b/content/reference/overview/zh-hans.md new file mode 100644 index 0000000..52ecff2 --- /dev/null +++ b/content/reference/overview/zh-hans.md @@ -0,0 +1,40 @@ +# Reference 网站编辑指南 + +Reference 是 Fuyeor 生态的文档网站。网站内容以 `content/` 下的模块目录为来源,每个模块通过 `structure.json` 描述标题、简介和导航,再由内容生成器生成本地化结构与页面元数据。 + +## 内容目录 + +```text +content/ +├── / +│ ├── structure.json +│ ├── overview/ +│ │ └── zh-hans.md +│ └──
// +│ └── zh-hans.md +└── ... +``` + +`` 是 URL 中的模块名,例如 `fer`、`fon`、`ffm` 和 `reference`。文档路径必须与 `structure.json` 中的导航路径一致;如果导航节点包含子导航,节点的 `slug` 会成为实际目录的一部分。 + +## 模块边界 + +一个模块应围绕清晰的产品、语言、平台或编辑主题组织。Fer 与 FON 分别作为独立模块维护,Next Web 作为依赖 FON 与 Fer 的独立方向维护,Reference 模块只记录本网站的编辑和发布规则。 + +模块之间可以通过相对 Markdown 链接互相引用,但不应复制另一模块的正文。规范、教程、API 参考和编辑指南应保持各自的责任边界;如果一个页面需要解释另一个模块的完整规则,应链接到其权威页面,而不是维护第二份版本。 + +## 语言文件 + +当前新增规范模块先提供 `zh-hans.md`。未提供的英文页面不得在 `structure.json` 中伪造正文;内容生成器会为缺失语言生成回退结构,但编辑者仍应把实际存在的语言文件作为唯一内容来源。未来添加英文版时,应在同一目录补充 `en.md`,并保持语义、示例和链接同步。 + +## 编辑原则 + +文档应先表达稳定的概念和边界,再给出最小可运行示例。规范页使用明确的“必须”“不得”“应”和“可以”区分要求强度;尚未冻结的设计应说明其限制,不得把推测写成兼容承诺。 + +Reference 的更改通过分支和 Pull Request 审查。直接修改 `main` 只适用于已明确授权的紧急维护;普通文档更新应让差异、链接和生成结果在 PR 中可复查。 + +## 相关指南 + +- [structure.json 编写方式](../structure-json/zh-hans.md) +- [Markdown 编辑规范](../markdown/zh-hans.md) +- [编辑与 PR 工作流](../workflow/zh-hans.md) diff --git a/content/reference/structure-json/zh-hans.md b/content/reference/structure-json/zh-hans.md new file mode 100644 index 0000000..7419cc0 --- /dev/null +++ b/content/reference/structure-json/zh-hans.md @@ -0,0 +1,83 @@ +# structure.json 编写方式 + +`structure.json` 是一个 content 模块的导航源文件。它不承载正文,也不负责定义页面的 Markdown 内容;它只描述模块元数据和页面树。内容生成器会根据它生成 `structure.en.json`、`structure.zh-hans.json` 等本地化结构文件,并扫描实际 Markdown 文件生成页面元数据。 + +## 最小结构 + +```json +{ + "title": { + "zh-hans": "模块标题" + }, + "description": { + "zh-hans": "模块简介。" + }, + "navigation": [ + { "slug": "overview" } + ] +} +``` + +`title` 和 `description` 使用本地化对象。暂不提供英文版的模块可以只写 `zh-hans`;不要为了填充字段而复制机器翻译或虚构英文页面。`navigation` 中的每个叶节点必须对应一个目录及其中的 `.md` 文件。 + +## 页面节点 + +最简单的页面节点只有 `slug`: + +```json +{ "slug": "overview" } +``` + +如果需要给目录节点或没有对应正文的导航分组命名,可以提供本地化 `title` 和子 `navigation`: + +```json +{ + "slug": "tutorials", + "title": { + "zh-hans": "基础指南" + }, + "navigation": [ + { "slug": "getting-started" }, + { "slug": "syntax" } + ] +} +``` + +上例要求存在以下文件: + +```text +content//tutorials/getting-started/zh-hans.md +content//tutorials/syntax/zh-hans.md +``` + +子导航的 `slug` 会参与实际路径拼接。不要把根目录中的 `formatting/zh-hans.md` 放在名为 `tooling` 的子导航下,否则生成器会寻找不存在的 `tooling/formatting/zh-hans.md`。 + +## 叶节点与标题 + +叶节点的页面标题默认从 Markdown 第一个一级标题读取,因此推荐只写 `slug`,并把真实标题放在正文的 `#` 标题中。目录节点没有独立 Markdown 页面时,必须通过 `title` 提供导航显示名称。 + +```json +{ + "slug": "apis", + "title": { + "zh-hans": "服务端点" + }, + "navigation": [ + { "slug": "depict" } + ] +} +``` + +## 编写检查表 + +| 检查项 | 要求 | +| :--- | :--- | +| JSON 语法 | 必须是合法 JSON,使用双引号,不写注释和尾逗号。 | +| 模块目录 | `content//structure.json` 必须位于模块根目录。 | +| slug | 使用稳定、简短的 kebab-case,并与实际目录名一致。 | +| 页面文件 | 每个叶节点都必须存在对应语言的 Markdown 文件。 | +| 路径层级 | 子导航会增加目录层级,不能只改变显示名称。 | +| 语言 | 只提供实际存在的语言;中文-only 模块至少提供 `zh-hans`。 | +| 结构责任 | structure.json 只管导航,不把长篇正文塞入 JSON。 | + +结构变更应与新增或移动的页面放在同一个 PR 中。移动页面时必须同步修改所有相对链接,并检查生成器是否仍能找到每个叶节点。 diff --git a/content/reference/structure.json b/content/reference/structure.json new file mode 100644 index 0000000..2f99307 --- /dev/null +++ b/content/reference/structure.json @@ -0,0 +1,14 @@ +{ + "title": { + "zh-hans": "Reference 网站编辑指南" + }, + "description": { + "zh-hans": "Reference 文档网站的内容目录、structure.json、Markdown 写作、校验与 PR 发布指南。" + }, + "navigation": [ + { "slug": "overview" }, + { "slug": "structure-json", "title": { "zh-hans": "structure.json 编写方式" } }, + { "slug": "markdown", "title": { "zh-hans": "Markdown 编辑规范" } }, + { "slug": "workflow", "title": { "zh-hans": "编辑与 PR 工作流" } } + ] +} diff --git a/content/reference/workflow/zh-hans.md b/content/reference/workflow/zh-hans.md new file mode 100644 index 0000000..1349694 --- /dev/null +++ b/content/reference/workflow/zh-hans.md @@ -0,0 +1,54 @@ +# 编辑与 PR 工作流 + +Reference 的普通文档变更应通过独立分支和 Pull Request 完成。这样可以让结构、链接、正文和生成结果在合并前被复查,也能避免未审查内容直接进入 `main`。 + +## 推荐流程 + +```text +更新 main + → 创建 docs/ 或 fix/ 分支 + → 修改 Markdown 与 structure.json + → 检查链接、JSON 和导航路径 + → 运行测试与生成器 + → 检查 diff + → 创建 PR + → 根据审查意见修改 + → 合并后删除分支 +``` + +开始工作前先同步远端: + +```sh +git fetch origin main +git switch -c docs/update-reference-content origin/main +``` + +分支名应描述变更目的。文档提交遵循 Angular Conventional 风格,首字母大写,例如: + +```text +docs: Add Fer and FON reference modules +``` + +## 提交前检查 + +| 检查 | 目的 | +| :--- | :--- | +| `git diff --check` | 发现尾随空格和空白错误。 | +| JSON 解析 | 确认每个新增或修改的 `structure.json` 是合法 JSON。 | +| 导航路径 | 确认每个叶节点都有对应的 `zh-hans.md`。 | +| 相对链接 | 确认页面移动后没有残留旧路径或死链。 | +| 内容生成 | 运行仓库提供的 generator,检查本地化 structure 和页面元数据。 | +| 自动化测试 | 运行 `pnpm test`;若改动只涉及内容,也应记录测试结果。 | +| 差异审查 | 确认没有把生成文件、密钥、临时日志或无关格式化提交进 PR。 | + +生成器对缺少语言文件可能输出警告。中文-only 模块可以暂不提供英文正文,但 PR 描述应明确这是有意选择,而不是遗漏。 + +## PR 内容 + +PR 标题应简洁说明变更结果。正文至少说明变更模块、导航或链接影响、是否新增语言文件、运行过的检查,以及是否存在尚未冻结的内容。涉及规范迁移时,应说明源仓库、目标路径和被移除的头部元信息。 + +PR 不应包含研究日志、临时脚本、中文以外的过程性说明文件或与目标无关的代码。需要长期维护的编辑规则应写入 [Reference 网站编辑指南](../overview/zh-hans),而不是只留在 PR 对话中。 + +## 合并后 + +合并后确认 `main` 的内容目录、生成产物和站点页面都能访问。若发现导航路径错误,应优先修复 `structure.json` 或目录结构,而不是在前端增加额外的路径兜底。稳定链接一旦公开,后续重命名必须同时提供迁移或重定向策略。