🎨 style(markdown): format all markdown files with prettier

- 使用 prettier 格式化所有 markdown 文件
- prose-wrap: always, print-width: 80
- 保持代码块和表格格式
- 提升可读性和一致性

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
csh
2026-01-07 17:18:01 +08:00
co-authored by Claude Sonnet 4.5
parent 7e96bc86d8
commit 99bef309b7
86 changed files with 1858 additions and 981 deletions
+92 -42
View File
@@ -258,11 +258,13 @@
### 关于 TSL 语言
TSL 是 Tinysoft Statistical analysisLanguage 的简称,她是 Tinysoft Corp.专门为了迎合统计分析所开发的编程语言。TSL 拥有快捷的数据访问方法、强大的运算能力、丰富的函数分析库、灵活强大的数据呈现能力以及强大的数据导入导出功能,拥有了 TSL,统计分析将变得更快速,更容易。
TSL 是 Tinysoft Statistical analysisLanguage 的简称,她是 Tinysoft
Corp.专门为了迎合统计分析所开发的编程语言。TSL 拥有快捷的数据访问方法、强大的运算能力、丰富的函数分析库、灵活强大的数据呈现能力以及强大的数据导入导出功能,拥有了 TSL,统计分析将变得更快速,更容易。
TSL 语言开始于 2002 年,发展伊始,TSL 是一种类 Pascal 编程语言,它除了包含有作为一种编程语言所应具有的各种逻辑流程控制功能以外,更出色的是其具有的丰富的函数库以及方便灵活的数据类型。TSL 使用简单易用的函数而不是复杂的文件 IO 或者数据库作为数据访问的基本途径,TSL 无需用户开发数据呈现界面,无论是简单的整数,实数,字符串,还是复杂的数组、表或者图形,TSL 语言均可以快速地实现。
经过十余年的发展,目前已经是一种融合面向对象,矩阵计算,SQL,集合运算等等为一体的集成性语言,她兼具 Object pascal 的严谨,SQL 的优雅,矩阵语言的高效等特性,成为了数据处理数据挖掘的最佳选择。更难得的是,在历次重大升级中,TSL 语言一直秉承兼容性原则,使得 TSL 开发的代码总是可以无损升级到新的版本,而矩阵、SQL 等语法和基础语法之间的高度融合亦让 TSL 语言兼具效率与易读性。
经过十余年的发展,目前已经是一种融合面向对象,矩阵计算,SQL,集合运算等等为一体的集成性语言,她兼具 Object
pascal 的严谨,SQL 的优雅,矩阵语言的高效等特性,成为了数据处理数据挖掘的最佳选择。更难得的是,在历次重大升级中,TSL 语言一直秉承兼容性原则,使得 TSL 开发的代码总是可以无损升级到新的版本,而矩阵、SQL 等语法和基础语法之间的高度融合亦让 TSL 语言兼具效率与易读性。
TSL 语言不仅仅是一种拥有诸多算符和语法的语言,同时还拥有丰富的函数库,无论是基础的字符串、数字、日期、数据库、文件等处理函数,还是数理统计,优化,时间序列分析等数学性方法,TSL 语言函数包都提供了非常强大的支持。TSL 语言还为证券金融提供了非常丰富的 TOOLBOX 以及 FRAMEWORK,涵盖包括数据处理、财务分析、技术分析、风险收益分析、组合评价、归因分析、定价、优化、策略框架、回测框架等等诸多方面。
@@ -503,7 +505,8 @@ End.
##### DO
循环子句做,可组成 FOR TO/DOWNTO DO 或者 WHILE DO 循环子句。此外,DO 还可以组成 WITH DO 设置语句的运行时环境。
循环子句做,可组成 FOR TO/DOWNTO DO 或者 WHILE
DO 循环子句。此外,DO 还可以组成 WITH DO 设置语句的运行时环境。
参见:WHILEFORWITH
@@ -517,7 +520,8 @@ End.
##### WITH
为语句设置运行时环境,可组成 WITH DO,在类 SQL 语法中,可在 JOIN 子句中使用 with(expLeft…,expRight)作为快速条件。
为语句设置运行时环境,可组成 WITH
DO,在类 SQL 语法中,可在 JOIN 子句中使用 with(expLeft…,expRight)作为快速条件。
参见:DO,With 设值运算符,块环境设置语句,WITH ON 条件。
@@ -699,7 +703,8 @@ Return 18 Ror 1;
##### ARRAY
数组类型初始化,方法为:Array(下标 0:取值 0,下标 1:取值 1,…,下标 N:取值 N),当下标省略的时候,默认下标从整数 0 开始,例如 Array(1,2,3,4)相当于 Array(0:1,1:2,2:3,3:4),数组下标支持字符串,例如 Array('a':1, 'b':2),多维数组的声明例子:Array(('a':1,'b':2),('a':2,'b':3)),其规则为取值为数组,在 ARRAY 声明中的数组取值不再需要 ARRAY 关键字。注意:如果即无下标也无取值,则为空数组,例如 Array(),数组类型
数组类型初始化,方法为:Array(下标 0:取值 0,下标 1:取值 1,…,下标 N:取值 N),当下标省略的时候,默认下标从整数 0 开始,例如 Array(1,2,3,4)相当于 Array(0:1,1:2,2:3,3:4),数组下标支持字符串,例如 Array('a':1,
'b':2),多维数组的声明例子:Array(('a':1,'b':2),('a':2,'b':3)),其规则为取值为数组,在 ARRAY 声明中的数组取值不再需要 ARRAY 关键字。注意:如果即无下标也无取值,则为空数组,例如 Array(),数组类型
参见:ArrayTableArray 数组类型
@@ -859,13 +864,16 @@ Like 的计算方法如下:
###### Not Like
2025/8 月版本开始,TSL 语言中支持 NOT LIKE 这样 not(a like b)可以简单写成 a not like b
2025/8 月版本开始,TSL 语言中支持 NOT LIKE 这样 not(a like b)可以简单写成 a
not like b
Not Like 是与 FAQ:LIKE 相对应的模式匹配操作符,两者语法结构相似但逻辑功能完全相反。
Not
Like 是与 FAQ:LIKE 相对应的模式匹配操作符,两者语法结构相似但逻辑功能完全相反。
字符串中的 Not Like
Not Like 可用于判断某个字符串是否不符合指定的模式规则,当且仅当字符串与给定模式不匹配时返回 True。
Not
Like 可用于判断某个字符串是否不符合指定的模式规则,当且仅当字符串与给定模式不匹配时返回 True。
例如:
@@ -883,7 +891,8 @@ else return "包含'YYYY-MM-DD'格式";
数值中的 Not Like
Not Like 可用于判断某个数值是否和指定值相似,当且仅当数值与给定模式不相似时返回 True。
Not
Like 可用于判断某个数值是否和指定值相似,当且仅当数值与给定模式不相似时返回 True。
例如 1.000001 not like 1 为 False。
@@ -903,7 +912,8 @@ IN 也支持判定是否在多维数组中存在。
###### Not IN
Not IN 用于判断指定元素是否不存在于数组中。若该元素在数组中未被找到,则返回 True;否则返回 False。
Not
IN 用于判断指定元素是否不存在于数组中。若该元素在数组中未被找到,则返回 True;否则返回 False。
与 IN 操作符的使用方式类似,但意义相反。同时也支持如下特性:
@@ -971,7 +981,8 @@ VAR 还可以用来声明变量,在使用 Explicit 编译选项的时候,变
##### ECHO
输出内容(输出到控制台或者 WEB 应用输出到浏览器),语法:echo <expression>[,…],输出的内容必需是简单类型,否则仅仅只是输出一个基本的类型信息。
输出内容(输出到控制台或者 WEB 应用输出到浏览器),语法:echo
<expression>[,…],输出的内容必需是简单类型,否则仅仅只是输出一个基本的类型信息。
例:echo 'Today is ',DateToStr(today()),'now->',timetostr(now());
@@ -1324,7 +1335,8 @@ End;
####### Not IS
not is 用于判断是否不是指定对象的实例。若不是指定对象的实例,则返回 True;否则返回 False。
not
is 用于判断是否不是指定对象的实例。若不是指定对象的实例,则返回 True;否则返回 False。
与 FAQ:IS 语法结构相似但逻辑功能完全相反。
@@ -1819,7 +1831,8 @@ Echo "不支持逗号表达式";
例如,在编辑一个函数时,给函数的参数中输入一个实例对象变量,由于天软中变量都是弱类型,无法通过该变量快速查找到目标类的相关方法等信息。
此时,可通过在函数中增加{$dependency class1,class2}语句,对指定类的信息进行加载,使得在编辑函数时,能够通过不完整的函数名自动搜索到相关模型,并补充完整。
此时,可通过在函数中增加{$dependency
class1,class2}语句,对指定类的信息进行加载,使得在编辑函数时,能够通过不完整的函数名自动搜索到相关模型,并补充完整。
具体表现如:
@@ -1903,7 +1916,9 @@ TSL 语言的实数常量除了直接使用数字加小数点外,还可以用
实数的基础含义每个读者都应明白,为了用户使用方便,在 TSL 中用户一般不需要去理解关于实数更多的知识,只需要使用就可以了。
但有例外,一个是将实数处理成为要存贮的字节流,写入文件或者和其他的外部程序发生交互的时候,需要理解实数在计算机中的具体存贮大小。二是和外部 DLL(Dynamic Link Library,一种在 Windows 中经常使用并依赖的开发技术,使得开发可以模块式开发)发生关系的,必需明确实数的计算机里的标准类型。
但有例外,一个是将实数处理成为要存贮的字节流,写入文件或者和其他的外部程序发生交互的时候,需要理解实数在计算机中的具体存贮大小。二是和外部 DLL(Dynamic
Link
Library,一种在 Windows 中经常使用并依赖的开发技术,使得开发可以模块式开发)发生关系的,必需明确实数的计算机里的标准类型。
在计算机里,实数一般是以浮点的方式来表达的,关于浮点的表达方式在这里就不做具体描述。我们只关注下具体的数据类型,一般存在如下数据类型:
@@ -1911,11 +1926,14 @@ Single 也叫 Float:单精度浮点数,存贮位数为 32 位,也就是占
Double:双精度浮点数,存贮位数位 64 位,也就是占用八个字节的存贮空间,可表达的范围为:正数为 5.0E-308 1.7E+308,负数为-1.7E+308~-5.0E-308,有效精度为十进制的 16 位。Double 是目前应用得最广的数据类型,也是 TSL 语言中默认采用的实数数据类型。当和 DLL 发生关系的时候,又或者执行字节流处理的,TSL 会自动按照指定的位数或者类型采用 DOUBLE 或者 Single 类型。
其他实数数据类型:有占用 16 个字节的 Long Double 类型,有占用 10 个字节的 Extended Double 类型,这些类型可以描述更精确地数字,可以表达更大的数据范围,但是这些类型并不常用。
其他实数数据类型:有占用 16 个字节的 Long
Double 类型,有占用 10 个字节的 Extended
Double 类型,这些类型可以描述更精确地数字,可以表达更大的数据范围,但是这些类型并不常用。
特殊的实数
在实数中,有几个特殊的实数,-INF,+INF,NaN。也就是负无穷大,正无穷大,以及错误的数据(Not a Number)。
在实数中,有几个特殊的实数,-INF,+INF,NaN。也就是负无穷大,正无穷大,以及错误的数据(Not
a Number)。
这些为什么放在实数中呢?事实上这些数据往往都是实数运算产生的结果,例如正数处以 0 得到的是+INF,负数处以 0 得到的是-INF,而 0 处以 0 则是 NaN。
@@ -1965,7 +1983,8 @@ TSL 还支持 20101231.0931T 表达 2012 年 12 月 31 日 9 点 31 分。
这种表达方式可以达到最高 10 毫秒的精度。没有小数点即为 0 点 0 分, 20111231T 则为 2011 年 12 月 31 日 0 点 0 分。
采用这样的方式,历史和未来的任何一天的时间都可以很容易地表达。这种表达方式也是一种国际标准,像 Object pascal 语言,Excel 等通用开发语言和工具中的日期类型也都采纳了这个标准。
采用这样的方式,历史和未来的任何一天的时间都可以很容易地表达。这种表达方式也是一种国际标准,像 Object
pascal 语言,Excel 等通用开发语言和工具中的日期类型也都采纳了这个标准。
其他语言的日期时间表达方式
@@ -2007,13 +2026,15 @@ TSL 语言还支持在字符串常量中表达'或者"的另外的方式,例
在字符串常量中,连续的两个与字符串开始的引号相同的引号可代表一个引号。
也就是说,"This""s a book."代表 This"s a book.,但是"This''s a book."则代表的是 This''s a book.
也就是说,"This""s a book."代表 This"s a book.,但是"This''s a
book."则代表的是 This''s a book.
####号字符表达方式
有时候,程序中需要表达特殊的难以直接输入的 ASCII 符,例如笑脸符的 ASCII 值为 1,要表达的时候就用#1 就可以表达了,而同样的,回车符的 ASCII 码值为 13,可以用#13 来表达,而字符 0 的 ASCII 码值为 48,则#48 可以表达数字字符 0。
#号字符表达方式可以和引号的字符串表达方式串起来表达字符串常量,例如:'The first line,Hello!'#13#10'The second line,Yeah!'#13#10'The End.'描述的字符串内容为:
#号字符表达方式可以和引号的字符串表达方式串起来表达字符串常量,例如:'The first
line,Hello!'#13#10'The second line,Yeah!'#13#10'The End.'描述的字符串内容为:
The first line,Hello!
@@ -2033,7 +2054,8 @@ Pascal 语言的字符串常量是以单引号将内容括起来,并且没有
对于 TSL 语言的字符串类型,采用的是有长度信息的字符串,所以可以支持存在 ASCII 码 0 的字符的字符串,并且理论上,支持长度为 4G 的串,实际上由于内存空间的限制,能表达的字符串会小很多。
ASCIIAmerican Standard Code for Information Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统。
ASCIIAmerican Standard Code for Information
Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统。
参考:字符串运算章节。
@@ -2349,7 +2371,8 @@ arrTable[0]['日期2'] := '2002-06-23'
##### 数组的表达方式
在 TSL 中表达一个数组是很简单的,array(2,3,5,7,11)就是一个数组,里边有 5 个整数数据元素,分别为 2、3、5、7、11,也就是说,数组的表达方式就是在在 array()中将数组中的项使用逗号分隔就可以了。采用这种数组表达方式,TSL 中的默认的数组下标从 0 开始,也就是说值 2 的下标为 0,值 3 的下标为 1,依次类推,值 11 的下标为 4。由于数组中的值都是整数,我们称 array(2,3,5,7,11)这样的数组为一维整数数组,这种类型我们可以描述为 array of Integer。
在 TSL 中表达一个数组是很简单的,array(2,3,5,7,11)就是一个数组,里边有 5 个整数数据元素,分别为 2、3、5、7、11,也就是说,数组的表达方式就是在在 array()中将数组中的项使用逗号分隔就可以了。采用这种数组表达方式,TSL 中的默认的数组下标从 0 开始,也就是说值 2 的下标为 0,值 3 的下标为 1,依次类推,值 11 的下标为 4。由于数组中的值都是整数,我们称 array(2,3,5,7,11)这样的数组为一维整数数组,这种类型我们可以描述为 array
of Integer。
如果 array()的中间没有数组的项,这就是空数组了,空数组就是项数为 0 的数组。这个项数在计算机中有一个专有名词,叫做数组长度,英语表达一般为 length。例如我们也可以说 array(2,3,5,7,11)是一个数组长度为 5 的一维整数数组。
@@ -2369,7 +2392,8 @@ TSL 语言的数组支持数组中的不同项的数据类型不相同,例如
由于这样表达稍嫌繁杂,当数组为 0 开始的连续数字下标的时候,其项如果是数组,该项的数组的 array 可以被省略,也就是说,在这种情况,TSL 语言允许省略掉除第一维以外其他维的 array(),也就是说:
Array((0,1,2,3,4),(3,4,5,6,7))等同于上面的 array(array(0,1,2,3,4), array(3,4,5,6,7))。
Array((0,1,2,3,4),(3,4,5,6,7))等同于上面的 array(array(0,1,2,3,4),
array(3,4,5,6,7))。
TSL 的数组中不仅仅允许使用常量,还允许进行计算,例如 array(1+3,2+5)和 array(4,7)的结果是相同的。
@@ -2403,7 +2427,8 @@ Matrix 类型非常类似于 Array 类型,但是对于许多操作符,仅仅
NIL 类型是一种很特殊的类型,在 TSL 语言中,NIL 往往用来判断数据是否存在。与 NIL 相关的函数有 IfNil 用来判定是否为 NIL。
当然,和 DLL 程序的外部交互的时候,NIL 是有用的,例如外部要一个空指针,和 COM(Windows 开发中的一种组件开发模式,Component Object Model,组件对象模型)交互的时候,也是有意义的。
当然,和 DLL 程序的外部交互的时候,NIL 是有用的,例如外部要一个空指针,和 COM(Windows 开发中的一种组件开发模式,Component
Object Model,组件对象模型)交互的时候,也是有意义的。
绝大多数的语言都没有 NIL 类型,但是有 NIL 值,例如 C 语言中的 NULL,PASCAL 中的 NIL。但那些都只是空指针的概念。TSL 中的 NIL 更接近于 COM 中的 Unassigned。
@@ -2457,7 +2482,8 @@ TCLASS 型数据可以用.操作符来调用类方法。
如果对象的属性或者方法返回的仍然是对象,支持嵌套调用:
ComObjVariant.<PropName|MethodName>[(P1,P2...)]. <PropName|MethodName>[(P1,P2...)]...
ComObjVariant.<PropName|MethodName>[(P1,P2...)].
<PropName|MethodName>[(P1,P2...)]...
NIL 和 COM 的兼容性:由于 Excel,Matlab,S-PLUS 等多种统计软件对空类型的支持不尽相同,导致出现兼容性问题,
@@ -2573,7 +2599,8 @@ TSL 语言标示符大小写无关,未初始化的变量为整数 0。
全局变量必需预先声明。
例如 global x,y,z;声明了三个全局变量 X,Y,Z。在每个引用全局变量的函数中,均需要采用 global 进行声明,不进行声明,TSL 会假设其为局部变量。
例如 global
x,y,z;声明了三个全局变量 X,Y,Z。在每个引用全局变量的函数中,均需要采用 global 进行声明,不进行声明,TSL 会假设其为局部变量。
例如:
@@ -2778,7 +2805,8 @@ a:=100+now();</td></tr></tbody></table>
A:="My test string"; //先给 A 赋值字符串
A:=length(A); //取 A 的长度赋予 A,A 变成了整数 14,函数 length 可以得到字符串 A 的长度,关于 TSL 语言的函数参阅后面章节
A:=length(A);
//取 A 的长度赋予 A,A 变成了整数 14,函数 length 可以得到字符串 A 的长度,关于 TSL 语言的函数参阅后面章节
A:=A\*10.0; //A 的类型运算后变成了实数 140.0
@@ -2827,7 +2855,8 @@ A:="1234";
B:=1;
C:=B+StrToInt(A); //StrToInt 是一个把字符串转换成为整数的函数,我们先不去理解 TSL 的函数的表达方式,函数会在后续章节中讲解
C:=B+StrToInt(A);
//StrToInt 是一个把字符串转换成为整数的函数,我们先不去理解 TSL 的函数的表达方式,函数会在后续章节中讲解
在 TSL 中,我们很明确地先把字符串 A 用相关函数转换成为整数再和 B 相加,这样我们很清楚 C 的结果是 1+1234=1235。
@@ -2855,7 +2884,8 @@ C:= A+B;
正因为数据类型的自动转换和算符重载功能是一把双刃剑,因此 TSL 语言并不支持数据类型的自动转换和算符重载。所有算符重载的功能都可以使用不重载的方法来实现,仅仅只是代码看起来繁杂一点,但是其意义的明确带来的好处完全可以抵消代码繁杂的坏处。
2016 年下半年的 Object TSL 已经支持对象的算符重载,以支持 TSL 的对象利用标准算符进行计算。
2016 年下半年的 Object
TSL 已经支持对象的算符重载,以支持 TSL 的对象利用标准算符进行计算。
#### Explicit 变量声明的编译选项
@@ -2903,7 +2933,8 @@ Var varName1,varName2[:Type];
三元运算符在 TSL 中只有一个,就是?:表达式,如:a>b?1:2,当前的条件为真时候,返回:前的表达式值,否则返回后边的。
TSL 的算符有的存在.前导,例如 .&,.>等等,需要注意的是,由于.是实数的小数部的分割符,所以当运算常量数字的时候,要格外小心,否则非常容易出现意想不到的结果。例如 1.&2 会出错,因为系统将 1.理解成为实数 1,类似于(1.)&2,因此需要用户写成 1 .& 2,也就是在 1 和.&之间使用空格分隔。
TSL 的算符有的存在.前导,例如 .&,.>等等,需要注意的是,由于.是实数的小数部的分割符,所以当运算常量数字的时候,要格外小心,否则非常容易出现意想不到的结果。例如 1.&2 会出错,因为系统将 1.理解成为实数 1,类似于(1.)&2,因此需要用户写成 1
.& 2,也就是在 1 和.&之间使用空格分隔。
此外,还有一些带.的算符可能在读者看起来毫无存在的必要,例如既然存在=算符,.=的计算也和=一样,为什么还要.=呢?这是有原因的,因为=和.=在对数组类型运算的时候表现将不一致,但是这些差异我们在这一节将不做详细解释,等到后边的矩阵计算的相关章节再做详细说明。
@@ -3008,7 +3039,8 @@ return r2;//返回array(3,4)
其传参数可理解为:先将 3 赋值给变量 e,再将 e 的值作为函数的第一个参数传入,再执行表达式[f,g]:=array(1,2),分别给变量 f、g 赋值并将变量 f([f,g]中的第一个值)的值作为函数的第二个参数传入,最后一步将变量 g 的值作为函数的第三个参数传入;所以执行结果为 3+1+2=6。
而当执行 return test(e:=3,[f,g]:=array(1,2))会返回 4。原因是,没有传入第三个参数,因此结果为 3+1+nil=4。(nil 参与运算不报错的情况下,若报错模式则会引发程序报错)。
而当执行 return
test(e:=3,[f,g]:=array(1,2))会返回 4。原因是,没有传入第三个参数,因此结果为 3+1+nil=4。(nil 参与运算不报错的情况下,若报错模式则会引发程序报错)。
注:此种用法并不常用。
@@ -3232,7 +3264,8 @@ TSL 在很多方面和 Pascal 语言比较类似,但是在 Pascal 语言中,
Not 作为结合算符的支持
判断别算法 In,SQLIn,Like,Is 没有对应的反向含义算符,如果需要判定非则需要使用 not( a in b)这样的模式。
判断别算法 In,SQLIn,Like,Is 没有对应的反向含义算符,如果需要判定非则需要使用 not(
a in b)这样的模式。
为了更简便书写和可读性,特别在 2025/8 月版本中增加了 not 和这四个算法的结合。
@@ -3295,7 +3328,9 @@ Not 作为结合算符的支持
说明:若 Condition 为真,则返回 Condition,若 Condition 为假,则返回 FalseResult。
在计算中,经常会出现有 NIL 值,NIL 值的产生原因是多种多样的,例如多表的 SELECT JOIN 查询产生(我们姑且先不去理解什么是 SELECT JOIN),当产生 NIL 值以后,NIL 无法和其他数据类型进行运算,会产生错误。用户可能会希望在计算的时候利用 0 或者空字符串来替代掉 NIL,使得计算可以继续。
在计算中,经常会出现有 NIL 值,NIL 值的产生原因是多种多样的,例如多表的 SELECT
JOIN 查询产生(我们姑且先不去理解什么是 SELECT
JOIN),当产生 NIL 值以后,NIL 无法和其他数据类型进行运算,会产生错误。用户可能会希望在计算的时候利用 0 或者空字符串来替代掉 NIL,使得计算可以继续。
例如:
@@ -3333,7 +3368,8 @@ return s;
说明:为真的单元格采用条件的自身单元格,为假的单元格用 FalseResult 或者 FalseResult 内的单元格替代。
支持矩阵,可以对 fmarray 或 array 的单元格进行判别,组装出对应的矩阵,这样的做法可以避免有些需要循环判别的矩阵操作。对于全数字而言,以前实现需要使用 bool 矩阵和值矩阵相乘后相加来完成:如(a.>3) * a1 + (a.<=3)*a2,或者采用 mfind 得到的数组取子矩阵来操作。
支持矩阵,可以对 fmarray 或 array 的单元格进行判别,组装出对应的矩阵,这样的做法可以避免有些需要循环判别的矩阵操作。对于全数字而言,以前实现需要使用 bool 矩阵和值矩阵相乘后相加来完成:如(a.>3)
* a1 + (a.<=3)*a2,或者采用 mfind 得到的数组取子矩阵来操作。
新的支持会使得这种操作极为便捷,也符合思维定式
@@ -3442,7 +3478,8 @@ ROR</td><td>
[]是对特殊的运算符,和()类似,他们总是成对出现的,有[的时候,必定有匹配的]作为结尾。
我们在前面的章节里看到过 MOV EAX,[EBP+4]这样的指令,这里的[]是取地址 EBP+4 位置存贮的双字,而前面我们也提到计算机的内存也像是一个数组一样,地址像是数组的下标。
我们在前面的章节里看到过 MOV
EAX,[EBP+4]这样的指令,这里的[]是取地址 EBP+4 位置存贮的双字,而前面我们也提到计算机的内存也像是一个数组一样,地址像是数组的下标。
在 TSL 语言中,[]可以有三个用途,一个指示数组的下标项。
@@ -3802,11 +3839,18 @@ Minus=,&amp;=,:*=,:/=,:\=,:^=,::=,::,.|=,.&amp;=,.||=,.&amp;&amp;=,.^=</td><td>
值得注意的是,虽然 TSL 语言的算符和 Pascal 语言在很多方面相似,但是算符的优先级却不尽相同,有一个很典型的例子:
在 Pascal 语法中,A>1 and B<2 这样的表达式是不成立的,这是因为在 Pascal 中 And 可作为位与算符,而且优先级比>要高,那么 A>1 and B<2 等同于 A>(1 and B)<2,这样的表达式显然是不对的。
在 Pascal 语法中,A>1 and
B<2 这样的表达式是不成立的,这是因为在 Pascal 中 And 可作为位与算符,而且优先级比>要高,那么 A>1
and B<2 等同于 A>(1 and B)<2,这样的表达式显然是不对的。
而在 TSL 语法中,And 为逻辑运算符,而且优先级低于>和<,这样 A>1 and B<2 就等同于(A>1) and (B<2)。在 C 或者类 C 语言中,由于逻辑运算符与位运算符是独立的,所以与 TSL 类似,在 C 语言中 A>1 && B<2 也是成立的。
而在 TSL 语法中,And 为逻辑运算符,而且优先级低于>和<,这样 A>1 and
B<2 就等同于(A>1) and
(B<2)。在 C 或者类 C 语言中,由于逻辑运算符与位运算符是独立的,所以与 TSL 类似,在 C 语言中 A>1
&& B<2 也是成立的。
正是由于运算的优先级存在很多的语言差异,而且算符优先级即使对于一个有着丰富经验的程序员而言,也是经常容易混淆的。正因为如此,笔者建议读者在不确认甚至于无论是否确认,也是用圆括弧来把优先级标出来。例如 A>1 and B<2 我们就应该写成(A>1) and (B<2),这样不仅仅阅读起来一目了然,形成这个良好的习惯对于转换于多种计算机语言开发的人也可以起到很大的帮助。
正是由于运算的优先级存在很多的语言差异,而且算符优先级即使对于一个有着丰富经验的程序员而言,也是经常容易混淆的。正因为如此,笔者建议读者在不确认甚至于无论是否确认,也是用圆括弧来把优先级标出来。例如 A>1
and B<2 我们就应该写成(A>1) and
(B<2),这样不仅仅阅读起来一目了然,形成这个良好的习惯对于转换于多种计算机语言开发的人也可以起到很大的帮助。
#### ?.模式
@@ -3926,7 +3970,8 @@ BBB
#### 算术表达式
算术表达式是由算术运算符连接常量、变量、函数的式子。算术表达式中各个运算次序为: ( ),函数,算符
算术表达式是由算术运算符连接常量、变量、函数的式子。算术表达式中各个运算次序为: (
),函数,算符
#### 布尔表达式
@@ -3976,7 +4021,8 @@ TSL 语言中目前支持的关系运算符:
##### 标量链式算符
链式比较表达式形式为 a :< b: < c 或 x :== y: > z 等, 运算过程中会将其隐式转换为逻辑与(and)连接的多个独立比较
链式比较表达式形式为 a :< b: < c 或 x :== y: >
z 等, 运算过程中会将其隐式转换为逻辑与(and)连接的多个独立比较
执行顺序:从左到右依次计算每个比较
@@ -4000,7 +4046,8 @@ return 0:<a:<b:<100;
##### 矩阵链式算符
矩阵链式比较的表达式形式为 a ::< b:: < c 或 x ::== y::> z 等, 运算过程中会将其隐式转换为逻辑与(.&&)连接的多个独立比较
矩阵链式比较的表达式形式为 a ::< b:: < c 或 x ::== y::>
z 等, 运算过程中会将其隐式转换为逻辑与(.&&)连接的多个独立比较
执行顺序:从左到右依次计算每个比较
@@ -4206,7 +4253,8 @@ WITH DO 则提供了一个方便的功能。
### With \*,SysParamArray Do,与 With \*\*,SysParamArray Do
假定我临时需要修改系统参数,但需要执行一大堆的代码,这个时候 SpecAll 就不方便了,我们引入 With \*,SysParamArray Do 的模式来解决这个问题。
假定我临时需要修改系统参数,但需要执行一大堆的代码,这个时候 SpecAll 就不方便了,我们引入 With
\*,SysParamArray Do 的模式来解决这个问题。
假定有 a:=array(pn_stock():"SZ000002",pn_cycle():cy_1m(),pn_date():Today()+10/24);
@@ -4228,7 +4276,9 @@ end;
这样,我们可以用指定的系统参数环境执行一大段的代码,运算结束后恢复特殊的系统环境变量。
而在某些极为特别的情况下,我们希望在执行的过程中不修改任何系统参数,无论是否是特殊的系统环境变量,我们可以使用 with \*\*,a do 的模式,其含义是切换环境为 a,这样原有的环境失效,运算结束后恢复原有的所有的环境。
而在某些极为特别的情况下,我们希望在执行的过程中不修改任何系统参数,无论是否是特殊的系统环境变量,我们可以使用 with
\*\*,a
do 的模式,其含义是切换环境为 a,这样原有的环境失效,运算结束后恢复原有的所有的环境。
### With => Do