Supponiamo che X sia la lingua di input, Z è la lingua di output, quindi f è il compilatore, che è scritto nella lingua Y.
f = X -> Z
Dato che f è solo un programma, penso che Y possa essere qualsiasi lingua, giusto? Quindi possiamo avere compilatori f1, f2, ciascuno scritto in Y1, Y2.
f1 = f Y1
f2 = f Y2
g = Z -> M
h = g . f # We get a compiler X -> M
Prendi il compilatore cpython per esempio, X è Python, Z è il codice Python VM, Y è C.
cpython = Python -> PythonVMCode C
interpreter = PythonVMCode -> Nothing
interpreter2 = PythonVMCode -> MachineCode
I sorgenti Python sono compilati nel codice VM Python, i file .pyc, quindi interpretati dall'interprete. Sembra che sia possibile esiste un compilatore che può fare direttamente Python - > MachineCode, anche se molto difficile da implementare:
hardpython = interpreter2 . cpython
Possiamo anche scrivere un altro compilatore esegui il lavoro Python - > PythonVMCode, in un'altra lingua, dice Python stesso.
mypython = Python -> PythonVMCode Python
mypython2 = Python -> PythonVMCode Ruby
Ora, ecco l'esempio complicato PyPy. Sono solo un principiante di PyPy, correggimi se sbaglio:
PyPy doc link
Our goal is to provide a possible solution to the problem of language implementers: having to write l * o * p interpreters for l dynamic languages and p platforms with o crucial design decisions.
Possiamo pensare che l sia X, p sia Y. Esiste un programma che traduce tutti i programmi RPython in C:
rpython_compiler = RPython -> C Python
pypy = Python -> Nothing RPython
translate = compile the program pypy written in RPython using rpython_compiler
py2rpy = Python -> RPython Python
py2c = Python -> C Python
py2c = rpython_compiler . py2rpy
I programmi RPython sono proprio come le istruzioni VM, rpython_compiler è la VM.
q1. pypy è l'interprete, un programma RPython in grado di interpretare il codice Python, non c'è un linguaggio di output, quindi non possiamo considerarlo come un compilatore, giusto?
Aggiunto:
- Ho appena scoperto che anche se dopo la traduzione, pypy è ancora un interprete, solo questa volta scritto in C
- Se guardiamo in profondità nella topologia dell'interprete, credo che debba esistere un qualche tipo di compilatore, che compila i sorgenti Python in qualche AST, quindi esegue
come questo:
compiler_inside_pypy = Python -> AST_or_so
q2. Può esistere il compilatore py2rpy, che trasforma tutti i programmi Python in RPython? In quale lingua è scritto è irrilevante. Se sì, otteniamo un altro compilatore py2c. Qual è la differenza tra pypy e py2rpy in natura? Py2rpy è molto più difficile da scrivere rispetto a Pypy?
q3. ci sono alcune regole generali o teorie disponibili su questo?
Altri compilatori:
gcc_c = C -> asm? C # not sure, gimple or rtl?
g++ = C++ -> asm? C
clang = C -> LLVM_IR C++
jython = Python -> JVMCode java
ironpython = Python -> CLI C#
q4. Dato f = X - > Z, un programma P scritto in X. Quando vogliamo accelerare P, cosa possiamo fare? Possibili modi:
-
riscrivi P nell'algoritmo più efficiente
-
riscrivi f per generare meglio Z
-
se Z è interpretato, scrivi un interprete Z migliore (PyPy è qui?)
-
velocizza i programmi scritti in Z ricorsivamente
-
ottieni una macchina migliore
ps. Questa domanda non riguarda il materiale tecnico di come scrivere un compilatore, ma la fattibilità e la complessità di scrivere un certo tipo di compilatore.