📝 docs(tsl): restructure agent-facing reference

Rework TSL syntax, catalog, modules, and routing docs around deterministic agent lookup and generation.

Split large catalog pages into focused function fact pages, remove obsolete pending/verified/unavailable paths, and update consistency tests for the new structure.
This commit is contained in:
csh
2026-06-09 17:24:30 +08:00
parent 9c194170a1
commit 540b3c0a1b
192 changed files with 32929 additions and 13533 deletions
@@ -0,0 +1,325 @@
# TSL 对象重载与迭代
文档类型:语法深水专题
是否可直接用于生成代码:仅部分
是否含可直接照写示例:是
是否含不可照写反例:否
遇到不确定时:先按本页候选页继续判断;[08_objects_and_classes.md](08_objects_and_classes.md)、[20_object_runtime_and_introspection.md](20_object_runtime_and_introspection.md)、[17_types_and_conversions.md](17_types_and_conversions.md);仍不命中时回到语法路由中心 [index.md](index.md);如果问题已经超出语法层,回到 TSL 总入口 [../index.md](../index.md)
这一篇只讲对象直接参与语言级操作的文档能力:基础算符重载、`[]` 重载、`for in` 重载,以及 `mrows` / `mcols` / `msize` 这类矩阵关键字重载。
## 本篇职责
回答“当类不只是普通对象,而要直接参与 `obj + x``obj[index]``for v in obj``mrows(obj)` 这类语言级操作时,支持哪些文档明确写法”。
## 智能体对象重载/迭代判断流程
1. 先判断要重载二元算符、下标、`for in`,还是矩阵尺寸函数。
2. 对象重载只照本页明确的 `operator` 签名写,不要从未写入文档资料扩展未知重载。
3. 普通对象模型先回看 `08_objects_and_classes.md`,不要在重载页发明类基础语法。
4. 未列入本页主干的重载族不要写成语法事实。
5. 没有对应代码块时不要发明对象重载/迭代写法。
## 核心规则
- 对象二元算符重载的最小可靠形态是成员方法 `function operator + (data);` 这一类写法。
- 比较算符可写成 `function operator < (data, isLeft);`,用 `isLeft` 区分对象在左边还是右边。
- 对象 `[]` 读取有两种文档明确写法:`function operator[](index);``function operator[0](index, s1);`
- 对象 `[]` 写入的文档明确写法是 `function operator[1](index, v);`
- `function operator for(flag);` 可以重载 `for in`
-`operator for(flag)` 里,`flag .& 2` 可用来区分“一个循环变量”还是“两个循环变量”,`flag .& 1` 可用来区分“第一次进入”还是“继续迭代”。
- `mrows` / `mcols` / `msize` 可以在类里先声明 `function operator mrows(n);` 这类签名,再在类外实现 `function operator ClassName.mrows(n);`
- 可用形态包括 `mrows(obj)``mcols(obj)``msize(obj)` 这类关键字调用,以及 `obj.mcols(1)` 这类对象方法式调用。
- `function operator++(v);``function operator += (v);` 也可用。
- 不要把未写入文档资料里的裸 `function operator;` / `function operator1;`,或未列入本页的 `mcell` / `mrow` / `mcol` / `::` / `:.` 重载,直接当成语法事实。
## 可直接照写示例
### 二元算符重载
代码块身份:可直接照写示例
```tsl
t1 := new TComplex();
t1.vReal := 10;
t1.vImaginary := 100;
t2 := t1 + 10;
writeLn(t2.vReal);
writeLn(t1 < 5);
writeLn(t1 < 300);
writeLn(5 < t1);
type TComplex = class
public
vReal;
vImaginary;
function operator + (data);
begin
r := new TComplex();
if ifNumber(data) then
begin
r.vReal := vReal + data;
end
else
begin
r.vReal := vReal + data.vReal;
r.vImaginary := vImaginary + data.vImaginary;
end
return r;
end;
function operator < (data, isLeft);
begin
if ifNumber(data) then
begin
v := vReal < data;
end
else
begin
v := (vReal ^ 2 + vImaginary ^ 2) < data.vReal ^ 2 + data.vImaginary ^ 2;
end
if not isLeft then v := not v;
return v;
end;
end;
```
结果说明:
- 依次输出 `20``0``1``1`
- 说明 `obj + value` 可以通过成员 `operator +` 接管
- 说明带 `isLeft` 的比较算符可以同时处理 `obj < value``value < obj`
代码块身份:输出片段
```text
20
0
1
1
```
### `[]` 重载:`operator[]` / `operator[1]`
代码块身份:可直接照写示例
```tsl
t := array(1, 2, 3, 4, 5);
b := new bb(t);
writeLn(b[2]);
b[3] := 999;
writeLn(b.data[3]);
type bb = class
public
data;
function create(v);
begin
data := v;
end;
function operator[](index);
begin
return data[index];
end;
function operator[1](index, v);
begin
data[index] := v;
end;
end;
```
结果说明:
- 依次输出 `3``999`
- 说明 `operator[]``operator[1]` 可以完成单层下标读取和写入
### `[]` 重载:`operator[0]` / `operator[1]`
沿用上一段的 `bb` 类与测试主体,只把读取签名从 `function operator[](index);` 改成 `function operator[0](index, s1);`
代码块身份:配置片段 / 概念骨架
```tsl
type bb = class
public
// 其余字段、create()、operator[1] 和测试主体同上一段
function operator[0](index, s1);
begin
return data[index];
end;
end;
```
结果说明:
- 依次输出 `3``999`
- 说明 `operator[0]` / `operator[1]` 这组写法在单层下标场景同样可用
### `for in` 重载
代码块身份:可直接照写示例
```tsl
box := new Box(array("A", "B", "C"));
for v in box do
writeLn(v);
for i, v in box do
writeLn(i$":"$v);
type Box = class
public
data;
findex;
function create(v);
begin
data := v;
end;
function operator for(flag);
begin
use_pair := flag .& 2;
again := flag .& 1;
if not again then
begin
findex := 0;
end
else if findex < length(data) - 1 then
begin
findex++;
end
else
begin
return nil;
end
if use_pair then
return array(findex, data[findex]);
return data[findex];
end;
end;
```
结果说明:
- 单变量循环依次输出 `A``B``C`
- 双变量循环依次输出 `0:A``1:B``2:C`
- 说明 `operator for(flag)` 可以重载 `for in`
- 也说明同一个对象可以按返回值形态同时支持“单变量遍历”和“索引 + 值遍历”
### `mrows` / `mcols` / `msize` 重载
代码块身份:可直接照写示例
```tsl
g := new GridWrap();
writeLn(mrows(g));
writeLn(mcols(g));
sz := msize(g);
writeLn(sz[0]);
writeLn(sz[1]);
cols := g.mcols(1);
writeLn(cols[0]);
writeLn(cols[1]);
writeLn(cols[2]);
type GridWrap = class
public
data;
function create();
begin
data := array(
("A": 1, "B": 2, "C": 3),
("A": 4, "B": 5, "C": 6)
);
end;
function operator mrows(n);
function operator mcols(n);
function operator msize(n);
end;
function operator GridWrap.mrows(n);
begin
_n := ifNil(n) ? 0 : n;
return mrows(data, _n);
end;
function operator GridWrap.mcols(n);
begin
_n := ifNil(n) ? 0 : n;
return mcols(data, _n);
end;
function operator GridWrap.msize(n);
begin
_n := ifNil(n) ? 0 : n;
return msize(data, _n);
end;
```
结果说明:
- 依次输出 `2``3``2``3``A``B``C`
- 说明 `mrows(obj)``mcols(obj)``msize(obj)` 都可由对象重载接管
- 说明对象方法式调用 `obj.mcols(1)` 也可继续取得列下标列表
### `++` 与 `+=`
代码块身份:可直接照写示例
```tsl
b := new bb(10);
++b;
writeLn(b.data);
c := b++;
writeLn(c.data);
writeLn(b.data);
b += 5;
writeLn(b.data);
type bb = class
public
data;
function create(v);
begin
data := v;
end;
function operator++(v);
begin
if v = 0 then
begin
r := new bb();
r.data := data;
r.data++;
return r;
end
else
data++;
end;
function operator += (v);
begin
data += v;
end;
end;
```
结果说明:
- 依次输出 `11``11``12``17`
- 说明前置 `++` 会直接修改对象状态
- 说明这个最小样例里,后置 `b++` 返回的是递增前快照
- 说明 `operator += (v)` 可以接管 `b += 5`
## 本页不生成的范围
- `::` / `:.` 遍历重载
- `mcell` / `mrow` / `mcol` / `mIndexCount` / `mIndex`
- 多级 `[]` 下标重载
- 右侧算术如 `value + obj`
- 对基础二进制函数的大规模重载族
这些名称只作为边界提示,不作为本页可生成模板。
## 禁止项
- 不要从本页 `operator` 示例外推未写入文档的重载族。
- 不要把 `mcell` / `mrow` / `mcol` / `::` / `:.` 直接写成可用语法。
- 不要把多级 `[]` 下标重载或 `value + obj` 这类右侧算术写成文档事实。
- 不要在本页发明普通类语法;基础对象模型回 [08_objects_and_classes.md](08_objects_and_classes.md)。