6.3 インタプリタ (1)インタプリタ(interpreter)とは ①解釈実行系、直接実行系、通訳系等と呼ばれる。 ②原則的には原始プログラムとデータを入力して結果を 出力。 ③中間言語を出力して中間言語を解釈実行する方法もあ る。 ④仮想的な機械語を設定し、これを解釈実行するタイプ もある(これをエミュレータということもある)。 ただし、最後の例は、マクロ定義と組み合わせることで コンパイラとなりうる。 (2)スタックマシンエミュレータの例 初期化 private void Eval_Initialize() { ptrEvalStack=0; ptrNameTable=0; ptrProgStack=0; } トップレベルのみの概要(1) private void Eval() { NameData P1,P2; int i=0; pushEvalStack(new NameData("*Function*")); while(i<numStatement) { nextIP =i+1; if (AllStatement[i].operation=="end") { MessageBox.Show(“プログラムの終了です。カウンタ=” + i.ToString()); break; } switch (AllStatement[i].operation) { case "+" :Eval_add();break; case "-" :Eval_sub();break; case "%" :Eval_mod();break; トップレベルのみの概要(2) case case case case case case case case case case case case case case case case case case "*" "mod" "/" "^" "=" "++" "--" "++$" "--$" "-$" "+$" "+=" "-=" "*=" "/=" "==" "!=" ">" :Eval_mult();break; :Eval_mod();break; :Eval_dev();break; :Eval_exp();break; :Eval_set();break; :Eval_PPset();break; :Eval_MMset();break; :Eval_BeforPPset();break; :Eval_BeforMMset();break; :Eval_minus();break; :Eval_plus();break; :Eval_AsignPset();break; :Eval_AsignMset();break; :Eval_AsignMultset();break; :Eval_AsignDivset();break; :Eval_equal();break; :Eval_not_equal();break; :Eval_greater_than();break; トップレベルのみの概要(3) case case case case case case case case case case case case case case case ">" ">=" "<" "<=" "||" "&&" "%%" "!" "ArgEnd" "Func" :Eval_greater_than();break; :Eval_greater_than_equal();break; :Eval_less_than();break; :Eval_less_than_equal();break; :Eval_or();break; :Eval_and();break; :Eval_exclusive_or();break; :Eval_not();break; :Eval_Arg();break; :Eval_func(AllStatement[i].str); break; "*dimStart" :Eval_dimStart(AllStatement[i].str); break; "dim" :Eval_dim();break; "*PStart*" :Eval_PStart();break; "*Parm*" :Eval_Param(AllStatement[i].str); break; "return" :Eval_return();break; トップレベルのみの概要(4) case "StNo" :StatementNo=int.Parse(AllStatement[i].str); ptrEvalStack=0;break; case "goto" :P1=Eval(popEvalStack()); nextIP=(int)P1.Val; break; case "then" :P2=Eval(popEvalStack()); P1=Eval(popEvalStack()); if(P1.Type=="Number" && P2.Type=="Number" ) { if(P1.Val ==0) nextIP=(int)P2.Val; } else MessageBox.Show("評価エラーです"); break; default :pushEvalStack(AllStatement[i]);break; } i=nextIP; } } (3)仮想マシンエミュレータ ①命令取出(命令フェッチ) 実行アドレス(注)の命令を取り出してオペランドに分離する。 ②次のアドレス計算 次の実行アドレスを設定。なお、ジャンプ命令は次の実行アドレ スを変更することで実現される。 ③命令実行 命令の実行。 ④命令実行後の状態フラグ設定 算術演算等により演算結果の状態フラグを設定する。この状態フ ラグより、JP, JZ, JM でジャンプするかどうかを判定する。 (注)実行アドレスは、命令カウンタ(instruction counter)、プロ グラムカウンタ(program counter)とも呼ばれる。 以下VB6による例 初期化 Private Sub 初期化() SVC_Call = 0 ExecAddress = 0 End Sub 1命令の実行 Private Sub Command2_Click() 命令取出 アドレス計算 命令実行 If SVC_Flag Then If SVC_Call = 0 Then CRLF = Chr(13) & Chr(10) Text3.Text = Right(Text3.Text, 5000) & CRLF & _ "プログラムの終了です." ExecAddress = 0 命令表示 End If End If End Sub 命令取出し Private Sub 命令取出() A = MCode(ExecAddress): MPart(0) = A \ &H100: A2 = A Mod &H100 If MPart(0) >= &H80 Then MPart(1) = A2 \ &H10: MPart(2) = A2 Mod &H10 MPart(3) = MCode(ExecAddress + 1) ExecAddress = ExecAddress + 2 ElseIf MPart(0) = &H50 Then MPart(1) = A2 \ &H10: MPart(2) = A2 Mod &H10 ExecAddress = ExecAddress + 1 Else MPart(1) = 0: MPart(2) = 0: MPart(3) = A2 ExecAddress = ExecAddress + 1 End If End Sub アドレス計算 Private Sub アドレス計算() If MPart(0) >= &H80 Then If MPart(2) = 0 Then EffectAddress = MPart(3) Else ID = MPart(2) EffectAddress = Register(ID) + MPart(3) End If Else EffectAddress = MPart(3) End If End Sub 命令実行直後の状態フラグ設定 Private Sub 状態フラグ設定(Rno) Status(0) = 0: Status(1) = 0: Status(2) = 0 If Register(Rno) > 0 Then Status(0) = 1 ElseIf Register(Rno) = 0 Then Status(1) = 1 Else Status(2) = 1 End If End Sub 命令実行(その1) Private Sub 命令実行() SVC_Flag = False Select Case MPart(0) Case &HA0: Register(MPart(1)) = MCode(EffectAddress) 'Load 状態フラグ設定 MPart(1) Case &HA2: MCode(EffectAddress) = Register(MPart(1)) 'Store 状態フラグ設定 MPart(1) Case &HB0: Register(MPart(1)) = EffectAddress 'LI (Load Imediate) 状態フラグ設定 MPart(1) Case &H81: Register(MPart(1)) = Register(MPart(1)) + _ MCode(EffectAddress) 'ADD 状態フラグ設定 MPart(1) Case &H82: Register(MPart(1)) = Register(MPart(1)) - _ MCode(EffectAddress) 'SUB 状態フラグ設定 MPart(1) Case &H83: Register(MPart(1)) = Register(MPart(1)) * _ MCode(EffectAddress) 'MULT 状態フラグ設定 MPart(1) 命令実行(その2) Case &H84: Register(MPart(1)) = Register(MPart(1)) \ _ MCode(EffectAddress) 'DIV 状態フラグ設定 MPart(1) ・ ・ (中略) ・ Case &HE0: ExecAddress = EffectAddress 'JMP Case &HE1: If Status(0) <> 0 Then ExecAddress = EffectAddress 'JP (Jump Plus) Case &HE2: If Status(1) <> 0 Then ExecAddress = EffectAddress 'JZ (Jump Zero) Case &HE3: If Status(2) <> 0 Then ExecAddress = EffectAddress 'JM (Jump Minus) ・ ・ ・ (中略) 命令実行(その3) ・ ・ ・ (中略) Case &H61: Register(MPart(1)) = Val(InputBox("データ入力")) Case &H1: SVC_Call = MPart(1): SVC_Flag = True 'SVC_Call End Select End Sub
© Copyright 2024 ExpyDoc