東京工業大学 >
大学院理工学研究科 >
基礎物理学専攻 >
中村研究室 >
メンバー >
ホームページ >
おぼえがき >
kumac
kumac
PAWのマクロであるkumacの書き方おぼえがき。kumacの文法的なものを書きたい。kumacはANAPAWでも使える。
(壊れかけのおぼえがき。)
マクロの実行
kumac_name.kumacという名のマクロを実行するには、exec kumac_nameとする。execコマンドの引数はファイル名を指定する。ファイル名の拡張子が.kumacのときは、.kumacを省略しても良い。逆にファイル名の拡張子が.kumac以外のときは、拡張子を省略できない。
ファイル名: kumac_name.kumac
|
---|
macro kumac_name
mes 'Hello, world!'
return
|
実行結果
|
---|
PAW > exec kumac_name
Hello, world!
PAW > exec kumac_name.kumac
Hello, world!
|
マクロファイルはPAWを実行したディレクトに置いておく。ほかのディレクトリに置いたマクロファイルを実行するには、execコマンドの引数にファイルの相対パス/絶対パスを指定する。
ファイルパス: /home/username/kumac/test.kumac
|
---|
macro test
mes 'Hello, world!'
return
|
端末で実行
|
---|
$ cd # ホームディレクトリ/home/username に移動。
$ ls kumac # ホームディレクトリにあるkumacディレクトリの中身を表示。
test.kumac
$ paw
PAW > exec kumac/test
Hello, world!
PAW > exec /home/username/kumac/test
Hello, world!
PAW > exec ~/kumac/test
Hello, world!
|
コーディング
基本的にkumacの文法は、FORTRANの文法に近い。
■ 大文字/小文字
FORTRANと同じく、kumacに大文字/小文字の区別はない。
■ コメント
コメントは行の最初に *, | を書くか、行末に | を書く。
| ここはコメント
* ここはコメント
mes 'aa' | ここもコメント
|
■ 行頭
行頭はFORTARNのように6文字分のスペースを開ける必要はない。しかし、開けてもかまわない。すなわち、字下げを行いプログラムを見やすくできる。
mes 'aa'
mes 'bb'
mes 'cc'
|
■ 継続行を書く&コマンドをまとめて実行する
マクロの一行が長くなる場合は、_ を用いて継続行を表すことができる。また、複数のコマンドを一行でまとめて実行するには、; を用いる。
mes 'aaaaaaaaaa_
aaaaaaaaaa'
mes 'bb'; mes 'cc'; mes 'dd'
|
実行結果
|
---|
aaaaaaaaaaaaaaaaaaaa
bb
cc
dd
|
■ マクロの始まりと終わり
マクロはmacro kumac_nameで始まり、returnで終わる。しかし、macro kumac_nameの部分は省略しても良い。ひとつのファイルに複数のmacroを書くこともできる。途中でマクロを抜けるには、exitm文を用いる(下記参照)。
ファイル名: kumac_name.kumac
|
---|
macro kumac_name
mes 'aa'
exec subkumac_name
return
macro subkumac_name
mes 'bb'
return
|
実行結果
|
---|
PAW > exec kumac_name
aa
bb
|
ファイル名: kumac_name2.kumac
|
---|
mes 'aa'
mes 'bb'
|
実行結果
|
---|
PAW > exec kumac_name2
aa
bb
|
変数
■ 代入
= を用いて、変数に整数、実数、文字列を代入できる。
para1 = 1
para2 = 1.1
para3 = 'aa'
|
vectorの値を変数に代入することも可能。
vec/cre par(3) r 0.1 0.2 0.3 | 一次元ベクトル作成
vec/cre par2(2,2) r 1.1 1.2 1.3 1.4 | 二次元ベクトル作成
val1 = par(1) | ベクトルの値代入
val2 = $eval(par(3)) | ベクトルの値を参照して代入?
val3 = par(1,1)
val4 = $eval(par(2,1))
mes [val1] [val2] [val3] [val4] | 0.1 0.3 1.1 1.2 が表示される。
|
■ 参照
変数に代入された値を参照するには、変数を[ ]で囲む。
para1 = 'aa'
mes [para1] | aa が表示される。
para2 = 10
para3 = 20
para4 = [para2] + [para3]
mes [para4] | 30 が表示される。
|
マクロ内の[ ]で囲まれた変数を含む行は、変数の参照を行ってから実行されている?むしろ、変数を一度評価してから、実行している?
para1 = 'aa'
[para1] = 10
mes [aa] | 10 が表示される。
para2 = 'bb'
para3 = 'cc'
para4 = 'dd'
[para2] = [para3][para4]ee
mess [bb] | ccddee が表示される。
|
参照[ ]は入れ子にすることも可能。参照[ ]の中の入れ子は98重まで可能。
bb = 'aa'
cc = 'bb'
mes [[cc]] | aa が表示される。
dd=cc
mess [[[dd]]] | aaが表示される。これを2重の入れ子とすると、98重まで可能。
|
■ 計算
変数同士は四則演算ができる。複雑な計算をする場合は、$sigmaを用いる。
a = 1.0
b = 2.0
c = 3.0
d = 4.0
e = ([a] + [b]) * [c] / [d]
mes [e] | 2.25と表示される。
f=$sigma( sqrt([d]) + [a])
mes [f] | 3 と表示される。
g=$sigma( exp(log([d]) + sin([c])) + cos([c])**[b] )
mes [g] | 5.58634 と表示される。
pi=3.14159
h=$sigma( cos([pi]) )
mes [h] | -1 と表示される。
|
■ 文字列の結合
文字列は // を用いて結合することができる。たまに使う。大抵は、文字列同士をただ並べるだけで結合される。
str1 = aa
str2 = bb
mess [str1]//[str2]//'cc' | aabbcc と表示される
mess [str1][str2]cc | aabbcc と表示される
|
■ シングルクオート
文字列としてシングルクオートを用いる場合は、シングルクオートを重ねる。
str1 = 'aa''bb''cc'
mess [str1] | aa'bb'cc と表示される
|
■ スコープ
変数の参照は、通常その変数が宣言されたマクロ内でのみ有効である。すなわち、変数はローカル変数として宣言される。静的ローカル変数はむりかも?また、マクロを入れ子にした場合、入れ子から外側のローカル変数は参照できない。
macro main
par='aa'
mes [par]
exec sub
return
macro sub
mess [par]
return
|
マクロや、マクロの入れ子から外側の変数を参照するには、変数をグローバル変数として宣言し、インポート(?)する。
macro main
global/create par
global/create str
par=3
str='aa'
exec sub
return
macro sub
import par str | グローバル変数: par, str をインポート
mess [par]
mess [str]
return
|
上記マクロの別記
|
---|
macro main
global/create par 3
global/create str 'aa'
exec sub
return
macro sub
import * | すべてのグローバル変数をインポート
mess [par]
mess [str]
return
|
■ 配列もどき
変数名として( )が使える様なので、配列もどきを作ることができる。
do i = 1, 5
a([i]) = [i]*2
enddo
mes [a(1)] [a(2)] [a(3)] [a(4)] [a(5)] | 2 4 6 8 10 が表示される。
j=3
mes [a([j])] | 6 が表示される。
|
■ 特殊な値
[0],[1],[2],[3],...と、[#],[*],[@]は特別な値を表す。詳しくは、Paw Reference Manualの/MACRO/SYNTAX/Variables/Special の項目を参照。
特殊な値 |
値 | 意味 |
[0] | 実行されたマクロファイル名を格納する。 |
[1],[2],[3],... | マクロに渡される引数を参照する。 |
[#] | マクロに渡される引数の数をあらわす。引数がないときは0。 |
[*] | すべての引数をあらわす。引数同士は空白で区切られる。for文で用いると便利。 |
[@] | 最後に実行されたマクロの返し値(exitm 文または return 文で指定)を格納する。 |
[0],[1],...,[*],[#]の例
ファイル名: spe_test.kumac
|
---|
macro spe_test
mes [1]
mes [2]
mes [3]
mes [*]
mes [#]
mes [0]
return
|
実行結果
|
---|
PAW > exec spe_test aa bb cc
aa
bb
cc
aa bb cc
3
spe_test.kumac#spe_test
|
[@]の例
ファイル名: spe_test2.kumac
|
---|
macro spe_test2
mes [@]
exe sub
mes [@]
return
macro sub
return aa
|
実行結果
|
---|
PAW > exec spe_test2
0
aa
|
マクロの呼び出し、引数、返し値
一つのマクロファイルに複数のマクロを書くこともできる。それらのマクロは、同一マクロファイル内や、PAWのコマンドラインから呼び出すことができる。また、マクロは引数をとることもできる。また、マクロは引数をとったり、返し値を指定することもできる。すなわち、マクロを関数のように扱うこともできる。
■ マクロの呼び出し
PAWのコマンドラインから、マクロファイル内の複数のマクロのうちの一つを実行するには、マクロファイル名#マクロ名とする。
ファイル名: macro_test.kumac
|
---|
macro main_macro
mes main
return
macro sub_macro_1
mes sub_1
return
macro sub_macro_2
mes sub_2
return
|
実行結果
|
---|
PAW > exec macro_test
main
PAW > exec macro_test#main_macro
main
PAW > exec macro_test#sub_macro_2
sub_2
|
マクロファイル内で別のマクロを呼び出すこともできる。同一ファイル内のマクロは、exec マクロ名とすれば実行される。
ファイル名: macro_test2.kumac
|
---|
macro main_macro2
exec sub_macro_1
exec sub_macro_2
return
macro sub_macro_1
mes sub_1
return
macro sub_macro_2
mes sub_2
return
|
実行結果
|
---|
PAW > exec macro_test2
sub_1
sub_2
|
■ マクロに値を渡す(その1)
以下の例では、マクロ内の変数aa, bb, cc にマクロの引数として値 1, dd, 0.1 を渡している。マクロ中の"aa bb cc"の部分は"aa= bb= cc="、または"[aa] [bb] [cc]"と書いても良い。
ファイル名: arg_test.kumac
|
---|
macro arg_test aa bb cc
mes [aa]
mes [bb]
mes [cc]
return
|
実行結果
|
---|
PAW > exec arg_test 1 dd 0.1
1
dd
0.1
|
■ マクロに値を渡す(その2)
マクロのはじめ(macro文)で変数を指定しなくても、マクロ実行時の引数はマクロ内で[1],[2],[3],...を用いて参照できる。
ファイル名: arg_test2.kumac
|
---|
macro arg_test2
mes [1]
mes [2]
mes [3]
mes [4]
return
|
実行結果
|
---|
PAW > exec arg_test2 aa 'bb' 0.1 5
aa
bb
0.1
5
|
■ 引数すべてに対して処理をする
マクロに渡される引数の数は、[#]に格納される。これを用いれば、引数の数が不定でもすべての引数に対して処理をすることができる。
ファイル名: arg_test3.kumac
|
---|
macro arg_test3
do i =1,[#]
mes [[i]] | この [[i]] は、[%i]と書いても良い
enddo
return
|
実行結果
|
---|
PAW > exec arg_test3 aa 'bb' 0.1 5
aa
bb
0.1
5
|
SHIFT文を用いても、上記のような処理をすることができる。
ファイル名: arg_test3.1.kumac
|
---|
macro arg_test3.1
while [1] <> ' ' do
mes [1]
shift
endwhile
return
|
実行結果
|
---|
PAW > exec arg_test3.1 aa 'bb' 0.1 5
aa
bb
0.1
5
|
■ デフォルトの値を指定
マクロ呼び出し時に引数を指定しなかった場合の為に、変数にデフォルトの値を設定したいときは、macro文のマクロ名の後に変数名=デフォルト値とする。引数が設定されると、デフォルト値は上書きされる。
ファイル名: arg_test4.kumac
|
---|
macro arg_test3 aa=10 bb=test cc=0.1
mes [aa]
mes [bb]
mes [cc]
return
|
実行結果
|
---|
PAW > exec arg_test4
10
test
0.1
PAW > exec arg_test3 20 val 0.2
20
val
0.2
|
■ デフォルトの値を使ったり使わなかったりする
マクロのある変数には値を渡したいけれど、別の変数ではデフォルト値を使用したという場合は、マクロ呼び出し時に引数として ! を指定するか、引数として変数名と値のセットを指定する(変数名=値のように指定する)。
ファイル名: arg_test5.kumac
|
---|
macro arg_test3 aa=10 bb=test cc=0.1
mes [aa]
mes [bb]
mes [cc]
return
|
実行結果
|
---|
PAW > exec arg_test5 val ! 0.2
val
test
0.2
PAW > exec arg_test5 cc=0.2 aa=val
val
test
0.2
|
■ マクロに返し値を指定する
マクロに返し値を指定するには、retrun の後に値を指定する。返し値を参照するには、$EXEC('macro名')とする。$で始まる変数は特別な意味を持ち、これを使いこなすととても便利。Paw Reference Manualの/KUIP/FUNCTIONSの項目にいろいろ書いてある。
ファイル名: return_test.kumac
|
---|
macro return_test
mess aa
return bb
|
実行結果
|
---|
PAW > exec return_test | 普通に実行
aa
PAW > mess $exec('return_test') | マクロを実行後、返し値を表示
aa
bb
|
返し値は、マクロ内でも$exec('マクロ名')を用いて参照可能。
ファイル名: return_test2.kumac
|
---|
macro return_test2
mes $exec('mes_macro')
return
macro mes_macro
str = aa
return [str]
|
実行結果
|
---|
PAW > exec return_test2
aa
|
■ 関数もどき
$exec()は引数をとることもできる。すなわち、$exec('マクロ名 引数1 引数2')と引数を指定することもできる。これを用いて、マクロを関数のように扱うこともできる。
ファイル名: func_test.kumac
|
---|
macro func_test
sum = $exec('sum_func 3 2')
mes [sum]
return
macro sum_func
val = [1] + [2]
return [val]
|
実行結果
|
---|
PAW > exec func_test
5
|
マクロの途中で値を返したいときは、exitm 文を用いて値を返す。
ファイル名: func_test2.kumac
|
---|
macro func_test2
str = $exec('func 5')
mes [str]
return
macro func
if [1] = 5 then
str = five
exitm [str]
else
str = not_five
exitm [str]
endif
mess aa
return
|
実行結果
|
---|
PAW > exec func_test2
five
|
■ 変数を関数もどきの引数にする
変数を関数もどきの引数にするには、$exec()内にて変数を[]で参照すればよい。
ファイル名: func_test3.kumac
|
---|
macro func_test3 aa bb
sum = $exec('sum_func [aa] [bb]')
mes [sum]
return
macro sum_func
val = [1] + [2]
return [val]
|
実行結果
|
---|
PAW > exec func_test3 2 3
5
|
制御文
kumac内では、if文やdo文などの制御文が使える。文というよりコマンド?書式はFORTRANとほぼ同じ。
■ if文
条件分岐をするには、if文を用いる。書式は以下のとおり。
書式
|
---|
IF expression THEN
statements
ELSEIF expression THEN
statements
...
ELSEIF expression THEN
statements
ELSE
statements
ENDIF
|
例) 変数paraの値によって表示するメッセージを変更する。
para = 5
if ([para] = 0) then
mes 'aa'
elseif ([para] = 1) then
mes 'bb'
elseif ([para] = 2) then
mes 'cc'
else
mes 'dd'
endif
|
例) ELSEIFやELSEは書かなくても良い。
para = 5
if ([para] > 0) then
mes 'aa'
endif
|
■ case文
条件分岐には、case文もある。書式は以下のとおり。
書式
|
---|
CASE expression IN
(label) statement [statements]
...
(label) statement [statements]
ENDCASE
|
例) 変数paraの値によって表示するメッセージを変更する。
para = 1
case [para] in
(1) mess 'aa'
(2) mess 'bb'
(cc) mess 3
(*) mess 'other'
endcase
|
■ do文
繰り返し処理を行うにはdo文を用いる。
書式
|
---|
DO loop = start_expr, finish_expr [,step_expr]
statements
ENDDO
|
例) 1から10の値を表示する。
do i = 1,10
mes [i]
enddo
|
例) 1から9まで2おきに表示する。
do i = 1,10,2
mes [i]
enddo
|
■ for文
異なる値それぞれに対して、同じ処理をするにはfor文を用いる。
書式
|
---|
FOR name IN expr_1 [ expr_2 ... expr_n ]
statements
ENDFOR
|
例) 文字列を順に表示する。
for str in 'aa' 'bb' 'cc'
mes [str]
endfor
|
■ while文
繰り返し処理はwhile文を用いてもよい。do文でも同じことができる。
書式
|
---|
WHILE expression DO
statements
ENDWHILE
|
例) iが10よりも小さい間、iを1ずつ増やす。
i = 0
while ([i] < 10) do
mes [i]
i = [i] + 1
endwhile
|
■ repeat文
繰り返しの処理には、repeat文を用いてもよい。
書式
|
---|
REPEAT
statements
UNTIL expression
|
■ breakl文
ループを途中で抜けるには、breakl文を用いる。多重のループもlevelを指定することで一気に抜ける。levelを省略すれば、一重のループを抜ける。
例) do文を途中で抜ける。
do i = 1,10
mes [i]
if ([i] > 5) then
breakl
endif
enddo
mes 'aa'
|
例) 二重のdo文を抜ける。
do i = 1,10
do j =1,10
mes [i] [j]
if ([i] > 5 .and. [j] > 5) then
breakl 2 | breakl level で、level重のループを抜ける。
endif
enddo
enddo
mes 'aa'
|
■ nextl文
ループの途中でストップし、次のループに進むには、nextl文を用いる。levelを指定すれば、どのループの始まりに戻るかを決められる。
■ goto文
処理を飛ばしたり、ループを途中で抜けるには、goto文を用いる。
例) 条件を満たしたら、処理を飛ばす。
i = 1
if ([i] = 1) then
goto label_10
endif
mes 'aa' | この文は実行されない。
label_10:
mes 'b'
|
上記は以下のように短縮することもできる。
i = 1
if ([i] = 1) GOTO 10
mes 'aa' | この文は実行されない。
10: mes 'b'
|
例) do文を途中で抜ける。
do i = 1,10
mes [i]
if ([i] > 5) then
goto 10
endif
enddo
10:
mes 'aa'
|
■ exitm文
return 文の前にマクロを終了するには、 exitm 文を用いる。
ファイル名: exitm_test.kumac
|
---|
macro exitm_test
do i = 1,10
if [i] = 5 then
exitm
endif
mess [i]
enddo
return
|
実行結果
|
---|
PAW > exec exitm_test
1
2
3
4
|
演算子
■ 算術演算子
変数を計算するときなどに用いる算術演算子は以下のとおり。四則演算しかできず、%や**は使えないかも?複雑な演算をしたいなら、$sigmaを用いる。
算術演算子 |
演算子 | 意味 |
+ | 足す |
- | 引く |
* | 掛ける |
/ | 割る |
例) 変数を足したり引いたり掛けたり割ったりする。
a = 1
b = 2
c = 3
d = 4
e = ([a] + [b]) * [c] / [d]
mes [e] | 2.25と表示される。
|
■ 関係演算子(比較演算子)
if文などで条件を指定するときに用いる関係演算子は以下のとおり。
関係演算子 |
演算子 | 別記 | 意味 |
.gt. | > | greater than |
.ge. | >= | greater than / equal |
.lt. | < | less than |
.le. | <= | less than / equal |
.eq. | = | equal |
.ne. | <> | not equal |
■ 論理演算子
if文などで複数の条件を指定するときに用いる論理演算子は以下のとおり。
論理演算子 |
演算子 | 意味 |
.and. | かつ |
.or. | または |
.not. | 否定 |
使用法は以下の様。
i = 10
j= 11
if ((i = 10) .and. (j <> 10)) then | i が10でjが10以外ならmes 'aa'を実行
mes 'aa'
endif
|
参考文献・webページ
ページ制作履歴
2008/06/15 制作開始
2008/06/15 webにアップ
2008/06/24 変数あたり追加
2010/03/14 マクロの呼び出し、引数、返し値、特殊変数、文字列の結合を追加
2010/05/29 シングルクオート追加