簡単な答えは次のとおりです。あなたは疑う余地があります。常にXで書かれた別のインタープリターか、Yから既にインタープリターを持っている他の言語へのコンパイラーが必要です。インタープリターが実行され、コンパイラーはある言語から別の言語にのみ翻訳します。システムのある時点で、インタープリターが必要になります(それがCPUであっても)。
言語Yで作成する新しいインタープリターの数に関係なく、Xで記述された最初のインタープリターを使用して後続のインタープリターを常に解釈する必要があります。これは単に通訳者の性質のために問題のようです。
正しい。何ができるやっていることから、コンパイラ書き込みであるYにX(またはあなたが通訳を持っている別の言語)を、あなたもでそれを行うことができますY。次に、あなたの実行可能なYの中に書かれたコンパイラYにYで書かれたインタプリタX(または上のYで書かれたインタプリタY上で実行されているYで書かれたインタプリタX、または上のY用に書かれたインタプリタY上で実行されているYで書かれたインタプリタをYで実行されているY書かれたインタプリタXあなたコンパイルする、または...無限)のYで書かれたインタプリタYにXを使用すると、その後にそれを実行できるように、Xのインタプリタ。そうすれば、あなたはあなたの脱却ているYの中に書かれたインタプリタXが、今は必要なXの(そうでない場合は、私たちが走っていない可能性があるので、我々は、しかし、我々は既に持っていることを知っているインタプリタをX用に書かれたインタプリタYを)、そしてあなた最初にY -to- X-コンパイラを作成する必要がありました。
ただし、逆に、ウィキペディアの通訳に関する記事では、実際にセルフホスティングの通訳について説明しています。関連する小さな抜粋を次に示します。
自己通訳とは、自身を解釈できるプログラミング言語で書かれたプログラミング言語インタープリターです。例は、BASICで書かれたBASICインタプリタです。セルフインタープリターは、セルフホスティングコンパイラに関連しています。
解釈対象の言語用のコンパイラーが存在しない場合、セルフインタープリターを作成するには、ホスト言語(別のプログラミング言語またはアセンブラー)で言語を実装する必要があります。このような最初のインタープリターを持つことにより、システムはブートストラップされ、言語自体でインタープリターの新しいバージョンを開発できます
しかし、これがどのように行われるかは、まだはっきりしていません。何であれ、ホスト言語で書かれたインタープリターの最初のバージョンを常に使用せざるを得ないようです。
正しい。ウィキペディアの記事では、言語の2番目の実装が必要であると明示的に記載されており、最初の言語を削除できるとは記載されていないことに注意してください。
さて、上記の記事は別の記事にリンクしています。この記事では、Wikipediaがセルフホスティングインタープリターの例を示しています。よく調べてみると、これらのセルフホスティングインタープリターの多くの主な「解釈」部分(特にPyPyやRubiniusなどのより一般的なもの)は、実際にはC ++やCなどの他の言語で書かれているようです。
繰り返しますが これらは本当に悪い例です。たとえば、Rubiniusを取り上げます。はい、RubiniusのRuby部分が自己ホスト型であることは事実ですが、それはコンパイラーであり、インタープリターではありません。RubyソースコードにコンパイルしてRubiniusバイトコードに変換します。インタプリタ部分のOTOHは自己ホスト型ではありません。Rubiniusバイトコードを解釈しますが、C ++で記述されています。したがって、Rubiniusを「自己ホスト型インタープリター」と呼ぶのは間違っています。自己ホスト型部分はインタープリターではなく、インタープリター部分は自己ホスト型ではありません。
PyPyは似ていますが、さらに不正確です。そもそもPythonでさえ書かれておらず、異なる言語であるRPythonで書かれています。構文的にはPythonに構文的に似ており、意味的には「拡張サブセット」ですが、実際にはJavaとほぼ同じ抽象化レベルの静的型付け言語であり、その実装はRPythonをCソースコードECMAScriptにコンパイルする複数のバックエンドを持つコンパイラーですソースコード、CILバイトコード、JVMバイトコード、またはPythonソースコード。
それで、私が上で説明したことは可能ですか?セルフホストインタープリターは元のホストから独立できますか?もしそうなら、これはどのように正確に行われますか?
いいえ、それ自体ではありません。元のインタープリターを保持するか、コンパイラーを作成して自己通訳者をコンパイルする必要があります。
Klein(Selfで記述)やMaxine(Javaで記述)などのメタ循環VM がいくつかあります。ただし、ここで「メタ循環」の定義はまだ異なっていることに注意してください。これらのVMは実行する言語で記述されていません。KleinはSelfバイトコードを実行しますが、Selfで記述され、MaxineはJVMバイトコードを実行しますがJavaで記述されます。しかし、VMのセルフ/ Javaのソースコードは、実際にセルフ/ JVMバイトコードにコンパイルして、VMで実行されるので、時間によってVMが実行されます取得し、それがある、それが実行される言語で。ふう。
また、これはSqueakVMやJikes RVMなどのVMとは異なることに注意してください。JikesはJavaで記述されており、SqueakVMはSlang(Smalltalkの静的に型付けされた構文およびセマンティックサブセットは、高レベルアセンブラとほぼ同じ抽象化レベルにあります)で記述されており、実行前に静的にネイティブコードにコンパイルされます。彼らは自分の中では走りません。あなたはできる、しかし、それらを実行する上で、トップ自身の(または他のSmalltalk VM / JVMの上)。しかし、それはこの意味で「メタ円形」ではありません。
マキシンとクライン、大藤DO自分の中を走ります。独自の実装を使用して独自のバイトコードを実行します。これは本当に驚くべきことです!VMはユーザープログラムと共に実行されるため、ユーザープログラムからVMへの呼び出しをインラインで実行できます。たとえば、ガベージコレクターまたはメモリアロケーターへの呼び出しをユーザーにインライン化できます。コード、ユーザーコードのリフレクションコールバックをVMにインライン化できます。また、実行中のプログラムを監視し、実際のワークロードとデータに応じて最適化する最新のVMが行う巧妙な最適化トリックのすべては、VMがユーザープログラムの実行中にユーザープログラムの実行中に同じトリックを自分自身に適用できます特定のワークロードを実行しています。つまり、VMはそのために非常に特化した特定のワークロードを実行する特定のプログラム。
ただし、上記の「インタープリター」という言葉の使用を避け、常に「execute」を使用していることに注意してください。さて、これらのVMはインタプリタを中心に構築されているのではなく、(JIT)コンパイラを中心に構築されています。後でMaxineに追加されたインタープリターがありましたが、常にコンパイラーが必要です。VM を別のVM(Maxineの場合はOracle HotSpotなど)の上で1 回実行する必要があります。Maxineの場合、独自のブートアップフェーズをJITコンパイルし、コンパイルされたネイティブコードをブートストラップVMイメージにシリアル化し、非常に単純なブートローダーを前に貼り付けます(Cで記述されたVMの唯一のコンポーネントですが、それは便宜上のものです) 、Javaでも可能です)。これで、Maxineを使用して自分自身を実行できます。