📝 docs(tsl): expand syntax operator and object coverage

This commit is contained in:
csh
2026-06-10 15:25:42 +08:00
parent 540b3c0a1b
commit c0c2ffb6eb
6 changed files with 715 additions and 50 deletions
+132 -22
View File
@@ -6,11 +6,11 @@
是否含不可照写反例:是
遇到不确定时:先按本页表格和专题入口继续判断;[03_values_and_literals.md](03_values_and_literals.md)、[04_variables_and_constants.md](04_variables_and_constants.md)、[05_functions_and_calls.md](05_functions_and_calls.md)、[07_control_flow.md](07_control_flow.md)、[08_objects_and_classes.md](08_objects_and_classes.md)、[12_matrix_and_collections.md](12_matrix_and_collections.md)、[16_lexical_structure_and_compile_options.md](16_lexical_structure_and_compile_options.md)、[11_pitfalls.md](11_pitfalls.md);仍不命中时回到语法路由中心 [index.md](index.md);如果问题已经超出语法层,回到 TSL 总入口 [../index.md](../index.md)
这一篇集中放语言级表达式与运算符。智能体写代码时,只使用本页和对应专题页已经本页明确的表达式事实,不要把其他语言或外部资料里的运算符习惯直接搬进 TSL。
这一篇集中放语言级表达式与运算符。智能体写代码时,只使用本页和对应专题页已经明确的表达式事实,不要把其他语言或外部资料里的运算符习惯直接搬进 TSL。
## 本篇职责
回答“赋值、算术、比较、逻辑、位运算、集合/类型关系、条件求值、表达式对象、访问/调用和专题运算符入口在 TSL 里怎样写”。
回答“赋值、算术、比较、逻辑、位运算、集合/类型关系、条件求值、表达式对象、访问/调用、点前缀运算符和专题运算符入口在 TSL 里怎样写”。
## 智能体表达式/运算符判断流程
@@ -18,16 +18,17 @@
2. 普通变量赋值只能用 `:=`,不要把 `=` 当赋值写法;`const name = value;` 是常量初始化规则,回看 [04_variables_and_constants.md](04_variables_and_constants.md)。
3. 在普通表达式里,比较才用 `=`,并且把比较表达式放在 `writeLn(...)`、条件或其他需要布尔值的位置。
4. 函数签名里的默认参数 `name = value` 不是比较表达式;默认参数规则回 [05_functions_and_calls.md](05_functions_and_calls.md)。
5. 普通算术优先使用 `+``-``*``/``%`;整数除法和取模可用 `div``mod`;幂运算用 `^`;一元倒数用 `!x`
6. 逻辑表达式优先使用 `and``or``not``&&``||` 也已可用,但不要把 `!` 写成逻辑非。
7. 已有变量做原地更新时,才使用 `+=``-=``*=``/=``%=``^=``.&=``.|=``.^=``a++;``a--;``++a;``--a;`
8. 条件求值优先用 `flag ? true_value : false_value`;需要 Pascal 风格时可用 `if condition then true_value else false_value` 的形态,但必须带 `else`
9. 需要延迟求值或动态表达式对象时,才使用 `@expr``&"..."`,并用本页明确的 `eval(...)` 形态求值
10. 空安全访问只照本页文档明确形态写:`a?.member``a?.[index]`、以及 `c?.a?.[1]`。不要外推成任意深度、任意组合都可写
11. 需要连续比较时,标量用 `:<` / `:>` 这组链式比较;数组逐元素比较用 `::<` / `::>` 这组矩阵链式比较
12. 命中集合、矩阵、对象重载、函数值调用、网格调用、运行时后缀或 TS-SQL 时,按“专题运算符入口表”跳到对应页面
13. `{$ifdef ...}` 只作为能力探测;编译选项边界回 [16_lexical_structure_and_compile_options.md](16_lexical_structure_and_compile_options.md)
14. 任务需要的运算符没有文档事实时,不要生成猜测写法;只能切到对应专题页、项目自身文档或项目专属规则,仍无结论时记录文档缺口
5. 普通算术优先使用 `+``-``*``/``%`左除用 `\`整数除法和取模可用 `div``mod`;幂运算用 `^`对数用 `~`一元倒数用 `!x`
6. 逻辑表达式优先使用 `and``or``not``&&``||``.&&``.||``.!!` 也已可用,但默认不作为主写法;不要把 `!` 写成逻辑非。
7. 位运算使用点前缀或移位关键字:`.&``.|``.!``.^``shl``shr``rol``ror`;普通 `&``|``~` 不按位运算理解
8. 已有变量做原地更新时,才使用 `+=``-=``*=``/=``\=``%=``^=``~=``div=``.&=``.|=``.^=``.&&=``.||=``a++;``a--;``++a;``--a;`
9. 条件求值优先用 `flag ? true_value : false_value`;需要保留条件自身真值时可用 `value ?: fallback_value`;需要 Pascal 风格时可用 `if condition then true_value else false_value` 形态,但必须带 `else`
10. 需要延迟求值或动态表达式对象时,才使用 `@expr``&"..."`,并用本页明确的 `eval(...)` 形态求值
11. 空安全访问只照本页文档明确形态写:`a?.member``a?.[index]`、以及 `c?.a?.[1]`。不要外推成任意深度、任意组合都可写
12. 需要连续比较时,标量用 `:<` / `:>` 这组链式比较;数组逐元素比较用 `::<` / `::>` 这组矩阵链式比较
13. 命中集合、矩阵、过滤、对象重载、函数值调用、网格调用、运行时后缀或 TS-SQL 时,按“专题运算符入口表”跳到对应页面
14. `{$ifdef ...}` 只作为能力探测;编译选项边界回 [16_lexical_structure_and_compile_options.md](16_lexical_structure_and_compile_options.md)
15. 任务需要的运算符没有文档事实时,不要生成猜测写法;只能切到对应专题页、项目自身文档或项目专属规则,仍无结论时记录文档缺口。
## 核心规则
@@ -39,20 +40,24 @@
| 类别 | 运算符 / 形态 | 生成规则 |
| --- | --- | --- |
| 普通赋值 | `:=` | 变量赋值默认只用 `:=`。 |
| 多变量赋值 | `[a, b] := array(...)``[a, ] := array(...)` | 需要从数组按位置拆出多个值时使用;只有一个接收变量时保留末尾逗号。 |
| 常量初始化 | `const name = value;` | 这是常量声明规则,不按普通赋值处理。 |
| 函数默认参数 | `name = value` | 这是函数签名规则,不按比较表达式处理。 |
| 复合赋值 | `+=``-=``*=``/=``%=``^=``.&=``.&#124;=``.^=` | 已有变量需要原地更新时使用。 |
| 算术复合赋值 | `+=``-=``*=``/=``\=``%=``^=``~=``div=` | 已有变量需要原地更新时使用`div=` 是整除复合赋值。 |
| 点前缀复合赋值 | `.&=``.&#124;=``.^=``.&&=``.&#124;&#124;=` | 位运算或点前缀逻辑需要原地更新时使用。 |
| 自增 / 自减 | `a++``a--``++a``--a` | 普通数字变量可直接用;对象重载语义回 [24_object_overloads_and_iteration.md](24_object_overloads_and_iteration.md)。 |
| 算术 | `+``-``*``/``%``div``mod``^` | 普通数值计算使用;`^` 是幂运算。 |
| 算术 | `+``-``*``/``\``%``div``mod``^``~` | 普通数值计算使用;`\` 是左除,`^` 是幂运算,`~` 是对数运算。 |
| 一元正负号 | `+x``-x` | 可直接用于数值表达式。 |
| 一元倒数 | `!x` | 整型、实型输入返回实型倒数;矩阵逆/广义逆回 [22_matrix_deep_dive.md](22_matrix_deep_dive.md)。 |
| 字符串连接 | `+``$` | 字符串拼接两种写法都已写入文档;默认优先用 `+`。 |
| 比较 | `=``<>``<``>``<=``>=` | `=` 只作比较,不作普通赋值。 |
| 逻辑 | `and``or``not``&&`&#124;&#124; | 默认优先写 `and` / `or` / `not`;不要用 `!` 表示逻辑非。 |
| 位运算 | `.&``.&#124;``.^` | 生成代码时写成无空格形态:`.&``.&#124;``.^`。 |
| 点前缀比较 | `.=``.<>``.<``.>``.<=``.>=` | 标量比较可用;数组/矩阵样数据上的逐元素语义回 [12_matrix_and_collections.md](12_matrix_and_collections.md)。 |
| 逻辑 | `and``or``not``&&``&#124;&#124;``.&&``.&#124;&#124;``.!!` | 默认优先写 `and` / `or` / `not`;不要用 `!` 表示逻辑非。 |
| 位运算 | `.&``.&#124;``.!``.^``shl``shr``rol``ror` | 生成代码时写成点前缀或关键字形态;普通 `&``&#124;``~` 不作为位运算写法。 |
| 成员 / 下标 / 调用 | `obj.member``value[index]``Func(args)` | 普通访问和调用可直接使用;类、对象、函数细节回对应专题。 |
| 空安全访问 | `a?.member``a?.[index]``c?.a?.[1]` | 只按已写入文档形态生成。 |
| 条件求值 | `flag ? true_value : false_value` | 普通条件表达式默认写法。 |
| 省略真值的条件求值 | `value ?: fallback_value` | 条件为真时返回条件自身的值;条件为假时返回后备值。 |
| Pascal 风格条件表达式 | `if condition then true_value else false_value` | 必须带 `else`。 |
| 表达式对象 | `@expr``&"..."` | 需要延迟求值或动态表达式对象时使用,并用 `eval(...)` 求值。 |
| 逗号表达式 | `(exp1, exp2, ..., expN)` | 从左到右求值,返回最后一个表达式结果。 |
@@ -69,9 +74,11 @@
| 调用点 `in` / `out`、变参 `...` | [05_functions_and_calls.md](05_functions_and_calls.md) | 这是参数传递 / 变参规则,不按普通表达式运算符处理。 |
| `#Func() with array(...)` | [10_runtime_context_and_with.md](10_runtime_context_and_with.md) | 运行时环境参数调用只按运行时上下文页生成。 |
| `#Func(args)``timeout N``dupvalue(...)` | [10_runtime_context_and_with.md](10_runtime_context_and_with.md) | 网格调用和运行时服务后缀只按运行时上下文页生成。 |
| `union2``intersect``minus``outersect` | [12_matrix_and_collections.md](12_matrix_and_collections.md) | 行集合并、交、差、对称差只按数组/集合页生成。 |
| `union`、&#124;、`:&#124;` | [23_fmarray.md](23_fmarray.md) | `FMArray` 行拼接和矩阵并右方(按列拼接)只按 `FMArray` 页生成。 |
| `->``!matrix` | [22_matrix_deep_dive.md](22_matrix_deep_dive.md) | 数列数组初始化、矩阵逆/广义逆只按矩阵深水页生成。 |
| `union2``intersect``minus``outersect``union2=``intersect=``minus=``outersect=` | [12_matrix_and_collections.md](12_matrix_and_collections.md) | 行集合并、交、差、对称差及其复合赋值只按数组/集合页生成。 |
| `filterIn(...)``filterNotIn(...)` | [13_resultset_and_filters.md](13_resultset_and_filters.md) | 结果集过滤只按过滤页生成,不当作去重型集合运算。 |
| `:*``:/``:\``:^``union`、&#124;、`:&#124;``&#124;=``:&#124;=``&=``:*=``:/=``:\=``:^=` | [22_matrix_deep_dive.md](22_matrix_deep_dive.md)、[23_fmarray.md](23_fmarray.md) | 矩阵乘除、左右拼接、下方拼接和矩阵复合赋值只按矩阵专题页生成。 |
| `->``!matrix``.?``.?:` | [22_matrix_deep_dive.md](22_matrix_deep_dive.md) | 数列数组初始化、矩阵逆/广义逆、矩阵条件求值只按矩阵深水页生成。 |
| `::``::=``:.``:.=` | [22_matrix_deep_dive.md](22_matrix_deep_dive.md)、[24_object_overloads_and_iteration.md](24_object_overloads_and_iteration.md) | 矩阵遍历/深度遍历和对象遍历重载只按专题页生成,不在普通表达式里自行套用。 |
| 反引号转置 `` `value `` | [23_fmarray.md](23_fmarray.md) | `FMArray` 转置只按 `FMArray` 页生成。 |
| `operator +`、`operator <`、`operator[]`、`operator[0]`、`operator[1]`、`operator for`、`operator mrows/mcols/msize`、`operator++`、`operator +=` | [24_object_overloads_and_iteration.md](24_object_overloads_and_iteration.md) | 对象运算符重载只按对象重载页生成。 |
| `select` / `sselect` / `vselect` / `mselect`、`where`、`group by`、`order by`、`join` | [14_ts_sql.md](14_ts_sql.md) | TS-SQL 是查询语法,不按普通表达式拼接。 |
@@ -82,25 +89,28 @@
- 普通变量赋值使用 `:=`;常量初始化不按普通赋值判断,见 [04_variables_and_constants.md](04_variables_and_constants.md)。
- `=` 在普通表达式里用于比较,不用于赋值。
- `const name = value;` 和函数签名默认参数 `name = value` 不按本页普通表达式比较判断。
- 普通算术使用 `+`、`-`、`*`、`/`、`%`、`div`、`mod`、`^`
- 普通算术使用 `+`、`-`、`*`、`/`、`\`、`%``div``mod``^``~`
- 需要数值倒数时用 `!x`;整型和实型输入都会得到实型结果。
- 普通逻辑优先使用 `and``or``not``&&``||` 已写入文档但不作为默认主写法。
- 普通条件求值默认用 `flag ? true_value : false_value`
- 需要把条件自身作为真值返回时,使用 `value ?: fallback_value`
- 需要 Pascal 风格表达式时,才用 `if condition then true_value else false_value`,且必须带 `else`
- 字符串拼接默认用 `+`;需要明确字符串连接时也可用 `$`
- 字符串匹配用 `like` 时按正则理解,不按 SQL `%` 通配理解。
按需生成规则:
- 已有变量需要原地更新时,才用 `+=`、`-=`、`*=`、`/=`、`%=`、`^=`、`.&=`、`.|=`、`.^=`、`a++;`、`a--;`、`++a;`、`--a;`。
- 已有变量需要原地更新时,才用 `+=``-=``*=``/=``\=``%=``^=``~=``div=``.&=``.|=``.^=``.&&=``.||=``a++;``a--;``++a;``--a;`
- 需要矩阵逆/广义逆时才使用 `!A`,并回 [22_matrix_deep_dive.md](22_matrix_deep_dive.md) 确认矩阵生成规则。
- 位运算需要明确写成点前缀形态:`.&`、`.|`、`.^`;普通 `&` 不作为位与写法使用。
- 位运算需要明确写成点前缀或关键字形态:`.&``.|``.!``.^``shl``shr``rol``ror`;普通 `&` 不作为位与写法使用。
- 点前缀比较 `.=``.<>``.<``.>``.<=``.>=` 命中数组/矩阵样数据时,先回 [12_matrix_and_collections.md](12_matrix_and_collections.md) 判断逐元素语义。
- 需要延迟求值或动态表达式对象时,才用 `@expr``&"..."`,并用 `eval(...)` 求值。
- 需要在一个表达式内按顺序执行多个子表达式时,才用逗号表达式 `(exp1, exp2, ..., expN)`
- 空安全访问只按 `a?.member``a?.[index]` 和本页示例里的 `c?.a?.[1]` 生成,不外推任意深链。
- 否定形式只照 `not in``not like``not sqlin``not is` 这几种文档明确写法生成。
- 连续标量比较才用 `:>``:<``:<>``:==``:>=``:<=`
- 数组逐元素链式比较才用 `::>``::<``::<>``::==``::>=``::<=`
- 混合两类以上运算符时,优先用括号明确分组,不依赖跨语言记忆里的优先级。
边界规则:
@@ -136,6 +146,42 @@ writeLn(value);
10
```
省略真值的条件求值:
代码块身份:可直接照写示例
```tsl
writeLn(2 ?: 9);
writeLn(0 ?: 9);
```
代码块身份:输出片段
```text
2
9
```
多变量赋值:
代码块身份:可直接照写示例
```tsl
[a, b] := array(1, 2, 3);
writeLn(a);
writeLn(b);
[first_value, ] := array(4, 5);
writeLn(first_value);
```
代码块身份:输出片段
```text
1
2
4
```
运算赋值:
代码块身份:可直接照写示例
@@ -161,10 +207,12 @@ writeLn(1 + 2);
writeLn(5 - 2);
writeLn(3 * 4);
writeLn(8 / 2);
writeLn(3 \ 2);
writeLn(9 % 4);
writeLn(9 div 4);
writeLn(9 mod 4);
writeLn(2 ^ 3);
writeLn(8 ~ 2);
writeLn(-3 + 5);
writeLn(+3);
```
@@ -176,10 +224,12 @@ writeLn(+3);
3
12
4
0.666666666666667
1
2
1
8
3
2
3
```
@@ -208,6 +258,30 @@ writeLn(2 <> 3);
1
```
点前缀比较:
代码块身份:可直接照写示例
```tsl
writeLn(2 .= 2);
writeLn(2 .<> 3);
writeLn(1 .< 2);
writeLn(2 .> 1);
writeLn(2 .<= 2);
writeLn(2 .>= 2);
```
代码块身份:输出片段
```text
1
1
1
1
1
1
```
一元倒数:
代码块身份:可直接照写示例
@@ -245,8 +319,11 @@ writeLn(dataType(rb));
writeLn((1 < 2) and (2 < 3));
writeLn((1 > 2) or (2 < 3));
writeLn(not (1 > 2));
writeLn(.!! 0);
writeLn((1 < 2) && (2 < 3));
writeLn((1 > 2) || (2 < 3));
writeLn(1 .&& 0);
writeLn(0 .|| 2);
```
代码块身份:输出片段
@@ -257,6 +334,9 @@ writeLn((1 > 2) || (2 < 3));
1
1
1
1
0
1
```
位运算:
@@ -267,6 +347,11 @@ writeLn((1 > 2) || (2 < 3));
writeLn(6 .& 3);
writeLn(4 .| 1);
writeLn(6 .^ 3);
writeLn(.! 1);
writeLn(1 shl 2);
writeLn(8 shr 1);
writeLn(1 rol 1);
writeLn(2 ror 1);
```
代码块身份:输出片段
@@ -275,6 +360,11 @@ writeLn(6 .^ 3);
2
5
5
-2
4
4
2
1
```
基础算术复合赋值:
@@ -291,6 +381,15 @@ a /= 7;
writeLn(a);
a %= 5;
writeLn(a);
b := 3;
b \= 2;
writeLn(b);
c := 8;
c ~= 2;
writeLn(c);
d := 7;
d div= 3;
writeLn(d);
```
代码块身份:输出片段
@@ -300,6 +399,9 @@ writeLn(a);
28
4
4
0.666666666666667
3
2
```
幂运算和位运算也可以使用复合赋值:
@@ -319,6 +421,12 @@ writeLn(c);
d := 6;
d .^= 3;
writeLn(d);
e := 0;
e .||= 2;
writeLn(e);
f := 1;
f .&&= 0;
writeLn(f);
```
代码块身份:输出片段
@@ -328,6 +436,8 @@ writeLn(d);
2
5
5
1
0
```
字符串同样支持 `+=`