PyPy переводит сам себя? - PullRequest
       12

PyPy переводит сам себя?

48 голосов
/ 10 декабря 2011

Я правильно понял?Интерпретатор PyPy действительно интерпретирует себя и затем переводит сам себя?

Так вот мое текущее понимание:

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

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

Ответы [ 2 ]

65 голосов
/ 20 декабря 2011

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

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

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

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

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

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

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


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

12 голосов
/ 10 декабря 2011

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

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

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

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

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

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

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

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

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

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

...