
コンピュータサイエンスにおいて、インタープリタとは、プログラミング言語またはスクリプト言語で記述された命令を、事前に機械語プログラムにコンパイルされることなく直接実行するコンピュータプログラムです。インタープリタは一般に、プログラム実行に次のいずれかの戦略を使用します。
- ソースコードを解析し、その動作を直接実行します。
- ソース コードを効率的な中間表現またはオブジェクト コードに変換し、すぐに実行します。
- コンパイラによって作成され、インタープリタの仮想マシンとマッチングされた、保存されたプリコンパイル済みバイトコード[1]を明示的に実行する。
初期のLisp プログラミング言語や、ミニコンピュータおよびマイクロコンピュータの BASIC 方言は、最初のタイプの例です。Perl、Raku、Python、MATLAB、Ruby は2 番目の例で、UCSD Pascal は3 番目のタイプの例です。 ソースプログラムは事前にコンパイルされ、マシンに依存しないコードとして保存され、実行時にリンクされ、インタープリタやコンパイラ ( JITシステムの場合) によって実行されます。 Smalltalkや、現代版のBASICやJava などの一部のシステムでは、2 つまたは 3 つのタイプを組み合わせることもできます。[2] Algol、Fortran、Cobol、C、C++など、従来はコンパイルに関連付けられていた多くの言語用に、さまざまなタイプのインタープリタも構築されています。
解釈とコンパイルはプログラミング言語を実装する 2 つの主な手段ですが、ほとんどの解釈システムはコンパイラと同様に何らかの翻訳作業も行うため、これらは相互に排他的ではありません。「解釈言語」または「コンパイル言語」という用語は、その言語の標準的な実装がそれぞれ解釈プログラムまたはコンパイラであることを意味します。高水準言語は、理想的には特定の実装に依存しない 抽象化です。
歴史
インタプリタは、1952年という早い時期に、当時のコンピュータの制限(プログラム記憶領域の不足、浮動小数点数のネイティブサポートがないなど)内でのプログラミングを容易にするために使用されていました。インタプリタは、低レベルの機械語間の翻訳にも使用され、開発中のマシン用にコードを記述し、既存のコンピュータでテストすることができました。[3]最初のインタプリタ型高水準言語はLispでした。Lispは、 IBM 704コンピュータでSteve Russellによって最初に実装されました。Russellは、 John McCarthyの論文「記号式の再帰関数とマシンによる計算、パートI」を読んで、Lispのeval関数をマシンコードで実装できることに気付きました(McCarthyは驚きました)。[4]その結果、Lispプログラムを実行する、より正確には「Lisp式を評価する」ために使用できる実用的なLispインタプリタが生まれました。
一般的な操作
通常、インタープリタは、実行可能な既知のコマンドのセットと、プログラマが実行したい順序で並べられたこれらのコマンドのリストで構成されます。各コマンド (命令とも呼ばれる)には、プログラマが変更したいデータと、データを変更する方法に関する情報が含まれています。たとえば、インタープリタはこれを変数に 5 を追加する要求として読み取って解釈する場合があります。
ADD Books, 5Books
インタプリタには、さまざまなタスクを実行するために特化したさまざまな命令がありますが、基本的な数学演算、分岐、メモリ管理のためのインタプリタ命令がよく見られるため、ほとんどのインタプリタはチューリング完全です。また、多くのインタプリタは、ガベージ コレクターやデバッガーと密接に統合されています。
コンパイラとインタープリタ

高級言語で書かれたプログラムは、何らかのインタープリタによって直接実行されるか、またはコンパイラ(およびアセンブラとリンカー)によってマシンコードに変換されてCPUで実行されます。
コンパイラ (およびアセンブラ) は一般に、コンピュータ ハードウェアで直接実行可能なマシン コードを生成しますが、多くの場合 (オプションで)オブジェクト コードと呼ばれる中間形式も生成できます。これは基本的に同じマシン固有コードですが、実行可能ブロック (またはモジュール) を識別および再配置可能にするために、名前とタグを含むシンボル テーブルが追加されています。コンパイルされたプログラムは通常、このようなオブジェクト コード モジュールのライブラリに保持されているビルディング ブロック (関数) を使用します。リンカーは、(事前に作成された) ライブラリ ファイルとアプリケーションのオブジェクト ファイルを組み合わせて、単一の実行可能ファイルを形成します。したがって、実行可能ファイルの生成に使用されるオブジェクト ファイルは、異なるタイミングで生成されることが多く、場合によっては (同じオブジェクト形式を生成できる) 異なる言語によって生成されることもあります。
低水準言語 (例:アセンブリ)で記述された単純なインタープリタには、高水準言語の関数を実装する同様のマシン コード ブロックが格納され、ルックアップ テーブル内の関数のエントリがそのコードを指すときに実行される場合があります。ただし、高水準言語で記述されたインタープリタは通常、解析ツリーを生成して走査する、中間のソフトウェア定義命令を生成して実行する、またはその両方などの別のアプローチを使用します。
したがって、コンパイラとインタープリタはどちらも、一般的にソース コード (テキスト ファイル) をトークンに変換し、解析ツリーを生成する場合と生成しない場合があり、スタック マシン、4 重コード、またはその他の手段で即時命令を生成する場合があります。基本的な違いは、(組み込みまたは個別の) リンカーを含むコンパイラ システムはスタンドアロンのマシン コードプログラムを生成するのに対し、インタープリタ システムは代わりに高レベル プログラムによって記述されたアクションを 実行することです。
したがって、コンパイラはソースコードの意味からマシンレベルへのほぼすべての変換を一度で完了できます (つまり、プログラムを変更する必要があるまで)。一方、インタープリタは、ステートメントまたは関数が実行されるたびに、この変換作業の一部を実行する必要があります。ただし、効率的なインタープリタでは、変換作業の多く (型の分析などを含む) が分離され、プログラム、モジュール、関数、またはステートメントが最初に実行されるときにのみ実行されるため、コンパイラの動作と非常に似ています。ただし、コンパイルされたプログラムは、ほとんどの場合、それでもはるかに高速に実行されます。これは、コンパイラがコードを最適化するように設計されており、これに十分な時間を与えられる可能性があるためです。これは、(多くの) 動的データ構造、チェック、または型チェックのない、より単純な高水準言語に特に当てはまります。
従来のコンパイルでは、リンカーの実行可能出力(.exe ファイルまたは .dll ファイル、またはライブラリ、図を参照) は、一般的なオペレーティング システムで実行する場合、通常、再配置可能です。これは、オブジェクト コード モジュールとよく似ていますが、この再配置は実行時、つまりプログラムが実行のためにロードされるときに動的に行われるという違いがあります。一方、小さな組み込みシステム用にコンパイルおよびリンクされたプログラムは、通常、静的に割り当てられ、多くの場合、 NOR フラッシュメモリにハード コードされます。これは、この意味では二次ストレージやオペレーティング システムがないことが多いためです。
歴史的に、ほとんどのインタープリタシステムには自己完結型のエディタが組み込まれていました。これはコンパイラ(当時はIDEと呼ばれることが多かった)でも一般的になりつつありますが、プログラマーの中には自分で選んだエディタを使い、コンパイラ、リンカー、その他のツールを手動で実行することを好む人もいます。歴史的に、コンパイラはインタープリタよりも古く、当時のハードウェアではインタープリタと解釈されたコードの両方をサポートできず、当時の典型的なバッチ環境では解釈の利点が制限されていました。[5]
開発サイクル
ソフトウェア開発サイクル中、プログラマーはソース コードを頻繁に変更します。コンパイラーを使用する場合、ソース コードに変更を加えるたびに、コンパイラーが変更されたソース ファイルを変換し、すべてのバイナリ コード ファイルをリンクするまでプログラムを実行できません。プログラムが大きいほど、待機時間は長くなります。対照的に、インタープリターを使用するプログラマーは待機時間がはるかに短くなります。インタープリターは通常、作業中のコードを中間表現に変換するだけでよい (またはまったく変換しない) ため、変更をテストするまでの時間が大幅に短縮されます。効果は、ソース コードを保存してプログラムを再ロードすると明らかになります。コンパイルされたコードは、編集、コンパイル、リンクが適切なコマンド セットを使用して適切な順序で実行する必要がある連続したプロセスであるため、一般的にデバッグが容易ではありません。このため、多くのコンパイラーには、Makefileおよびプログラムと呼ばれる実行補助機能もあります。 Makefile には、コンパイラとリンカーのコマンド ラインおよびプログラム ソース コード ファイルがリストされますが、単純なコマンド ライン メニュー入力 (例: 「Make 3」) を受け取ることもあります。この入力では、3 番目の命令グループ (セット) が選択され、その後、コンパイラとリンカーにコマンドが発行され、指定されたソース コード ファイルが提供されます。
分布
コンパイラは、ソース コードを特定のプロセッサのアーキテクチャ用のバイナリ命令に変換するため、移植性が低くなります。この変換は開発者の環境で 1 回だけ行われ、その後は同じバイナリをユーザーのマシンに配布して、それ以上の変換を行わずに実行できます。クロス コンパイラは、コードがコンパイルされたマシンとは異なるプロセッサを搭載している場合でも、ユーザーのマシン用のバイナリ コードを生成できます。
インタープリタ プログラムはソース コードとして配布できます。最終的なマシンごとに翻訳する必要があるため、時間がかかりますが、プログラムの配布はマシンのアーキテクチャに依存しません。ただし、インタープリタ ソース コードの移植性は、ターゲット マシンに適切なインタープリタが実際にインストールされているかどうかに依存します。インタープリタをソースとともに提供する必要がある場合、インタープリタ自体もインストールする必要があるものの一部であるため、全体的なインストール プロセスはモノリシックな実行可能ファイルの配布よりも複雑になります。
解釈されたコードは人間が簡単に読み取ってコピーできるという事実は、著作権の観点から懸念される可能性があります。しかし、暗号化や難読化のさまざまなシステムが存在します。バイトコードなどの中間コードの配信は難読化と同様の効果がありますが、バイトコードは逆コンパイラや逆アセンブラでデコードできます。[要出典]
効率
インタプリタの主な欠点は、インタプリタで解釈されたプログラムは通常、コンパイルされたプログラムよりも遅く実行されることです。速度の差はごくわずかの場合もあれば、大きく、桁違いになることもよくありますが、それ以上の場合もあります。一般に、インタプリタでプログラムを実行するにはコンパイルされたコードを実行するよりも時間がかかりますが、コンパイルと実行に必要な合計時間よりも解釈にかかる時間が短くなる場合があります。これは、編集-解釈-デバッグのサイクルが編集-コンパイル-実行-デバッグのサイクルよりもずっと短い場合が多いため、コードのプロトタイプ作成とテストを行うときに特に重要です。[6] [7]
コードの解釈はコンパイルされたコードの実行よりも遅くなります。これは、インタープリタがプログラム内の各ステートメントを実行するたびに分析し、目的の動作を実行する必要があるのに対し、コンパイルされたコードは、コンパイルによって決定された固定コンテキスト内で動作を実行するだけだからです。この実行時の分析は「解釈オーバーヘッド」と呼ばれます。変数へのアクセスもインタープリタでは遅くなります。これは、識別子を記憶域にマッピングする処理がコンパイル時ではなく実行時に繰り返し実行する必要があるためです。[6]
インタプリタを使用する場合の開発速度とコンパイラを使用する場合の実行速度の間には、さまざまな妥協点があります。一部のシステム (一部のLispなど) では、インタプリタされたコードとコンパイルされたコードが相互に呼び出し、変数を共有できます。つまり、ルーチンがインタプリタでテストおよびデバッグされたら、それをコンパイルして、他のルーチンの開発中に高速実行のメリットを享受できます。[要出典]多くのインタプリタは、ソース コードをそのまま実行するのではなく、よりコンパクトな内部形式に変換します。多くのBASICインタプリタは、キーワードを1バイトの トークンに置き換えます。このトークンは、ジャンプ テーブルで命令を見つけるために使用できます。 [6] PBASICインタプリタなどのいくつかのインタプリタは、バイト指向ではなくビット指向のプログラム メモリ構造を使用して、さらに高いレベルのプログラム圧縮を実現します。コマンド トークンはおそらく 5 ビットを占め、名目上は「16 ビット」の定数は3、6、10、または 18 ビットを必要とする可変長コードに格納され、アドレス オペランドには「ビット オフセット」が含まれます。多くの BASIC インタープリタは、独自のトークン化された内部表現を保存し、読み戻すことができます。
インタープリタは、コンパイラと同じ字句解析器とパーサを使用して、結果として得られる抽象構文木を解釈する場合があります。後者のデータ型定義の例と、 C式から取得された構文木のおもちゃのインタープリタがボックスに示されています。
回帰
解釈は実行の唯一の方法として使用することはできない。インタープリタ自体も解釈できるが、解釈されるコードは定義上、CPUが実行できるマシンコードと同じではないため、スタックの下部のどこかに直接実行されるプログラムが必要である。[8] [9]
バリエーション
バイトコードインタープリタ
解釈とコンパイルの間には、プログラム実行前に行われる解析の量に応じて、さまざまな可能性があります。たとえば、Emacs Lispはバイトコードにコンパイルされます。これは Lisp ソースの高度に圧縮され最適化された表現ですが、マシン コードではありません (したがって、特定のハードウェアに結び付けられていません)。この「コンパイルされた」コードは、バイトコード インタープリタ (それ自体がCで記述されています) によって解釈されます。この場合のコンパイルされたコードは、仮想マシンのマシン コードであり、ハードウェアではなく、バイトコード インタープリタに実装されています。このようなコンパイル インタープリタは、コンプリーターと呼ばれることもあります。[10] [11]バイトコード インタープリタでは、各命令は 1 バイトで始まるため、バイトコード インタープリタには最大 256 個の命令がありますが、すべてが使用されるわけではありません。バイトコードによっては、複数のバイトを必要とする場合があり、任意に複雑になる場合があります。
制御テーブルは、必ずしもコンパイル段階を通過する必要はなく、バイトコード インタープリタと同様の方法でカスタマイズされたインタープリタを介して 適切なアルゴリズム制御フローを指示します。
スレッドコードインタープリタ
スレッド コード インタプリタはバイトコード インタプリタに似ていますが、バイトの代わりにポインタを使用します。各「命令」は関数または命令シーケンスを指すワードで、パラメータが続く場合もあります。スレッド コード インタプリタは、命令をフェッチしてそれが指す関数を呼び出すループを実行するか、最初の命令をフェッチしてそこにジャンプし、すべての命令シーケンスはフェッチして次の命令にジャンプすることで終了します。バイトコードとは異なり、使用可能なメモリとアドレス空間以外に、異なる命令の数に実質的な制限はありません。スレッド コードの典型的な例は、Open Firmwareシステムで使用されるForthコードです。ソース言語は「F コード」(バイトコード) にコンパイルされ、仮想マシンによって解釈されます。[引用が必要]
抽象構文木インタープリタ
解釈とコンパイルの間には、ソースコードを最適化された抽象構文木 (AST) に変換し、この木構造に従ってプログラムを実行するか、それを使用してジャストインタイムでネイティブコードを生成するという別のアプローチもあります。[12]このアプローチでは、各文を解析する必要があるのは 1 回だけです。バイトコードに対する利点として、AST はグローバルなプログラム構造と文間の関係 (バイトコード表現では失われます) を維持し、圧縮するとよりコンパクトな表現を提供します。[13]そのため、AST の使用は、バイトコードよりもジャストインタイムコンパイラのより優れた中間形式として提案されています。また、これにより、システムは実行時に優れた分析を実行できます。
しかし、インタープリタにとって、ASTはバイトコードインタープリタよりもオーバーヘッドが大きくなります。これは、構文に関連するノードが役に立たないこと、表現が連続的でないこと(より多くのポインタのトラバースが必要)、ツリーを訪問するオーバーヘッドなどが原因です。[14]
ジャストインタイムコンパイル
インタープリタ、バイトコード インタープリタ、コンパイルの区別をさらに曖昧にするのが、ジャストインタイム (JIT) コンパイルです。これは、中間表現を実行時にネイティブマシン コードにコンパイルする手法です。これにより、ネイティブ コードの実行効率が向上しますが、起動時間が長くなり、バイトコードまたは AST が最初にコンパイルされるときにメモリ使用量が増加します。公開された最も古い JIT コンパイラは、一般に、1960 年にJohn McCarthyがLISPで行った作業に起因します。 [15]適応最適化は、インタープリタが実行中のプログラムをプロファイルし、最も頻繁に実行される部分をネイティブ コードにコンパイルする補完的な手法です。後者の手法は数十年前から存在し、1980 年代にSmalltalkなどの言語で登場しました。 [16]
ジャストインタイムコンパイルは近年、言語実装者の間で主流の注目を集めており、Java、.NET Framework、最新のJavaScript実装のほとんど、およびMatlabには現在 JIT コンパイラが含まれています。[要出典]
テンプレートインタープリター
コンパイラとインタープリタの区別をさらに曖昧にしているのは、テンプレート インタープリタと呼ばれる特別なインタープリタ設計です。ソフトウェア スタックまたはツリー ウォークで動作しながら、考えられるすべてのバイトコードを含む大きな switch ステートメントによってコードの実行を実装するのではなく、テンプレート インタープリタは、ホスト ハードウェア上でキー値のペア (または、より効率的な設計では、ネイティブ命令への直接アドレス) として実行できる対応するネイティブ マシン命令に直接マップされたバイトコード (または任意の効率的な中間表現) の大きな配列を維持します。[17] [18]これは「テンプレート」と呼ばれます。特定のコード セグメントが実行されると、インタープリタはテンプレート内のオペコード マッピングをロードまたはジャンプし、ハードウェア上で直接実行します。[19] [20]テンプレートインタープリタは、その設計上、従来のインタープリタというよりジャストインタイムコンパイラに非常によく似ていますが、コードセグメント全体から最適化されたCPU実行可能命令のシーケンスを作成するのではなく、一度に1つのオペコードずつ言語のコードをネイティブ呼び出しに変換するだけなので、技術的にはJITではありません。インタープリタは、呼び出しを直接実装するのではなく、ハードウェアに直接渡すだけのシンプルな設計のため、バイトコードインタープリタを含む他のすべてのタイプよりもはるかに高速で、ある程度バグが発生しにくいですが、プラットフォームに依存しない仮想マシン/スタックではなく、複数の異なるアーキテクチャへの変換をサポートする必要があるため、トレードオフを維持するのがより困難です。現在までに、広く知られている言語のテンプレートインタープリタ実装は、Javaの公式リファレンス実装であるSun HotSpot Java仮想マシン内のインタープリタ、[17]と、Google V8 JavaScript実行エンジンのIgnitionインタープリタのみです。
自己通訳者
自己インタープリタは、自分自身を解釈できるプログラミング言語で書かれたプログラミング言語インタープリタです。例としては、 BASIC で書かれたBASICインタープリタがあります。自己インタープリタは、自己ホスティング コンパイラに関連しています。
解釈する言語用のコンパイラが存在しない場合、自己インタープリタを作成するには、ホスト言語 (別のプログラミング言語またはアセンブラ) で言語を実装する必要があります。このような最初のインタープリタがあることで、システムがブートストラップされ、インタープリタの新しいバージョンを言語自体で開発できます。ドナルド・クヌースは、この方法で、事実上の標準であるTeX組版システムの言語WEB用の TANGLE インタープリタを開発しました。
コンピュータ言語の定義は、通常、抽象マシンに関連して(いわゆる操作的意味論)、または数学関数として(表示的意味論)行われます。言語は、ホスト言語の意味論が与えられたインタープリタによって定義されることもあります。自己インタープリタによる言語の定義は根拠が十分ではありません(言語を定義できません)が、自己インタープリタは言語の表現力と優雅さについて読者に伝えます。また、インタープリタはソース コードを解釈することができ、これは反射的解釈への第一歩です。
自己インタープリタの実装における重要な設計上の側面は、インタープリタ言語の機能がインタープリタのホスト言語の同じ機能を使用して実装されているかどうかです。例としては、Lispのような言語のクロージャがインタープリタ言語のクロージャを使用して実装されているか、または環境を明示的に格納するデータ構造を使用して「手動で」実装されているかが挙げられます。ホスト言語で同じ機能によって実装されている機能が多いほど、インタープリタのプログラマーが制御できる範囲は狭くなります。たとえば、算術演算がホスト言語の対応する演算に委任されている場合、数値オーバーフローを処理するための異なる動作は実現できません。
LispやPrologなどの言語には、優れた自己インタープリタがあります。[21]自己インタープリタ(特にリフレクションインタープリタ)に関する研究は、Lispの方言であるプログラミング言語Schemeで多く行われてきました。しかし、一般的にチューリング完全な言語であれば、独自のインタープリタを書くことができます。Lispはそのような言語です。Lispプログラムはシンボルと他のリストのリストだからです。XSLTはそのような言語です。XSLTプログラムはXMLで書かれているからです。メタプログラミングのサブドメインは、ドメイン固有言語(DSL)の記述です。
クライブ・ギフォードは[22]自己インタープリタの品質の尺度(固有比)を導入した。これは、Nが無限大に近づくにつれて、 N個の自己インタープリタのスタックを実行するのに費やされるコンピュータ時間とN −1個の自己インタープリタのスタックを実行するのに費やされる時間との間の比率の限界である。この値は実行されるプログラムに依存しない。
『 Structure and Interpretation of Computer Programs』という本では、 Scheme とその方言のメタ循環解釈の例が紹介されています。自己インタープリタを持つ言語の他の例としては、ForthやPascalがあります。
マイクロコード
マイクロコードは、コンピュータのハードウェアとアーキテクチャレベルの間にインタープリターを配置する非常に一般的に使用されている技術です。[23]そのため、マイクロコードは、多くのデジタル処理要素で高レベルのマシンコード命令または内部ステートマシンシーケンスを実装するハードウェアレベルの命令のレイヤーです。マイクロコードは、汎用中央処理装置だけでなく、マイクロコントローラ、デジタル信号プロセッサ、チャネルコントローラ、ディスクコントローラ、ネットワークインターフェイスコントローラ、ネットワークプロセッサ、グラフィックス処理装置などのより特殊なプロセッサやその他のハードウェアでも使用されます。
マイクロコードは通常、特殊な高速メモリに常駐し、マシン命令、ステート マシンデータ、またはその他の入力を詳細な回路レベルの操作のシーケンスに変換します。マイクロコードは、マシン命令を基盤となる電子機器から分離するため、命令をより自由に設計および変更できます。また、複雑なマルチステップ命令の構築を容易にし、コンピュータ回路の複雑さを軽減します。マイクロコードの記述は、マイクロプログラミングと呼ばれることが多く、特定のプロセッサ実装のマイクロコードはマイクロプログラムと呼ばれることもあります。
より広範なマイクロコーディングにより、小さくシンプルなマイクロアーキテクチャで、より広いワード長、より多くの実行ユニットなどを備えたより強力なアーキテクチャをエミュレートできます。これは、プロセッサ ファミリ内の異なる製品間でソフトウェアの互換性を実現する比較的簡単な方法です。
コンピュータプロセッサ
マイクロコーディングされていないコンピュータ プロセッサ自体も、マシン コード命令を解析して即座に実行するシステムを作成するためにVHDLなどの汎用ハードウェア記述言語で記述された解析即時実行インタープリタであると考えることができます。
通訳者のパフォーマンスを理解する
Java、Perl、Tcl などで書かれたインタープリタは、バイナリ エミュレーションやインターネット アプリケーションなど、さまざまな計算タスクに必要不可欠なものとなっています。インタープリタのパフォーマンスは、特にハードウェア リソースが限られたシステムでは、適応性に優れているにもかかわらず依然として懸念事項となっています。高度なインストルメンテーションおよびトレース アプローチでは、MIPS 命令セットや Tcl、Perl、Java などのプログラミング言語に合わせてカスタマイズされたインタープリタを評価することで、インタープリタの実装や実行時のプロセッサ リソース使用率に関する洞察が得られます。パフォーマンス特性は、コンパイルされたコードとの比較でわかるように、インタープリタの複雑さによって左右されます。インタープリタのパフォーマンスは、解釈される特定のアプリケーションよりも、インタープリタのニュアンスやリソース要件に大きく依存していることは明らかです。
アプリケーション
- インタプリタは、コマンド言語やグルー言語を実行するために頻繁に使用されます。これは、コマンド言語で実行される各演算子が、通常、エディタやコンパイラなどの複雑なルーチンの呼び出しとなるためです。[要出典]
- 自己修正コードは、インタープリタ型言語で簡単に実装できます。これは、Lisp と人工知能研究におけるインタープリタの起源に関連しています。[引用が必要]
- 仮想化。ハードウェア アーキテクチャ向けのマシン コードは、仮想マシンを使用して実行できます。これは、対象のアーキテクチャが利用できない場合や、複数のコピーを実行する場合によく使用されます。
- サンドボックス: サンドボックスの種類によっては、オペレーティング システムの保護に依存しますが、インタープリタや仮想マシンがよく使用されます。実際のハードウェア アーキテクチャと、当初意図されたハードウェア アーキテクチャは同じである場合も、そうでない場合もあります。これは無意味に思えるかもしれませんが、サンドボックスは、処理中のソース コードのすべての命令を実際に実行する必要はありません。特に、サンドボックスは、動作しているセキュリティ制約に違反するコードの実行を拒否できます。 [引用が必要]
- 時代遅れで入手不可能なハードウェア用に作成されたコンピュータ ソフトウェアを、より現代的な機器で実行するためのエミュレーター。
参照
参考文献
- ^ この意味では、CPU はマシン命令のインタープリターでもあります。
- ^ただし、この方式 (戦略 2 と 3 を組み合わせたもの) は、たとえば ABC 80の効率的な BASIC インタープリタなど、1970 年代にすでに特定の BASIC インタープリタを実装するために使用されていました。
- ^ Bennett, JM; Prinz, DG; Woods, ML (1952). 「解釈サブルーチン」。ACM National Conference Proceedings、トロント。
- ^ ポール・グラハムがHackers & Paintersの185 ページで報告している内容によると、マッカーシーは次のように語っています。「スティーブ・ラッセルが、このevalをプログラムしてみないか、と言ったので、私は、おいおい、理論と実践を混同しているじゃないか、このeval は読むためのもので、計算するためのものではない、と言いました。しかし、彼はそれを実行しました。つまり、私の論文のeval をIBM 704マシン コードにコンパイルしてバグを修正し、これを Lisp インタープリタとして宣伝したのです。確かに、それは Lisp インタープリタでした。つまり、その時点で Lisp は基本的に今日の形になっていました...」
- ^ 「なぜ最初のコンパイラは最初のインタープリタより先に書かれたのか?」Ars Technica 2014 年 11 月 8 日 。2014年11 月 9 日閲覧。
- ^ abcこの記事は、2008 年 11 月 1 日より前に Free On-line Dictionary of Computingの Interpreter から取得した資料に基づいており、 GFDLバージョン 1.3 以降 の「再ライセンス」条件に基づいて組み込まれています。
- ^ 「コンパイラとインタープリタ:説明と違い」。IONOSデジタルガイド。 2022年9月16日閲覧。
- ^ セオドア・H・ローマー、デニス・リー、ジェフリー・M・ヴォルカー、アレック・ウォルマン、ウェイン・A・ウォン、ジャン=ルー・ベアー、ブライアン・N・バーシャッド、ヘンリー・M・レヴィ『通訳者の構造とパフォーマンス』
- ^ Terence Parr、Johannes Luber、「コンパイラとインタープリタの違い」、2014 年 1 月 6 日にWayback Machineにアーカイブ
- ^ クラウス、キューネル (1987) [1986]. 「4. クラインコンピュータ - 固有シャフトとモーグリヒカイテン」 [4.マイクロコンピュータ - 特性と可能性]。ライナーのエルレカンフにて。メンク、ハンス=ヨアヒム(編)。Mikroelektronik in der Amapraxis [実用的なアマチュアのためのマイクロエレクトロニクス] (ドイツ語) (第 3 版)。ベルリン: Militärverlag der Deutschen Demokratischen Republik 、ライプツィヒ。 p. 222.ISBN 3-327-00357-2. 7469332.
- ^ ハイン、R. (1984)。 「Basic-Compreter für U880」 [U880 (Z80) 用 BASIC コンプリッター]。radio-fernsehn-elektronik (ドイツ語)。1984 (3): 150–152。
- ^ AST 中間表現、Lambda the Ultimate フォーラム
- ^ Kistler, Thomas; Franz, Michael (1999 年 2 月). 「Java バイトコードのツリーベースの代替手段」(PDF) . International Journal of Parallel Programming . 27 (1): 21–33. CiteSeerX 10.1.1.87.2257 . doi :10.1023/A:1018740018601. ISSN 0885-7458. S2CID 14330985 . 2020 年 12 月 20 日閲覧。
- ^ Surfin' Safari - ブログ アーカイブ » SquirrelFish の発表。Webkit.org (2008-06-02)。2013-08-10 に取得。
- ^ Aycock 2003、2. JIT コンパイル手法、2.1 Genesis、p. 98。
- ^ L. Deutsch、A. Schiffman、「Smalltalk-80 システムの効率的な実装」、第 11 回 POPL シンポジウムの議事録、1984 年。
- ^ ab "openjdk/jdk". GitHub . 2021年11月18日.
- ^ 「HotSpot ランタイムの概要」。Openjdk.java.net 。2022 年 8 月 6 日閲覧。
- ^ 「JVM の謎を解明: JVM バリアント、Cppinterpreter、TemplateInterpreter」。metebalci.com。
- ^ 「JVM テンプレートインタープリター」。ProgrammerSought。
- ^ Bondorf, Anders. 「Logimix: Prolog 用の自己適用可能な部分評価器」 Logic Program Synthesis and Transformation. Springer、ロンドン、1993 年、214-227 ページ。
- ^ ギフォード、クライヴ。「自己解釈者の固有比」。Blogger 。 2019年11月10日閲覧。
- ^ ケント、アレン、ウィリアムズ、ジェームズ G. (1993 年 4 月 5 日)。コンピュータサイエンスとテクノロジーの百科事典: 第 28 巻 - 補足 13。ニューヨーク: マルセル デッカー社。ISBN 0-8247-2281-7. 2016年1月17日閲覧。
出典
- Aycock, J. ( 2003 年 6 月)。「ジャストインタイムの簡単な歴史」。ACMコンピューティング調査。35 (2): 97–113。CiteSeerX 10.1.1.97.3985。doi : 10.1145 /857076.857077。S2CID 15345671 。
外部リンク
- コロンビア大学の IBM カード インタープリタ ページ
- 実用的な「完全関数型プログラミング」の理論的基礎(特に第7章)インタプリタとは何かを形式化する問題に取り組む博士論文
- インタープリターとコンパイラーの主な概念上の違いを説明する短いアニメーション。2022 年 5 月 9 日に ghostarchive.org にアーカイブされました。
