Lesson 6インタプリタの構成インタプリタは,どのように動作するか
開発する Tiny BASIC のインタプリタの基本構造を示します.このページは,石田晴久著「マイクロコンピュータプログラミング入門 —Tiny BASIC インタプリタ—」の内容です.これを理解するために書きました.
目次
インタプリタの記述方法
どうやって書くか
インタプリタは,いろいろな方法で作成できる.C言語みなたいなプログラミング言語を使うこともできるし,機械語で記述することも可能である.ここでは,
中間言語
Tiny BASIC インタプリタ
構成図
図1に BASIC インタプリタの構成図を示します.インタプリタのプログラは左上の INIT から動作が始まり,矢印に従いぐるぐる回ります.通常は,GETLI(行番号付きで1行を入力) — INSERT(エディタ機能) 間のループで BASIC プログラムを1行毎に入力します.プログラムの入力が終われば,コマンド RUNによりプログラムを実行します.このプログラム実行開始コマンド RUN は,GETLI で入力されます.行番号が無いので,TSTLのルーチンで構成図の下側に分岐されます.その後は,実行行を取り出し,順次実行されます.プログラム中で END を見つけると,再びコマンド入力の GETLI に戻ります.
これだけでも,大筋の動作は分かるでしょう.より詳細な動作については,次節以降のルーチンの説明と合わせて,ひとつずつプログラムのシーケンスを追うと理解が深まります.
機械語ルーチンの機能
先に示した Tiny BASIC のインタプリタ の構成図中の機械語ルーチンの機能は,次の通りです.
制御の流れに関するルーチン |
INIT |
ML-1 |
プログラムの初期化をします. |
NLINE |
ML-2 |
改行(CR)と復帰(LF)の文字コードを出力します. |
GETLI |
ML-3 |
プロンプト「*」を出力し,1行を読み込みます.行の入力が終わるまで,ここで待機します. |
INSRT |
ML-5 |
行の挿入や削除,置換,追加などの編集を行います.BASIC インタプリタ中でももっとも強力なルーチン. |
XINIT |
ML-6 |
ユーザー作成の BASIC プログラム実行時の初期化をします.スタックを空にし,最初に実行する文の行番号を用意します. |
DONE |
ML-13A |
改行「CR」かデリミッタ「:」かを判断する.デリミッタの場合,その後の文に制御を移す. |
DONEX |
ML-13B |
改行「CR」かデリミッタ「:」かを判断する.デリミッタの場合,その行の実行を止める. |
NXT |
ML-13C |
現在の行番号がゼロかどうかを判断する.ゼロならばこの行は直接実行されたことになり,次の入力を促すルーチンへ移る (FIN をコール).ゼロでなければ,次に実行する行番号を求める.NXT の後半では, NXTX が実行されます. |
NXTX |
ML-13D |
次の実行文のアドレスをスタックに積む. |
FIN |
ML-13E |
最終終了の処理を行います.最後にアドレス LNECL に移ります. |
XFER |
ML-14 |
GOTO あるいは GOSUB で,次の実行に実行する行番号に制御を移す. |
STORE |
ML-20 |
変数のアドレスを求め,そこに値を代入する. |
コマンド実行ルーチン |
SIZE |
ML-33 |
使用済みと残りのメモリーの量を表示します. |
LIST |
ML-34 |
リストの前処理を行います. |
LIST0 |
ML-34 |
プログラム全体を表示します. |
LIST1 |
ML-34 |
LIST 20 行番号 20 のみを表示します.このルーチンは,プログラムの特定の行のみを表示します. |
LIST2 |
ML-34 |
LIST 100,300 行番号 200 — 300 を表示します.このルーチンは,プログラムの指定の範囲を表示します. |
ある量の有無をテストするルーチン |
TSTL |
ML-4 |
入力した1行の行番号の有無を調べます.行番号があれば,それを二進数に変換し,桁上げフラグを(CYフラグ)を 1 にセットします.行番号が無い場合は,CY=0 です. |
TSTV |
ML-7A |
変数(英文字の A—Z)の有無を調べます.変数があれば,CY を 1 にセットし,変数のアドレスを求め,データスタックにプッシュします. |
IF 文,FOR 文,NEXT 文,DTA 文に関するルーチン |
CMPR |
ML-23 |
データスタックにある二つの数を比較し,真ならば IF に引き続く文を実行する.偽ならば,次の行次の行の実行の準備をする. |
FOR |
ML-19 |
FOR に続く文のアドレスを求める. |
NEXT |
ML-21 |
制御変数をひとつ増やし,最終値を超えたか調べます.超えていない場合には,繰り返しの入口の FOR の実行文の解釈の準備をします.超えた場合には,次の文の実行の準備をします. |
DATA |
ML-29 |
値を代入する. |
INPUT 文,PRINT 文に関するルーチン |
INNUM |
ML-15 |
「?」を出力後に,入力された数値を二進数に変換し,スタックにプッシュする. |
INSTR |
ML-15 |
「?」を出力後に,入力された文字を@配列に入力する. |
PRN |
ML-18 |
数値を出力する. |
PRS |
ML-16 |
文字列を出力する. |
OUTS |
ML-16 |
文字列配列@の文字列を出力する. |
SPAC |
ML-17 |
ゾーン(8文字)いっぱいになるまで,スペースを出力する. |
GOSUB 文と RETURN 文に関するルーチン |
SAVE |
ML-24 |
戻り番地をアドレススタックにプッシュする. |
RSTR |
ML-25 |
戻り番地をアドレススタックからポップする. |
配列に関するルーチン |
DIM1 |
ML-26 |
一次元配列に必要なメモリー量を計算し,メモリーを割り付ける.配列名に先頭番地を保管する. |
DIM2 |
ML-26 |
二次元配列に必要なメモリー量を計算し,メモリーを割り付ける.配列名に先頭番地を保管する. |
中間言語ルーチンの機能
先に示した Tiny BASIC のインタプリタ の構成図中の中間言語ルーチンの機能は,次の通りです.
中間言語のルーチン |
EXPR1 |
I-1 |
「=」の場合,EXPR をコールする. |
EXPR |
I-1 |
式の演算を行う.「+」あるいは「-」毎に項(乗算 or 除算で結ばれている式)の計算を行い,最後に合計する. |
TERM |
I-2 |
数式の項(term)の評価を行うルーチン.まず因子(変数,配列,関数)の評価を行いう.因子との間が「*」であれば乗算,「/」ならば除算を行う. |
FACT |
I-3 |
因子(factor)は,RND関数かSPACE関数,配列,変数,括弧で囲まれた式のいずれかである.このルーチンでは,それぞれに応じた処理を行う. |
RELOP |
I-4 |
関係演算子(relational operator)の評価を行うルーチン.演算子に応じて,ルーチンを呼び出す.呼び出すルーチンは,「=」:LIT0,「<」LIT1,「<=」LIT2,「<>」or「><<」LIT3,「>」LIT4,「>=」LIT5 である. |
ARRAY |
I-5 |
配列名(式)のときは ARRA1 を,配列名(式,式)のときは ARRA2 をコールする. |
AVTST |
I-6 |
変数/変数の判断を行う.変数であればそのまま戻り,配列であればARRY をコールする.いずれでもない場合はエラー. |
中間言語ルーチンの中の機械語ルーチンの機能
算術演算子と論理演算子の処理を行うルーチン |
NEG |
ML-9 |
データスタックの一番上のデータをポップし,符号を反転(2の補数)し,データスタックにプッシュする. |
SADD |
ML-10A |
データスタックの二つのデータをポップし,それらを加算する.その結果をデータスタックにプッシュする. |
SSUB |
ML-10B |
データスタックの二つのデータをポップし,それらを減算する.その結果をデータスタックにプッシュする. |
MUL |
ML-11 |
データスタックの二つのデータをポップし,それらを乗算する.その結果をデータスタックにプッシュする. |
DIV |
ML-12 |
データスタックの二つのデータをポップし,それらを除算する.その結果をデータスタックにプッシュする. |
LIT1—5 |
ML-22 |
各論理演算子 (=, <, <=, <> or ><, >, >=) のアドレスをデータスタックにプッシュする.実際の論理演算は,CMPR ルーチンで行われる. |
配列と関数の処理を行うルーチン |
ARRA1 |
ML-28 |
一次元配列の要素のアドレスを計算する.添え字の値はデータスタックにある. |
ARRA2 |
ML-28 |
二次元配列の要素のアドレスを計算する.添え字の値はデータスタックにある. |
RANDM |
ML-31 |
0—32767の間の乱数を計算する. |
SPACE |
ML-32 |
データスタックの一番上の値に等しい位置まで,空白を置く. |
制御の流れを司るルーチン |
TSTN |
ML-8 |
数字があるかどうか調べる.数字の場合,二進数に変換し,CY=1 とする.数字以外は,CY=0. |
TSTA |
ML-27 |
英字の後に「(」があれば,配列とみなし,必要な処理を行う.CY=1 にする. |
TSTF |
ML-30 |
英字が続いて二つあれば,関数名とみなす.必要な処理を行い,CY=1 とする. |
VALUE |
ML-7B |
変数のアドレスをデータスタックからポップする.そのアドレスの値を求め,データスタックにプッシュする. |
RETRN |
ML-35 |
サブルーチンを終わり,呼び出し元の次の行へ処理を移す. |
ERROR |
ML-36 |
エラー番号とエラーが起きた行番号を表示する. |
ページ作成情報
参考資料
- 以下の書籍は BASIC インタプリタの作成方法が細かくかかれており,参考になります.このページはこの書籍の内容を分かりやすく解説します.残念なことに,この書籍は絶版なので,入手は難しいでしょう.
更新履歴
|