2.03.制御命令

以下の制御命令が使用可能です。そして それぞれの構文を持ちます。

switch, if, for, while, do, break, continue, end,

label, goto, gosub, func, return, module

(オリジナルのSPALMには continue と module はありません)

(オリジナルのSPALMにある try ~ catch には未対応です(エラーになります))

(オリジナルのSPALMにある 分割ロード(#ソース#) には未対応です(エラーになります))

(オリジナルのSPALMにある goto,gosubのジャンプ先に計算式を指定する機能には非対応です(v6.00から))


(現状の SPALM Web インタープリターには、

「ループのプログラムで固まる」という制限事項があります。

(アプリケーション説明の「1.3.制限事項」参照))


2.3.1.制御命令の詳細


(1)switch

switch (式1) {

case 式A: 命令 break

:

case 式X: 命令 break

default: 命令 break

}


式1を評価し、式A~Xのうち最初に一致したcaseの命令にジャンプします。

一致したものがなければ、defaultがあればdefaultの命令にジャンプします。

ジャンプ後は、breakがあれば、switchを抜けます。

breakがなければ、続くcaseやdefaultの命令も実行します。

(オリジナルのSPALMではcaseの式は数値か文字列である必要があります)



(2)if

if (式1) { 命令1 }

elsif (式A) { 命令A }

elsif (式B) { 命令B }

:

elsif (式X) { 命令X }

else { 命令2 }


式1を評価し、それが非0であれば命令1を実行します。そうでなければ、elsifがあれば、

式Aを評価し、それが非0であれば命令Aを実行します。そうでなければ、elsifがあれば、

式Bを評価し、それが非0であれば命令Bを実行します。これを続けて、

最後の式Xまですべて0であった場合には、elseがあれば、命令2を実行します。



(3)for

for (式1; 式2; 式3) { 命令 }


最初に1回だけ式1を評価します。そして、

式2が非0である間、命令を繰り返し実行します。

また、命令を1回実行するごとに 式3を評価します。

命令の中にbreakがあった場合には、ループを抜けます。

命令の中にcontinueがあった場合には、ループの先頭に戻ります。

式1-3は省略可能です(セミコロン(;)は省略できません)。

式2を省略すると、無限ループになります。



(4)while

while (式) { 命令 }


式が非0である間、命令を繰り返し実行します。

命令の中にbreakがあった場合には、ループを抜けます。

命令の中にcontinueがあった場合には、ループの先頭に戻ります。



(5)do

do { 命令 } while (式)


まず最初に命令を実行します。そして、

式が非0である間、命令を繰り返し実行します。

(最低1回は命令が実行されます)

命令の中にbreakがあった場合には、ループを抜けます。

命令の中にcontinueがあった場合には、ループの先頭に戻ります。



(6)break

switch, for, while, do から抜けるときに使用します。



(7)continue

for, while, do でループの先頭に戻るときに使用します。



(8)end

プログラムを終了します。



(9)label

label ラベル名


指定した名前でラベルを定義します。

ラベルは、gotoかgosubのジャンプ先になります。


ラベル名には、半角数字のみのものも指定できます。

また、ラベル名は、ダブルクォートでくくったものも認識されます。

(過去との互換性維持のため)



(10)goto

goto ラベル名


ラベルにジャンプします。


(オリジナルのSPALMにある goto,gosubのジャンプ先に計算式を指定する機能には非対応です(v6.00から))



(11)gosub

gosub ラベル名


ラベルにジャンプします。

このとき、ジャンプ元の位置を保存し、returnがあるとそこに戻って、

(gosubの次の命令から)再開します。


(オリジナルのSPALMにある goto,gosubのジャンプ先に計算式を指定する機能には非対応です(v6.00から))



(12)func

func 関数名(仮引数1,仮引数2, ... ,仮引数n) {

命令

return 式1

}


ユーザ定義の関数を定義します。

仮引数には変数名を指定します。仮引数は省略可能です。


ユーザ定義の関数が呼び出されると、仮引数に引数の値がセットされ、

命令が実行されます。

returnに到達すると、式1を戻り値として関数を終了します。

もしくは、 } に到達すると、戻り値を0として関数を終了します。

returnの式1を省略した場合には、戻り値は0になります。

このときは returnにセミコロン(;)をつける必要があります。


プログラム中でユーザ定義の関数を呼び出すには、

関数名(引数1,引数2, ... ,引数n)

のように記述します。もしくは、

y=関数名(引数1,引数2, ... ,引数n)

のように式の中で呼び出すこともできます。

引数の数が定義よりも少ない場合には、不足した引数には0を指定したことになります。

また、引数の数が定義よりも多い場合には、超過した引数は無視されます。



(13)return

return 式1


関数内であれば、式1を戻り値として関数を終了します。

式1を省略した場合には、戻り値は0になります。

このときは returnにセミコロン(;)をつける必要があります。


関数内でなければ、gosubの戻り先に戻ります。

このときは戻り値がないため、式1を省略して、

returnにセミコロン(;)をつける必要があります。



(14)module

module モジュール名 { 命令 }


モジュールを定義します。

(オリジナルのSPALMには存在しません)

(現状、モジュールを別のファイルに分離することはできません)

(本命令は、v14.00で追加され、v18.00で制御命令になりました。

記述方法が module(MZ) から module MZ { } に変わったため、

v18.00より前のバージョンとは互換性がなくなっています)


例えば、module MZ { 命令 } とすると、命令の部分は モジュール MZ に所属します。

そして、モジュール内では、グローバル変数名,ユーザ定義関数名,ラベル名 の前に

'MZ#' が自動的に付加されます。

これらの要素には、同一モジュール内であれば 'MZ#' を付けなくてもアクセス可能です。

しかし、モジュールの外部からは 'MZ#' を付けてアクセスする必要があります (MZ#x 等)。


また、逆にモジュール内から、

モジュールに所属しない グローバル変数名,ユーザ定義関数名,ラベル名 に

アクセスする場合には、先頭に # を付けてアクセスする必要があります (#x 等)。


(現状、定数名は、モジュールの影響を受けません)


モジュールは、入れ子にすることができます(v18.00から)。

例えば、module MX { module MY { 命令 } } とすると、

命令の部分の グローバル変数名,ユーザ定義関数名,ラベル名 の前には

'MX#MY#' が付加されます。


(2019-4-15)