Suponha que X é o idioma de entrada, Z é o idioma de saída e f é o compilador, escrito no idioma Y.
f = X -> Z
Como f é apenas um programa, acho que Y pode ser qualquer idioma, certo? Portanto, podemos ter os compiladores f1, f2, cada um escrito em Y1, Y2.
f1 = f Y1
f2 = f Y2
g = Z -> M
h = g . f # We get a compiler X -> M
Tomemos o compilador cpython, por exemplo, X é Python, Z é o código da VM Python, Y é C.
cpython = Python -> PythonVMCode C
interpreter = PythonVMCode -> Nothing
interpreter2 = PythonVMCode -> MachineCode
As fontes Python são compiladas no código da VM Python, nos arquivos .pyc, e depois interpretadas pelo intérprete. Parece que é possível que exista um compilador que possa executar diretamente o Python -> MachineCode, embora seja muito difícil de implementar:
hardpython = interpreter2 . cpython
Também podemos escrever outro compilador para o trabalho Python -> PythonVMCode, em outra linguagem, como o próprio Python.
mypython = Python -> PythonVMCode Python
mypython2 = Python -> PythonVMCode Ruby
Agora, aqui está o exemplo complicado de PyPy. Sou apenas um novato no PyPy, me corrija se estiver errado:
Doc PyPy http://doc.pypy.org/en/latest/architecture.html#pypy-the-translation-framework
Nosso objetivo é fornecer uma possível solução para o problema dos implementadores de linguagem: ter que escrever intérpretes l * o * p para l linguagens dinâmicas ep plataformas sem decisões cruciais de design.
Podemos pensar que eu sou X, p é Y. Existe um programa que traduz todos os programas RPython para 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
Os programas RPython são exatamente como as instruções da VM, rpython_compiler é a VM.
q1. pypy é o intérprete, um programa RPython que pode interpretar o código Python; não há linguagem de saída; portanto, não podemos considerá-lo um compilador, certo?
Adicionado:
- Acabei de descobrir que, mesmo após a tradução, pypy ainda é um intérprete, só que desta vez escrito em C.
- Se olharmos profundamente para o interpretador pypy, acredito que deve existir algum tipo de compilador, que compila as fontes do Python para algum AST e execute
como isso:
compiler_inside_pypy = Python -> AST_or_so
q2. O compilador py2rpy pode existir, transformando todos os programas Python em RPython? Em que idioma está escrito é irrelevante. Se sim, obtemos outro compilador py2c. Qual é a diferença entre pypy e py2rpy na natureza? Py2rpy é muito mais difícil de escrever do que pypy?
q3. Existe alguma regra ou teoria geral disponível sobre isso?
Mais compiladores:
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. Dado f = X -> Z, um programa P escrito em X. Quando queremos acelerar P, o que podemos fazer? Maneiras possíveis:
reescrever P em algoritmo mais eficiente
reescreva f para gerar Z melhor
se Z for interpretado, escreva um interpretador Z melhor (o PyPy está aqui?)
acelerar programas escritos em Z recursivamente
consiga uma máquina melhor
ps. Esta questão não é sobre os aspectos técnicos de como escrever um compilador, mas a viabilidade e complexidade de escrever um determinado tipo de compilador.