📝 docs(tsl): align agent-facing guidance
This commit is contained in:
@@ -8,26 +8,87 @@
|
||||
|
||||
手册位置:第 3 篇,共 32 篇。上一篇:[02_quickstart.md](02_quickstart.md)。下一篇:[04_values_and_literals.md](04_values_and_literals.md)。
|
||||
|
||||
这一篇说明 TSL 的文件模型判断规则:顶层主体是什么、辅助语句是什么、为什么很多错误其实是“文件模型选错了”。
|
||||
这一篇说明 TSL 的文件模型判断规则:agent 如何区分 `.tsl` 可执行脚本与 `.tsf` 模块,如何识别脚本语句区和声明区,以及为什么很多错误其实是“文件模型选错了”。
|
||||
|
||||
## 这一篇解决什么问题
|
||||
|
||||
回答“当前文件到底属于哪一种顶层写法,以及哪些语句只是辅助组织,不应该被误当成主体声明”。
|
||||
回答“当前文件到底是 `.tsl` 脚本还是 `.tsf` 模块,以及 `.tsl` 里的哪些内容会顺序执行、哪些内容只是后置声明”。
|
||||
|
||||
如果问题已经变成赋值、命名参数、类外形、`unit` 骨架或下标规则这类通用硬规则,统一回 [02_quickstart.md](02_quickstart.md) 的“语言核心事实速查”;这一页只处理文件模型判断。
|
||||
|
||||
## Agent 文件模型判断流程
|
||||
|
||||
1. 后缀是第一证据:用户明确要求 `.tsl` 时,按可执行脚本写;用户明确要求 `.tsf` 时,按模块 / 函数扩展写。
|
||||
2. 没有后缀时看交付目标:可执行交付对应 `.tsl`,可复用扩展交付对应 `.tsf`。
|
||||
3. 目标仍不明确时先问用户;不要把脚本入口和通用模块替用户合并成一个猜测文件。
|
||||
4. 写 `.tsl` 时,先生成脚本语句区;需要函数、过程或类时,把声明区放在语句区之后。
|
||||
5. 写 `.tsf` 时,生成顶层函数 / 过程或 `unit`;不要写成会直接顺序执行的脚本入口。
|
||||
6. 没有文档证据时不要发明文件模型;只能回到对应专题页、项目规则,或记录文档缺口。
|
||||
|
||||
## 必须记住的规则
|
||||
|
||||
- 比起扩展名,更可靠的判断方式是看顶层内容。
|
||||
- 顶层主体在当前手册里优先按四种外形理解:顶层松散语句、`function / procedure`、`type Name = class`、`unit`。
|
||||
- 用户已给出 `.tsl` / `.tsf` 后缀时,后缀就是判断依据;未给后缀时,再按交付目标判断。
|
||||
- 未给后缀时,可执行代码对应 `.tsl`,通用模块对应 `.tsf`;仍不明确时向用户确认。
|
||||
- `.tsl` 脚本按两段理解:语句区在前并按顺序执行;声明区在后,可放 `function / procedure` 或 `type Name = class`。
|
||||
- `.tsf` 模块按可部署扩展理解:顶层函数部署到解释器 `funcext` 后,`.tsl` 可以直接调用;`unit` 仍按模块组织理解。
|
||||
- `uses` 可以出现在顶层,但这里只把它当成辅助语句,不把它当成主体声明;函数体和类定义体里的位置限制见 [10_units_and_scope.md](10_units_and_scope.md)。
|
||||
- 裸 `class Name` 不作为类定义写法使用。
|
||||
- 如果一个文件已经采用“顶层 `function / procedure`”模型,就不要再混入松散语句。
|
||||
- 在 `.tsl` 中,不要在声明区之后继续追加脚本语句。
|
||||
- `unit` 默认先按完整形态理解;它也可以省略 `interface` / `implementation` 写成简写形态,见 [10_units_and_scope.md](10_units_and_scope.md)。
|
||||
- 不要把 `.tsl` 写成只有顶层函数的模块;如果用户要通用可复用函数,优先写 `.tsf`。
|
||||
- 不要把 `.tsf` 写成会直接执行脚本语句的入口;如果用户要顺序执行入口,优先写 `.tsl`。
|
||||
|
||||
## 已验证语法
|
||||
|
||||
顶层主体的最小形态:
|
||||
`.tsl` 脚本语句区的最小形态:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
a := 1;
|
||||
```
|
||||
|
||||
`.tsl` 语句区后接函数声明区:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
a := 1;
|
||||
test();
|
||||
|
||||
function test();
|
||||
begin
|
||||
echo "test";
|
||||
end;
|
||||
```
|
||||
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
```text
|
||||
test
|
||||
```
|
||||
|
||||
`.tsl` 语句区后接类声明区:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
obj := CreateObject("MyClass");
|
||||
obj.value := 5;
|
||||
echo obj.value;
|
||||
|
||||
type MyClass = class
|
||||
value;
|
||||
end;
|
||||
```
|
||||
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
```text
|
||||
5
|
||||
```
|
||||
|
||||
`.tsf` 顶层函数的最小形态:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
@@ -38,35 +99,39 @@ begin
|
||||
end;
|
||||
```
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
代码块说明:这个 `.tsf` 部署为函数扩展后,可由 `.tsl` 脚本调用 `Demo()` 并取得返回值。
|
||||
|
||||
```tsl
|
||||
procedure DemoProc();
|
||||
begin
|
||||
end;
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
```text
|
||||
1
|
||||
```
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
type DemoType = class
|
||||
end;
|
||||
```
|
||||
`.tsf` `unit` 的最小形态:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
unit DemoUnit;
|
||||
interface
|
||||
function Ping();
|
||||
function Ping();
|
||||
|
||||
implementation
|
||||
function Ping();
|
||||
begin
|
||||
return 1;
|
||||
end;
|
||||
function Ping();
|
||||
begin
|
||||
return 1;
|
||||
end;
|
||||
end.
|
||||
```
|
||||
|
||||
代码块说明:这个 `.tsf` `unit` 已通过 `.tsl` 脚本 `uses DemoUnit` 调用 `Ping()` 验证返回值为 `1`;调用脚本和查找路径边界见 [10_units_and_scope.md](10_units_and_scope.md)。
|
||||
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
```text
|
||||
1
|
||||
```
|
||||
|
||||
已验证失败的形态:
|
||||
|
||||
代码块身份:反例 / 不可照写
|
||||
@@ -78,14 +143,20 @@ end;
|
||||
|
||||
上面这种裸 `class` 顶层写法会编译失败。
|
||||
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
```text
|
||||
invalid statement
|
||||
```
|
||||
|
||||
## 最小可编译示例
|
||||
|
||||
如果当前任务只是“先让 session 判断当前文件属于哪一种模型”,先记住下面这组归类:
|
||||
如果当前任务只是“先让 agent 判断当前文件属于哪一种模型”,先记住下面这组归类:
|
||||
|
||||
- 顶层语句骨架:直接写松散语句。
|
||||
- 顶层函数 / 过程骨架:写 `function ... begin ... end;` 或 `procedure ... begin ... end;`。
|
||||
- 顶层类骨架:写 `type Name = class ... end;`。
|
||||
- 顶层单元骨架:默认先写 `unit ... interface ... implementation ... end.`;简写形态见 [10_units_and_scope.md](10_units_and_scope.md)。
|
||||
- `.tsl` 脚本语句区:直接写会顺序执行的语句。
|
||||
- `.tsl` 声明区:在语句区之后写 `function ... begin ... end;`、`procedure ... begin ... end;` 或 `type Name = class ... end;`。
|
||||
- `.tsf` 顶层函数 / 过程:写可部署到 `funcext` 的 `function` / `procedure` 文件。
|
||||
- `.tsf` 顶层单元:默认先写 `unit ... interface ... implementation ... end.`;简写形态见 [10_units_and_scope.md](10_units_and_scope.md)。
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
@@ -95,9 +166,10 @@ a := 1;
|
||||
|
||||
## 常见误写
|
||||
|
||||
- 误以为扩展名本身就完全决定能否写函数、类或 `unit`。
|
||||
- 把 `.tsl` 当成 `.tsf` 来写,只给一个顶层函数,不写任何会执行的脚本语句。
|
||||
- 把 `.tsf` 当成 `.tsl` 来写,在模块文件里直接堆顺序执行的脚本语句。
|
||||
- 把 `uses` 当成主体声明,而不是辅助组织语句。
|
||||
- 把 `function / procedure` 定义体和松散语句混写。
|
||||
- 在 `.tsl` 声明区之后继续追加脚本语句。
|
||||
|
||||
## 跳转指引
|
||||
|
||||
|
||||
Reference in New Issue
Block a user