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
ダウンロード

6.3 インタプリタ