docs: establish Endorphin language documentation baseline
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# 1. 语言概览
|
||||
|
||||
Endorphin 是一门兼顾前端与后端的云原生编程语言。它用共享的数据结构和普通逻辑调用连接应用的不同部分,使开发者可以直接表达业务输入、计算过程和结果。
|
||||
|
||||
一段业务逻辑可以由其他 namespace 引用和调用。调用方使用逻辑的名称、参数和结果类型;通信、缓存和执行组织由系统承担,不要求业务代码另行编写协议客户端或服务接口。
|
||||
|
||||
## 1.1 应用模型
|
||||
|
||||
Endorphin 应用由相互引用的声明组成:
|
||||
|
||||
| 声明 | 描述的内容 | 典型用途 |
|
||||
| --- | --- | --- |
|
||||
| 类 | 数据结构与字段类型 | 前后端共同理解商品数据 |
|
||||
| 函数 | 输入、计算和输出 | 计算价格、组合业务步骤 |
|
||||
| 场景 | 界面与渲染树 | 展示文本和排列界面元素 |
|
||||
|
||||
Agent 是后续扩展的应用领域;其声明与行为语法尚未定义,见[应用领域](../appendices/application-domains.md)。
|
||||
|
||||
## 1.2 代码组织
|
||||
|
||||
每段代码属于一个用户和至少一级 namespace。用户通过唯一用户名标识,namespace 通过完整 key 定位,例如:
|
||||
|
||||
```text
|
||||
alice:shop.pricing
|
||||
```
|
||||
|
||||
`alice` 是用户名,`shop.pricing` 是 namespace 路径。代码归属保存在外部上下文与索引中,正文无需声明自己的 namespace。
|
||||
|
||||
代码以独立代码段存储,通过索引形成 namespace 的可见代码视图。namespace 是语言的代码组织单位,源码文件不承担这一职责。
|
||||
|
||||
## 1.3 声明与调用
|
||||
|
||||
代码归属:`alice:shop.pricing`。该 namespace 定义价格计算函数:
|
||||
|
||||
```endorphin
|
||||
function discountedPrice(price: Int, discount: Int): Int {
|
||||
return price - discount
|
||||
}
|
||||
```
|
||||
|
||||
函数接收原价和优惠额,返回两者之差。应用的另一部分可以引用其 namespace,再用调用表达式计算价格:
|
||||
|
||||
```text
|
||||
discountedPrice(100, 10) → 90
|
||||
```
|
||||
|
||||
这里展示的是本书采用的函数写法。关键字、类型标注和调用规则会在基础语法部分逐项说明;完整跨 namespace 示例见[函数与调用](09-functions-and-calls.md)。
|
||||
|
||||
## 1.4 执行阶段
|
||||
|
||||
Endorphin 将程序处理划分为两个阶段:
|
||||
|
||||
- **Preflight**:理解声明与引用,检查名称、类型和程序结构,准备执行。
|
||||
- **inflight**:使用实际输入执行逻辑,交付结果,并产生界面或其他业务效果。
|
||||
|
||||
阶段与前端、后端是不同概念。前端界面与后端逻辑都可以经过 Preflight,并在 inflight 中产生效果。namespace 的路径名称不决定阶段或执行位置。
|
||||
|
||||
## 1.5 本书范围
|
||||
|
||||
本书描述源码写法及其可观察行为,包括代码归属、声明、类型、表达式、调用、数据读取和 UI。通信协议、数据库绑定、缓存、部署和编排机制属于系统实现,不在语言介绍中展开。
|
||||
|
||||
下一章首先说明参与代码定位的用户身份,再介绍 namespace 与程序结构。
|
||||
|
||||
[下一章:用户身份](02-user-identity.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,77 @@
|
||||
# 2. 用户身份
|
||||
|
||||
用户身份是代码归属与 namespace 定位的基础。每个代码段必须关联一个归属用户,该用户以系统内唯一的用户名标识。
|
||||
|
||||
## 2.1 用户名与显示名
|
||||
|
||||
用户名(handle)是用于定位用户的唯一名称,其作用类似社交平台的 `@` 名。显示名是用于界面展示的姓名或昵称,不承担唯一定位职责。
|
||||
|
||||
| 属性 | 用户名 | 显示名 |
|
||||
| ---------------- | ------------------ | -------- |
|
||||
| 用途 | 唯一定位用户及其 namespace | 面向读者展示名称 |
|
||||
| 唯一性 | 在本系统内唯一 | 可以重复 |
|
||||
| 参与 namespace key | 是 | 否 |
|
||||
| 示例 | `alice` | `林` |
|
||||
|
||||
两个用户可以同时使用显示名“林”,但其用户名必须不同。检索代码时使用用户名,不能以显示名替代。
|
||||
|
||||
用户名的唯一性限定在本系统的身份范围内。其他系统中相同的用户名不自动表示同一用户。
|
||||
|
||||
## 2.2 key 中的用户部分
|
||||
|
||||
完整 namespace key 由用户名与非空 namespace 路径组成:
|
||||
|
||||
```text
|
||||
用户名:namespace路径
|
||||
alice:shop.ui
|
||||
```
|
||||
|
||||
冒号前的 `alice` 是用户名,不带 `@` 前缀;冒号后的 `shop.ui` 定位该用户名下的 namespace。
|
||||
|
||||
| key | 归属用户 | namespace 路径 |
|
||||
| --- | --- | --- |
|
||||
| `alice:shop` | `alice` | `shop` |
|
||||
| `bob:shop` | `bob` | `shop` |
|
||||
| `alice:shop.ui` | `alice` | `shop.ui` |
|
||||
|
||||
`alice:shop` 与 `bob:shop` 是不同的 namespace,即使它们具有相同的路径或相同的代码内容。
|
||||
|
||||
只有用户名不能构成代码归属地址。代码必须同时属于至少一级 namespace,完整格式见[namespace](03-namespaces.md)。
|
||||
|
||||
## 2.3 归属上下文
|
||||
|
||||
用户身份通过代码之外的 key 与索引成员关系关联。读取、编辑和处理代码时,系统使用该归属上下文。
|
||||
|
||||
场景名、变量名、注释、字符串和存储对象名均不定义归属用户。两段内容相同的代码分别关联不同用户时,其归属上下文仍然不同。
|
||||
|
||||
正文中的 `use alice:shop.pricing` 表示引用目标,不表示当前代码属于 alice。例如,`bob:shop.checkout` 可以引用 alice 的逻辑,其自身归属仍是 bob。
|
||||
|
||||
## 2.4 归属用户、操作用户与作者
|
||||
|
||||
三种身份承担不同职责:
|
||||
|
||||
| 身份 | 含义 | 关联对象 |
|
||||
| --- | --- | --- |
|
||||
| 归属用户 | 代码位于谁的 namespace | namespace key 与代码成员关系 |
|
||||
| 操作用户 | 谁发起读取、修改或执行 | 本次操作的身份上下文 |
|
||||
| 作者或修改者 | 谁编写或修改了代码 | 编辑或历史记录 |
|
||||
|
||||
在协作授权存在的情况下,操作用户可以与归属用户不同。例如 bob 获得修改 `alice:shop` 的权限后,修改行为不会将目标自动改归 `bob:shop`。
|
||||
|
||||
Agent 或服务代用户操作时同样需要区分操作身份与目标归属。协作、委托和历史记录的具体规则参见[规范状态](../appendices/specification-status.md#身份与权限)。
|
||||
|
||||
## 2.5 身份与访问权限
|
||||
|
||||
namespace key 是定位信息,不是访问凭据。知道用户名或 key,不等于获得读取、修改或调用其中声明的权限。
|
||||
|
||||
代码归属与访问控制分别处理:归属确定目标,授权确定本次操作是否允许。代码默认公开性、跨用户可见性及权限继承规则不由 key 的结构推导。
|
||||
|
||||
## 2.6 名称比较与生命周期
|
||||
|
||||
注册、检索与改名必须使用一致的用户名相等判定。两个被判定为相同的用户名不能同时指向不同用户。
|
||||
|
||||
显示名不参与 key,修改显示名不改变代码归属。handle 的变更涉及既有 key 与引用的定位;旧名称复用还涉及历史引用是否继续指向原用户。
|
||||
|
||||
用户名字符集合、大小写、Unicode 处理、改名、名称复用、账号停用和归属转移的具体规则集中列于[规范状态](../appendices/specification-status.md#身份与权限)。本书示例使用简单的小写用户名说明结构,不据此限定最终字符集。
|
||||
|
||||
[上一章:语言概览](01-overview.md) · [下一章:namespace](03-namespaces.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,65 @@
|
||||
# 3. namespace
|
||||
|
||||
namespace 是代码归属、组织与检索的单位。系统使用 namespace key 查找索引,取得对应代码段,并形成可见代码视图。
|
||||
|
||||
## 3.1 key 格式
|
||||
|
||||
```text
|
||||
用户名:第一级namespace.后续namespace
|
||||
```
|
||||
|
||||
key 由一个用户名、一个冒号和至少一个 namespace 路径段组成。路径段之间用点号连接:
|
||||
|
||||
| key | 结构 |
|
||||
| --- | --- |
|
||||
| `alice:shop` | 用户名与一级 namespace |
|
||||
| `alice:shop.pricing` | 用户名与两级 namespace |
|
||||
| `alice:shop.backend.orders` | 用户名与三级 namespace |
|
||||
|
||||
key 中的用户名规则见[用户身份](02-user-identity.md)。namespace 路径段在本文词法草案中使用标识符,详见[词法结构](06-lexical-structure.md)。
|
||||
|
||||
## 3.2 最小归属
|
||||
|
||||
代码必须同时具有用户和非空 namespace 路径。下列形式缺少必要信息:
|
||||
|
||||
| 形式 | 缺少的内容 |
|
||||
| --- | --- |
|
||||
| `alice` 或 `alice:` | namespace 路径 |
|
||||
| `:shop` | 用户名 |
|
||||
| `alice.shop.ui` | 用户名与 namespace 的分隔冒号 |
|
||||
|
||||
显示名不能替代用户名。代码也不能直接归属于没有 namespace 的用户根层级。
|
||||
|
||||
## 3.3 层级语义
|
||||
|
||||
用户之下的第一级 namespace 与所有后续层级具有相同语义。`shop` 在位置上类似 repository 那一层,但不构成独立的 repository 或特殊 module 类型。
|
||||
|
||||
namespace 路径表示组织关系。路径段名 `ui`、`backend`、`data` 或 `agents` 不自动决定执行位置、数据存储、通信方式或语言阶段。
|
||||
|
||||
父子 namespace 的可见性与成员范围需要独立规则;仅凭路径前缀不能认定读取父级一定包含全部子级代码。
|
||||
|
||||
## 3.4 可见代码视图
|
||||
|
||||
代码以独立代码段存储,索引关联完整 key 与代码段。可见代码视图是根据这些成员关系获得的逻辑代码集合:
|
||||
|
||||
```text
|
||||
alice:shop.pricing
|
||||
→ namespace 索引
|
||||
→ 对应的独立代码段
|
||||
→ 可见代码视图
|
||||
```
|
||||
|
||||
视图可以用于阅读和程序处理,不依赖源码文件的物理路径。S3 承担代码段的存储职责;对象键与语言中的 namespace key 是不同概念,详细约定见[代码存储与视图](../appendices/code-storage-and-views.md)。
|
||||
|
||||
## 3.5 归属与引用
|
||||
|
||||
归属 key 定位当前代码,use key 定位它引用的代码。两者使用同一 key 格式,但承担不同职责:
|
||||
|
||||
```text
|
||||
当前代码:bob:shop.checkout
|
||||
引用目标:alice:shop.pricing
|
||||
```
|
||||
|
||||
当前代码的 key 由外部上下文提供;引用目标写入正文的 `use` 声明。引用不改变归属,也不自动授予访问权限。下一章说明声明与导入的组织方式。
|
||||
|
||||
[上一章:用户身份](02-user-identity.md) · [下一章:程序结构与导入](04-program-structure.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,65 @@
|
||||
# 4. 程序结构与导入
|
||||
|
||||
一个 namespace 的代码视图由导入和声明组成。声明描述类型、逻辑或界面;导入使代码能够引用其他 namespace 中允许使用的声明。
|
||||
|
||||
## 4.1 正文结构
|
||||
|
||||
本文采用的程序结构为:
|
||||
|
||||
```text
|
||||
零个或多个 use 声明
|
||||
一个或多个 class、function 或 export scene 声明
|
||||
```
|
||||
|
||||
声明之间不使用逗号或分号。正文不含自身 namespace 声明,其归属来自外部 key 与索引。
|
||||
|
||||
这是一份逻辑代码视图的语法结构,不规定独立代码段的存储粒度或物理排列。代码段边界及视图组装规则见[代码存储与视图](../appendices/code-storage-and-views.md)。
|
||||
|
||||
## 4.2 use 声明
|
||||
|
||||
代码归属:`bob:shop.checkout`。导入声明:
|
||||
|
||||
```endorphin
|
||||
use alice:shop.pricing
|
||||
```
|
||||
|
||||
`use` 后跟一个完整 namespace key。用户名与路径用冒号分隔,路径层级用点号分隔。每个 `use` 引用一个 namespace,不附加类名、函数名或选择性名称列表。
|
||||
|
||||
引用整个 namespace 表示指定依赖来源,不表示获得访问权限或自动执行其中的函数。
|
||||
|
||||
## 4.3 声明组合
|
||||
|
||||
代码归属:`alice:shop.data`。
|
||||
|
||||
```endorphin
|
||||
class Product {
|
||||
name: String
|
||||
price: Int
|
||||
}
|
||||
|
||||
function listedPrice(product: Product): Int {
|
||||
return product.price
|
||||
}
|
||||
```
|
||||
|
||||
同一视图可以同时包含类和函数,也可以包含场景。类与函数不需要依附 UI 场景;只有业务逻辑的 namespace 无需声明 render。
|
||||
|
||||
类、函数和场景的内部结构分别在[类型与类](07-types-and-classes.md)、[函数与调用](09-functions-and-calls.md)和[场景与渲染树](11-scenes-and-render-trees.md)中定义。
|
||||
|
||||
## 4.4 名称引用
|
||||
|
||||
导入后的声明必须依据可见性和名称查找规则使用。跨 namespace 示例采用“导入的名称可直接查找且没有冲突”的简化条件,用于展示调用含义;这不是对全部声明自动进入作用域的承诺。
|
||||
|
||||
名称限定、别名、同名冲突与可见性规则列于[规范状态](../appendices/specification-status.md#引用与代码视图)。官方 UI 组件的来源单独说明,不属于示例用户库。
|
||||
|
||||
## 4.5 程序与局部片段
|
||||
|
||||
本书区分三类示例:
|
||||
|
||||
- 声明示例:展示可以出现在代码视图中的类、函数或场景。
|
||||
- 函数体片段:展示 let、return 或局部表达式。
|
||||
- 渲染节点片段:展示 render 内的组件树。
|
||||
|
||||
局部片段用于查询语法,不自动成为程序顶层入口。入口选择、空视图与多个场景的选择规则仍列于[规范状态](../appendices/specification-status.md#声明与类型)。
|
||||
|
||||
[上一章:namespace](03-namespaces.md) · [下一章:Preflight 与 inflight](05-preflight-and-inflight.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,63 @@
|
||||
# 5. Preflight 与 inflight
|
||||
|
||||
Endorphin 将构建阶段称为 **Preflight**,将运行阶段称为 **inflight**。这两个名称表示程序处理职责,不是源码关键字。
|
||||
|
||||
## 5.1 Preflight
|
||||
|
||||
Preflight 读取代码视图及其归属上下文,理解声明和引用,为程序执行做好准备。
|
||||
|
||||
其语言职责包括:
|
||||
|
||||
- 按词法和语法规则理解类、函数、场景与表达式。
|
||||
- 解析 use 指向的 namespace 及允许使用的声明。
|
||||
- 检查名称、字段、参数与返回类型。
|
||||
- 检查场景结构及组件用法。
|
||||
- 识别逻辑调用与结果使用之间的依赖。
|
||||
- 报告可以静态确定的错误。
|
||||
|
||||
声明函数不表示在 Preflight 中执行函数体,声明类也不表示读取业务数据。导入 namespace 用于理解依赖,而不是执行其所有逻辑。
|
||||
|
||||
## 5.2 inflight
|
||||
|
||||
inflight 使用实际输入执行程序,产生程序可以观察到的结果。
|
||||
|
||||
其语言职责包括:
|
||||
|
||||
- 按函数定义计算并返回结果。
|
||||
- 取得调用所请求的数据。
|
||||
- 向后续表达式提供成功结果。
|
||||
- 保持代码定义的数据依赖与业务效果。
|
||||
- 根据场景和程序结果产生 UI。
|
||||
- 表达执行中出现的失败或其他结果状态。
|
||||
|
||||
通信、缓存和执行组织方式可以由系统安排,但必须保持语言定义的值、类型、依赖和效果。
|
||||
|
||||
## 5.3 阶段边界
|
||||
|
||||
| 程序内容 | Preflight | inflight |
|
||||
| --- | --- | --- |
|
||||
| class 声明 | 理解字段及类型 | 在数据使用中遵守该结构 |
|
||||
| function 声明 | 检查参数、函数体与返回类型 | 调用发生时执行逻辑 |
|
||||
| use 声明 | 理解依赖并解析可用声明 | 在调用中使用相应逻辑 |
|
||||
| 调用表达式 | 检查目标与输入类型 | 使用实际输入并取得结果 |
|
||||
| 场景声明 | 检查渲染树与组件约束 | 呈现内容和排列关系 |
|
||||
|
||||
实际业务调用属于 inflight。Preflight 的准备与检查不改变调用发生时应有的语义;若引入构建阶段求值,需要另外定义相应规则。
|
||||
|
||||
## 5.4 诊断与执行失败
|
||||
|
||||
语法错误、未定义名称和可静态判断的类型错误由 Preflight 报告。数据不存在、调用无法完成等执行情况由 inflight 表达。
|
||||
|
||||
静态检查通过不保证业务调用一定成功。诊断应能定位相关声明或表达式;错误处理、取消和持续结果的具体写法见[规范状态](../appendices/specification-status.md#调用与数据)。
|
||||
|
||||
## 5.5 阶段与执行角色
|
||||
|
||||
阶段、应用角色和代码归属是不同维度:
|
||||
|
||||
- Preflight 与 inflight 表示处理阶段。
|
||||
- 前端、后端与 Agent 表示应用角色。
|
||||
- namespace key 表示代码归属与引用位置。
|
||||
|
||||
它们不要求一一对应,也不要求位于不同进程或机器。`alice:shop.ui` 的名称不会自动将其中所有代码限定在某个阶段或某类设备。
|
||||
|
||||
[上一章:程序结构与导入](04-program-structure.md) · [下一章:词法结构](06-lexical-structure.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,111 @@
|
||||
# 6. 词法结构
|
||||
|
||||
词法规则将源码划分为标识符、关键字、字面量、运算符和标点。源码使用 UTF-8;空白与注释用于分隔词法单元。
|
||||
|
||||
本章代码块展示局部词法形式,使用位置由后续表达式和声明规则决定,不是独立程序。
|
||||
|
||||
## 6.1 标识符
|
||||
|
||||
标识符以 `_` 或 Unicode 字母开头,后续可以包含 `_`、Unicode 字母或数字。名称区分大小写。
|
||||
|
||||
```text
|
||||
Product
|
||||
discountedPrice
|
||||
price
|
||||
product_1
|
||||
```
|
||||
|
||||
namespace 路径段使用标识符。用户名属于系统身份规则,不直接使用源码标识符的定义。
|
||||
|
||||
## 6.2 关键字
|
||||
|
||||
本文语法使用以下关键字:
|
||||
|
||||
| 关键字 | 用途 |
|
||||
| --- | --- |
|
||||
| `use` | 引用 namespace |
|
||||
| `class` | 声明数据结构 |
|
||||
| `function` | 声明函数 |
|
||||
| `let` | 绑定局部结果 |
|
||||
| `return` | 返回函数结果 |
|
||||
| `export`、`scene` | 声明导出的 UI 场景 |
|
||||
| `render` | 定义场景的渲染树 |
|
||||
|
||||
这些关键字在相应产生式的位置出现。完整保留字集合见[规范状态](../appendices/specification-status.md#词法与表达式)。
|
||||
|
||||
## 6.3 数字
|
||||
|
||||
数字字面量采用十进制,至少包含一位数字。小数点两侧均须有数字:
|
||||
|
||||
```endorphin
|
||||
0
|
||||
100
|
||||
1.5
|
||||
```
|
||||
|
||||
负号是运算符,而不是数字词法单元。`-4` 是对 `4` 使用一元负号,详见[表达式与绑定](08-expressions-and-bindings.md)。
|
||||
|
||||
本文数字语法不包含科学计数法、前导正号或省略小数点一侧数字的形式。数字类型、精度和范围由类型规则定义,而不是由字面量的字符形式决定。
|
||||
|
||||
## 6.4 字符串
|
||||
|
||||
字符串由双引号包围,可以直接包含 Unicode 字符:
|
||||
|
||||
```endorphin
|
||||
"Product"
|
||||
"商品"
|
||||
"First\nSecond"
|
||||
```
|
||||
|
||||
| 转义 | 含义 |
|
||||
| --- | --- |
|
||||
| `\n` | 换行 |
|
||||
| `\t` | 水平制表符 |
|
||||
| `\"` | 双引号 |
|
||||
| `\\` | 反斜杠 |
|
||||
|
||||
双引号、反斜杠和换行在字符串内使用上述转义。未闭合字符串和本文未定义的转义在 Preflight 中产生诊断。
|
||||
|
||||
## 6.5 符号字面量
|
||||
|
||||
点号后接标识符表示符号字面量:
|
||||
|
||||
```endorphin
|
||||
.title
|
||||
```
|
||||
|
||||
符号表达命名值,例如 UI 的标题角色。不带点号的 `title` 是名称引用,`product.name` 是成员访问,二者均不等同于 `.title`。
|
||||
|
||||
符号可用于哪些参数,由对应声明的类型与取值约定决定。
|
||||
|
||||
## 6.6 标点与运算符
|
||||
|
||||
| 字符 | 用途 |
|
||||
| --- | --- |
|
||||
| `{`、`}` | 声明体、函数体和子节点块 |
|
||||
| `(`、`)` | 参数、调用和表达式分组 |
|
||||
| `:` | key 分隔、类型标注和命名参数 |
|
||||
| `,` | 分隔参数 |
|
||||
| `.` | namespace 层级、成员访问和符号前缀 |
|
||||
| `=` | let 绑定 |
|
||||
| `+`、`-`、`*`、`/` | 算术运算 |
|
||||
|
||||
冒号的含义由语法位置确定:`alice:shop.data` 中分隔用户与路径,`price: Int` 中标注类型,`gap: 12` 中指定参数名。
|
||||
|
||||
## 6.7 空白与注释
|
||||
|
||||
空格、制表符和换行可出现在词法单元之间。缩进不构成代码块,代码块由花括号界定。
|
||||
|
||||
行注释以 `//` 开始,持续到下一行或源码结束。函数体片段:
|
||||
|
||||
```endorphin
|
||||
// 计算优惠后的金额
|
||||
let amount = 100 - 10
|
||||
return amount
|
||||
```
|
||||
|
||||
注释不参与求值。本文语法不包含块注释。
|
||||
|
||||
词法产生式集中列于[形式文法](../appendices/formal-grammar.md#词法)。
|
||||
|
||||
[上一章:Preflight 与 inflight](05-preflight-and-inflight.md) · [下一章:类型与类](07-types-and-classes.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,64 @@
|
||||
# 7. 类型与类
|
||||
|
||||
类型描述值的结构及其允许的用法。类型标注用于字段、函数参数和返回值,使不同应用部分能够依据同一声明理解数据。
|
||||
|
||||
## 7.1 类型标注
|
||||
|
||||
类型标注采用 `名称: 类型` 的形式:
|
||||
|
||||
```text
|
||||
price: Int
|
||||
name: String
|
||||
```
|
||||
|
||||
本文示例使用:
|
||||
|
||||
| 类型名 | 表达的值 |
|
||||
| --- | --- |
|
||||
| `Int` | 整数 |
|
||||
| `String` | 字符串 |
|
||||
| 用户声明的类名 | 具有该类字段结构的数据 |
|
||||
|
||||
数值范围、其他基础类型、可选类型和转换规则尚未构成完整类型体系,范围见[规范状态](../appendices/specification-status.md#声明与类型)。
|
||||
|
||||
## 7.2 class 声明
|
||||
|
||||
代码归属:`alice:shop.data`。
|
||||
|
||||
```endorphin
|
||||
class Product {
|
||||
name: String
|
||||
price: Int
|
||||
}
|
||||
```
|
||||
|
||||
该声明定义名为 `Product` 的数据结构,含有两个字段:`name` 为字符串,`price` 为整数。使用 Product 数据的代码依据同一结构读取字段,不需要为前端另写一份对应结构。
|
||||
|
||||
类名是标识符。类体由字段声明组成,每个字段写出名称和类型,字段之间不使用逗号或分号。
|
||||
|
||||
## 7.3 类型与值
|
||||
|
||||
`Product` 表示数据的类型;符合 Product 结构的某个值,才包含本次业务数据。
|
||||
|
||||
类声明本身不取得某件商品,也不指定数据库、表或连接。通过类型取得数据的用法在[数据读取](10-data-access.md)中说明;构造、方法与默认值属于独立的类型规则。
|
||||
|
||||
## 7.4 字段访问
|
||||
|
||||
函数体片段;局部名称 `product` 表示已取得的 Product 值:
|
||||
|
||||
```endorphin
|
||||
let name = product.name
|
||||
let price = product.price
|
||||
```
|
||||
|
||||
成员访问使用点号。第一行取得字符串字段,第二行取得整数字段。字段使用的类型由声明决定;读取不存在的字段不是有效的 Product 用法。
|
||||
|
||||
成员访问和 let 的表达式规则见下一章。
|
||||
|
||||
## 7.5 类型检查与共享
|
||||
|
||||
Preflight 理解类和字段声明,检查字段访问、函数参数与返回值的类型关系。inflight 中取得和使用的数据必须遵守对应结构。
|
||||
|
||||
跨 namespace 引用类时,引用的是定义该结构的声明,不改变调用方代码的归属。声明是否可访问取决于可见性和权限规则,见[程序结构与导入](04-program-structure.md)。
|
||||
|
||||
[上一章:词法结构](06-lexical-structure.md) · [下一章:表达式与绑定](08-expressions-and-bindings.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,68 @@
|
||||
# 8. 表达式与绑定
|
||||
|
||||
表达式描述计算并产生值。let 将表达式结果绑定到局部名称,后续表达式可以使用这个结果。
|
||||
|
||||
## 8.1 表达式形式
|
||||
|
||||
本文语法包含以下表达式:
|
||||
|
||||
| 形式 | 示例 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| 字面量 | `100`、`"商品"`、`.title` | 直接表达一个值 |
|
||||
| 名称引用 | `amount` | 使用已解析的名称 |
|
||||
| 一元表达式 | `-4` | 对值使用一元负号 |
|
||||
| 算术表达式 | `100 - 10` | 计算数值 |
|
||||
| 成员访问 | `product.price` | 使用字段或成员 |
|
||||
| 调用 | `discountedPrice(100, 10)` | 调用逻辑并取得结果 |
|
||||
| 分组 | `(100 - 10) * 2` | 改变表达式组合方式 |
|
||||
|
||||
具体名称和成员必须存在并符合类型要求。调用的参数和返回规则见[函数与调用](09-functions-and-calls.md)。
|
||||
|
||||
## 8.2 运算与优先级
|
||||
|
||||
从高到低的组合顺序为:
|
||||
|
||||
| 顺序 | 形式 |
|
||||
| --- | --- |
|
||||
| 1 | 分组中的表达式 |
|
||||
| 2 | 成员访问与调用 |
|
||||
| 3 | 一元负号 |
|
||||
| 4 | 乘法、除法 |
|
||||
| 5 | 加法、减法 |
|
||||
|
||||
同级二元算术运算在本文草案中按从左到右组合。`100 - 10 * 2` 先做乘法,结果为 `80`;`(100 - 10) * 2` 的结果为 `180`。
|
||||
|
||||
数值溢出、除法、隐式转换和其他运算符的规则见[规范状态](../appendices/specification-status.md#词法与表达式)。
|
||||
|
||||
## 8.3 let 绑定
|
||||
|
||||
函数体片段:
|
||||
|
||||
```endorphin
|
||||
let amount = 100 - 10
|
||||
let payable = amount - 5
|
||||
```
|
||||
|
||||
第一行将结果 `90` 绑定到 amount,第二行使用它得到 `85`。每个绑定包含关键字 `let`、局部名称、等号和表达式。
|
||||
|
||||
let 是结果绑定,不是 namespace 声明。本文函数文法将绑定放在函数体内;顶层绑定、重新赋值与可变性不由该语句推导。
|
||||
|
||||
## 8.4 成员访问
|
||||
|
||||
`值.成员名` 访问该值的字段或其他可用成员。类型检查决定访问是否合法。
|
||||
|
||||
`product.price` 使用 Product 的字段。`Product.get(...)` 则在形式上是先找到类成员,再调用;成员调用的形式不会自动为 Product 创建 get 方法,详见[数据读取](10-data-access.md)。
|
||||
|
||||
## 8.5 结果依赖
|
||||
|
||||
当一个表达式使用前一个调用的结果时,存在数据依赖:
|
||||
|
||||
```text
|
||||
第一次调用 → 结果绑定 → 使用该结果的第二次调用
|
||||
```
|
||||
|
||||
inflight 必须在结果可用后使用它,不能将未就绪状态替换为伪造成功值。Preflight 检查表达式结构与类型,不能据此保证所有实际调用成功。
|
||||
|
||||
表达式是否带有业务修改效果,以及失败、等待与取消的表示方式,由调用语义定义。算术的组合顺序不自动确定所有调用参数的求值顺序。
|
||||
|
||||
[上一章:类型与类](07-types-and-classes.md) · [下一章:函数与调用](09-functions-and-calls.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,90 @@
|
||||
# 9. 函数与调用
|
||||
|
||||
函数定义可调用的逻辑,包括名称、输入参数、结果类型和函数体。调用表达式提供输入,并取得函数定义的结果。
|
||||
|
||||
## 9.1 函数声明
|
||||
|
||||
代码归属:`alice:shop.pricing`。
|
||||
|
||||
```endorphin
|
||||
function discountedPrice(price: Int, discount: Int): Int {
|
||||
return price - discount
|
||||
}
|
||||
```
|
||||
|
||||
声明的组成如下:
|
||||
|
||||
| 部分 | 含义 |
|
||||
| --- | --- |
|
||||
| `function` | 函数声明关键字 |
|
||||
| `discountedPrice` | 函数名 |
|
||||
| `price: Int, discount: Int` | 两个输入参数及其类型 |
|
||||
| 参数列表后的 `: Int` | 返回类型 |
|
||||
| 花括号内的内容 | 函数体 |
|
||||
|
||||
参数按逗号分隔,每个参数都有名称与类型。本文基本函数体由零个或多个 let 绑定和一个末尾 return 组成;完整控制流另列于[规范状态](../appendices/specification-status.md#声明与类型)。
|
||||
|
||||
## 9.2 返回值
|
||||
|
||||
`return 表达式` 产生函数结果。表达式的类型必须符合返回类型。
|
||||
|
||||
discountedPrice 返回两个整数的差值。对于输入 `100` 与 `10`,成功结果为 `90`。定义函数不立即执行它;执行发生在 inflight 调用中。
|
||||
|
||||
## 9.3 跨 namespace 调用
|
||||
|
||||
代码归属:`bob:shop.checkout`。
|
||||
|
||||
```endorphin
|
||||
use alice:shop.pricing
|
||||
|
||||
function payable(price: Int, discount: Int): Int {
|
||||
let amount = discountedPrice(price, discount)
|
||||
return discountedPrice(amount, 5)
|
||||
}
|
||||
```
|
||||
|
||||
payable 引用定价 namespace,先使用原价与优惠额计算 amount,再从 amount 中扣除 `5`。对于输入 `100` 与 `10`,两次成功结果依次为 `90` 和 `85`。
|
||||
|
||||
该例采用第 4 章所述的无名称冲突、被引用函数可见的条件。use 定位依赖来源,函数调用使用其中的逻辑;二者分别承担引用和执行职责。
|
||||
|
||||
## 9.4 调用组合
|
||||
|
||||
代码归属:`bob:shop.ui`。业务函数声明:
|
||||
|
||||
```endorphin
|
||||
use bob:shop.checkout
|
||||
|
||||
function checkoutAmount(): Int {
|
||||
return payable(100, 10)
|
||||
}
|
||||
```
|
||||
|
||||
checkoutAmount 的成功结果为 `85`。它不需要重复实现价格计算,也不需要为跨 namespace 调用另写客户端、网络请求或编排配置。
|
||||
|
||||
相同的普通调用形式用于本地逻辑和跨执行位置的逻辑。执行位置和通信方式不改变输入、结果类型与数据依赖。
|
||||
|
||||
## 9.5 Preflight 检查
|
||||
|
||||
在名称和类型规则确定的范围内,Preflight 检查:
|
||||
|
||||
- 调用目标是否存在且允许使用。
|
||||
- 参数数量和类型是否符合声明。
|
||||
- return 表达式是否符合返回类型。
|
||||
- 使用调用结果的后续表达式是否合法。
|
||||
|
||||
例如,discountedPrice 需要两个整数参数。`discountedPrice(100)` 数量不符;`discountedPrice("100", 10)` 在本文不进行隐式字符串到整数转换的示例条件下类型不符。
|
||||
|
||||
## 9.6 inflight 行为
|
||||
|
||||
inflight 使用实际参数执行函数,并把成功结果交给调用表达式。依赖关系必须保留:payable 的第二次优惠计算使用第一次调用的 amount。
|
||||
|
||||
| 情况 | 行为要求 |
|
||||
| --- | --- |
|
||||
| 调用成功 | 结果的值和类型符合函数定义 |
|
||||
| 结果未就绪 | 依赖该结果的代码不能提前将它作为成功值使用 |
|
||||
| 调用失败 | 失败可被观察,不伪造成功结果 |
|
||||
| 执行位置变化 | 已定义的值、类型、依赖与业务效果保持一致 |
|
||||
|
||||
函数不默认被视为纯计算。对带业务修改效果的调用,系统不能为了执行组织而任意重复或并行执行;相关顺序、失败和取消语义见[规范状态](../appendices/specification-status.md#调用与数据)。
|
||||
|
||||
[上一章:表达式与绑定](08-expressions-and-bindings.md) · [下一章:数据读取](10-data-access.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,66 @@
|
||||
# 10. 数据读取
|
||||
|
||||
数据读取是逻辑调用的一种用法:代码引用数据结构,发起读取,并按声明的字段使用取得的结果。调用方处理业务数据,不处理传输响应或缓存连接。
|
||||
|
||||
## 10.1 数据结构
|
||||
|
||||
代码归属:`alice:shop.data`。商品结构沿用第 7 章的 Product:
|
||||
|
||||
```endorphin
|
||||
class Product {
|
||||
name: String
|
||||
price: Int
|
||||
}
|
||||
```
|
||||
|
||||
结构使调用方能够共同理解商品名称和价格。它不定义数据库表、持久化实体或自动建表行为。
|
||||
|
||||
## 10.2 读取形式
|
||||
|
||||
> 语法提案:本节用 `Product.get(...)` 表达“通过类取得数据”。get 的存在与声明方式尚未定义,该写法不是所有 class 自动拥有的成员。
|
||||
|
||||
代码归属:`bob:shop.checkout`。读取函数示例,采用 Product 与读取成员均可访问的条件;成功路径中,读取成员接收一个 String 标识并返回 Product,其正式声明语法仍未定义:
|
||||
|
||||
```endorphin
|
||||
use alice:shop.data
|
||||
|
||||
function productPrice(id: String): Int {
|
||||
let product = Product.get(id)
|
||||
return product.price
|
||||
}
|
||||
```
|
||||
|
||||
调用参数 id 表达所需数据的标识,不是 namespace key。`alice:shop.data` 定位数据结构与逻辑来源,id 指定本次业务对象。
|
||||
|
||||
成功调用 productPrice 后,返回值应为取得商品的 price 字段。结果已经具有 Product 结构,调用方无需先解析 HTTP 响应或手动转换传输数据。
|
||||
|
||||
## 10.3 读取与字段使用
|
||||
|
||||
读取结果可用后,才可读取它的字段。函数中的 product.price 依赖 Product.get 的成功结果;系统必须保持这一依赖。
|
||||
|
||||
Preflight 理解结构、引用和成员调用的类型关系,inflight 取得本次数据并交付结果。声明 Product 本身不在 Preflight 中读取商品。
|
||||
|
||||
具体读取成员必须在最终规则中具有可检查的参数与返回定义。仅有前面的字段声明不足以证明 get 调用合法。
|
||||
|
||||
## 10.4 结果状态
|
||||
|
||||
| 状态 | 调用方需要获知的内容 |
|
||||
| --- | --- |
|
||||
| 成功 | 符合 Product 结构的结果 |
|
||||
| 缺失 | 目标数据不存在 |
|
||||
| 失败 | 本次读取无法完成 |
|
||||
| 未就绪 | 成功结果尚未可用 |
|
||||
|
||||
上述函数只展示成功路径。缺失、失败和未就绪不能自动当作合法 Product,也不能默认替换成空字符串或零。
|
||||
|
||||
状态的类型与处理语法,以及是否需要显式等待,集中列于[规范状态](../appendices/specification-status.md#调用与数据)。
|
||||
|
||||
## 10.5 一次读取与持续结果
|
||||
|
||||
本节 get 提案按一次读取说明。持续跟随数据变化与一次读取具有不同的可观察行为;是否使用不同表达式或结果类型仍未定义。
|
||||
|
||||
UI 可以使用成功取得的字段展示内容,但加载、缺失、失败与后续更新需要对应的界面语义。正文不将未定义的数据绑定或读取调用直接混入 render 示例。
|
||||
|
||||
数据读取的协议、缓存和后端绑定不影响上述源码目标,也不在本章选择。
|
||||
|
||||
[上一章:函数与调用](09-functions-and-calls.md) · [下一章:场景与渲染树](11-scenes-and-render-trees.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,101 @@
|
||||
# 11. 场景与渲染树
|
||||
|
||||
场景声明描述一个 UI 视图。render 块包含该视图的渲染树,树中的节点表示组件、参数和子节点。
|
||||
|
||||
## 11.1 场景声明
|
||||
|
||||
代码归属:`bob:shop.ui`。
|
||||
|
||||
```endorphin
|
||||
export scene Main {
|
||||
render {
|
||||
Column(gap: 12, padding: 24) {
|
||||
Text("Shop", role: .title)
|
||||
Row(gap: 8) {
|
||||
Text("Price")
|
||||
Spacer(size: 4)
|
||||
Text("90")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Main 是场景名。Column 是根节点,包含一个标题和一个横向排列的 Row。
|
||||
|
||||
本章使用[UI 组件](12-ui-components.md)中的官方组件。官方库的 key 和引用形式未定义,示例仅省略这一依赖部分,不表示官方组件属于任何示例用户库或必然免导入可用。
|
||||
|
||||
## 11.2 render 与单根结构
|
||||
|
||||
本文场景文法要求一个场景包含一个 render 块,render 中恰好包含一个根节点。
|
||||
|
||||
多个同级节点放入同一个布局根节点。下面是 render 内的有效节点片段:
|
||||
|
||||
```endorphin
|
||||
Column {
|
||||
Text("First")
|
||||
Text("Second")
|
||||
}
|
||||
```
|
||||
|
||||
两个 Text 是 Column 的子节点,不是两个 render 根节点。单根规则仅约束 render 内部,不限制 namespace 只能有一个声明。
|
||||
|
||||
## 11.3 节点形式
|
||||
|
||||
节点包含组件名、可选参数列表和可选子节点块:
|
||||
|
||||
```text
|
||||
组件名
|
||||
组件名(参数列表)
|
||||
组件名(参数列表) { 子节点 }
|
||||
```
|
||||
|
||||
组件名是标识符。省略参数列表与空参数列表都表示没有显式参数;默认值由组件约定决定。
|
||||
|
||||
渲染节点片段:
|
||||
|
||||
```endorphin
|
||||
Column {}
|
||||
Spacer(size: 16)
|
||||
Text("Product")
|
||||
```
|
||||
|
||||
这三行分别展示空容器、带命名参数的节点和带位置参数的节点,不是一个具有三个根的完整 render 块。
|
||||
|
||||
## 11.4 参数
|
||||
|
||||
位置参数按参数位置表达输入,命名参数用 `参数名: 表达式`:
|
||||
|
||||
```endorphin
|
||||
Text("Product", role: .title)
|
||||
```
|
||||
|
||||
字符串为第一个位置参数,role 为命名参数。参数按逗号分隔,不使用尾随逗号。命名参数与位置参数可以在节点形式中共存,具体绑定与重复传参规则见[规范状态](../appendices/specification-status.md#ui)。
|
||||
|
||||
参数引用通用表达式文法,但 render 中允许哪些调用、状态读取和修改效果,需要另外规定;文法可以表达一种形式不等于该形式在所有渲染上下文中合法。
|
||||
|
||||
## 11.5 子节点与嵌套
|
||||
|
||||
子节点由花括号包围,相邻节点不使用逗号或分号。布局组件可以递归嵌套:
|
||||
|
||||
```endorphin
|
||||
Column(gap: 12) {
|
||||
Text("Shop", role: .title)
|
||||
Row(gap: 8) {
|
||||
Text("Left")
|
||||
Text("Right")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Column 从上到下排列标题与 Row,Row 从左到右排列两段文本。结构文法允许子节点块,组件语义决定具体组件是否接受子节点;Text 和 Spacer 的用法不接受子节点。
|
||||
|
||||
## 11.6 检查与展示
|
||||
|
||||
Preflight 检查场景结构、单根约束、组件名称、参数和子节点是否合法。不合法节点或参数应得到诊断,而不是静默替换为别的组件或默认参数。
|
||||
|
||||
inflight 展示声明的内容与排列关系。渲染树不指定绘制协议、字体引擎或某个布局计算必须发生在哪一阶段。
|
||||
|
||||
数据绑定、事件、加载状态和界面更新的具体语法见[规范状态](../appendices/specification-status.md#ui)。
|
||||
|
||||
[上一章:数据读取](10-data-access.md) · [下一章:UI 组件](12-ui-components.md) · [目录](../README.md)
|
||||
@@ -0,0 +1,89 @@
|
||||
# 12. UI 组件
|
||||
|
||||
本章是官方基础组件的用法参考,定义本文 UI 草案中的参数、默认值和展示效果。示例是 `bob:shop.ui` 场景 render 内的节点片段。
|
||||
|
||||
官方库的 key 和引用形式尚未定义,来源约定见[场景与渲染树](11-scenes-and-render-trees.md)。用户库提供的组件则以其实际声明为准。
|
||||
|
||||
## 12.1 Column
|
||||
|
||||
Column 从上到下排列子节点。
|
||||
|
||||
```endorphin
|
||||
Column(gap: 12, padding: 24) {
|
||||
Text("First")
|
||||
Text("Second")
|
||||
}
|
||||
```
|
||||
|
||||
| 参数 | 值类型 | 默认值 | 含义 |
|
||||
| --- | --- | --- | --- |
|
||||
| `gap` | 数字 | `0` | 相邻子节点的垂直间距 |
|
||||
| `padding` | 数字 | `0` | 四个方向的内边距 |
|
||||
|
||||
**子节点:** 接受零个或多个节点。
|
||||
|
||||
**布局效果:** 在本文简单内容布局模型中,宽度为最宽子节点宽度加左右内边距;高度为子节点高度、相邻间距和上下内边距之和。空容器没有子节点间距。
|
||||
|
||||
## 12.2 Row
|
||||
|
||||
Row 从左到右排列子节点。
|
||||
|
||||
```endorphin
|
||||
Row(gap: 8, padding: 4) {
|
||||
Text("Left")
|
||||
Text("Right")
|
||||
}
|
||||
```
|
||||
|
||||
| 参数 | 值类型 | 默认值 | 含义 |
|
||||
| --- | --- | --- | --- |
|
||||
| `gap` | 数字 | `0` | 相邻子节点的水平间距 |
|
||||
| `padding` | 数字 | `0` | 四个方向的内边距 |
|
||||
|
||||
**子节点:** 接受零个或多个节点。
|
||||
|
||||
**布局效果:** 在本文简单内容布局模型中,宽度为子节点宽度、相邻间距和左右内边距之和;高度为最高子节点高度加上下内边距。空容器没有子节点间距。
|
||||
|
||||
## 12.3 Spacer
|
||||
|
||||
Spacer 占据布局空间,不显示可见内容。
|
||||
|
||||
```endorphin
|
||||
Spacer(size: 16)
|
||||
```
|
||||
|
||||
| 参数 | 值类型 | 默认值 | 含义 |
|
||||
| --- | --- | --- | --- |
|
||||
| `size` | 数字 | `0` | 占位宽度与高度 |
|
||||
|
||||
**子节点:** 不接受。
|
||||
|
||||
**布局效果:** 在父组件的排列中占据指定空间。它不是间距参数本身,而是树中的一个节点。
|
||||
|
||||
## 12.4 Text
|
||||
|
||||
Text 显示字符串内容。
|
||||
|
||||
```endorphin
|
||||
Text("Product")
|
||||
Text("Shop", role: .title)
|
||||
```
|
||||
|
||||
| 参数 | 值类型 | 默认值 | 含义 |
|
||||
| --- | --- | --- | --- |
|
||||
| 第一个位置参数 | 字符串 | `""` | 显示的文本 |
|
||||
| `role` | 符号值 | 普通文本角色 | `.title` 表示标题视觉角色 |
|
||||
|
||||
**子节点:** 不接受。
|
||||
|
||||
**展示效果:** 内容按字符串显示;role 表达文本的视觉角色,不指定固定字号、颜色、字符宽度或缩放比例。
|
||||
|
||||
## 12.5 尺寸与参数检查
|
||||
|
||||
数字布局参数表达逻辑尺寸,本文不将其等同于设备像素。单位、数值范围、负数、显式尺寸、溢出、主题与文字测量规则列于[规范状态](../appendices/specification-status.md#ui)。
|
||||
|
||||
Preflight 检查组件名称、参数数量与类型、子节点约束;inflight 保持组件规定的内容和排列效果。未知参数、错误类型或不支持的子节点不能通过静默忽略获得有效语义。
|
||||
|
||||
本章组件参数与默认值属于 UI 提案,确定程度与其他语言主题一起记录在规范状态附录。
|
||||
|
||||
[上一章:场景与渲染树](11-scenes-and-render-trees.md) · [附录:形式文法](../appendices/formal-grammar.md) · [目录](../README.md)
|
||||
Reference in New Issue
Block a user