私はこれをまっすぐにしていますか? PyPyインタープリターは実際にそれ自体を解釈してからそれ自体を変換しますか?
だからここに私の現在の理解があります:
これが本当なら、これは私が今まで見た中で最も心を曲げるものの1つです。
PyPyの翻訳プロセスは、実際には、思ったよりも概念的に再帰的ではありません。
本当にすべてがPythonプログラムであり、Python関数/クラス/その他のオブジェクトを処理します(notPythonソースコード)、Cコードを出力します。しかしもちろん、anyPythonオブジェクトだけを処理するわけではありません。 RPythonで翻訳対象のコードを記述した場合に得られる特定のフォームのみを処理できます。
翻訳ツールチェーンはPythonプログラムであるため、PyPyのPythonインタープリターが含まれているpythonインタープリターの上で実行できます。これは特別なことではありません。
RPythonオブジェクトを変換するため、RPythonで記述されたPyPyのpythonインタープリターを変換するために使用できます。
ただし、翻訳フレームワーク自体では実行できません。つまり、notRPythonです。 PyPyのpythonインタープリター自体だけがRPythonです。
RPythonコードもPythonコード(ただし、その逆ではない)であり、RPythonがソースファイルに「実際に」存在することはなく、動作しているPython他の非RPythonコードを必ず含むプロセス(たとえば、トランスレータはalreadyが定義およびインポートされている関数を操作するため、「pure-RPython」のインポートや関数定義はありません) 。
翻訳ツールチェーンはインメモリPythonコードオブジェクトで動作することに注意してください。 Pythonの実行モデルとは、これらのPythonコードが実行されるまで存在しないを意味します。翻訳プロセスを非常に単純化すると、翻訳プロセスの開始は次のようになると想像できます。
from my_interpreter import main
from pypy import translate
translate(main)
ご存知のように、main
をインポートするだけで、他のすべてのモジュールmy_interpreter
インポートを含む多数のPythonコードが実行されます。しかし、変換プロセスは関数オブジェクトmain
の分析を開始します。 main
を作成するために実行されたコードが表示されることはありません。
これを考える1つの方法は、「RPythonでのプログラミング」は「RPythonプログラムを生成し、それを翻訳プロセスに供給するPythonプログラムを書く」ことを意味するということです。これは比較的理解しやすく、他の多くのコンパイラが機能する方法に似ています(たとえば、Cでのプログラミングを考える1つの方法は、基本的にCプログラムを生成するCプリプロセッサプログラムを作成し、それをCコンパイラ)。
3つのコンポーネントすべて(RPythonプログラム、RPythonプログラム、および変換プロセスを生成するPythonプログラム)がにロードされるため、PyPyの場合にのみ混乱が生じます。同じPythonインタプリタ。これは、いくつかの引数で呼び出されたときにRPythonであり、他の引数では呼び出されない関数、RPythonプログラムの生成の一部として変換フレームワークからヘルパー関数を呼び出すこと、および他の多くの奇妙なことを行うことは十分に可能であることを意味しますしたがって、状況はかなりぼやけてしまい、ソース行を「翻訳対象のRPython」、「PythonがRPythonプログラムを生成する」、「RPythonプログラムを翻訳フレームワークに引き渡す」にきれいに分割できるとは限りません。
CPythonの上で実行されているPyPyインタープリターが実行され、それ自体を部分的に解釈します。
ここで触れていると思うのは、PyPyが翻訳中に フローオブジェクトスペース を使用して、抽象的な解釈を行っていることです。これでさえ、最初のようにクレイジーで心が折れることはありません。 PyPyのこの部分についてはあまり詳しくありませんが、理解すると次のようになります。
PyPyは、Pythonインタープリターのすべての操作を、「オブジェクトスペース」に委任することで実装します。このオブジェクトスペースには、すべての基本的な組み込み操作の実装が含まれています。ただし、さまざまなオブジェクトスペースを接続してさまざまな効果を得ることができ、それらが同じ「オブジェクトスペース」インターフェースを実装している限り、インタープリターはPythonコードを「実行」することができます。
PyPy変換ツールチェーンが処理するRPythonコードオブジェクトは、インタープリターで実行できるPythonコードです。そのため、PyPyは、フローオブジェクトスペースをプラグインすることにより、Pythonインタープリターの一部を変換ツールチェーンの一部として再利用します。このオブジェクトスペースでコードを「実行」すると、インタープリターは実際にはコードの操作を実行せず、代わりにフローグラフを生成します。これは、他の多くのコンパイラーで使用される一種の中間表現に類似しています。これは、機械で操作できる単純なコードの表現であり、さらに処理されます。これが、通常の(R)Pythonコードオブジェクトが残りの変換プロセスの入力になる方法です。
翻訳プロセスで翻訳される通常のものはPyPyのPythonインタープリターであるため、フローオブジェクトスペースで実際に「自分自身を解釈」します。しかし、それが実際に意味することは、処理を行うものを含め、Python関数を処理するPythonプログラムがあるということです。それ自体は、デコレータをそれ自体に適用したり、ラッパークラスにそれ自体のインスタンスをラップさせたり(またはクラス自体をラップさせたり)するよりも簡単です。
ええと、それは少し乱暴になりました。とにかくそれが役に立てば幸いです。そして、不正確なことを言っていないことを願っています。あれば訂正してください。
免責事項:私はPyPyの専門家ではありません。特に、RPythonの翻訳の詳細が理解できません。以前に読んだことだけを引用しています。 RPythonの翻訳mayの動作に関するより具体的な投稿については、こちら answer をご覧ください。
答えは、はい、可能です(ただし、CPythonを使用して最初にコンパイルされた後のみ)。
長い説明:
最初は心が曲がり、逆説的であるように見えますが、一度理解すれば簡単です。 Wikipedia で答えを確認してください。
プログラム開発におけるブートストラップは1950年代に始まり、各プログラムは紙に10進コードまたは2進コードでビットごと(1および0)に構築されました。リンカ。小さなアセンブラプログラムが新しいコンピュータ(たとえば、IBM 650)用に手動でコード化され、いくつかの命令が2進または10進コードに変換されました:A1。この単純なアセンブラープログラムは、定義されたばかりのアセンブリ言語で書き直されましたが、より複雑な操作コードでいくつかの追加のニーモニックを使用できるようにする拡張機能が追加されています。
このプロセスは、ソフトウェアブートストラップと呼ばれます。基本的には、1つのツール(C++コンパイラなど)を、既に作成されている下位言語で(ある時点ではすべてバイナリからコーディングする必要がありました)ビルドします(ASMなど)。 C++が存在するようになったので、C++でC++コンパイラーをコーディングし、ASM C++コンパイラーを使用して新しいコンパイラーをコンパイルできます。新しいコンパイラーをコンパイルしたら、それを使用してそれ自体をコンパイルできます。
したがって、基本的に、最初のコンピューターツールを手作業でコーディングし、そのインタープリターを使用して別の少し優れたツールを作成し、そのインタープリターを使用してより優れたツールを作成します。 :)
別の興味深いケースは、--- CoffeeScriptで記述された CoffeeScript 言語です。 (ただし、この使用例では、外部インタープリター、つまりNode.jsを使用する必要があります)
CPythonの上で実行されているPyPyインタープリターは、それ自体を部分的に解釈するために実行されます。その時点で、制御をRPythonの半分に渡し、変換を実行しますか?
コンパイル済みのPyPyインタープリターを使用してPyPyをコンパイルするか、代わりにCPythonを使用してコンパイルすることができます。ただし、PyPyは現在JITを備えているため、CPythonではなくそれ自体を使用してPyPyをコンパイルする方が速くなります。 ( PyPyはCPythonより高速になりました ほとんどの場合)