Allegroskill大体语法.docx
《Allegroskill大体语法.docx》由会员分享,可在线阅读,更多相关《Allegroskill大体语法.docx(20页珍藏版)》请在冰点文库上搜索。
Allegroskill大体语法
SKILL语言简介
SKILL是用于Cadence软件二次开发的语言。
咱们关于SKILL的介绍基于SKILL语言参考档和AllegroSKILL的应用。
语法格式
SKILL语法支持lisp格式的语法,可是咱们不推荐,推荐类C的语法格式。
Lisp例如:
(max53)=>5
C例如:
max(53)=>5
Max是求最大值的函数,lisp格式的不便阅读。
简单的SKILL运行环境
Allegro的SKILL运行环境:
在Allegro的命令窗口输入settelskill窗口就能够够用来运行就能够够打开一个新的窗口,那个SKILL命令。
窗口的大小能够手动调剂。
LoadSkill
能够直接在SKILLdevelopment里面运行SKILL,能够把写好的代码放load命令一次性装载。
在说明load之前,先说一下getSkillPath和setSkillPath这2个函数。
因为load要找到SKILL来装载,通常咱们都不喜爱通过绝对途径来装载一个文件,因为那样包括的字符太多了。
文件getSkillPath()将取得当前Allegro设置的SKILL加载途径,而setSkillPath用来指定加载途径。
目前先不用考虑那个setSkillPath。
我的Allegro当前默许的SKILL途径是Allegro的工作途径和C:
\home\pcbenv\skill如此我先把文件放在C:
\home\pcbenv\skill\函数。
下面,下一步来加载那个文件,然后运行概念的函数
的源代码:
procedure(hello()
let(()
println("HelloWorld!
")
)
);endprocedure
注释
SKILL支持2种注释方式:
a./*…*/用于注释多行,像C一样
b.;用于注释单行,类似C的.
操作符
数学运算+,-,*,/,++,**
比较运算>,<,=,>=,<=,==
逻辑运算||,&&,!
赋值=
输出数据
例如:
%d---integer,%f---float,%s---string,%L---多种数据格式
List数据类型
List是CadenceSKILL中经常使用的数据类型。
能够把List能够有多种类型的常量组成的列表。
明白得为一个数据结构表,它能够是空的,也能够有多种类型的常量组成的列表例如:
'(12abc"PCB")
在上面那个List中包括的数据有整数、字符、字符串。
在List中也能够包括List类型的数据。
例如:
'(1(2aa)b)
创建List数据
创建新的List数据能够用单引号'或函数list来新建一个List数据类型的变量。
例如:
aList='(12abc)=>(12abc)
bList=list(12'a'b'd)=>(12abd)
cList='(1(2aa)b)=>(1(2aa)b)
注意:
当有字符显现的时候,用list函数创建必需在字符前加单引号。
List在内存中的贮存方式
咱们能够把List看做是一个List单元,其中一个List单元占用两个内存位置。
如此便于明白得。
第一个位置保留List的首个数据元素,第二个位置保留后面的List单元(除第一个元素之外的所有元素组成的表),它能够为空数据。
用car函数能够取得保留在第一个位置的List元素:
car(aList)=>2
用cdr函数能够取得保留在第二个位置的List单元:
cdr(aList)=>(34)List
中能够包括有子List,例如:
bList='(1(234)5)=>(1(234)5)
bList在内存中的贮存方式如以下图所示:
List中能够同时包括List和字符,例如:
bList='(1(2aa)b)=>(1(2aa)b)
bList在内存中的贮存方式如以下图所示:
读取List元素
1)读取List中的第一个元素利用car函数能够读取List中的第一个元素。
例:
car('(abc))=>a
z='(123)=>(123)
y=car(z)=>1
y=>1
z=>(123)
car(nil)=>nil
2)读取List中后面的List单元利用cdr函数能够读取List中后面的List
单元。
例:
cdr('(abc))=>(bc)
z='(123)
cdr(z)=>(23)
3)对List重复混合利用car或cdr函数读取car和cdr函数混合利用,组合的格式为:
ca|d[a|d][a|d][a|d]r,以c开头,r中间能够由多个结尾,a或d组成函数。
例如:
caadr功能等同于car(car(cdr(l_list))),caadr对函数List的操作顺序为:
1.先执行一次cdr,读取后面的List单元。
2.对第1步读取的值,执行car,读取其第一元素。
3.对第2步读取的值,执行car,读取其第一元素。
实例:
caaar('(((123)(456))(789)))=>1等同于car(car(car(l_list)))
caadr('(((123)(456))(789)))=>7等同于car(car(cdr(l_list)))
caar('(((123)(456))(789)))=>(123)等同于car(car(l_list))
cadr('(123))=>2等同于car(cdr(l_list))
4)按元素序号读取List中的元素用nthelem并输入所有读取的元素序号,即可读取该编号位置的元素。
如nthelem(1l_list)同于等car(l_list)。
实例:
nthelem(1'(abc))=>a
z='(123)
nthelem(2z)=>2
类似的函数还有nthcdr。
实例:
nthcdr(3'(abcd))=>(d)
z='(123)
nthcdr(2z)=>(3)
5)读取List中最后一个List单元用last函数能够读取List中最后一个元素单元,其数据类型也是一个List。
实例:
last('(abc))=>(c)
z='(123)
last(z)=>(3)
修改List单元
1)rplaca函数用rplaca函数能够替换List中的第一个元素。
aList='(123)=>(123)
bList=rplaca(aList4)=>(423)
aList=>(423)
eq(aListbList)=>t
2)rplacd函数用rplacd函数能够替换List中后面的List单元。
aList='(123)=>(123)
bList=rplacd(aList'(45))=>(145)
aList=>(145)
eq(aListbList)=>t
添加List元素和归并List
1)在List前添加元素(cons,xcons)用cons函数能够添加元素到List前。
aList='(234)
aList=cons(1aList)=>(1234)
xcons函数和cons函数的功能一样,但格式有所区别,前面的变量为List素。
,后面的变量为添加的元xcons('(bc)'a)=>(abc)
2)在List后添加元素(append1)用append1函数能够添加元素到List后。
append1('(123)4)=>(1234)
3)归并List(ncons,append)
cList='(12)
dList='(345)
eList='(67)
append(cListdList)=>(12345)
cList=>(12)
dList=>(345)
append函数只能归并两个List,而且不改变所归并List变量的值。
nconc(cListdListeList)=>(1234567)
cList=>(1234567)
dList=>(34567)
eList=>(67)
nconc函数能够归并多个List,但会改变所归并List变量的值。
List元素排序
1)倒序排列(reverse)
aList='(123)
aList=reverse(aList)=>(321)
anotherList='(12(345)6)
reverse(anotherList)=>(6(345)21)
anotherList=>(12(345)6)
2)按条件排序(sort)
sort的书写格式为:
sort(l_datau_comparefn),其中第一个变量l_data为List量变量,第二个变u_comparefn为对照函数。
对照函数也能够是自概念函数。
sort('(4321)'lessp)=>(1234)
sort('(dbca)'alphalessp)=>(abcd)
sort('("U5""U10""U1""U5""U2")'axlStrcmpAlpNum)
=>("U1""U2""U5""U5""U10")
当List元素都是由List组成的时候,还能够利用sortcar函数对照子List的第一个元素排序。
sortcar('((4four)(3three)(2two))'lessp)
=>((2two)(3three)(4four)
sortcar('((d4)(b2)(c3)(a1))nil)
=>((a1)(b2)(c3)(d4))
查找List元素
1)member函数
member函数从List到返回第一个元素查找到最后,若是找到返回找到的元素开始直到最后的元素,找不返回nil。
member(3'(23435))=>(3435)
member(6'(23435))=>nil
2)assoc函数
assoc函数的书写格式为:
assoc(g_keyl_alist),g_key变量为所查找的关键值,l_alist是为一个由多个List组成的List,格式为:
((key1value1)(key2value2)(key3alue3)...)。
assco返回查找到的子List。
aList='((1"one")(2"two")(3"three"))
assoc(2aList)=>(2"two")
assoc(5aList)=>nil
过滤List元素
1)按条件过滤List元素(setof)setof函数的书写格式为:
setof(s_formalVarl_valueListg_predicateExpression)其中,s_formalVar变量为局部变量,作用于
g_predicateExpression表达式中;l_valueList变量为要过滤的List变量;g_predicateExpression变量为自概念表达式。
setof函数会把l_valueList历赋值给变量中的所有元素,遍s_formalVar局部变量,带入到g_predicateExpression表达式中,若是表达式返回的值为nil输出的新,在List中会将其元素过滤。
setof(x'(1234)(x>2))=>(34)
setof(x'(1234)(x<3))=>(12)
setof(x'(123456)oddp(x))=>(135)
2)exists函数
exists函数和setof函数区别在于exists函数查找List余元素组成的新中知足条件的第一个元素,并返回其元素和其List。
exists(x'(1234)(x>2))=>(34)
exists(x'(4345)(x<4))=>(345)
exists(x'(1234)(x>4))=>nil
3)forall函数
forall函数判定List中所有的元素是不是全数知足表达式,全数知足返回
t,不是就返回nil。
forall(x'(1234)(x>0))=>t
forall(x'(1234)(x<4))=>nil
forall(x'(2468)evenp(x))=>t
forall(x'(2478)evenp(x))=>nil
移除List元素
1)remove函数
remove函数能够移除List中所指定的元素,若是List中没有所指定的元素,那么返回原
List。
remove函数可不能改变原List变量的值。
aList='(12345)
remove(3aList)=>(1245)
aList=>(12345)
remove('(12)'(1(12)3))=>(13)
遍历List元素
1)foreach函数
foreach(x'(1234)println(x))
1
2
3
4
=>(1234)
foreach((xy)'(123)'(456)(printlnx+y))
5
7
9
=>(123)
2)mapc函数
mapc('list'(123)'(987))=>(123)
mapc('(lambda(xy)(print(listxy)))'(123)'(987))
(19)(28)(37)
=>(123)
3)map函数
map('list'(123)'(987))
=>(123)
map('(lambda(xy)(print(appendxy)))'(123)'(987))
(123987)(2387)(37)
=>(123)
4)mapcar函数
mapcar('plus'(123)'(987))
=>(101010)
mapcar('list'(abc)'(123)'(xyz))
=>((a1x)(b2y)(c3z))
mapcar('lambda((x)plus(x1))'(246))
=>(357)
5)maplist函数
maplist('length'(123))
=>(321)
maplist('list'(abc)'(123))
=>(((abc)(123))((bc)(23))((c)(3)))
6)mapcan函数
mapcan('list'(123)'(abc))
=>(1a2b3c)
mapcan((lambda(n)(and(pluspn)(listn)))'(1-23-45))
=>(135)
遍历List元素实例
1)取得List中字符串的长度
假设,有一个由字符串元素组成的List变量stringList:
下面写一段代码,它的功能是输出stringList中每一个字符串元素的字符长度:
若是在没有熟悉mapcar函数的情形下,可能会利用以下代码:
利用mapcar函数的代码:
其实mapcar函数就已经包括遍历List的功能,能够简化代码如下:
2)将List中的所有元素(包括子List中的元素)从头组合成新List
假设,有一个由List组成的List变量x:
下面写一个函数flatten,它的功能是将List中的所有元素从头组合成新List,如下:
下面用mapcan函数,代码如下:
但上面的代码有一个问题,它改变了x变量的值,运行flatten(x)后,x的值如下:
能够利用copy函数复制List副本来幸免改变原list值,代码:
上面的代码运行结果如下:
3)将List中的所有元素(多重List)从头组合成新List
假设,有一个由List和多重List组成的List变量x:
下面写一个函数flatten,它的功能是将List中的所有元素从头组合成新List,如下:
能够重复挪用自身函数来解决多重List读取的难题,代码如下:
流程操纵
注:
下面的一些例如包括多行语句,可是allegro的skill调试窗口不支持多行的调试,因此多于多行的情形,要么把所有的代码从头编辑为一行,或将代码放到一个文件里面,采纳第一章里面说的load的方法来调试。
逻辑值(t,nil)
在第一节说到关系操作和逻辑操作,结合这些操作和条件选择及循环操纵命令能够选择程序运行。
关系操作和逻辑操作的结果是真值或假值,前面说到skill的boolean型数据有2种,一种是t表示真值,一种是nil表示假值,其实skill中把一切非nil的结果都看成真值,而不是仅仅局限于t。
分支操纵
单分支命令(when,unless)
when(bCondition ;bCondition为逻辑表达式,nil或其它(真值)
expressions ;bCondition为真的时候执行when里面的命令
)
例如nCount=5
when(nCount>=5
println(“nCountisnolessthan5”)
)
=>“nCountisnolessthan5”
unless(bCondition
expressions ;bCondition为假(nil)的时候执行unless里面的命令
)
例如nCount=5
unless(nCount<5
println(“nCountisnolessthan5”)
)
注意到when和unless的2个例如的区别了吗?
其实when==(!
unless),也确实是说when在condition为
真的时候执行内部的表达式,而unless是在condition为假的时候执行表达式。
unless算是when的一
个补充,判定nil的情形比用wehn要简练。
双分支命令(if)
if(bConditionthen
exp1 ;bCondition为真的时候执行
else
if(bConditionthenexp1;bCondition为真的时候执行else
exp2 ;bCondition为假的时候执行
)
例如nAge=17
if(nAge<18then
print(“E-not18yearsold,cannotwatchthismovie!
\n”)
else
print(“I-enjoythemovie!
\n”)
)
=>“E-not18yearsold,cannotwatchthismovie!
”
若是用when来写的话,就要写2个when语句。
when(nAge<18
print(“E-not18yearsold,cannotwatchthismovie!
\n”)
)
when(nAge>=18
print(“I-enjoythemovie!
\n”)
多分支命令(cond,case)
sSymbol=“test”
cond((!
sSymbolprintln(“itisnil”))
(numberp(sSymbol)println(“itisanumber”))
(stringp(sSymbol)println(“itisanumber”))
(tprintln(“Idonotcarethetype”)
);endcond
=>itisastring。
cond命令里面有多个程序块,程序会逐个判定里面各个块里面的程序,然后退出块的条件,直到找到一个逻辑为真的块,执行cond。
cond就像是ifthenelse的多次叠加。
case(type(sSymbol)
(“fixnum”
println(“itisanumber”)
)
(“floatnum”
println(“itisafloatnum”)
)
(“string”
println(“itisastring”)
)
);endcase
=>itisastring
case命令里面也有多个程序块,程序会判定case条件的程序块。
后面的那个表达式知足其中的哪个条件,只执行知足case和cond的区别在于cond中的判定表达式能够不唯一,而
case只判定一个表达式。
比如:
cond((numberp(“a”)println(“anumber”))
(5>=3println(“itistrue”))
(tprintln(“nothing”))
);endcond
=>“itistrue”
那个地址有3个条件表达式,第一个是numberp(“a”),若是是真值就执行后面的println命令;第二个