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 |