連載
» 2014年11月19日 21時33分 UPDATE

カウントダウン企画……あと1回:日刊!プチコン3号――開発効率UP!「ライブラリ機能」

配信が開始されてますね。もう手に入れた?

[瓜生聖,ITmedia]

連載:日刊プチコン3号

開発効率を上げる「ライブラリ機能」

 クラシカルなBASICの特徴としては、ローカル変数を持たない、構造化機能がないことなどが挙げられる。そのため、スコープの概念を学んだことのないプログラミング初心者にとっても理解しやすい、という一面もあるが、その半面、大規模なプログラムの開発――複数人による開発や、プログラム部品の再利用などがしづらい理由にもなっている。

 プチコン3号ではとっつきやすさを残しつつ、モダンな仕組みも取り込んでいる。その1つがユーザー関数を作成する「DEF」命令だ。DEFからENDまでが関数の内容となり、その中で定義された変数はローカル扱いとなって関数外からは参照も設定もできない。また、複数の戻り値を指定することもできるなど、構造化言語に慣れている人にとってはGOSUBよりも使いやすいのではないだろうか。

 プチコン3号はプチコンmkIIにあったAPPEND命令がなくなっており、実行中のプログラムにほかのプログラムリストを追加読み込みすることはできない。その代わり、プログラムSLOTが4つに増えており、現在実行中以外のプログラムSLOTにプログラムを読み込むことができる。

 DEF命令の前にCOMMON(C言語のexternに相当)を付けたユーザー関数はプログラムSLOTをまたいで呼び出すことができるので、ライブラリ化したいユーザー関数はCOMMON DEFで定義、使う側からはLOAD命令で空きSLOTに読み込んで利用する、という使い方が可能だ。すでにスマイルブームからトランプゲームに使えるライブラリが登場している。

 ちなみにユーザー関数だけでなくGOTO、GOSUB、RESTOREのラベルもプログラムSLOTをまたいで指定できる。RESTOREやGOSUBはともかく、GOTOで別SLOTを指定するのはよほど気をつけないと2つの皿のスパゲティが絡まりあったような状態になりかねない。用途を十分吟味した上で利用すべきだろう。

 なお、別SLOTにプログラムをLOADした時点では関数名やラベルがテーブル登録されておらず、COMMON DEFで定義した関数も他のSLOTから呼び出すことができない。いったんUSE命令でテーブルに登録することで利用可能な状態になる。

 そのほか、関連する命令には可変関数(関数名を文字列として動的に指定する)呼び出しのCALL、プログラムを読み込んで実行するEXECがある。EXECの特筆すべき特徴は、現在実行中のプログラムSLOTへの読み込み(自分自身との差し替え)ができることだ。ブートストラップやランチャー、各面ごとに独立したプログラムの読み込みなど、使い方次第では面白い活用ができそうだ。

 ただし、SLOTをまたいだ命令の挙動はかなり実装優先の部分がある。例えば、EXECはプログラム内での実行履歴がない場合は実行元に制御が戻ってくるが、ある場合は戻ってこない(同じEXEC文を実行しても1回目と2回目で挙動が異なる)。

 このあたりの挙動は配信開始後の解析が待たれるところだが、製品のアップデートによって仕様が変わる場合もあるかもしれない。呼び出し先のプログラムは関数定義等のみ、実際の実行は呼び出し元で制御するほうが無難だろう。

og_puticom3_001.jpg プログラムSLOTをまたいだ利用例。メインプログラムが置かれたPRG0を実行する

og_puticom3_002.jpg LOAD命令は指定プログラムSLOT(省略時は0)にファイルを読み込む

og_puticom3_003.jpg USE命令によってCOMMON DEFで定義された関数がプログラムSLOTを超えて利用可能になる

og_puticom3_004.jpg 利用可能になったPRG1の関数FUNC()を呼び出し

og_puticom3_005.jpg RETURNによって戻り値とともにPRG0に制御が戻る

og_puticom3_006.jpg EXEC命令の場合。PRG0のプログラムを実行

og_puticom3_007.jpg PRG0からEXEC命令を実行。指定プログラムSLOT PRG1にファイルを読み込む

og_puticom3_008.jpg PRG1を頭から実行

og_puticom3_009.jpg PRG1が終了したらPRG0に制御が戻る

og_puticom3_010.jpg PRG0のGOTO命令で制御が@LOOPに戻り、再度EXEC。再びファイルから読み込みが行われる

og_puticom3_011.jpg PRG1を頭から実行

og_puticom3_012.jpg PRG1が終了したらそこでおしまい。PRG0に制御は戻らない

関係する命令

DEF 関数名([引数[,引数...]])

 説明(1/2)

  ユーザー関数の定義。DEF〜ENDまでが定義範囲となる

  ・戻り値の値は関数名の型に従う(#,$)

  ・DEF〜END範囲で定義された変数やラベルはローカル扱い

  ・DEF〜END範囲を越えるGOTOはできない

  ・DEF〜END範囲でGOSUBやON GOSUBは使用できない

 戻り値の定義

  定義内のRETURN命令により戻す

  ※2つ以上の場合は「OUT」に続く変数列により戻す

  ・引数を2つ渡し、数値を返す関数

   DEF ADW(X,Y)

    RETURN X+Y

   END

  ・再帰を使った関数

   DEF FACTORIAL(N)

    IF N==1 THEN

     RETURN 1

    ELSE

     RETURN N*FACTORIAL(N-1)

    ENDIF

   END

  ・文字列型関数の定義

   DEF REVERSE$(ARG$)

    VAR A$ ←A$はローカル変数。外部のA$とは違う変数

    L=LEN(ARG$)

    FOR I=0 TO L-1

     A$=A$+MID$(ARG$,L-1,-I,1)

    NEXT

    RETURN A$

   END

DEF 命令名 [引数[,引数...]] [OUT 変数[,変数...]]

 説明(2/2)

  ユーザー命令の定義。DEF〜ENDまでが定義範囲となる。

  ・DEF〜END範囲で定義された変数やラベルはローカル扱い

  ・DEF〜END範囲を越えるGOTOはできない

  ・DEF〜END範囲でGOSUBやON GOSUBは使用できない

 戻り値の定義

  「OUT」に続く変数列により複数の戻り値を返す

END

 説明(1/2)

  プログラムを終了

END

 説明(2/2)

  ユーザー関数、ユーザー命令の定義を終了

RETURN

 説明(1/2)

  サブルーチンから呼び出し元へ復帰

RETURN 戻り値

 説明(2/2)

  ユーザー定義関数から戻り値を設定して呼び出し元へ復帰

 引数

  戻り値

   ユーザー定義関数の戻り値

COMMON DEF 関数名([引数[,引数...])

 説明(1/2)

  プログラムSLOTを超えて利用可能なユーザー関数を定義

  ・他のSLOTから使用するには、USE命令で使用可能にする必要あり

  ・詳細はDEFを参照

COMMON DEF 命令名 [引数[,引数...]] [OUT 変数[,変数...]]

 説明(2/2)

  プログラムSLOTを超えて利用可能なユーザー命令を定義

  ・OUTに続く変数列で複数の戻り値を返せる

  ・他のSLOTから使用するには、USE命令で使用可能にする必要あり

  ・詳細はDEFを参照

GOTO @ラベル

 説明(1/3)

  強制分岐

 引数

  @ラベル

   ジャンプ先の@ラベル名

   または@ラベル名を""でくくったラベル文字列(文字列変数も可)

   ・ラベル文字列の場合、GOTO "1:@ラベル名"の形式で、異なるプログラムSLOTにジャンプすることも可能

   ※あらかじめUSE 1等で対象SLOTを使用可能にしておく

ON 制御変数 GOTO @ラベル0,@ラベル1,@ラベル2...

 説明(2/3)

  制御変数の内容(0以上の整数)に応じ、列挙したラベル行に分岐

  ・従来型のBASICでの制御変数は1以上なので、違いに注意

 引数

  @ラベル0

   制御変数が0のときのジャンプ先

  @ラベル1

   制御変数が1のときのジャンプ先

  @ラベル2

   制御変数が2のときのジャンプ先

  ※以下同様。列挙するラベル数は任意

  ※ON〜GOTOのラベルには、ラベル文字列は使えません

  (著者注:そのためプログラムSLOTを超えてのラベル指定はできない)

IF 条件式 GOTO @ラベル [ELSE 不成立時処理]

 説明(3/3)

  条件が成立した際、@ラベルに分岐

 条件式

  条件式の比較演算子は次のとおり

   等しい ==

   等しくない !=

   より大きい >

   より小さい <

   以上 >=

   以下 <=

 ラベルに文字列を使う場合

  ラベルにはラベル文字列も使用可能

  ただしELSE直後でGOTOを省略するときは、文字列は使えない

  ×IF A=0 GOTO "@LABEL1" ELSE "@LABEL2"

  ○IF A==0 GOTO "@LABEL1" ELSE @LABEL2

  ○IF A==0 GOTO "@LABEL1" ELSE GOTO "@LABEL2"

GOSUB @ラベル

 説明(1/2)

  サブルーチンの呼び出し

 引数

  @ラベル

   呼び出すサブルーチンの@ラベル名

   または@ラベル名を""でくくったラベル文字列(文字列変数も可)

   ・ラベル文字列の場合、GOSUB "1:@ラベル名"の形式で、異なるプログラムSLOTのサブルーチンも呼び出し可能

   ※あらかじめUSE 1等で対象SLOTを使用可能にしておく

ON 制御変数 GOSUB @ラベル0, @ラベル1, @ラベル2...

 説明(2/2)

  制御変数(0以上の整数)に応じ、列挙したサブルーチンを呼び出し

  ・従来のBASICでの制御変数は1以上なので、違いに注意

 引数

  @ラベル0

   制御変数が0のときの呼び出し先

  @ラベル1

   制御変数が1のときの呼び出し先

  @ラベル2

   制御変数が2のときの呼び出し先

  ※以下同様。列挙するラベル数は任意

  ※ON〜GOSUBのラベルには、ラベル文字列は使えません

  (著者注:そのためプログラムSLOTを超えてのラベル指定はできない)

USE プログラムSLOT

 説明

  指定プログラムSLOTのソースコードを実行可能な状態にする

 引数

  プログラムSLOT:0〜3

EXEC "[リソース名:]ファイル名"

 説明(1/2)

  プログラムのLOADと実行

  ・EXECで実行を始めたプログラムから元のプログラムに戻ってくることはできない

  ・DIRECTモードでは実行できない

 引数

  リソース名

   PRG0〜PRG3:読み込み先プログラムSLOTの指定(PRG=PRG0)

  ファイル名

   読み込むプログラムのファイル名

EXEC プログラムSLOT

 説明(2/2)

  他のSLOTのプログラムを実行

  ・EXECで実行を始めたプログラムから元のプログラムに戻ってくることはできない

  ・DIRECTモードでは実行できない

 引数

  プログラムSLOT

   0〜3:実行するプログラムSLOT番号

CALL "命令名" [,引数...] [OUT 変数1 [,変数2...]]

 説明(1/2)

  指定名称をもつユーザー定義命令を呼び出す

 引数

  命令名

   呼び出すユーザー定義命令名の文字列

   ※文字列なので""でくくるか、文字列変数を使用

  引数

   指定した命令に必要な引数

  変数

   戻り値が入る変数を列挙

変数=CALL("関数名"[,引数...])

 説明(2/2)

  指定名称を持つユーザー定義関数を呼び出す

 引数

  関数名

   呼び出すユーザー定義関数名の文字列

   ※文字列なので""でくくるか、文字列変数を使用

  引数

   指定した命令に必要な引数を列挙


 さて、待ちに待ったプチコン3号もついに入手可能となった。次回はファイルのアップロード/ダウンロードを紹介する。……次回!?

※本稿の内容は開発中のものです。製品版配信時には仕様が変更される場合があります。


Copyright© 2016 ITmedia, Inc. All Rights Reserved.