Переводит ли PyPy?

Я получаю это прямо? Интерпретатор PyPy фактически интерпретирует себя и затем переводит себя?

Итак, мое нынешнее понимание:

  • Инструментальная цепочка RPython включает в себя частичное выполнение программы, которая должна быть переведена, чтобы получить своего рода предварительно обработанную версию для аннотации и перевода.
  • Интерпретатор PyPy, работающий поверх CPython, выполняет частичную интерпретацию себя, и в этот момент он передает управление своей половине RPython, которая выполняет перевод?

Если это правда, то это одна из самых увлекательных вещей, которые я когда-либо видел.

Ответ 1

Процесс перевода PyPy на самом деле гораздо менее концептуально рекурсивный, чем кажется.

В действительности все это программа Python, которая обрабатывает функции/класс/другие объекты Python ( не исходный код Python) и выводит код C. Но, конечно, он не обрабатывает только любые объекты Python; он может обрабатывать только определенные формы, которые вы получаете, если вы пишете свой переведенный код в RPython.

Так как инструментальная цепочка перевода является программой Python, вы можете запустить ее поверх любого интерпретатора Python, который, очевидно, включает в себя PyPy-интерпретатор python. Так что ничего особенного.

Так как он переводит объекты RPython, вы можете использовать его для перевода PyPy-интерпретатора python, который написан в RPython.

Но вы не можете запустить его в самой структуре перевода, которая является не RPython. Только PyPy python-интерпретатор - это RPython.

Все становится интересным, потому что код на RPython также является кодом Python (но не наоборот), а потому, что RPython никогда не "действительно существует" в исходных файлах, а только в памяти внутри рабочего процесса Python, который обязательно включает в себя другие, -RPython (нет имен импорта или функций pure-RPython, например, потому что переводчик работает с уже определенными и импортированными функциями).

Помните, что инструментальная цепочка трансляции работает с объектами кода Python в памяти. Модель исполнения Python означает, что они не существуют до того, как был запущен некоторый код Python. Вы можете себе представить, что начало процесса перевода выглядит примерно так, если вы очень упростите его:

from my_interpreter import main
from pypy import translate

translate(main)

Как мы все знаем, просто импортирование main будет запускать много кода Python, включая все остальные модули my_interpreter import. Но процесс перевода начинает анализ объекта функции main; он никогда не видит и не заботится о том, какой код был выполнен, чтобы придумать main.

Один из способов думать об этом заключается в том, что "программирование в RPython" означает "запись программы Python, которая генерирует программу RPython, а затем передает ее в процесс перевода". Это относительно легко понять и похоже на то, как работают многие другие компиляторы (например, один из способов думать о программировании на C состоит в том, что вы, по сути, пишете программу предварительного процессора C, которая генерирует программу C, которая затем подается на C).

В случае с PyPy все запутается, потому что все 3 компонента (программа Python, которая генерирует программу RPython, программу RPython и процесс перевода) загружаются в тот же интерпретатор Python. Это означает, что вполне возможно иметь функции, которые являются RPython при вызове с некоторыми аргументами, а не при вызове с другими аргументами, для вызова вспомогательных функций из фреймворка перевода как части генерации вашей программы RPython и множества других странных вещей. Таким образом, ситуация становится довольно размытой по краям, и вы не можете полностью разделить исходные строки на "RPython для перевода", "Python, генерирующий мою программу на RPython" и "передача программы RPython в рамки перевода".


Интерпретатор PyPy, работающий поверх CPython, выполняет частично интерпретировать себя

Я думаю, что здесь вы ссылаетесь на использование PyPy пространства объектов потока во время перевода, чтобы сделать абстрактную интерпретацию. Даже это не так сумасшествие и изгиб ума, как кажется на первый взгляд. Я гораздо менее информирован об этой части PyPy, но, насколько я понимаю,

PyPy реализует все операции интерпретатора Python, делегируя их в "пространство объектов", которое содержит реализацию всех основных встроенных операций. Но вы можете подключить разные пространства объектов для получения разных эффектов, и пока они реализуют одно и то же "пространство пространства", интерпретатор все равно сможет "выполнить" код Python.

Объекты кода RPython, которые связаны с обработкой инструментария PyPy, представляют собой код Python, который может быть выполнен интерпретатором. Таким образом, PyPy повторно использует часть своего интерпретатора Python как часть цепочки инструментов перевода, подключая пространство объектов потока. Когда "исполняемый" код с этим пространством объектов, интерпретатор фактически не выполняет операции кода, он вместо этого создает потоковые графики, которые аналогичны типам промежуточного представления, используемым многими другими компиляторами; это просто простое машинное представление кода, которое будет дополнительно обработано. Вот как обычные (R) объекты кода Python превращаются во вход для остальной части процесса перевода.

Так как обычная вещь, которая переводится с процессом перевода, является интерпретатором PyPy Python, она действительно "интерпретирует себя" с пространством объектов потока. Но все, что на самом деле означает, это то, что у вас есть программа Python, которая обрабатывает функции Python, включая те, которые выполняют обработку. Сам по себе он не является более гибким, чем применение декоратора к себе или наличие класса-оболочки обертывает сам экземпляр (или обертывает сам класс).


Ум, это немного рассердилось. Надеюсь, в любом случае это поможет, и я надеюсь, что я ничего не сказал неточно; пожалуйста, поправьте меня, если у меня есть.

Ответ 2

Отказ от ответственности: я не эксперт по PyPy - в частности, я не понимаю детали перевода RPython, я только цитирую материал, который я читал раньше. Для более конкретной публикации о том, как может работать перевод RPython, ознакомьтесь с этим ответом.

Ответ: да, он может (но только после того, как он был сначала скомпилирован с использованием CPython).

Более длинное описание:

Поначалу кажется, что изгиб ума и парадоксальный, но как только вы это понимаете, это легко. Оформить ответ на Wikipedia.

Начальная загрузка в разработке программ началась в 1950-х годах, когда каждая программа была построена на бумаге в десятичном коде или двоичном коде, побитно (1 с и 0), потому что не было компьютерного языка высокого уровня, никакого компилятора, ассемблера, и никакой компоновщик. Крошечная программа ассемблера была ручной кодировкой для нового компьютера (например, IBM 650), который преобразовал несколько инструкций в двоичный или десятичный код: A1. Эта простая ассемблерная программа была затем переписана на ее просто определенном языке ассемблера, но с расширениями, которые позволили бы использовать некоторые дополнительные мнемоники для более сложных кодов операций.

Процесс называется загрузкой программного обеспечения. В принципе, вы строите один инструмент, например, компилятор С++, на более низком языке, который уже был сделан (все в одной точке должно быть закодировано из двоичного кода), скажем, ASM. Теперь, когда у вас есть С++, теперь вы можете закодировать компилятор С++ в С++, а затем использовать компилятор ASM С++ для компиляции своего нового. После того как вы скомпилировали новый компилятор, вы можете использовать его для компиляции.

Итак, в первую очередь, сделайте первый компьютерный инструмент, когда-либо вручную его кодируя, используйте этот интерпретатор, чтобы сделать еще немного лучше, и используйте его, чтобы сделать лучший,... И в итоге вы получите все сложное программное обеспечение сегодня!:)

Еще один интересный случай - это CoffeeScript, который написан на... CoffeeScript. (Хотя в этом случае все еще требуется использование внешнего интерпретатора, а именно Node.js)

Интерпретатор PyPy, работающий поверх CPython, выполняет частичную интерпретацию себя, и в этот момент он передает управление своей половине RPython, которая выполняет перевод?

Вы можете скомпилировать PyPy, используя уже скомпилированный интерпретатор PyPy, или вы можете использовать CPython для его компиляции. Однако, поскольку PyPy теперь имеет JIT, быстрее будет скомпилировать PyPy, а не CPython. (PyPy теперь быстрее, чем CPython в большинстве случаев)