📝 docs(tsl): align agent-facing guidance
This commit is contained in:
@@ -12,13 +12,24 @@
|
||||
|
||||
## 这一篇解决什么问题
|
||||
|
||||
回答“如何正确声明 `function` 和 `procedure`、如何组织主函数和子函数、怎样使用参数修饰、默认参数与可变参数,以及哪些混写方式会直接编译失败”。
|
||||
回答“如何正确声明 `function` 和 `procedure`、`.tsl` 脚本语句区如何调用后置函数声明、怎样使用参数修饰、默认参数与可变参数,以及哪些函数写法会直接编译失败”。
|
||||
|
||||
## Agent 函数/调用判断流程
|
||||
|
||||
1. 先判断当前文件是 `.tsl` 还是 `.tsf`;文件形态不明确时回 [03_core_model.md](03_core_model.md)。
|
||||
2. `.tsl` 中先写语句区,再把 `function` / `procedure` 声明放在后面;不要在声明区后面追加脚本语句。
|
||||
3. `.tsf` 中把顶层 `function` / `procedure` 当成模块 / 函数扩展声明;不要写成顺序执行入口。
|
||||
4. 需要返回值时用 `function`,不需要返回值时用 `procedure`。
|
||||
5. 调用普通 TSL 函数时,命名参数只写 `name: value`;不要把 `name = value` 当成命名参数。
|
||||
6. 参数是否写回调用方要看 `const` / `var` / `{$VarByRef-}` / `in` / `out`,不要默认按其他语言习惯推断。
|
||||
7. 没有已验证代码块时不要发明函数/调用写法;尤其不要把二进制函数、系统函数、函数指针和匿名函数都套成同一种调用语法。
|
||||
|
||||
## 必须记住的规则
|
||||
|
||||
- 最稳妥的函数骨架仍然是 `function Name(...); begin ... end;`。
|
||||
- 不需要返回值时,可以改用 `procedure Name(...); begin ... end;`。
|
||||
- 在文件模型层,`function` 和 `procedure` 归同一类顶层外形;见 [03_core_model.md](03_core_model.md)。
|
||||
- 在 `.tsl` 文件模型层,脚本语句后可以接函数声明;语句区在前顺序执行,声明区在后提供函数/过程定义。见 [03_core_model.md](03_core_model.md)。
|
||||
- 在 `.tsf` 文件模型层,顶层 `function` / `procedure` 是模块/函数扩展声明;部署到解释器 `funcext` 后可被脚本直接调用。
|
||||
- 当前解释器接受省略函数头后的分号,但文档默认仍保留这个分号。
|
||||
- 一个函数定义体里可以同时出现主函数和子函数。
|
||||
- 函数支持参数类型注解和返回值类型注解。
|
||||
@@ -48,12 +59,32 @@
|
||||
- 当前解释器没有通过 `f(...)` 这种“函数变量直接调用”写法;无论 `f` 是匿名函数、`FindFunction(...)` 还是 `ThisFunction(...)` 返回的函数指针,都不要默认写成直调。
|
||||
- 当前解释器接受 `::FuncName(...)` 指向全局/系统函数,用来绕过当前作用域里的同名局部函数。
|
||||
- `external`、`MakeInstance` 和线程调用统一移到 [21_external_calls_and_threads.md](21_external_calls_and_threads.md)。
|
||||
- 不要把顶层函数定义和松散语句混在同一个文件模型里。
|
||||
- 不要在 `.tsl` 的函数声明区之后继续追加脚本语句。
|
||||
|
||||
## 已验证语法
|
||||
|
||||
### 基础函数 / 过程骨架
|
||||
|
||||
`.tsl` 语句区调用后置函数声明:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
a := 1;
|
||||
test();
|
||||
|
||||
function test();
|
||||
begin
|
||||
echo "test";
|
||||
end;
|
||||
```
|
||||
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
```text
|
||||
test
|
||||
```
|
||||
|
||||
最短函数骨架:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
@@ -121,9 +152,11 @@ begin
|
||||
end.
|
||||
```
|
||||
|
||||
已验证运行结果:
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
- `Bump(a)` 后输出 `2`
|
||||
```text
|
||||
2
|
||||
```
|
||||
|
||||
### 签名增强
|
||||
|
||||
@@ -316,10 +349,7 @@ end.
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
function NamedArgsDemo();
|
||||
begin
|
||||
return Pack(a: 1, b: 2);
|
||||
end;
|
||||
WriteLn(Pack(a: 1, b: 2));
|
||||
|
||||
function Pack(a, b);
|
||||
begin
|
||||
@@ -327,7 +357,13 @@ begin
|
||||
end;
|
||||
```
|
||||
|
||||
已验证运行结果:
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
```text
|
||||
12
|
||||
```
|
||||
|
||||
已验证补充:
|
||||
|
||||
- `Pack(a: 1, b: 2)` 返回 `12`
|
||||
- `Pack(b: 2, a: 1)` 返回 `12`
|
||||
@@ -820,12 +856,25 @@ end.
|
||||
|
||||
## 最小可编译示例
|
||||
|
||||
如果你只是要写一个能被 session 稳定续写的函数 / 过程,从下面任一骨架起步:
|
||||
如果你只是要写一个能被 agent 稳定续写的 `.tsl` 脚本,从语句区起步,需要函数时把声明区放在后面:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
Hello();
|
||||
|
||||
function Hello();
|
||||
begin
|
||||
echo "hello";
|
||||
end;
|
||||
```
|
||||
|
||||
如果你要写 `.tsf` 模块/函数扩展,从下面任一骨架起步:
|
||||
|
||||
代码块身份:已验证可执行示例
|
||||
|
||||
```tsl
|
||||
function HelloValue();
|
||||
begin
|
||||
return 1;
|
||||
end;
|
||||
@@ -841,7 +890,7 @@ end;
|
||||
|
||||
## 常见误写
|
||||
|
||||
- 把顶层函数定义和松散语句混写。
|
||||
- 在 `.tsl` 的声明区后面继续写脚本语句。
|
||||
- 以为函数头后的分号是当前解释器的硬性要求。
|
||||
- 以为 `procedure` 只是 `function` 的别名,不涉及参数传递语义。
|
||||
- 带类型注解时仍然用逗号分隔参数。
|
||||
@@ -857,15 +906,24 @@ end;
|
||||
代码块身份:反例 / 不可照写
|
||||
|
||||
```text
|
||||
a := 1;
|
||||
Add(1, 2);
|
||||
|
||||
function Add(a, b);
|
||||
begin
|
||||
return a + b;
|
||||
end;
|
||||
|
||||
value := Add(1, 2);
|
||||
echo "after function";
|
||||
```
|
||||
|
||||
上面这种混写方式会编译失败,问题不在 `Add` 本身,而在于文件模型混了“函数定义体”和“松散语句”两种写法。
|
||||
上面的问题不在 `Add` 本身,而在于 `.tsl` 的函数声明区后面又继续出现脚本语句。正确做法是把会执行的语句全部放在声明区之前。
|
||||
|
||||
代码块身份:已验证输出片段
|
||||
|
||||
```text
|
||||
invalid statement
|
||||
```
|
||||
|
||||
代码块身份:反例 / 不可照写
|
||||
|
||||
@@ -884,7 +942,7 @@ end;
|
||||
Pack(a = 1, b = 2)
|
||||
```
|
||||
|
||||
这类写法不要当成命名参数。它虽然可能编译通过,但在我于 `2026-04-09` 的实测里返回结果不对,不能当成可靠的命名参数语法。
|
||||
这类写法不要当成命名参数。它虽然可能编译通过,但当前已验证返回结果不对,不能当成可靠的命名参数语法。
|
||||
|
||||
代码块身份:反例 / 不可照写
|
||||
|
||||
|
||||
Reference in New Issue
Block a user