保姆级教程超硬核包会,TCL解释语言

前言:对在EDA仿真工具中使用的TCL语言做了简单介绍。

TCL解释语言

  • TCL在EDA工具中使用。
  • TCL(Tool Command Language)是一种解释执行的脚本语言,使用c、c++语言的过程库实现。
  • TCL脚本执行依赖于解释器(逐行执行)。
  • TCL有效命令行以命令+字符串(结合空格间隔符)形成。
  • 置换($、[]、 \)和引用(“”, {})。
  • 命令eval、expr、source、exec
  • 掌握{*}配合glob等返回list后的操作。
  • TCL中的注释是#,类似于 //。

1. 基本用法

一个TCL脚本可以包含一个或多个命令,命令之间必须用换行符隔开。

set a 1
set b 2
或set a 1; set b 2 //TCL有效命令行以命令+字符串(结合空格间隔符)形成

TCL有效命令行以命令+字符串(结合空格间隔符)形成。

  • set是有效命令 a是字符串参数。
  • TCL的每一个命令包含一个或几个单词,第一个单词代表命令名,另外的单词则是这个命令的参数,单词之间必须用空格或Tab键隔开。
  • TCL在分析命令时,把所有的命令参数都当做字符串看待
%set x 10 //定义变量x,并把x的值赋为10
%set y x+100 //y的值是x+100 ,而不是110

上述代码,x被看做字符串 x+100的一部分,如果想使用x的值10,会必须告诉TCL:这里的x不是字符串,是变量的值。这时候就会用到置换功能。

2. 置换功能

TCL提供三种形式的置换:变量置换、命令置换和反斜杠置换。

2.1 变量置换

  • 变量置换由$符号标记,会导致变量的值插入一个单词中。
%set y $x+100 //y的值是10+100,x被置换成它的值100

这时,y的值还不是110,而是10+100, 此时TCL把10+100看成一个字符串而不是表达式,y要想得到值110,必须使用命令置换,使TCL把10+100看成一个表达式并求值。

2.2 命令置换

  • 命令置换是由[]括起来的TCL命令及其参数,会导致某一个命令的所有或部分单词被另一个命令的结果所代替。
%set y [expr $ x+100]

y的值为110,当TCL遇到字符’ [ ’ 时,会把随后的expr作为命令名,执行与expr对应的c过程。如果去掉[] ,此时会报错,因为TCL只会把第一个单词作为命令,其他单词只是字符串。

2.3 反斜杠置换

  • 反斜杠置换可以在单词符号中插入,插入符号会把特殊符号当做普通符号处理。
%set msg multiple\ space 

如果没有\的话 此时有四个单词,TCL会报错,加了\后,空格不会被当做分隔符,mulltiple space被认为是一个单词。

2.4 双引号和花括号

  • 双引号和花括号可以把分隔符等特殊符号当做普通字符,与反斜杠相同,但有所不同。

  • 对双引号中的各种分隔符将不做处理。但对换行符、 $ 和[] 两种置换符会正常处理。

%ser y " $x ddd" //x会被转换

3. TCL中的变量

  • TCL简单变量包含两部分,名字和值(可以是任意字符串),可以从在上面的代码中看出来。
  • 在变量置换时, $符号与 $f符号之后第一个不是字符、数字和下划线之间的内容作为置换的变量。
%set a 2
%set a.1 4
%set b $a.1 

执行最后一个命令时,置换的是 $a,最终结果为2.1,与我们想象的结果不同。这时候可以使用{}把变量名括起来。

%set b ${a.1} //结果为4
  • TCL中set能生成一个变量,也能读取或改变一个变量的值。
%set a {kdfj kdfg}//定义a并赋值
%set a //读取a的值

3.1 变量:数组

  • 数组是元素的集合。 与之前所学的数组不同。
%set day(monday)1
%set day(tuesday)2

day为数组名,monday、tuesday分别为数组中的元素,值分别为1和2.

3.2 相关命令

  • unset删除变量,可以同时删除很多个。
%unset a b day(monday)
  • append把文本加到变量的后面。
% set t hello
%append t " !" //结果为hello!
  • incr把一个变量值加上一个整数。要求两个值都是整数。
%set n 2; incr n 3

3.3 表达式

  • TCL支持常用的数学函数
%set x 2
%expt 2*sin(3)

数学函数只有出现在expr之后才有意义

  • list在TCl中表示集合,可以嵌套,里边的元素默认为字符串。
  • 生成一个list,1 2 {3 4 }是list 的元素。
%list 1 2 {3 4}
  • 合并两个listconact
%concat{1 2 3 }{4 5 6}// {1 2 3 4 5 6}
  • 返回第n个元素 lindex list n
%lindex {1 2 {3 4}} 2 
  • 返回list的元素个数llength list
%llength{1 2 {3 4}}
  • list插入元素
%linsert {1 3 4}  1 2 3 //结果为1234
  • if
if{ $x>0 } { //花括号必须在这里,if与花括号直接有空格
...
}else{
...}
  • 循环命令while
set b " "  //给b一个变量
set i [expr [llength $a] -1]//  
while { $i>0}{
lappend b [lindex $a $i] //把a的值给b
incr i -1 //给i-1
}
  • 循环变量for

语法:for init test reinit body
参数init是一个初始化脚本,第二个参数test是一个表达式,用来决定循环什么时候中断,第三个reinit是重新初始化的脚本,第四个body也是脚本,代表循环体。
假设a是一个链表,把a 的复制到b

set b ""
for {set i [expr[llength $a] -]} { $i>0} {incr i -1} {lappend b [lindex $a $i]}
  • foreach

foreach varname list body

第一个参数varname是一个变量。第二个参数list是一个集合,第三个参数body是循环体,每次取得一个元素都会循环一次。

set b "" 
foreach i $a{
set b [linsert $b 0 $i]
}
  • switch

一旦switch找到一个模式匹配,就会执行相应的脚本,并返回脚本的值。

%switch $x{
b {incr t1}
c {inct t2}}
  • 在循环体中,可以用break和continue命令中断循环。 break命令结束整个循环过程并从循环中跳出,continue结束本次循环。
  • source命令读一个文件并把这个文件内容作为脚本求值。
%source e:/tcl&c/hello.tcl
  • eval命令用来构造和执行TCL脚本。把所有参数以空格隔开组合到一起,并进行求值。
%eval set a 2; set b 4
  • TCL中过程由proc命令产生
%proc add {x y }{expr $x+ $y}
  • proc命令的第一个参数是要定义的过程名字,第二个参数为参数列表,参数之间空格隔开,第三个参数为过程体,生成命令后可以调用。
%add 1 2  //3

在定义过程中,可以使用return在任何地方中断过程,并返回参数作为结果。

3.3 局部变量和全局变量

%set a 4
%proc sample {x}{
	global a //声明a来自外部
	incr a
	return[expr $a + $x]}
%sample 3
%set a
  • 字符串操作

format formatstring ? vlue value…?
按formatstring提供的格式,把各个value的值组合到formatstring中形成新字符串,并返回。

%set name john
%set age 20
%set masg[format "%s is %d years old" $name $age]
//john is 20 years old
  • scan

scan是format命令的逆。

%scan "some 26 34 "  "some %d %d " a b 
%set a //26
%set b  //34 
  • 文件访问

open name ? access?
open命令,以access方式打开name。

  • 使用pwd和cd管理工作目录。pwd返回当前目录的完整路径,没有参数,cd切换工作目录。
  • glob和file用来操作或获取文件。

glob命令采用一种或多种模式作为参数,并返回所有文件的列表。

%glob *.c * .h //把文件中后缀是.c 和.h的找出来
file delete *.tmp //错误不识别 *
file delete{*}[glob *.tmp]
eval  file delete[glob *.tmp]

file copy? force??source target
这个命令把source中指明的文件或目录递归的拷贝到目的地址,只有当存在force选项时,已经存在的文件才会被覆盖。试图覆盖一个非空的目录、以文件覆盖目录、目录覆盖文件都会报错

file mkdir dir? dir ...? //创建dir中指明的目录
file owned name //name是否存在,存在返回1,否则0
file executable name //name是否可以执行,可以返回1,否则0
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值