個人用備忘録です。
公式掲示板
簡単な〇〇がやりたい、というのはこちらで調べる。
直接利用できなくても、部分的に参考になるのがとても役立つ。
日本語wiki
あまり情報量は多くないが取っ掛かりにはよいかも。
API Finder
CIWメニューのToolsからSKILL API Finderを選択。
用途のわからない関数はとりあえずこれで調べる。
上の公式掲示板でそれらしい関数を見つけて検索するとよさげ。
データ構造
変数(SKILLでは"symbol"や"variable"と呼ばれる)は
- Print name
- Value
- Function binding
- Property list
という要素を持っている。valueとproperty listを同時に持つ、ということが可能。
valueとfunction bindingを同時に持つことは推奨されない。
Disembodied Property List
変数のvalueに入れることのできるproperty list。
通常nilで始まり、name/valueペアが続くリストで表される。
Association Table
RubyのHash、PythonのDictionaryのようにkey/valueペアでデータを保持する。
Property Listのkeyはsymbolしか使えないが、Association Tableのkeyはinteger, float, stringなどが使える。
setq
変数を代入する関数
(setq x 100)
x
;=> 100
setof
Pythonのリスト内包表記に似た機能。戻り値がフィルターされた後のリストになる。
setofのみでは変数はセットされない。
foreachでも同じことができる。
x = setof(x '(1 2 3 4) (x > 2))
x
;=> (3 4)
x = foreach(mapcan x '(1 2 3 4) if(x > 2 list(x)))
x
;=> (3 4)
Arrow operator->
変数のvalueがsymbolであるときに、symbolのproperty listに間接的にアクセスする。
designator = 'U235
U235.x = 200
U235.y = 300
designator->x ;=> 200
designator->y ;=> 300
U235.x = 200
の.
はproperty listの要素にアクセスする演算子。
また、変数の値がdisembodied listの場合はその要素にアクセスする。
loc = '(nil x 100 y 200) ;=> (nil x 100 y 200)
loc->x ;=> 100
~>
と->
の違い
procedure
関数定義用
procedure( myadd(a b)
a + b
)
myadd(2 3)
;=> 5
split
parseString()が使える
s = "aaa/bbb/ccc"
parseString(s "/")
=> ("aaa" "bbb" "ccc")
append
リスト末尾に他のリストを加える
l = list()
l = append(l '(1 2))
l = append(l '(4 5))
l
;=> (1 2 4 5)
append()
はnon-destractiveなのでprocedure()
内からリストを操作するには使えない。
l = '(1 2)
procedure(myappend(list)
list = append(list '("a" "b"))
)
myappend(l)
print(l)
;=> (1 2) : myappend関数内でappendされたリストは関数外には反映されない
lconc
lconc()
を使うとdestracticveにリストに要素を追加できる。
一旦tconc()
でリストのような構造を作ってから、lconc()
を使って要素を追加、その後car()
を使って取り出す。
x = tconc(nil 1) ; x is initialized ((1) 1)
lconc(x '(2 3 4)) ; x is now ((1 2 3 4) 4)
lconc(x nil) ; Nothing is added to x.
lconc(x '(5)) ; x is now ((1 2 3 4 5) 5)
x = car( x ) ; x is now (1 2 3 4 5)
pop
末尾にアクセスするには…
popと違い非破壊的
l = '(1 2 3 4)
reverse(cdr(reverse(l)))
=> (1 2 3)
list to string
buildString( '("test" "il") ".") => "test.il"
if
if( 条件文 then
Trueのときの処理1
Trueのときの処理2
...
else
Falseのときの処理1
Falseのときの処理2
...
)
リストに要素がふくまれているかどうかで条件分岐
member()
を使う
if(member(1 '(1 2 3)) then
println("true"))
foreach
foreach内で使った変数は外では参照されない
i=100
foreach(i '(1 2 3 4) println(i))
;1
;2
;3
;4
println(i)
;100
zip
pythonのzipに相当する操作はforeachでできる
foreachのマニュアルに書かれているので参照するとよい
(foreach (x y) '(1 2 3) '(4 5 6) (println x+y))
5
7
9
=> (1 2 3)
map
リストからnil
を取り除く。
foreachのそれぞれのループで返る値はlistにする必要があるので注意。
l = list("a" "b" nil "c")
foreach(mapcan s l if(s != nil list(s)))
; ("a" "b" "c")
let
ブロック内でのみ有効な関数の宣言
let( (x y)
x = 3
y = 5
print(x + y)
)
; 8
x
; *Error* toplevel: undefined variable - x
parseString
文字列を分割してリストを返す。
parseString( "Now is the time" ) => ("Now" "is" "the" "time")
parseString( "~/exp/test.il" "./") => ("~" "exp" "test" "il")
Both . and / are break characters.
parseString( "-abc-def--ghi-" "-" )
=> ("abc" "def" "ghi")
parseString( "-abc-def--ghi-" "-" t )
=> ("" "abc" "def" "" "ghi" "")
cons
リストの先頭に要素を追加
cons(
g_element
l_list
)
=> l_result
###ファイル出力
例
cv = getCurrentWindow()~>cellView
tmpout = outfile("./inputPinList.txt")
foreach(terminal cv~>terminals if(terminal~>direction=="input" then fprintf(tmpout "%s\n" terminal~>name)))
close(tmpout)
ciUtilsMakeUnique
リストの重複する要素を除いて返す
ciUtilsMakeUnique('("a" "a" "b" "c" "a" "a" "b" "c"))
=> ("a" "b" "c")
各種プロパティの値の取得
インスタンス名 instance~>name
セル名 instance~>cellName
CDFパラメータ cdfGetInstCDF(instance)~>c~>value
cellViewがRead-OnlyかEditableか cv~>mode
正規表現オブジェクトの作成とマッチ
pcreCompile()
で正規表現オブジェクトを作って、pcreExecute()
でマッチするかどうか比較する。
PCRE(=Perl Compatible Regular Expression)
let( (namePat)
namePat = pcreCompile("^(dff|lat)") ;; name begins with either 'dff' or 'lat'
foreach(cell ddGetObj("shem")~>cells
when(pcreExecute(namePat cell~>name)
;; do your processing here
): when
); foreach
); let
参考
https://community.cadence.com/cadence_technology_forums/f/custom-ic-skill/36833/regular-expressions
正規表現 バックスラッシュについて
pcreCompile("\\d")
のように特殊文字を使うときはバックスラッシュが2つ必要らしい。
正規表現 キャプチャ
comPat = pcreCompile("^([a-z]+)_([a-z]+)")
pcreobj@0x3431b9a0
>
pcreExecute(comPat "abc_def")
t
>
pcreSubstitute("\\0")
"abc_def"
>
pcreSubstitute("\\1")
"abc"
>
pcreSubstitute("\\2")
"def"
>
Sort
セル名でソート。アルファベット順。
insts = sort(insts (lambda (i1 i2) alphalessp(i1~>cellName i2~>cellName)))
nilガード
input = nil
nil
>
s = (input || "")
""
>
built-ins
dbFindMemInstByName()
dbGetAnyInstSwitchMaster()
dbFindSigByName()
dbFindTermByName()
dbProduceMemName()
;; cellViewオブジェクトからnetを探してオブジェクトを返す
net = dbFindNetByName(cv "net01")
;; cellViewオブジェクトからインスタンスを探してオブジェクトを返す
inst = dbGetInstByName(cv "INST1") ;; maintained only for backward compatibility; you should now use dbFindAnyInstByName.
Screenshot
hiExportImage(?fileName "sample.png" ?window getCurrentWindow() ?bBox inst~>bBox ?scaleFactor 2)
テキストファイル読み込み
;; 関数定義
procedure( parseFile( file )
let( ( table tokens fpFile )
fpFile = infile( file )
table = list()
while( gets( line fpFile )
tokens = parseString( line )
tokens && ( table = cons( tokens table ) )
);while
close( fpFile )
reverse( table )
);let
);procedure
;tmp.txt
;0 aaa AAA
;1 bbb BBB
;2 ccc CCC
;; 各行が空白区切りでリストになって出てくる
parseFile("tmp.txt")
;(("0" "aaa" "AAA")
; ("1" "bbb" "BBB")
; ("2" "ccc" "CCC")
;)