TCL学习笔记
Fluent是用Scheme编的,Marc是用Fortran编的,Hypermesh是用的TCL,这都是什么鬼东西……
配置
1 | apt install tcl |
安装完成后,可以得到解释器tclsh,可以直接运行交互式解释器(命令提示符为%),也可以用于运行程序文件。另外,也可以在程序文件开头指明解释器:
1 | #!/usr/bin/tclsh |
基础
基本规则
TCL 是一种类似shell的命令式语言,各种语句都是command arg1 arg2 ...的形式,其中所有参数都被视为字符串,
TCL会先对字符串进行置换,再进行分析处理。置换包括变量置换、命令置换和转义字符置换。另外,
""也可以用于表示含空白字符的字符串,{}则表示原始字符串,其中不会发生任何置换。在TCL中,换行和
;都表示一句命令结束;#开头的行为注释,因此行内注释需要这样:
1
some command ;# 这是注释
- 对于空白比较敏感,例如
if{...}是不对的,因为if{会被认为是一个命令,必须用if {...}。
变量置换
变量名称较为随便,可包括各种奇怪符号,但是为了变量替换的方便,建议只使用字母、数字和下划线。无需变量声明,使用set赋值,使用$进行变量置换从而取值:
1 | %set a 1 ;# a = 1 |
$变量将$之后直到第一个非字母、数字和下划线字符(以及圆括号)之前的字符视为变量名,因而$a.2会变成1.2;稳妥的方式是使用${a.1}。
命令置换
[]内的内容会被认为是一条命令进行运行,其实就类似于匿名函数。两点注意:[]内必须是一或多条完整命令,最后一条的结果被作为输出;[]可以嵌套:
1 | %set m [$a+2] ;# $a+2 并不是完整命令 |
常用命令
puts aim text:将text输出至aim(可以是文件ID、stdout);可以省略aim参数,则默认输出至stdout。expr formula:返回算式formula的值,算式中数字/变量与运算符之间的空格没有影响。append var text:把text追加到变量var之后,返回var。incr var_int int:即var_int += int,返回var_int,var_int和int都必须可被识别为整数。若省略int,则相当于var_int++。关系符号:
< > <= >= == !=,注意还是必须用到expr才能得到值,值为1或0。数学函数:写法类似C,例如
1
2% expr 2 + sin($a)
2.8414709848078967
逻辑控制
if
1 | if {$x > 0} { |
注意空格,注意花括号的左边要留在上一行,不然会被认为语句已结束。
switch
1 | switch options string { |
options表示匹配方式,可以为-exact精确匹配、-glob广泛匹配、-regexp正则表达式匹配;可以省略,默认为-glob。
while
1 | while {$i <= n} { |
while命令结束后返回空字符串。
for和foreach
1 | for {set i 1} {$i < n} {incr i 1} { |
for命令结束后返回空字符串。
foreach是针对列表的,类似于python的for i in a:
1 | set sum 0 |
也可以实现多重的列表循环:
1 | foreach i {a b c} {i k} {d e f g} { |
最终x的值为a b e b f g c {} {}。
过程(函数)
1 | proc add {x y} { |
不用return的话,以最后一条语句的结果作为返回值。
变量作用域
TCL很奇怪,全局变量的作用与不包括过程内部,如果要在过程内引用全局变量,要使用global:
1 | set a 4 |
缺省参数
1 | proc add {x {y 2} {z 3}} { |
变数量参数
1 | proc add { val1 args } { |
引用
通过upvar,可以访问到函数参数对应的原变量,类似于C中的引用:
1 | proc temp { arg } { |
则myexp 7输出13。
数据结构
字典
一般被称为数组,其实是字典,支持两重的变量置换:
1 | % set day(monday) 1 |
可以用array命令对字典进行操作,常用包括:
1 | # 字典元素个数 |
列表
可包含任意的字符串或子列表,可以直接用花括号声明或者用list命令,注意用空格而不是逗号分隔:
1 | % set a {} |
访问数组元素需要使用lindex list indexNumber命令,注意第一变量需要是$x而不是x,下标从0开始:
1 | % puts [lindex [lindex $c 3] 2] |
其它命令:
1 | % llength {1 2 {3 4}} ;# 元素个数 |
其他
文件
open fileFullName access:以access方式打开file,返回文件标识符。打开方式包括:
| 参数 | 打开方式 | 对文件的要求 |
|---|---|---|
r |
只读 | 文件已存在 |
r+ |
读写 | 文件已存在 |
w |
只写 | 已存在则清空文件,否则创建文件 |
w+ |
读写 | 已存在则清空文件,否则创建文件 |
a |
追加 | 文件已存在 |
a+ |
只读 | 文件已存在,否则创建文件 |
close fileID:关闭file,返回空字符串。gets fileID varName:读取file的下一行,赋给var,返回字符数。read -nonewline fileID:读取并返回file所剩的全部内容。puts fileID string:把字符串写入file,结尾添加换行符(采用-nonewline参数禁止)。fileID也可以是stdin, stdout, stderr,省略则默认为stdout。flush fileID:把缓冲区的数据写入文件中,一般在close时会自动flush。pwd和cd:类似bash命令,分别是获取当前路径与切换路径。
其它命令
eval:把所有参数以空格隔开组成一个脚本,如
1
2% eval set a 2 ; set b 4
4
source:读入文件并将其作为脚本求值,注意使用/而不是\:
1
2% source e:/tcl/hello.tcl
Hello
扩展
TCL支持的数据类型较少,也不能面向对象编程,incr TCL(捏他C++)解决了这一问题:
1 | apt install itcl |
