From a33f80903cf66d6b855f2afd8655bf74c7fa6592 Mon Sep 17 00:00:00 2001 From: Codex Bot Date: Wed, 7 Oct 2026 22:04:09 +0800 Subject: [PATCH] docs: establish Endorphin language documentation baseline --- .gitignore | 10 +++ AGENTS.md | 33 +++++++ README.md | 48 +++++++++++ appendices/application-domains.md | 30 +++++++ appendices/code-storage-and-views.md | 38 ++++++++ appendices/formal-grammar.md | 124 +++++++++++++++++++++++++++ appendices/glossary.md | 27 ++++++ appendices/specification-status.md | 111 ++++++++++++++++++++++++ guide/01-overview.md | 64 ++++++++++++++ guide/02-user-identity.md | 77 +++++++++++++++++ guide/03-namespaces.md | 65 ++++++++++++++ guide/04-program-structure.md | 65 ++++++++++++++ guide/05-preflight-and-inflight.md | 63 ++++++++++++++ guide/06-lexical-structure.md | 111 ++++++++++++++++++++++++ guide/07-types-and-classes.md | 64 ++++++++++++++ guide/08-expressions-and-bindings.md | 68 +++++++++++++++ guide/09-functions-and-calls.md | 90 +++++++++++++++++++ guide/10-data-access.md | 66 ++++++++++++++ guide/11-scenes-and-render-trees.md | 101 ++++++++++++++++++++++ guide/12-ui-components.md | 89 +++++++++++++++++++ 20 files changed, 1344 insertions(+) create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 README.md create mode 100644 appendices/application-domains.md create mode 100644 appendices/code-storage-and-views.md create mode 100644 appendices/formal-grammar.md create mode 100644 appendices/glossary.md create mode 100644 appendices/specification-status.md create mode 100644 guide/01-overview.md create mode 100644 guide/02-user-identity.md create mode 100644 guide/03-namespaces.md create mode 100644 guide/04-program-structure.md create mode 100644 guide/05-preflight-and-inflight.md create mode 100644 guide/06-lexical-structure.md create mode 100644 guide/07-types-and-classes.md create mode 100644 guide/08-expressions-and-bindings.md create mode 100644 guide/09-functions-and-calls.md create mode 100644 guide/10-data-access.md create mode 100644 guide/11-scenes-and-render-trees.md create mode 100644 guide/12-ui-components.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..08166ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Local editor state and machine-specific files +.obsidian/ +.DS_Store + +# Credentials and local environment files must not be published +.env +.env.* +!.env.example +*.pem +*.key diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..0521258 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,33 @@ +# 文档维护约定 + +适用于本目录及所有子目录。 + +## 文档组织 + +- 正文放在 guide,按概念依赖顺序编号;术语、文法、设计状态和补充说明放在 appendices。 +- README 作为读者入口,提供顺序目录与查询索引,不用核心约定清单替代语言介绍。 +- 每章先定义概念,再说明语法、示例和行为。内容应在未阅读讨论历史的情况下独立成立。 +- 使用技术文档陈述句,不使用对话回应、提问清单、讨论过程或开发日志作为正文。 +- 不在各章重复说明全书目标、全部约束和设计过程;未定规则集中维护在规范状态附录,必要的局部提案保留短注。 +- 每个概念指定主要说明章节,其余章节使用引用;完整 EBNF 集中在形式文法附录。 +- 修改章节位置时同步更新目录、相邻导航、术语索引、正文链接与文法。外部读者正文使用中文。 + +## 语言边界 + +- 只使用语言名称 Endorphin,不出现开发软件代称、版本或实现兼容说明。 +- 文档定义源码与可观察效果,不以开发实现进度定义语言规则。 +- 构建阶段固定为 Preflight,运行阶段固定为 inflight,保持大小写;定义见 guide/05-preflight-and-inflight.md。 +- 两个阶段名称不自动成为源码关键字。新增语法说明必要的 Preflight 检查和 inflight 效果。 +- 不设计云端实体、持久化类或自动建表。数据读取只是逻辑调用用法,不引入通信、缓存、部署与编排方案。 +- 普通调用不要求业务代码额外定义 RPC 服务、监听器、协议客户端或接口描述文件。 + +## 示例与状态 + +- key 采用用户名:namespace路径,用户名唯一,路径至少一级;各层 namespace 语义一致。 +- 归属通过外部 key 与索引提供,正文不声明自身 namespace。 +- use 只引用完整 key,不附加选择性名称列表。 +- 官方 UI 组件不列为示例用户库的内容;未定的官方引用方式不可写成免导入默认能力。 +- 示例围绕商品定价展开,标明外部归属与片段位置;局部片段不能混写为完整程序。 +- 名称查找、可见性和数据读取成员的假设明确说明,不虚构未确认 API。 +- 已确定约定、语法提案和未定义边界统一记录在 appendices/specification-status.md;文档重构不代表语法提案被确认。 +- 共用程序和表达式文法;UI 单根限制仅约束 render,不限制全语言。 diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b94748 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# Endorphin 语言文档 + +Endorphin 是一门面向云原生应用的编程语言,使用统一的语言模型描述前端界面、数据结构和后端业务逻辑。开发者编写声明、表达式与调用关系,系统负责组织这些逻辑的执行。 + +## 阅读指南 + +正文按概念的依赖顺序编排。首次阅读从第 1 章开始;查询具体写法时,可以直接进入相应章节。每章包含概念定义、语法、示例和行为说明。 + +本书为语言设计稿。用户身份、namespace key、use 形式和阶段命名等基础约定已经确定;函数、类型、数据读取与 UI 的具体写法以本文收录的草案为准。各主题的确定程度统一记录在[规范状态](appendices/specification-status.md),正文不反复叙述设计过程。 + +## 正文 + +### 第一部分:语言与程序模型 + +1. [语言概览](guide/01-overview.md) — 语言用途、核心概念与应用模型。 +2. [用户身份](guide/02-user-identity.md) — 唯一用户名、显示名、代码归属与访问身份。 +3. [namespace](guide/03-namespaces.md) — key、层级和可见代码视图。 +4. [程序结构与导入](guide/04-program-structure.md) — 声明组织、外部上下文和 use。 +5. [Preflight 与 inflight](guide/05-preflight-and-inflight.md) — 构建与执行阶段的职责。 + +### 第二部分:基础语法 + +6. [词法结构](guide/06-lexical-structure.md) — 标识符、字面量、符号、标点和注释。 +7. [类型与类](guide/07-types-and-classes.md) — 类型标注、class 与字段。 +8. [表达式与绑定](guide/08-expressions-and-bindings.md) — 求值、运算、成员访问和 let。 +9. [函数与调用](guide/09-functions-and-calls.md) — 函数声明、返回值和跨 namespace 组合。 + +### 第三部分:应用用法 + +10. [数据读取](guide/10-data-access.md) — 通过类型取得数据及结果状态。 +11. [场景与渲染树](guide/11-scenes-and-render-trees.md) — scene、render、节点与嵌套。 +12. [UI 组件](guide/12-ui-components.md) — Column、Row、Spacer 和 Text 的参数与效果。 + +## 附录 + +- [术语表](appendices/glossary.md) — 语言术语的简要定义与章节索引。 +- [形式文法](appendices/formal-grammar.md) — 集中查询 EBNF 产生式。 +- [代码存储与视图](appendices/code-storage-and-views.md) — 独立代码段、S3 与索引的组织约定。 +- [应用领域](appendices/application-domains.md) — UI、业务逻辑、数据访问和 Agent 的适用范围。 +- [规范状态](appendices/specification-status.md) — 已确定约定、语法提案及未定义的边界。 + +## 记法 + +源码以 `endorphin` 代码块展示,文法以 `ebnf` 代码块展示。源码中的关键字和名称区分大小写;语言阶段名称固定为 `Preflight` 和 `inflight`。 + +“代码归属”写在代码块之前,用于说明外部上下文,不属于源码。函数体片段和渲染节点片段会注明使用位置。示例中的用户和 namespace 为示意名称。 + +正文的函数示例围绕商品定价展开:`alice:shop.pricing` 提供定价逻辑,`bob:shop.checkout` 组合它,`bob:shop.ui` 表达界面;数据读取示例使用 `alice:shop.data`。这些路径表示代码组织,不指定执行位置。 diff --git a/appendices/application-domains.md b/appendices/application-domains.md new file mode 100644 index 0000000..b3ad63a --- /dev/null +++ b/appendices/application-domains.md @@ -0,0 +1,30 @@ +# 应用领域 + +各应用领域共用身份、namespace、类型、表达式、调用以及 Preflight / inflight 阶段模型。领域划分用于说明用途,不为每个领域建立不同的语言基础。 + +| 领域 | 语言中的内容 | 参考章节 | +| --- | --- | --- | +| UI | 场景、渲染树、组件及展示效果 | [场景与渲染树](../guide/11-scenes-and-render-trees.md)、[UI 组件](../guide/12-ui-components.md) | +| 业务逻辑 | 函数、结果、调用组合及业务效果 | [函数与调用](../guide/09-functions-and-calls.md) | +| 数据结构与访问 | class、共享类型、读取与字段使用 | [类型与类](../guide/07-types-and-classes.md)、[数据读取](../guide/10-data-access.md) | +| Agent | 后续的能力、上下文、任务及行为模型 | [规范状态](specification-status.md#agent) | + +## 跨领域调用 + +普通调用是共有语义。UI、业务逻辑或后续 Agent 代码可以在允许访问的前提下使用相应逻辑,而不为跨领域调用建立独立的 RPC 协议声明。 + +类似 RPC 的体验指“调用逻辑并取得结果”。输入、输出、依赖和失败需要在语言中明确,传输客户端、连接方式和缓存由系统承担。 + +## 领域与 namespace + +`alice:shop.ui`、`alice:shop.pricing`、`alice:shop.data` 和 `alice:shop.agents` 是组织示例,不是强制目录或具有特殊行为的保留路径。 + +namespace 的名称不自动决定逻辑在何处执行。一个 namespace 也不必只包含一种声明类别。 + +## Agent 范围 + +Agent 尚无具体源码语法。需要独立定义的内容包括能力、工具、上下文、任务、生命周期、权限,以及确定性代码和模型驱动行为的边界。 + +本书不为尚未定义的领域提供虚构关键字或 API;其扩展仍应共用语言已有的组织与调用模型。 + +[目录](../README.md) diff --git a/appendices/code-storage-and-views.md b/appendices/code-storage-and-views.md new file mode 100644 index 0000000..a7c322e --- /dev/null +++ b/appendices/code-storage-and-views.md @@ -0,0 +1,38 @@ +# 代码存储与视图 + +本附录说明无源码文件模型中的代码组织约定。它补充 namespace 的逻辑视图,不定义业务数据的存储方式。 + +## 独立代码段 + +代码分别存储为独立代码段,每段关联一个唯一用户和至少一级 namespace。S3 承担代码内容的存储职责,索引维护 namespace key 与代码段的成员关系。 + +源码文件不作为代码身份或 module 边界。本书中的 Markdown 文件是文档章节,不对应语言中的源码组织单位。 + +代码段的具体语法粒度尚未定义,不能将一个场景、一条声明或一个 S3 对象直接规定为同一种单位。 + +## 索引与视图 + +```text +完整 namespace key + → 索引中的成员关系 + → S3 中的独立代码段 + → namespace 的可见代码视图 +``` + +视图是逻辑上的代码集合。它的归属来自 key 与索引,不由对象名或物理目录确定。 + +S3 对象键不是语言中的 namespace key。bucket 名、对象键和存储接口不属于业务源码语法。 + +## 视图与程序结构 + +程序结构描述视图内导入与声明的语法关系,见[程序结构与导入](../guide/04-program-structure.md)。这一结构不要求将物理对象按文件顺序机械拼接。 + +视图成员范围、下级 namespace 是否纳入、导入作用范围、声明顺序、版本一致性与编辑映射尚未定义,统一记录在[规范状态](specification-status.md#引用与代码视图)。 + +## namespace 制 + +namespace 同时表达归属与查找位置,使业务函数、类型、场景和后续 Agent 代码遵循一致的组织模型。第一级与后续层级具有相同语义。 + +这一组织选择不自动决定构建边界、执行位置、权限继承或业务数据存储。相关语义需要由各自规则定义,而不是从 S3 物理布局推导。 + +[相关章节:namespace](../guide/03-namespaces.md) · [目录](../README.md) diff --git a/appendices/formal-grammar.md b/appendices/formal-grammar.md new file mode 100644 index 0000000..6d03496 --- /dev/null +++ b/appendices/formal-grammar.md @@ -0,0 +1,124 @@ +# 形式文法 + +本附录集中列出正文采用的文法草案。文法说明可表达的源码结构;名称、类型、可见性与执行效果由相应章节定义。各主题的确定程度见[规范状态](specification-status.md)。 + +## EBNF 记法 + +| 记法 | 含义 | +| --- | --- | +| `=` | 定义产生式 | +| `;` | 结束产生式 | +| `|` | 选择 | +| `,` | 顺序连接 | +| `[ ... ]` | 可选项 | +| `{ ... }` | 零次或多次重复 | +| `( ... )` | 产生式分组 | +| 引号中的文本 | 源码终结符 | + +产生式中的逗号和分号属于 EBNF 记法,不要求源码在相同位置包含分隔符。任意词法单元之间可出现空白或行注释。EOF 表示输入结束。 + +## 程序与导入 + +```ebnf +program = { use-decl }, declaration, { declaration }, EOF ; +declaration = class-decl | function-decl | scene-decl ; + +use-decl = "use", namespace-key ; +namespace-key = user-handle, ":", namespace-path ; +namespace-path = identifier, { ".", identifier } ; +``` + +user-handle 是系统认可的唯一用户名,由身份规则提供,不等同于源码 identifier。代码自身的归属通过外部上下文提供,程序文法中没有自身 namespace 声明。 + +相关说明:[namespace](../guide/03-namespaces.md)、[程序结构与导入](../guide/04-program-structure.md)。 + +## 类与类型 + +```ebnf +class-decl = "class", identifier, "{", { field-decl }, "}" ; +field-decl = identifier, ":", type-name ; +type-name = identifier ; +``` + +相关说明:[类型与类](../guide/07-types-and-classes.md)。 + +## 函数与绑定 + +```ebnf +function-decl = "function", identifier, "(", [ parameters ], ")", + ":", type-name, block ; +parameters = parameter, { ",", parameter } ; +parameter = identifier, ":", type-name ; + +block = "{", { binding }, return-stmt, "}" ; +binding = "let", identifier, "=", expression ; +return-stmt = "return", expression ; +``` + +本基本函数体文法只包含绑定和末尾返回,不覆盖完整控制流或独立表达式语句。 + +相关说明:[表达式与绑定](../guide/08-expressions-and-bindings.md)、[函数与调用](../guide/09-functions-and-calls.md)。 + +## 表达式 + +```ebnf +expression = sum ; +sum = product, { ("+" | "-"), product } ; +product = unary, { ("*" | "/"), unary } ; +unary = "-", unary | postfix ; +postfix = primary, { member-access | call-arguments } ; + +member-access = ".", identifier ; +call-arguments = "(", [ expression-list ], ")" ; +expression-list = expression, { ",", expression } ; + +primary = identifier | string | number | symbol + | "(", expression, ")" ; +``` + +成员访问与调用先于一元负号,一元负号先于乘除,乘除先于加减。正文采用同级二元算术运算从左到右组合的规则。 + +此处能表达成员调用,不代表某个类型自动拥有相应成员。数据读取提案使用同一套表达式文法,没有单独的 get 关键字。 + +相关说明:[表达式与绑定](../guide/08-expressions-and-bindings.md)、[数据读取](../guide/10-data-access.md)。 + +## 场景与渲染节点 + +```ebnf +scene-decl = "export", "scene", identifier, "{", render-decl, "}" ; +render-decl = "render", "{", node, "}" ; + +node = identifier, [ arguments ], [ children ] ; +arguments = "(", [ argument, { ",", argument } ], ")" ; +argument = [ identifier, ":" ], expression ; +children = "{", { node }, "}" ; +``` + +render 内单根结构由产生式表达。组件是否接受子节点、参数是否合法以及 render 内可使用哪些表达式效果,属于语义规则。 + +相关说明:[场景与渲染树](../guide/11-scenes-and-render-trees.md)、[UI 组件](../guide/12-ui-components.md)。 + +## 词法 + +```ebnf +identifier = identifier-start, { identifier-continue } ; +identifier-start = "_" | unicode-letter ; +identifier-continue = "_" | unicode-letter | unicode-number ; + +digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +number = digit, { digit }, [ ".", digit, { digit } ] ; +symbol = ".", identifier ; + +string = '"', { string-character | escape }, '"' ; +escape = "\\n" | "\\t" | '\\"' | "\\\\" ; + +line-comment = "//", { character-except-line-feed }, [ line-feed ] ; +``` + +unicode-letter、unicode-number、string-character、character-except-line-feed 和 line-feed 为词法字符类别。string-character 不包括未转义的双引号、反斜杠和换行;负号不属于 number。 + +Unicode 分类边界及源码中的换行字符规则列于[规范状态](specification-status.md#词法与表达式)。 + +相关说明:[词法结构](../guide/06-lexical-structure.md)。 + +[目录](../README.md) diff --git a/appendices/glossary.md b/appendices/glossary.md new file mode 100644 index 0000000..19c0c44 --- /dev/null +++ b/appendices/glossary.md @@ -0,0 +1,27 @@ +# 术语表 + +| 术语 | 定义 | 详见 | +| --- | --- | --- | +| Endorphin | 用统一声明与调用模型描述前后端应用的云原生编程语言 | [语言概览](../guide/01-overview.md) | +| 用户名 / handle | 在系统内唯一标识用户并参与代码定位的名称 | [用户身份](../guide/02-user-identity.md) | +| 显示名 | 用于界面展示、可重复的姓名或昵称 | [用户身份](../guide/02-user-identity.md) | +| 归属用户 | namespace key 指定的代码所属用户 | [用户身份](../guide/02-user-identity.md) | +| 操作用户 | 发起本次读取、修改或执行的身份 | [用户身份](../guide/02-user-identity.md) | +| namespace | 代码归属、组织与检索的单位 | [namespace](../guide/03-namespaces.md) | +| namespace key | 用户名与非空 namespace 路径组成的定位标识 | [namespace](../guide/03-namespaces.md) | +| 代码段 | 独立存储、具有明确归属的代码内容单位 | [代码存储与视图](code-storage-and-views.md) | +| 可见代码视图 | 由索引成员关系获得的 namespace 逻辑代码集合 | [代码存储与视图](code-storage-and-views.md) | +| use | 引用完整 namespace key 的声明 | [程序结构与导入](../guide/04-program-structure.md) | +| Preflight | 理解、检查和准备程序的构建阶段 | [Preflight 与 inflight](../guide/05-preflight-and-inflight.md) | +| inflight | 使用实际输入执行逻辑并产生可观察结果的运行阶段 | [Preflight 与 inflight](../guide/05-preflight-and-inflight.md) | +| 类型 | 描述值的结构及其允许用法的定义 | [类型与类](../guide/07-types-and-classes.md) | +| class | 数据结构声明 | [类型与类](../guide/07-types-and-classes.md) | +| 表达式 | 描述计算并产生值的源码形式 | [表达式与绑定](../guide/08-expressions-and-bindings.md) | +| 绑定 | 将表达式结果关联到局部名称 | [表达式与绑定](../guide/08-expressions-and-bindings.md) | +| 函数 | 定义输入、结果和执行逻辑的可调用声明 | [函数与调用](../guide/09-functions-and-calls.md) | +| 数据依赖 | 后续计算需要前一计算结果的关系 | [函数与调用](../guide/09-functions-and-calls.md) | +| 场景 / scene | 描述一个 UI 视图的声明 | [场景与渲染树](../guide/11-scenes-and-render-trees.md) | +| 渲染树 | render 块内由组件节点组成的树 | [场景与渲染树](../guide/11-scenes-and-render-trees.md) | +| 符号字面量 | 以点号和标识符表达的命名值,如 `.title` | [词法结构](../guide/06-lexical-structure.md) | + +[目录](../README.md) diff --git a/appendices/specification-status.md b/appendices/specification-status.md new file mode 100644 index 0000000..82c8ae1 --- /dev/null +++ b/appendices/specification-status.md @@ -0,0 +1,111 @@ +# 规范状态 + +本附录记录语言设计的确定程度与尚未定义的边界。它用于理解设计稿,不代表软件实现进度或可执行性保证。 + +## 已确定约定 + +| 主题 | 已确定内容 | +| --- | --- | +| 语言定位 | 前后端共用的云原生编程语言,UI 是应用领域之一 | +| 代码归属 | 每段代码属于唯一用户名和至少一级 namespace | +| 用户身份 | 使用唯一 handle 定位,不用显示名替代 | +| namespace | 各层语义一致;以外部 key 检索,不在正文声明自身归属 | +| key 形式 | `用户名:namespace路径`,冒号分隔用户与路径,点号分隔层级 | +| use | 引用完整 namespace,不附加选择性名称列表 | +| 代码组织 | 独立代码段存储在 S3,由索引组装可见代码视图,不采用源码文件 module 制 | +| 数据结构目标 | 用 class 表达共享结构,通过类取得数据的具体形式另行定义 | +| 调用目标 | 普通逻辑调用表达输入、结果与依赖,系统组织执行 | +| 官方组件 | 官方 UI 组件与用户库内容分别定义 | +| 阶段命名 | 构建阶段为 Preflight,运行阶段为 inflight;名称本身不增加源码关键字 | + +## 收录的语法提案 + +| 提案 | 正文位置 | 说明 | +| --- | --- | --- | +| 词法与字面量 | [第 6 章](../guide/06-lexical-structure.md) | 本书统一采用的标识符、字符串、数字和符号形式 | +| 类字段与类型标注 | [第 7 章](../guide/07-types-and-classes.md) | class 目标已确定,字段和类型体系仍为具体写法提案 | +| 表达式与 let | [第 8 章](../guide/08-expressions-and-bindings.md) | 基础运算、成员访问与局部绑定 | +| function 与 return | [第 9 章](../guide/09-functions-and-calls.md) | 函数签名、基本函数体与调用组合 | +| Product.get | [第 10 章](../guide/10-data-access.md) | 读取体验提案,不是 class 自动附带的 API | +| 场景与组件 | [第 11、12 章](../guide/11-scenes-and-render-trees.md) | scene、render、参数、布局与默认值 | + +程序声明组合与[形式文法](formal-grammar.md)同样属于设计稿。正文中的陈述定义这些提案内部的用法,不将其确定程度提升为最终规范。 + +## 身份与权限 + +尚未定义: + +- 用户名的字符、长度、大小写、Unicode 归一化及身份范围扩展。 +- handle 改名、旧名称复用、历史引用稳定性及账号生命周期。 +- 代码的默认公开性、读取与执行权限,以及 namespace 权限继承。 +- 协作、Agent 委托、操作身份记录与归属转移。 + +定位信息不构成授权,是这些规则必须保留的边界。 + +## 引用与代码视图 + +尚未定义: + +- 代码段的语法边界、视图成员范围和下级 namespace 的纳入方式。 +- use 的作用范围、声明可见性、限定名、别名与同名冲突。 +- 视图顺序、版本选择、成员一致性及编辑操作映射。 +- key 的传递编码和索引关联机制。 + +正文跨 namespace 示例采用目标声明可见、名称可直接解析且无冲突的条件;该条件不代替正式名称查找规则。 + +## 声明与类型 + +尚未定义: + +- 程序入口、空代码视图、多个场景的选择与顶层绑定。 +- 完整基础类型、数值范围、可选值、泛型及类型转换。 +- 类构造、方法、默认值、继承和字段可见性。 +- 重复声明、完整控制流、可变性、赋值和作用域细节。 + +本文简单函数体仅收录 let 与末尾 return,不意味着整门语言只允许这两种语句。 + +## 词法与表达式 + +尚未定义: + +- 完整保留字集合、Unicode 版本与字符类别边界。 +- 换行字符、字符串扩展转义、更多字面量和运算符。 +- 数值溢出、除法、隐式转换与所有调用参数的求值顺序。 + +正文中同级二元算术运算的组合顺序属于表达式提案,不规定所有调用的执行顺序。 + +## 调用与数据 + +尚未定义: + +- 显式等待、失败处理、缺失值、取消和超时的源码形式。 +- 数据读取成员的声明、参数与结果类型。 +- 一次结果、持续结果及其更新语义。 +- 带业务修改的调用顺序、重复执行限制与失败行为。 +- 更新代码时已有调用使用哪个版本。 + +正常结果必须符合声明,未就绪或失败不能伪造为成功结果。Product.get 示例只展示成功路径。 + +## UI + +尚未定义: + +- 官方组件库的 key、显式引用形式与名称可见性。 +- 命名参数和位置参数的完整绑定规则及重复传参处理。 +- 渲染中的调用、状态、数据绑定、事件与更新。 +- 布局单位、参数范围、负数、显式尺寸、约束与溢出。 +- 主题、样式、文字测量和其他组件。 + +正文的官方组件示例省略未定义的依赖部分,不承诺免导入使用。 + +## Agent + +Agent 是规划应用领域。声明、能力、工具、上下文、任务、生命周期、权限及模型驱动行为的边界尚未定义。 + +## 规范范围 + +本文定义源码及应有的语言效果。云端实体、持久化类、自动建表、通信、缓存、部署和编排实现不在本阶段规范中。 + +S3 约定仅用于代码存储,不规定业务数据后端。Preflight 与 inflight 的职责不要求特定机器码、执行图或部署产物。 + +[目录](../README.md) diff --git a/guide/01-overview.md b/guide/01-overview.md new file mode 100644 index 0000000..beb756a --- /dev/null +++ b/guide/01-overview.md @@ -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) diff --git a/guide/02-user-identity.md b/guide/02-user-identity.md new file mode 100644 index 0000000..63d06e3 --- /dev/null +++ b/guide/02-user-identity.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) diff --git a/guide/03-namespaces.md b/guide/03-namespaces.md new file mode 100644 index 0000000..85eefca --- /dev/null +++ b/guide/03-namespaces.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) diff --git a/guide/04-program-structure.md b/guide/04-program-structure.md new file mode 100644 index 0000000..d3b9847 --- /dev/null +++ b/guide/04-program-structure.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) diff --git a/guide/05-preflight-and-inflight.md b/guide/05-preflight-and-inflight.md new file mode 100644 index 0000000..13d9d5f --- /dev/null +++ b/guide/05-preflight-and-inflight.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) diff --git a/guide/06-lexical-structure.md b/guide/06-lexical-structure.md new file mode 100644 index 0000000..ab9d9f4 --- /dev/null +++ b/guide/06-lexical-structure.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) diff --git a/guide/07-types-and-classes.md b/guide/07-types-and-classes.md new file mode 100644 index 0000000..8be43a9 --- /dev/null +++ b/guide/07-types-and-classes.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) diff --git a/guide/08-expressions-and-bindings.md b/guide/08-expressions-and-bindings.md new file mode 100644 index 0000000..422754f --- /dev/null +++ b/guide/08-expressions-and-bindings.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) diff --git a/guide/09-functions-and-calls.md b/guide/09-functions-and-calls.md new file mode 100644 index 0000000..ff82c3f --- /dev/null +++ b/guide/09-functions-and-calls.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) diff --git a/guide/10-data-access.md b/guide/10-data-access.md new file mode 100644 index 0000000..61956a2 --- /dev/null +++ b/guide/10-data-access.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) diff --git a/guide/11-scenes-and-render-trees.md b/guide/11-scenes-and-render-trees.md new file mode 100644 index 0000000..f645f4c --- /dev/null +++ b/guide/11-scenes-and-render-trees.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) diff --git a/guide/12-ui-components.md b/guide/12-ui-components.md new file mode 100644 index 0000000..a49505b --- /dev/null +++ b/guide/12-ui-components.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)