インタプリタ
インタプリタ(英: interpreter)とは、プログラミング言語で書かれたソースコードないし中間表現を逐次解釈しながら実行するプログラムのこと。「インタープリタ」「インタープリター」などと表記することもある。
インタプリタは、およそ次のいずれかの動作をするプログラムである。
ソースコードを直接解釈実行する。
ソースコードを何らかの効率的な中間的なコード(中間表現)に、最初に全て変換して、あるいは、逐次変換しながら、解釈実行する。
何らかのコンパイラが生成し出力した、何らかの効率的な(マシンに依存しない、あるいは、マシン依存の)中間表現を解釈実行する。
このように程度の差はあるが、ソフトウェアがソフトウェアを実行するという形になる。
いずれにしても、「インタプリタ言語」などという分類は本来は存在しない。単にそれぞれの言語の代表的な処理系の実装がインタプリタであったというだけで、理論上はどの言語であってもインタプリタとコンパイラのどちらでも作ることができる。
プログラミング言語処理系の実装には、インタプリタとコンパイラの2つがある、とされてきた。インタプリタは実行を行うが、コンパイラは実行を行わない、という差がある。
インタプリタは、インタプリタが提供する言語のプログラム文を1文ずつ、インタプリタを実装した言語の機能を呼び出していく(単純な)方式が一般的であった。コマンドラインインタプリタではこれに加えて、別のプログラムに処理を委ねて一つの機能を実現する。
この時代のインタプリタの長所と欠点については、およそ次のような解説がされることが一般的であった。
(長所)プログラムを作成している途中でも、とりあえず書かれた箇所まで実行させることができ、プログラマの期待通りの動作をしている場合も、期待通りの動作をしていない場合も、早期にそれを確認・発見し、そして修正後すばやく実行、再確認できる。
(短所)実行速度が遅い。(ループ(=繰り返し)の箇所などでは)1度構文解釈した文でも、毎回(あらためて、最初から)解釈と実行を行うので、コンパイラ方式に比べて実行速度が遅くなる。
それ自体はインタプリタの手法とも言えるしコンパイラの手法とも言える。そのどちらと言うよりも、中間表現の1種類というべきかもしれない。仮想関数テーブルやテーブルジャンプによるフロー制御に似ていなくもない。
スレッデッドコードは、呼び出されるべきサブルーチンのアドレスのみが順番に羅列されたものである。「直接スレッディング」の場合は、そのアドレスが指す先は機械語のサブルーチンである。他にもいくつかのバリエーションがある。「サブルーチン・スレッディング」は最も違うタイプのバリエーションで、アドレスのみではなく、機械語のCALL命令として羅列するので、ハードウェアのプロセッサで直接実行できる。これは実行のオーバーヘッドは極小だが、メモリ効率は悪い。サブルーチン・スレッディング以外のスレッデッドコードは、きわめて単純なインタプリタで実行できる。Forthでは「内部インタプリタ」と呼んでいる(これは、Forth言語自体を実装しているインタプリタである「外部インタプリタ」と対になっている)。
他のインタプリタ言語に変換して、ターゲット言語のインタプリタ上で実行する方式。例えば CoffeeScript は JavaScript に変換されて、JavaScript インタプリタ上で実行される。
命令ボディ(英: instruction body、命令本体とも)は仮想命令をホスト言語でエミュレートするコードである。命令ボディがホストマシンで実行されることで仮想命令が事実上実行される。すなわち命令ボディは仮想命令の実装である。例えば二項和仮想命令 ADD2 に対応してC言語で書かれた push(pop() + pop()) は命令ボディである。
ソースコードを実行可能な形にするには、まず、ソースコードを構文木に変換する必要がある。構文木のまま、インタプリタ型の処理系で実行する処理系もあるが、構文木をさらに、中間コード(バイトコードなど)などの中間表現に変換してから実行する物もある。中間コードをバイトコードと呼んでいる処理系ではそのインタプリタをバイトコードインタプリタと呼ぶ。Java や .NET Framework のように、中間コードの仕様を公開しファイルに書き出すものもあるし、仕様は公開せず処理系内部だけで使用するものもある。動的コンパイルを使っているインタプリタは、内部で実機の機械語に変換し実行する。
インタプリタとコンパイラの間には様々な中間的実装が存在し、それぞれにプログラム実行前に行われる解析の度合いが異なる。