リファレンス 1.0 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
このページでは「へたれBASIC」(1.0)の詳細な仕様、いわゆるリファレンスというのを載せてみようと思います。しかし簡単なプログラムといっても、仕様を書き出してみると以外と書く事が多いのに気が付きました。そんなわけで、プログラムの骨格となるような重要な仕様だけを最初に書いて、その他の細々とした部分は随時更新しながら書くことにしました。 こうして文章で書いてみると、各インターフェイスがいかに整合性が取れていないのかが良く分ります(爆)。ソースコードだけを追ってると、以前に作ったまま放ってあるインターフェイス(爆!)にも意味があるものと思っちゃうので、文書化はやっぱり重要です!!っていうか、もっと記憶力良くなれよ自分!(泣) 目次 型クラスの仕様 CInterpreterの実装 抽象演算子の種類 CMachineメンバと制御用OP_HANDLER 型クラスの仕様
CInterpreterの実装 CInterpreterは翻訳に関わる処理を統括しているクラスです。記号表や、構文木といったデータ構造を用いて、翻訳の過程で必要となる情報を記憶しています。 構文木について 構文木は式の構造を表すために導入しました。CDag型を使ったデータ構造で、4つのint値の組み合わせで一つのノードとなっています。構文木はCInterpreterの一連のMake〜()の内部で生成され、それぞれのint値はノードの種類毎に適宜キャスティングして使用されるため、ノードの種類毎に値の意味は異なります。ある種のノードは、別のノードの番号をint値として記憶する形で、子のノードへの参照を持つものがあり、これによって木構造の参照関係を作り出しています。全ての種類のノードに共通する構成は次のようになっています。 {ノードの種類,任意,任意,ノードが表す部分式の型} ノードの種類には抽象演算子のIDが流用されています。これは計算式の構文の種類と、演算処理の種類にはあまり違いがないと思ったのでそうしました。これによって構文木から実行コードを生成するGenExpression()の実装を簡素化しています。 「任意」と書かれている箇所は個々のノード毎に異なる意味を持ちます。子ノードへの参照や、記号表への参照、その他の付加的な情報などが、Make〜()によって設定されます。 「ノードが表す部分式の型」は、そのノードによって作られた実行コードが、実行時、スタックトップへと積む値の 型を表します。「へたれBASIC」では全ての部分式の演算結果の型は静的に決まります。 メンバ関数 CInterpreterのメンバ関数は大別すると、yyparse()から呼び出される関数、main()から呼び出される関数、そしてCInterpreterの別のメンバ関数から呼び出される関数(ヘルパ関数)があります。 ヘルパ関数などは、privateで宣言しても、yyparse()やyyerror()などのフレンド指定された外部関数から呼び出されてしまう可能性もあります。せめて関数名から分かりやすくするため、内部的に呼び出される関数(ヘルパ関数)は、小文字とアンダーラインの組み合わせで書き、クラスの外側から呼び出される関数(インターフェイス関数)は、大文字と小文字の組み合わせで書くようにしました。 ![]() 引数 fp ... ソースコードが格納されているファイルのポインタ。 機能 翻訳対象となるソースコードが格納されているファイルをCInterpreterのインスタンスへ設定します。 ![]() 引数 machine ... 実行時環境のポインタ 機能 生成の対象となる実行時環境(CMachineのインスタンス)をCInterpreterのインスタンスへ設定します。 ![]() 戻り値 発生したエラーのID。 機能 ソースコードを翻訳して、実行時環境を構築します。 ![]() 戻り値 発生したエラーのID。 引数 pFuncTbl ... 関数の情報が入ったテーブルへのポインタ 機能 「へたれBASIC」のソースコードから呼び出される組込み関数を登録します。 ![]() 戻り値 発生したエラーのID。 機能 定数や変数が格納される領域を実行時環境のデータ領域に設定します。この関数はソースコードが全て解析された後に呼ばれます。 ![]() 戻り値 発生したエラーのID。 機能 コード領域の中で未解決の参照やジャンプ先に値を埋め込みます。この関数はソースコードが全て解析された後に呼ばれます。 ![]() ![]() 戻り値 ラベルが設定された記号表エントリへのポインタ。記号表エントリが不正の場合は0を返す。 引数 pstr ... ・ 宴xルの文字列へのポインタ。 strid ... ラベルの文字列を参照するためのID。 機能 記号表から指定された文字列で記号表エントリを検索し、そのエントリがラベル情報を保持しているかどうか調べます。もしエントリがラベルのものではない場合はFireError()し、0を返します。もしエントリが見つからなければ、新しいエントリを作り、ジャンプ先未定のラベルを設定して、記号表に登録します。 ![]() 戻り値 pidと同じ値。 引数 pid ... ラベルが登録されている記号表エントリへのポインタ。 cmd ... ジャンプ系のコマンドID(Jump, Jump_by_0, Callのどれか)。 機能 GenJump(), GenJumpBy_0(), GenCall()から共通して呼び出される、ジャンプ系コマンド生成用の関数です。ジャンプ先としてpidの値がコード領域に埋め込まれます。この値は構文解析終了後にジャンプ先のアドレスへと変換されます。 ![]() ![]() 戻り値 検索/生成されたラベル用の記号表エントリのポインタ。 引数 strid ... ラベルの文字列を参照するためのID。 機能 stridで示される名前のラベルへの無条件ジャンプコマンド(Jump)を生成します。stridで示される名前が記号表にない場合は、新しくエントリを生成し登録します。stridが渡されていない場合は、他と重複しない名前が自動的に生成され、記号表に登録されます。 ![]() ![]() 戻り値 検索/生成されたラベル用の記号表エントリのポインタ。 引数 strid ... ラベルの文字列を参照するためのID。 機能 stridで示される名前のラベルへの条件ジャンプコマンド(Jump_by_0)を生成します。stridで示される名前が記号表にない場合は、新しくエントリを生成 し登録します。stridが渡されていない場合は、他と重複しない名前が自動的に生成され、記号表に登録されます。 ![]() 戻り値 生成されたラベル用の記号表エントリのポインタ。 引数 strid ... ラベルの文字列を参照するためのID。 機能 stridで示される名前のラベルへのサブルーチンコールコマンド(Call)を生成します。stridで示される名前が記号表にない場合は、新しくエントリを生成し登録します。 ![]() 戻り値 エラーが発生した場合は、エラー値を返す。発生しなかったら、ERR_NOTHINGを返す。 機能 Return文に対応するOP_HANDLERのアドレスを、コード領域に書き込みます。 ![]() 戻り値 エラーが発生した場合は、エラー値を返す。発生しなかったら、ERR_NOTHINGを返す。 機能 Return文に対応するOP_HANDLERのアドレスを、コード領域に書き込みます。 ![]() ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 strid ... ラベルの文字列を参照するためのID。記号表エントリの検索に使います。 pid ... ラベルが設定された記号表エントリへのポインタ。 機能 stridが渡された場合は、記号表エントリを検索します。記号表エントリが見つからない場合はFireError()を呼び出し、エラーを返します。 エントリに設定されているラベル情報に、現在生成されているコード領域の最後尾のアドレスを設定します。すでに別のアドレスが設定されていた場合は、FireError()しエラーを返します。 ![]() 戻り値 エラーが発生・ オた場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 strid ... ループカウンタ用変数の名前を参照するためのID。 iniTree ... ループの初期値を計算する式を表す構文木。 dstTree ... ループの終了値を計算する式を表す構文木。 stpTree ... ループの増分を計算する式を表す構文木。 機能 For文に対応する実行コードを生成します。実行コードの構成についてはCMachineメンバと制御用OP_HANDLERをご参照下さい。 ![]() ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 strid ... ループカウンタ用変数の名前を参照するためのID。 機能 Next文に対応する実行コードを生成します。実行コードの構成についてはCMachineメンバと制御用OP_HANDLERをご参照下さい。 ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 strid ... ループカウンタ用変数の名前を参照するためのID。 機能 2つのGenNext()関数の共通の機能を提供するヘルパ関数です。 ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 strid ... 代入対象の変数名を参照するためのID。 機能 Input文に対応した実行コードを生成します。実行コードの構成については抽象演算子の種類をご参照下さい。 ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 index ... 表示する値を生成する式を表す 構文木のノード番号。 機能 Print文に対応した実行コードを生成します。実行コードの構成については抽象演算子の種類をご参照下さい。 ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 rtree ... 右辺式を表す構文木のノード番号。 機能 代入のない、右辺式のみの式文に対応する実行コードを生成します。右辺式の実行コードを生成のため、内部ではGenExpression()が呼び出されます。右辺式のコードによって計算された右辺値を削除するための実行コードが挿入されます。 ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 strid ... 代入対象の変数名を参照するためのID。 rtree ... 右辺式を表す構文木のノード番号。 機能 変数に対して代入を行う式文に対応する実行コードを生成します。変数名が始めて出てくるものであった場合は、この変数に対応する記号表エントリを生成します。右辺式の実行コードを生成のため、内部ではGenExpression()が呼び出されます。現バージョンでは右辺値の型と、変数の型が一致しなければ代入を行うことはできません。 右辺値を変数に代入する実行コードが挿入されます。 ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 strid ... 代入対象の配列変数名を参照するためのID。 arg_node ... 添字の式を表す構文木のノード番号。 rtree ... 右辺式を表す構文木のノード番号。 機能 配列変数に対して代入を行う式文に対応する実行コードを生成します。変数名が始めて出てくるものであった場合は、この変数に対応する記号表エントリを生成します。右辺式の実行コードを生成のため、また配列の添字スタックに積むコードを生成するために、内部でGenEx pression()が呼び出されます。配列の要素へ右辺値を代入する実行コードが生成されます。詳しくはAOP_ARRAY_POPをご参照下さい。現バージョンでは右辺値の型と、配列変数の型が一致しなければ代入を行うことはできません。 ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 index ... 構文木のノード番号。 機能 indexで示された構文木に対応する部分式の実行コードを生成します。この関数は構文木のノードの種類によって次のように別々の処理を行っています。 AOP_AND, AOP_OR, AOP_EQ, AOP_LE, AOP_GE, AOP_LT, AOP_GT, AOP_NQ, AOP_ADD, AOP_SUB, AOP_MUL, AOP_DIVの場合: ノードは左辺と右辺の子ノードを持っているので、その子ノードの番号を引数にして、GenExpression()を再帰的によびだし部分式の左辺と右辺の値をスタックトップに積むための実行コードを生成します。 次にノードの種類として設定されている抽象演算子のIDと、ノードが表す部分式の型から、対応する実行コード(OP_HANDLER)を生成します。 AOP_COMBINEの場合: AOP_COMBINEはカンマ式に対応する構文木です。GenExpression()を再帰的によびだしカンマの左側と右側の値をスタックトップに積むための実行コードを生成します。 これらの値に対して何らかの演算処理を行うコードは生成しないため、これらのはスタックトップに残ったままになります。カンマ式は、配列の添字や、関数の引数をスタック上に積み上げるために使われます。カンマ式が連続している場合は、次のようにカンマ式の一番右側の部分式が、スタックトップになります。
AOP_UMINUSの場合: AOP_UMINUSは単項マイナス式に対応する構文木です。対象となる部分式に対応した実行コードを再起呼び出しによって生成した後、単項マイナス演算を行う実行コードを書き込みます。 AOP_FCALLの場合: AOP_FCALLは関数式に対応した構文木です。関数に引数がある場合は、引数に対応した部分式を書き出し、次に関数を呼び出す実行コード(といっても関数のアドレスそのものですが…)を書き出します。 AOP_PUSHIの場合: AOP_PUSHIは定数式に対応した構文木です。定数値はAOP_PUSHIに対応するOP_HANDLERのオペランドとして取り込む形式となっています。詳しくはAOP_PUSHIをご覧下さい。 AOP_PUSHATの場合: AOP_PUSHATは変数参照に対応した構文木です。AOP_PUSHATに対応するOP_HANDLERに続いて、変数の格納場所を示す整数値が、コード領域に書きこまれます。 AOP_ARRAY_PUSHの場合: この構文木に対応する処理はヘルパ関数gen_array_push()が行っています。 ![]() 戻り値 エラーが発生した場合はエラー値を返します。それ以外はERR_NOTHINGを返します。 引数 index ... 配列参照を表す構文木のノード番号。 機能 配列参照に対応した構文木から実行コードを生成します。この関数が構成する実行コードについてはAOP_ARRAY_PUSHをご参照下さい。また構文木の値の定義についてはmake_array()をご参照下さい。 ![]() 戻り値 生成した構文木のノード番号を返します。エラーが発生するとCDag::NULL_NODEを返します。 引数 type ... 構文木に設定する演算の種類。 ltree ... 演算子の左辺を表す構文木のノード番号。 rtree ... 演算子の右辺を表す構文木のノード番号。 機能 以下の演算に対応する構文木を作ります。 AOP_AND, AOP_OR, AOP_EQ, AOP_LE, AOP_GE, AOP_LT, AOP_GT, AOP_NQ, AOP_ADD,AOP_SUB,AOP_MUL,AOP_DIV こららの演算の場合は、右辺と左辺との間での型・ フ互換性を検証した後に、{演算の種類,左辺のノード番号,右辺のノード番号,この演算の結果の型}という構成で構文木を生成します。型の互換性については、現バージョンでは左辺と右辺が同じ型でないと演算できない、という単純な規則を適用しています。 AOP_UMINUS {AOP_UMINUS, 右辺のノード番号,0(ゼロ), この演算の結果の型}という構成で構文木を生成します。 AOP_COMBINE {AOP_COMBINE, 左辺のノード番号, 右辺のノード番号,この演算の結果の型}という構成で構文木を生成します。 ![]() 戻り値 生成した構文木のノード番号を返します。エラーが発生するとCDag::NULL_NODEを返します。 引数 strid ... 変数名の文字列を参照するためのID。 機能 指定された文字列で記号表を検索し、それが変数であるかどうかを確認して、変数の参照に対応する構文木を作ります。構文木の構成は次のようになります。 {AOP_PUSHAT, 変数の記号表エントリのポインタ, 0, この演算(変数)の型} ![]() 戻り値 生成した構文木のノード番号を返します。エラーが発生するとCDag::NULL_NODEを返します。 引数 strid ... 定数値の文字列を参照するためのID。 id ... 定数値の型の種類を表す番号。 機能 stridで示された文字列をidで示される型(STRING or NUMBER)を持つ値へと変換します。その型に対応した型変数を生成し、型変数に値を設定します。その型変数を、他と重複しない名前を付け記号表に登録します。そしてその記号表エントリのポインタと共に以下の構成の記号表を生成します。 {AOP_PUSHI, 定数の記号表エントリのポインタ, 0, この演算(定数)の型} ![]() 戻り値 生成した構文木のノード番号を返します。エラーが発生するとCDag::NULL_NODEを返します。 引数 strid ... 定数値の文字列を参照するためのID。 id ... 定数値の型の種類を表す番号。< br>機能 関数や配列参照に対応した構文木を作ります。関数と配列は、構文としては変わらないので、識別子で記号表を検索し、型に合わせて、関数の構文木を作るmake_function()か、配列参照の構文木を作るmake_array()を呼び出します。どちらの型でもない場合は、エラーを報告します。 ![]() 戻り値 生成した構文木のノード番号を返します。エラーが発生するとCDag::NULL_NODEを返します。 引数 pid ... 関数が登録されている記号表エントリへのポインタ。 arg_node ... 関数の引数を表す構文木のノード番号。 機能 関数呼び出しに対応する構文木を作ります。arg_ndoeで渡された(「へたれBASIC」の文法としての)引数の型の組み合わせが、正しいかどうかを、pidに登録されているCFuncTypeのインスタンスに問い合わせて確認します。次の形式で構文木を作ります。 {AOP_FCALL, pid, arg_node, この演算の結果(関数の戻り値)の型} ![]() 戻り値 生成した構文木のノード番号を返します。エラーが発生するとCDag::NULL_NODEを返します。 引数 pid ... 配列変数が登録されている記号表エントリへのポインタ。 arg_node ... 配列の添字を表す構文木のノード番号。 機能 配列参照に対応する構文木を生成します。arg_nodeには1つ以上の整数型か、文字列型の添字がなくてはならないので、これを確認します。そして次の構成の構文木を生成します。 {AOP_ARRAY_PUSH, pid, arg_node + (添字の個数 16), この演算(=pidに設定されている配列要素)の型} ![]() 戻り値 errで渡されたエラー値。 引数 err ... 報告対象となるエラー値。 pstr ... エラーが発生した単語。 機能 エラーを報告する際に呼び出される関数です。この関数はput_error()でエラーを標準エラー出力へ出力した後、致命的なエラーで あれば、構文解析を終了する処理を行います。また以下のメンバ変数に値を設定します。 m_bErrorHasFired ... 一度でもエラーが発生すると、trueになります。翻訳終了後、このフラグが立っていると、プログラムの実行は行われません。 m_lastError ... 直前に起こったエラーを保持します。CInterpeterの他のメンバ関数は、この値を参照することで、エラーが既に発生しているかどうか知ることが出来ます。この値はyyparse()によって翻訳単位の一文毎に初期化しています。 ![]() 戻り値 生成した構文木のノード番号を返します。エラーが発生するとCDag::NULL_NODEを返します。 引数 err ... 表示するエラー番号。 pstr ... エラーメッセージと共に出力する文字列。 lineno ... エラーの発生した行番号。 機能 標準エラー出力にエラーを書き出します。 ![]() 機能 m_lastErrorの値を初期化します。この関数は、yyparse()によって、一つの文の解析が終わる度に呼び出されます。 抽象演算子の種類 抽象演算子は、各型クラスのGetOperator()関数によって実際の演算処理を行うOP_HANDLERに変換されます。これらのOP_HANDLERが、実行時にデータ領域に及ぼす作用や、コード領域でのオペランド(コード領域中に埋め込まれていて、OP_HANDLERに取り込まれる値)の形式は、どんな型であっても変わりありません。 各抽象演算子の作用 凡例; 抽象演算子のID スタック状態の変化 “→”を境にして、左側は処理前のスタック状態、右側が処理後のスタック状態を表します。“,”で一つ一つのデータが区切られます。一番右側に書いた項目は、スタックトップの要素を表します。一番左側に“…”と書かれている部分は、その処理によって作用が及ぼされることのない要素が、スタックの底側にあるかもしれないことを表しています。また、データの名前の後に“…”が書かれ・ トいる場合は、同じ意味のデータが複数続くことを表し、“[”と“]”で囲まれている場合は、そのデータが省略される場合があることを表します。 オペランド オペランドを持つ処理の場合はその意味を書きます。 処理 その処理の具体的な内容を書きます。 AOP_AND スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 左辺と右辺の論理積(AND)を計算します。 AOP_OR スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 左辺と右辺の論理和(OR)を計算します。 AOP_EQ スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 左辺と右辺の等価判定を行います。計算結果は等価なら1、それ以外は0になります。 AOP_LE スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 計算結果は左辺が右辺より同じか小さい場合は1、それ以外は0。 AOP_GE スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 計算結果は左辺が右辺より同じか大きい場合は1、それ以外は0。 AOP_LT スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 計算結果は左辺が右辺より小さい場合は1、それ以外は0。 AOP_GT スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 計算結果は左辺が右辺より大きい場合は1、それ以外は0。 AOP_NQ スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 左辺と右辺の値が異なれば1、等価なら0。 AOP_ADD スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 左辺の値に右辺の値を加算します。 AOP_SUB スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 左辺の値から右辺の値を減算します。 A OP_MUL スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 左辺の値に右辺の値を乗算します。 AOP_DIV スタック状態の変化 …,左辺,右辺 → …,計算結果 処理 左辺の値を右辺で除算します。右辺が0ならばエラーを発生します。 AOP_UMINUS - (単項) スタック状態の変化 …,右辺 → …,計算結果 処理 右辺の値の正負を反転します。 AOP_PUSHI スタック状態の変化 … → …,オペランドの値のコピー オペランド 即値 処理 オペランドの値をコピーして、スタックにPush(スタックトップに積む)します。 AOP_PUSHAT スタック状態の変化 … → …,オペランドが示す場所の値のコピー オペランド アドレス 処理 オペランドの値によって示されたアドレス(データ領域の添字)に存在するデータをコピーして、スタックにPush(スタックトップに積む)します。 AOP_POPAT スタック状態の変化 …,データ → … /* オペランドで示される位置へコピーされます。 */ オペランド [アドレス] 処理 スタックトップのデータをPopして、オペランドの値によって示されたアドレス(データ領域の添字)に存在するデータヘコピーします。 AOP_REMOVE スタック状態の変化 …,データ → … /* データは消去されます。 */ 処理 スタックトップのデータをPopして、消去します。 AOP_FCALL 関数呼び出し スタック状態の変化 …,[引数…] → [戻り値] 処理 関数呼び出しを行います。引数や戻り値の型や個数は各OP_HANDLER毎に異なります。(現バージョンでは戻り値は1個以下です。) AOP_ARRAY_PUSH スタック状態の変化 …,配列を個別に識別するID,配列の添字… → …,配列からコピーされたデータ cIペランド 添字 の個数+1 処理 配列の内容をコピーして、スタックにPushします。配列の実装には、CMachine::m_DArray(ハッシュ表)が使われています。配列を個別に識別するIDや、配列の添字をキーにして、このオブジェクト内部を検索して、対応する要素を得ています。 AOP_ARRAY_POP ポップして配列の内部にコピー スタック状態の変化 …,配列へコピーするデータ,配列を個別に識別するID,配列の添字… → … /* データは配列内にコピーされます。*/ オペランド 添字の個数+1 処理 データを配列内部へコピーします。 AOP_COMBINE スタック状態の変化 …,左辺,右辺 → …,左辺,右辺 /* この演算に対応するOP_HANDLERはありません。*/ 処理 何もしません。スタックに積み上げられた値は、後ほど関数の引数や、配列の添字として使われます。 AOP_PRINT スタック状態の変化 …,表示するデータ → … /* データは標準出力へ出力されます。*/ 処理 スタックからデータをPopし、標準出力へ書き出します。 AOP_INPUT スタック状態の変化 … → …,入力されたデータ 処理 標準入力からデータを入力して、スタックにPushします。 CMachineメンバと制御用OP_HANDLER CMachineは実行時環境を保持する他にも、プログラムの流れを制御するためのOP_HANDLERを返す機能もあります。これらのOP_HANDLERはCMachineのインプリメントファイルと同じファイルスコープの中で定義されています。 メンバ関数 ![]() 戻り値 唯一のCMachineインスタンス。 機能 CMachineのインスタンスを得ます。CMachineのコンストラクタは隠蔽されているため、CMachineのインスタンスを生成できるのは、この関数だけです。この関数は、CMachineのインスタンスが1つしか生成されないことを保証します。 ![]() 機能 翻訳が終わったプログラムを実行します。この関数は、CInterpreter::Interpret()によって既に翻訳が終了していることを前提として機能します。OP_HANDLERのエラーをチェックして、エラーがあれば、PutError()を呼び出した後、処理を終了します。 ![]() 戻り値 コード領域上の値。 機能 現在解釈中のコード領域を1つ読み進めて、そこにある値を返します。各OP_HANDLERがその処理に必要とする値をコード領域から得る場合に呼び出されます。 ![]() 引数 err ... 表示するエラー値。 機能 各OP_HANDLERから返されるエラー値を標準エラー出力に書き出します。 ![]() 戻り値 制御用OP_HANDLERのアドレス。 引数 制御用コマンドのID。 機能 idで渡されたコマンドに対応するOP_HANDLERのアドレスを返します。 ![]() 機能 プログラム終了後に、データ領域や配列領域の後始末を行います。 制御用OP_HANDLER ここでは制御用OP_HANDLERが行う処理について詳解します。スタック状態などの表記法については、抽象演算子の種類をご参照下さい。 Jump オペランド ジャンプ先の一つ前のアドレス。 機能 無条件ジャンプを行います。 Jump_by_0 オペランド ジャンプ先の一つ前のアドレス。 スタック状態の変化 …,条件値 → … 機能 スタックトップからPopした値が0の時のみジャンプを行います。 Call オペランド コール先の一つ前のアドレス。 機能 サブルーチンコールを行います。コール先の文脈で、Returnコマンドが実行され ると、コール元の直後の命令から処理が開始されます。 Return 機能 直前に実行されたCallコマンドが存在する場所の1つ次の実行コードへジャンプします。 For オペランド ループカウンタに使用する変数のアドレス。 スタック状態の変化 …,目標値,増分 → … 機能 ループカウント変数のアドレスと、目標値、増分、この命令の場所を記憶します。この情報はNextコマンドを実行する際に、解釈されます。ループカウント変数の準備と初期化を行う実行コードは、CInterpreter::GenFor()で生成されています。 Next オペランド ループカウンタに使用する変数のアドレス。 機能 ループカウンタ変数に、Forコマンドで設定された増分を加算し、目標値を超えない場合は、対応するFor文の直後へジャンプします。Forコマンドにより設定されたループカウンタ変数のアドレスと、オペランドによって示されるアドレスが異なる場合は、エラーを返します。 End 機能 プログラムの実行を停止します。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||