[トップ][編集][ノート][編集履歴][一覧][最近の更新][->English]

HSP2.6:HSPPROG:スクリプト記述の基本


命令の書き方

スクリプトはどのような順番で、どのような処理をするかをまとめたテキスト ファイルです。その中の、どのような処理をするかを指示するものを命令(ステ ートメント)と呼びます。

BASICやCと同じように、命令はファイルの先頭行から下に向かって順に実行さ れていきます。

命令(ステートメント)は、プログラムの流れを制御したり、画面やファイル などの入出力を行ないます。大きくわけて、プログラム制御命令と、入出力制 御命令の2つからなる多くの命令が存在します。スクリプトはアルファベット の大文字・小文字を区別しません。どちらで記述してもかまいません。

パラメータ

HSPでは、命令の後にパラメータを付加する書式が基本になっています。命令に 付加するパラメータと、命令の間はスペースで空けておく必要があります。ま たパラメータが複数ある場合は、「,(カンマ)」で区切ります。たとえば、

width 640,480

というスクリプトは、「width」が命令(ステートメント)にあたり、 640と480 という数値がパラメータになります。この組み合わせで、「ウインドゥサイズ を640x480にする」という意味になります。

例 : ドキュメントファイルの「命令のリファレンス」の説明で、

statement p1,p2

p1=0〜3(1)
p2=0〜65535(0)

とあった場合は、この命令にはp1,p2の2つのパラメータが指定でき、 p1のとれ る値が0〜3まで、省略した場合の値が1。p2のとれる値が、0〜 65535まで、省 略した場合の値が0であることを示しています。パラメータの省略をすることも できます。上の例では、p2の値を省略して

statement 3

と書くこともできます。その場合は、省略した時の値が自動的に設定されて、

statement 3,0

と書いたのと同じことになります。パラメータの途中だけを省略する場合は、

statement ,100

のように省略したパラメータを飛び越えて別のパラメータを指定することがで きます。この場合は、

statement 1,100

と書いたのと同じことになります。

statement

とだけ書いてパラメータを指定しなかった場合でも、自動的に「1,0」という値 が設定されます。基本的にパラメーターは重要な順番に並んでいるので、すべ てを省略することはあまりありません。また、文字列を指定するパラメータや 、変数名でなければならないパラメータなどは省略ができないことがあります 。

マルチステートメント

命令と命令の間を:(コロン)で区切って1行に複数の命令を記述することも可能で す。これをマルチステートメントと呼びます。たとえば、

例:

mes "こんにちは" : mes "さようなら"

は、

mes "こんにちは"
mes "さようなら"

のように書くのと同じことです。このように複数の命令を1行にまとめて書く ことができます。 1行は最大1024文字まで認識されますが、テキストエディタ で見やすい程度に納めるようにした方がいいでしょう。

コメント

1行の中で;(セミコロン)以降はコメント(注釈)とみなし無視されます。

例:

pos 320,100 : print "(^_^)" ; 顔マーク表示

CやJavaと同様のコメント記述が可能です。 1行の中で//(ダブルスラッシュ) 以降はコメントとみなし無視されます。「/*」から「*/」までの間は、コメン トとみなし無視されます。

例:

pos 320,100 : print "(^_^;)"// 顔マーク表示
/* ここはコメントです */ goto *start

スペース、タブは見やすくするために自由に入れられます。

数式

命令のパラメータに数値を指定する場所では、以下のような演算子を使った式 を書くことができます。

-2147483647〜2147483647 10進整数
$0〜$FFFFFFFF 16進整数(0xでも可)
%0〜%111111... 2進整数(0bでも可)
'A' 文字コード(1バイト)
+,-,*,/ 加算,減算,乗算,除算
&,|,^ 論理演算(and,or,xor)
\ 割り算の余り
=,<,>,! 条件式(同じ,小さい,大きい,同じでない)
==,<=,>=,!= 条件式2(同じ,以下,以上,同じでない)
<<,>> 左、右方向にビットシフト

たとえば、

statement 1+2+3+4

は、

statement 10

と書いたのと同じになります。これを数式といいます。数式の評価は常に左か ら順に行なわれます。乗除算の優先はありません。たとえば、

2+7*2

は、18になります。計算の順番を変更したい場合はカッコを使って、

2+(7*2)

のように書けば、カッコ内の7*2が先に計算されて結果は16になります。条件式 や論理演算は、後に説明する条件判断の際に使われます。カッコは、8重まで ネスティングすることが可能です。もし、カッコの使い方が間違っている場合 は、「priority error」というエラーが表示されます。

HSPの標準機能では実数をサポートしていませんが、拡張プラグインに実数(小 数)を渡すための仕組みが用意されています。詳しくは、「小数値の記述につい て」を参照してください。

文字列

命令のパラメータに文字列を指定する場所では、文字列を"(ダブルクォーテーション) で 囲んでください。

例:

mes "This is test message..."

「+」を使って文字列同士、または変数との結合をすることができます。たとえ ば、

"ABCD"+"EFGH" は、 "ABCDEFGH" と同じになります。 "VALUE="+valは、 "VALUE=5"(変数valが5の場合)になります。

ただし、「\」は特殊な意味を持つキャラクタとして解釈されます。

  • 「\n」 は、改行して次の行にするという意味になります。
  • 「\t」 は、TABコードを表わします。
  • 「\r」 は、リターンコード(0x0d)を表わします。
  • 「\"」 は、ダブルクォート(")を表わします。
  • 「\\」 は、ただの「\」になります。

ですから、ディレクトリを示すための文字列、たとえば、

"C:\WINDOWS\SYSTEM" などの文字列は、 "C:\\WINDOWS\\SYSTEM" と記述しないと認識されません。

また、1行に収まりきらない長い文字列をまとめて記述することも可能です。

mes {"
ここには、1行まるまる直接メッセージを
書いてもいいです。
"}

このように、「{"」から「"}」までの間はすべて文字列として解釈されます。 複数行に渡っている時は、1行の最後に改行コードが挿入されます。文字列の 結合や複数行での文字列を指定する場合には、最大32768文字までが有効となり ます。 ver2.3c以降では、半角カナも使用可能です。

変数

名前をつけた変数を扱うことができます。変数とは、代入により内容を変化さ せることのできる容れ物のようなものです。 変数は、アルファベットまたは日本語で始まる59文字(半角)以下の文字列で識 別されます。変数は代入により数値か文字列、または数値の配列を記憶させる ことができます。 数値として記憶できる範囲は、数式で指定できる値と同じ-2147483647 から 2147483647までの32ビット整数値です。 変数にラベルと同じ名前や、命令と同じ名前は使用できません。変数は、代入 命令や、数式の中で使うことができます。 代入命令は次のようなものです。

例:

x=100; 変数xに100という数値を代入
y=200; 変数yに200という数値を代入

命令の数値指定として使うと、

例:

x=100:y=200:pos x,y ; (100,200)に移動

のようになります。 変数に値を代入すると、以前まで記憶されていたものは消され、新しい値が保 持されることになります。 変数に文字列を代入する場合にも同じように、

例:

x="strings" ; 変数xに「strings」という文字列を代入
print x ; 変数xの内容を画面に表示

代入は"="の先にあるものが数値ならば数値を、文字列ならば文字列として記憶 します。このことから変数には、記憶しているものが文字列だった場合の文字 列型と、数値だった場合の数値型の2つの状態があります。 パラメーターが数値を必要としている命令に文字列型の変数を指定しても、ま たパラメーターが文字列を必要としている命令に数値型の変数を指定しても、 「Type mismatch」エラーが出てしまうので注意してください。

変数に文字列を代入する場合には、通常63文字までとなります。もし、それ以 上の文字数を取り扱いたい場合はdim命令によりサイズを指定する必要がありま す。詳しくは「配列変数」の項目で解説されています。

また、いくつかの特殊な代入命令があります。

例:

a=10; 変数aに10を代入
a+=1; 変数aに1を加算(a=a+1と同じ)

上の例では、変数aは11という値になります。このように、「+=」を使用する と"="以降が変数a自身に対して加算されます。 同じように「-=」も使用することができます。さらに、

例:

a+  ; 変数aに1を加算
a-  ; 変数aから1を減算

のような表現で変数に+1と−1をすることができます。 (C言語やJavaと互換 のある書式、a++やa--でも同じ結果になります)

変数の型を特定するために、変数の型を強制的に変更することができます。そ のための命令がintとstrです。

例:

int a; 変数aを数値型にする
str b; 変数bを文字列型にする

変数の型を変更しても、できる限りその内容を保持しようとします。 "123"という文字列を含んだ変数を数値型に変更すると、123という数値になり ますし、逆に123という数値型の変数を文字列型に変更すると"123"という文字 列に変換されます。 また、str命令で数値型変数を文字列に変換する際には、通常の10進数文字列の 他にも 16進数、0を省略しないで指定した桁数の文字列に変換することができ ます。

配列変数

配列変数を使うと、変数に記憶させるものに対して番号をつけて大量に管理す ることができるようになります。通常は、変数aには1つの数値、または文字列 しか記憶させることができません。しかし配列変数を使えば、これに複数の数 値、または文字列を記憶させることができます。配列変数は次のようにして使 われます。

例:

a.0=10  ; 変数aの要素0に10を代入
a.1=20  ; 変数aの要素1に20を代入
a.2=30  ; 変数aの要素2に30を代入

変数の後に"."(ピリオド)をつけ、その後に数値による番号を指定します。この 番号を「配列の要素」といい変数の中のどこに記憶されているかを特定します 。要素は0から始まって、通常は15まで指定できます。要素が変わっても同 じ変数なので、要素ごとに数値型、文字列型をまぜることはできません。変数a が文字列型ならば、すべての要素も文字列型となります。数値型も同様です。 要素に変数を使用することもできます。

例:

i=0
a.i=123 ; 変数aの要素0に123を代入

ただし、要素に数式を使うことはできません。要素として判断されるのは "." (ピリオド)の後に続く1項目だけです。ですから、

例:

a.1=5
a.2=10
print a.1+1

は、変数aの要素2ではなく、変数aの要素1に1を加算したもの、つまり6にな るので注意してください。

配列変数の要素がもっとたくさん欲しい場合にはdim命令で拡張することができ ます。

例:

dim a,20; 変数aの要素は0〜19まで使えるようになります

また、dim命令を使って多次元配列を作成することも可能です。

例:

dim a,10,5  ; 変数aは2次元配列が使用できます
a.0.0=1 ; 要素(0,0)に1を代入
a.1.0=2 ; 要素(1,0)に2を代入
a.0.1=3 ; 要素(0,1)に3を代入

この場合は、「変数名.1つめの要素.2つめの要素」のように"."(ピリオド) を2つ使って要素を指定しなければなりません。同じようにdim命令を使って4 次元までの配列を作成することができます。

文字列型の変数に配列を使う場合にはsdim命令を使います。 sdim命令では、ま ず扱う文字列の最大文字数を指定してから、要素の数を指定します。たとえば 、

例:

sdim a,32,5  ; 変数aは32文字までの文字列を5つの要素で扱えます
a.0="test"
a.1="message"

のように変数名の次に2つのパラメータを指定します。また、sdim命令は通常 使う文字列の最大文字数を拡張することもできます。

例:

sdim a,200  ; 変数aは200文字までの文字列を扱えます

これは配列変数ではなく、通常の変数になります。通常の変数は64文字までし か文字列を扱うことができませんが、sdim命令を使用することで、最大文字数 を増やすことができます。

代入するパラメータに「,」をつけることで、配列変数への代入を連続して行な うこともできます。

例:

tmp=1,5,10  ; 配列に連続して代入をする

上の例では、「tmp.0=1:tmp.1=5:tmp.2=10」と同じことになります。配列の途 中から代入を開始するには、

例:

tmp.2=10,20,50  ; 要素2から連続して代入をする

この例では、「tmp.2=10:tmp.3=20:tmp.4=50」と同じことになります。「tmp= "ABC","DEF","GHI"」のように文字列を連続して代入することもできます。この 場合は、あらかじめsdim命令などで文字列型の配列を用意しなければなりませ ん。

ラベル

プログラム上の位置を示すためにラベルとして名前をつけることができます。 ラベルは*(アスタリスク)の後に続く59文字(半角)以下の文字列で示します。

例:

*label
mes "Wait.":wait 100
goto *label ; 無限ループを生成

ラベルは主に、goto命令、gosub命令またはbutton命令の飛び先を指定するのに 使用されます。

ローカルラベルについて

HSPではローカルラベル機能をサポートしています。これは、特殊な名前のラベ ルを何度でも使うことのできる機能で、何でもない部分や、名前をつけるのが 面倒な時などに便利です。

例:

mes "GO!"
*@
mes "A="+a
a+
if a<5 : goto *@back; 前のローカルラベルに戻る
stop

ローカルラベルは、「*@」という名前で定義します。これは、他のラベルと違 い1つのソーススクリプト内で何度でも置くことができます。 このローカルラベルを、goto命令などで参照する時には、「*@back」と「 *@forward」を使います。「*@back」は、その場所より上にあり一番近いローカ ルラベルを指します。「*@forward」は、その場所より下にあり一番近いローカ ルラベルを指すものになります。 「*back」は、「*b」と省略することが可能です。 「*forward」は、「*f」と省略することが可能です。

ローカルラベルは、多用するとかえって見にくいスクリプトになってしまう可 能性もあるので、後の見やすさを考えてから使ってみてください。

条件判断

条件判断を行う場合には、if命令を使用します。if命令は、パラメータで示さ れた条件が満たされた場合は、それ以降の命令を実行し、そうでなければ次の 行から実行を続けます。

例:

a=10
if a=10 : mes "aは10です。"

上の例では、「a=10」の部分が条件式になります。条件式には主に、

a=b aとbは等しい
a!b aとbは等しくない
a<b aはbよりも小さい
a>b aはbよりも大きい
a<=b aはbよりも小さいか等しい
a>=b aはbよりも大きいか等しい

の4つを使います。if+条件式の後は:(コロン)で区切り、それに続いて条件 が満たされた場合に実行される部分を書きます。 (C言語やJavaと同じように「=」「!」を「==」「!=」のように記述することも 可能です) もし、条件によってプログラムの流れを変えたい場合には、

例:

a=10
if a>10 : goto *over10
mes "aは10以下です。"
stop
*over10
mes "aは10より大きいです。"
stop

上のように、goto命令で別なラベルに飛ばすことも可能です。また、else命令 を使って条件が満たされなかった場合の処理を同じ行に書くことも可能です。

例:

a=10
mes "aは、"
if a=10 : mes "10です。" : else : mes "10ではありません。"
stop

この場合は、else命令のある部分までは、条件を満たした場合に実行され、 else命令以降は、条件を満たされなかった場合に実行されます。次の行以降は 、条件に関わらず通常通りに実行されます。

より複雑な条件判断をするために、論理演算式を使うこともできます。

a&b aとbがともに正しい (and)
a|b aとbのどちらかが正しい (or)

これによって複数の条件を一度に記述することができます。

例:

a=10:b=20
if (a=10)|(b=10) : mes "aかbのどちらかが10です。"

上の例では、「a=10」と「b=10」という条件式を|(or)でつないで、どちらかが 正しい場合には、正しいという結果が出るようにしています。論理演算は、「| 」「&」といった記号の他に「or」「and」という文字列でも記述することがで きます。

例:

if (a=10)or(b=10) : mes "aかbのどちらかが10です。"

上のように書いても、結果は同じになります。 HSPでは、論理演算はビットごとの演算として扱われているため、 C言語やJava などで用いられる「&&」「||」などの論理演算子とは等価ではありませんので ご注意下さい。

より複雑な条件判断

ver2.5では、いままで1行しか記述できなかった条件判断の実行を、複数行で行 なうことができるようになっています。 if命令の条件が正しい時に実行される スクリプトを複数行に渡って記述する場合は、

例:

a=10
if a>5 {
mes "TRUE"
mes "(MULTILINE IF)"
}

のように「{」で始めて「}」で終わる部分までを指定します。 (上の例では、 見やすくするためにC言語風に行の最初にTABを入れてありますが、特に必要な ものではありません。ユーザーの見やすいように記述してください)

例:

a=10
if a>5 : mes "TRUE"

「{」を使わなかった場合には、if命令以降の1行のみが実行されます。また、 else命令は、条件が正しくない時に実行されるスクリプトを指定します。

例:

a=10
if a>5 : mes "TRUE" : else : mes "FALSE"

上の例では、aが5より大きい場合は、「mes "TRUE"」が、そうでない場合は、 「mes "FALSE"」が実行されます。 else命令でも複数行の指定ができます。

例:

a=10
if a>5 {
mes "TRUE"
mes "(MULTILINE IF)"
}
else {
mes "  FALSE"
mes "  (MULTILINE IF)"
}
return

ただし、elseの後に「{」を記述しなければ複数行にはならないので注意してく ださい。

例:

if a>5 {
mes "TRUE"
}
else; <- 間違い
{
mes "FALSE"
}

上の例は間違いです。エラーになります。 else命令もまたif命令と同じように 、「{」がない限りは、その1行のみが有効範囲になります。 また、if命令を多重に実行させることも可能です。

例:

a=10
b=10
c=10
if a>5 {
if b>5 {
if c>5 { mes "--3" } else { mes "--2" }
}
else {
mes "--1"
}
}

上の例では、変数aが10より大きい場合は「--1」を、変数a,bが10より大きい場 合は「--2」を、変数a,b,cが10より大きい場合は「--3」を表示します。 if命 令の多重化は、スクリプトがだんだんと複雑になっていくので、注意して使っ てください。HSPでは、8重までの多重化が可能です。

*現在のHSPでは、if命令で「{」「}」を使った複数行記述と、通常の1行のみの 分岐を混在した場合の動作は保証されません。「{」「}」内でさらに条件分岐を 行なう場合には、「{」「}」を使用するようにしてください。 この問題は、今後のバージョンアップで解消していく予定です。

繰り返し命令

repeat〜loop命令は、HSPで繰り返しの動作をさせる場合に欠かすことのできな い重要な命令です。

repeat 5
mes "繰り返し["+cnt+"]"
loop

のように、repeat命令の後に回数を指定すると、loop命令までを指定回数だけ 繰り返します。繰り返し中は、システム変数cntが0、1、2、3…と自動的にカウ ントアップされていきます。

繰り返し回数に0が指定された場合には、repeat〜loopの範囲は実行されずに通 過します。また、繰り返し回数指定を省略するかまたはマイナス値を指定する と無限ループになります。

repeat〜loop命令と、break、continue命令を組み合わせることにより、さらに 高度な処理が可能になります。 repeat〜loop命令の繰り返しを、途中で強制的 に脱出させるのがbreak命令です。

repeat 5
if cnt=2 : break
mes "繰り返し["+cnt+"]"
loop

上の例では、システム変数が2になった時点、つまり3回目のループになると、 if命令の判断によって、break命令が実行されるしくみになっています。 break 命令が実行されると、繰り返しの回数がまだ残っていても、強制的に繰り返し から抜け出し、loop命令の次にある命令から実行を続けます。 break命令以降 (上の例では、mes命令)は実行されません。この命令を使うと、たとえば次のよ うなスクリプトが作成可能です。

repeat
getkey a,1
if a>0 : break
await 10
loop

上のスクリプトでは、マウスの左ボタンを押すまで待つループになります。 repeat命令の回数指定を省略するかまたはマイナス値を指定すると無限ループ になります。それを利用してボタンの状態が1になるまでは、ずっと同じところ を繰り返すようになっています。ボタンが押されると、break命令が実行され繰 り返しから抜け出します。いままでは、このようなスクリプトはgoto命令を使 って繰り返しの構造を記述する必要がありましたが、repeat〜loopとbreak命令 を使うことにより、ラベルを用意することなく手軽に条件付きの無限ループが 実現できます。

continue命令は、逆に繰り返しをやり直すための命令です。

repeat 5
if cnt=2 : continue
mes "cnt="+cnt
loop

上の例では、システム変数cntが2になった時点で、continue命令が実行される しくみになっています。 continue命令が実行されると、repeat命令まで戻り次 の繰り返しを実行します。上のスクリプトが実行されると、

cnt=0
cnt=1
cnt=3
cnt=4

のような表示になり、システム変数cntが2の時だけmes命令が実行されないの がわかります。最初はわかりにくいかもしれませんが、continue命令は、loop 命令の場所ではないが、 loop命令と同じ働きをするとも言えます。繰り返しの カウンタは、continue命令が実行された場合でも、loop命令と同様1つ増加し ます。もし、最後の繰り返しでcontinue命令が実行されると、repeat〜loopが 終わった状態、つまりloop命令の次の命令から実行を続けます。

さらにもう1つ、continue命令にはパラメータを指定する使い方が存在します 。 continueの後に、数値または数値型変数を指定することにより、繰り返しの カウンタを示すシステム変数cntの内容を変更することができます。たとえば、 「continue 1」と指定した場合は、システム変数cntの内容は1になり、その値 のままrepeat命令の次から繰り返しを続けます。パラメータを省略して、ただ の「continue」だけの場合はloop命令と同様の処理、数値を指定すると、カウ ンタの値を変更して繰り返しをやり直すことになります。ですから、

repeat 1
await 10
getkey a,1
if a=0 : continue 0
loop

このようなスクリプトでは、通常1回だけしか実行されないはずの、repeat〜 loopの繰り返しですが、マウスの左ボタンが押されていない場合は、カウンタ が0に戻され無限ループの状態になります。これで、ボタンを押すまで待つとい う動作になります。

このbreak命令と、continue命令は、ともにrepeat〜loop命令の中で使用しなけ ればなりません。また、repeat〜loop命令の中であれば、いくつでも使用でき ます。

注意しなければならないのは、プログラムの流れとしてrepeat〜loop命令は、 順番につながっていなければなりません。repeat命令があったら、そこから下 の行に必ず loop命令がなければいけないということです。 repeat命令だけを 、gosubでジャンプしたサブルーチンの中で実行したり、 goto命令でスクリプ ト上の別な場所にジャンプしてloop命令を実行させたりして、 repeat〜loop命 令の順番が狂ってしまうとコンパイラはエラーを出してしまいます。

repeat〜loop命令は、多重に使うことができます。

repeat 5
if cnt=2 : continue
repeat 2
mes "中のループcnt="+cnt
loop
mes "外のループcnt="+cnt
loop

上の例では、わかりやすいようにTABを入れて記述していますが、5回繰り返す 構造の中に、さらに2回繰り返すrepeat〜loop命令があります。繰り返しが多 重になった場合でも、break、continue命令は対応するループに対して機能しま す。これは、システム変数cntが、やはり対応したループに対しての値を示すの と同様です。

repeat〜loop命令は、多様な使い方のできる構文です。C言語や、Javaにおける 、 while文や、do〜until文などに近い記述もできますし、もちろんfor文のよ うな繰り返しの記述にも使えます。

プリプロセッサ命令

プリプロセッサ命令は、プログラム実行時ではなく、コンパイル時に解釈し実 行される命令のことです。プリプロセッサ命令は、他の命令と区別がつくよう に、行の最初に「#」に続けて記述しなければなりません。 プリプロセッサ命令により、スクリプトの記述そのものをカスタマイズするこ とも可能になります。ただし、使いすぎるとプログラムそのものがわかりにく くなったりするので、HSPを一通り使った上級者の方に使用をおすすめします。

#include "filename" [別ファイルを結合]

"filename"で指定されたファイルも同時にコンパイルされます。 スクリプトエディタで入りきらないスクリプトも、includeで別ファイルに分割 すればコンパイルすることができるようになります。

#define 新規名称  元名称[新規名称を登録する]

HSPに新しい命令の名前を追加するためのものです。 HSPの従来ある命令の名前を、別な名前でも使用できるようになります。新規名 称は、予約されている命令語や変数名と重ならない20文字以内の、スペースを 含まない英文字列でなければなりません。

例:

#define pr print
pr "message..."
stop

上のように#defineの後に、新規名称と元の名称をスペースで区切り記述します 。すると、「pr」という命令が新しく登録され、「print」命令とまったく同様 に使うことができるようになります。 元の名称は、命令の名前である必要はありません。数値や、記号なども新規の 名称として登録することが可能です。

例:

#define is =
#define plus +
a is 5 plus 10
print "A="+a
stop

上の例では、「=」という記号を「is」という言葉に、「+」という記号を「 plus」という言葉にそれぞれ置き換えるように定義しています。 すると、「a is 5 plus 10」という行は、「a=5+10」と同じことになります。 パラメーターを使用して展開することも可能です。

例:

#define reset(%1) %1=10
reset a
mes "A="+a
stop

上の例では、「reset a」を「a=10」というスクリプトに変換します。 このほか、特殊展開パラメーターなど多くのオプションが用意されています。 詳しくは、「#defineマクロについて」の項を参照してください。

#const マクロ名 数値式  [マクロ名の定数定義]

指定されたマクロ名に置換え文字列を設定します。 #defineと同様ですが、# constは定数(数値)の置き換えを行なう場合にあらかじめ計算を行なった結果を 置き換えます。

例:

#const KAZU 100+50
a=KAZU
↓(展開後)
a=150

あらかじめソース内で使用する値が確定している場合、ソースの高速化に有効 です。すでに定義されているマクロを含めることも可能なので、

例:

#const ALL 50
#const KAZU 100*ALL
a=KAZU
↓(展開後)
a=5000

のように使用することができます。計算式は、整数のみで演算子および数値の 記述スタイルは、HSPと同様のものが使えます。ただし、ver2.xのHSPと は異なり、演算子の優先順位を考慮しますので注意してください。

例:

#const KAZU $5+3*10
a=KAZU
↓(展開後)
a=35

演算子の優先順位は、

  • [*,/]>[+,-]>[比較演算子,<<,>>]>[!]>[&,|,^]

となっています。カッコによる順位の指定も可能です。

#undef マクロ名 [マクロ名の取り消し]

すでに登録されているマクロ名を取り消します。登録されていないマクロ名に 対して指定してもエラーにはならず無視されます。

#if 数値式  [数値からコンパイル制御]
#ifdef マクロ名 [マクロ定義からコンパイル制御]
#ifndef マクロ名[マクロ定義からコンパイル制御]
#else[コンパイル制御を反転]]
#endif  [コンパイル制御ブロック終了]

コンパイルのON/OFFを指定します。 #ifは指定した数値が0ならば以降のコンパ イル出力をOFFにしてコンパイル結果を無視します。数値が0以外の場合は、出 力がONとなります。このコンパイル制御は、#endifが出るまでの区間を対象に します。 #if、#ifdef、#ifndefのいずれかには、#endifがペアで存在している 必要があります。

例:

#if 0
mes "ABC"; この部分は無視されます
a=111; この部分は無視されます
mes "DEF"; この部分は無視されます
#endif

#ifの指定には式を使うことも可能なので、

例:

#define VER 5
#if VER<3
mes "ABC"; この部分は無視されます
a=111; この部分は無視されます
mes "DEF"; この部分は無視されます
#endif

のような使い方もできます。計算式の記述および演算子の注意点などは、 # const命令と同様です。 #ifdefは、指定したマクロ名が定義されていれば出力 をONに、そうでない場合は、出力をOFFにします。マクロ名は、#defineや# constによって定義されたものになります。

例:

#define SW
#ifdef SW
mes "ABC"; この部分はコンパイルされます
a=111; この部分はコンパイルされます
mes "DEF"; この部分はコンパイルされます
#endif

#ifndefは、#ifdefとは逆に指定したマクロ名が定義されていれば出力をOFFに 、そうでない場合は、出力をONにします。また、ブロック内に#elseを入れるこ とで条件が逆の場合の動作を記述することができます。

例:

#ifdef SW
mes "AAA"; SWが定義されている場合
#else
mes "BBB"; SWが定義されていない場合
#endif

また、#if、#ifdef、#ifndef〜#endifのプロックを入れ子にすることも可能で す。

例:

#ifdef SW
#ifdef SW2
mes "AAA"; SWとSW2が定義されている場合
#else
mes "BBB"; SWが定義されている場合
#endif
#endif
#uselib "filename"  外部DLLの指定
#func 新規名称  関数名  タイプ  外部DLL呼び出し命令登録

外部DLL内のプログラムを呼び出すための命令を増やすことができます。これに より、HSP本体のプログラムから、C言語やDelphiなどで作成した DLL内の関数 を呼び出すことが可能になります。 func命令により、外部の関数もHSPの命令として定義できるので、 HSPを自由に 機能拡張することが可能です。外部DLL作成の方法や、 HSPとのパラメータ受け 渡しの詳細は、インターネット上のONION software ホームページにて別途ファ イルをダウンロードすることができるようになっていますので、そちらの付属 サンプルプログラムソースなどを参照してください。 普通に使う場合には、まったく必要のない命令ですので、特に覚えておかなく ても問題ありません。

標準マクロ定義ファイル

プリプロセッサでは、commonディレクトリにある「hspdef.as」を標準のマクロ 定義として必ず最初に読み込みます。「hspdef.as」には、システムで定義する シンボル名やマクロ、基本的なモジュールなどが追加されていく予定です。ユ ーザーが「hspdef.as」をカスタマイズして、HSPをより使いやすく改造する こともできます。が、その場合ソースを他の環境でコンパイルできなくなるの で注意して下さい。標準マクロ定義ファイルは、以下の順に検索されます。

  1. ソースファイルのあるディレクトリにある「hspdef.as」
  2. commonディレクトリにある「hspdef.as」

ファイルが見つからない場合は無視されます。また、プリプロセッサが自動的 に追加するマクロがあります。

命令 内容
_debug デバッグモード時
__hsp26__ ver2.6拡張マクロ使用時

#ifdef、#ifndef命令などでこれらのマクロを判別して分岐させることが可能で す。

複数行をプリプロセッサに渡す

最後が「\」で終わるプリプロセッサ行は次行に継続されます。1行に収まらな い定義を行なう場合に、利用することができます。

例:

#define aaa mes "AAA"\
mes "BBB"\
mes "CCC"

これは、この3行すべてが#defineプリプロセッサ命令として解釈されます。

標準マクロについて

標準マクロは、より個人が書きやすい記述を実現するために用意されたもので す。 C言語など、すでに慣れた形式でスクリプトを記述したい場合にお使いく ださい。初心者の方には、標準マクロのご使用はお奨め致しません。また、標 準のサンプル類も基本的には標準マクロを使用しないものを提供していきます 。

ver2.6から、プログラム制御のための新しいマクロ定義が追加されました。見 かけ上、命令と同様に動作するほか、同様のマクロを新しく定義することも可 能です。詳しくは、別項「#defineマクロについて」を参照してください。以前 のスクリプトを動かす際に、新しく追加されたマクロ名がすでに変数名やラベ ル名として使われているとエラーになります。doやfor、nextなど短い単語は衝 突する可能性が高いので、注意してください。もし、衝突してしまっている場 合は、変数名・ラベル名を別なものに置き換えれば動作させることができます 。以前の名前を変更したくない場合は、スクリプトエディタの「HSPメニュー」 から、「HSP拡張マクロを使用する」のチェックを外すことで、標準マクロを使 用せずに以前(ver2.55)と同様の予約キーワードだけが定義されます。

do〜untilマクロ

untilに続く条件が満たされるまで、doからuntilまでの部分を繰り返します。 条件が満たされている場合でも、最低一回はdo〜until内を実行します。 until に続く条件を省略した場合は、繰り返しを行ないません。また、_continueによ り繰り返しの先頭から再開、_breakにより繰り返しを脱出することができます 。

例:

a=0
do
a=a+1:mes "A="+a
until a>5; aが5以上になるまでdo以下を繰り返す

while〜wendマクロ

whileに続く条件が満たされている間だけ、whileからwendまでを繰り返します 。条件が満たされていない場合はねwhileからwendまでを実行しません。 while に続く条件を省略した場合は、無限に繰り返しを行ないます。 _continueによ り繰り返しの先頭から再開、_breakにより繰り返しを脱出することができます 。

例:

a=0
while a<5
a=a+1:mes "A="+a
wend; aが5以下の間だけwhile以下を繰り返す

for〜nextマクロ

for 変数名,初期値(0),終値(0),増分(1)

をパラメーターとして指定すると、for〜nextの間を指定回数繰り返します。カ ッコ内は省略した場合の値です。変数名は省略できません。指定された変数を カウンターとして使用し、初期値から始まって、1回繰り返すごとに増分を足 していきます。終値に達した時点で、繰り返しから抜けます(終値はループに含 みません)。最初から終値の条件が満たされている場合は、繰り返しを実行しま せん。また、_continueにより繰り返しの先頭から再開、_breakにより繰り返し を脱出することができます。

例:

for a,0,5,1
mes "A="+a
next; aが0から4の間(5回)繰り返す

この例では、変数aは0,1,2,3,4と5回繰り返してループを終わります。増分に マイナス値を指定することも可能です。

例:

for a,5,0,-1
mes "A="+a
next; aが5から1の間(5回)繰り返す

この場合、変数aは5,4,3,2,1と5回繰り返してループを終わります。 forマク ロは、内部でマクロ展開後に特殊な新規命令exgotoを生成します。 exgoto命令 はforマクロのための補助命令で単体で使用することは推奨していません。

switch〜case〜swendマクロ

switch〜case〜swendは、ブロック内に複数の条件判断と処理をまとめて書くこ とができる構文です。

switch 比較元

でswitchブロックを開始します。比較元のパラメーターは、変数または式を指 定することができます。 switch以降は、

case 比較値

を置くことで、これ以降に「比較元」が「比較値」と同じだった場合に処理す る内容を記述することができます。 caseは、ブロック内に複数記述することが でき、それぞれの比較値ごとの処理を指定できます。 caseの比較が正しい場合 は、swbreakが存在するまで以降の命令を実行します。また、caseの替わりに

default

を置くと、caseで指定したどの比較値にもあてはまらない条件の場合に以降が 実行されます。 switchブロックが終了した場合は、

swend

を必ず最後に書いておく必要があります。以下は、switchマクロを使用したス クリプトの例です。

例:

a=0
switch a; aを比較対象とする
case 0  ; aが0だった場合
mes "A=0"
swbreak ; case0の条件実行終了
case 1  ; aが1だった場合
mes "A=1"
default ; aが0以外だった場合
mes "A!=0"
swbreak
swend

この例では、変数aの内容が0か1かそれ以外かで条件分岐を行なっています。「 case 0」以降は、「swbreak」までが実行されますが、「case 1」の場合は、「 swbreak」が存在しないため、「default」以降に実行される「mes "A!=0"」も 含めて実行されるので注意してください。