- PVSM.RU - https://www.pvsm.ru -

Мой компилятор Паскаля и польское современное искусство

Истоки

Несколько лет назад я написал компилятор Паскаля. Мотивация была простой: в юности я узнал из своих первых книжек по программированию, что компилятор — вещь чрезвычайно сложная. Это утверждение засело занозой в мозгу [1] и в конце концов потребовало проверки на опыте.

image
ha.art.pl

Сперва родился простейший компилятор PL/0 [2], а из него постепенно вырос почти полнофункциональный компилятор Паскаля для MS-DOS. Вдохновением мне служила книга Compiler Construction [3], написанная создателем языка Паскаль Никлаусом Виртом. И пусть взгляды Вирта уже устарели и утратили всякую связь с реалиями ИТ, а компиляторы делают совсем не так, как учил Вирт. Однако его методы по-прежнему просты, изящны, а главное — приносят радость, ведь самостоятельно разобрать текст программы рекурсивным спуском и сгенерировать машинный код намного заманчивее, чем призывать на помощь яков [4], бизонов [5] и всех их преемников.

Судьба моего компилятора оказалась не самой тривиальной. Он прожил две жизни: первую — в моих руках, вторую — в руках польских ценителей компьютерных древностей.

XD Pascal

Мой свежеиспечённый компилятор получил название XD Pascal [6]. Он поддерживал все операторы Паскаля, кроме goto и with. Первый показался мне трудным для реализации, поскольку разрушал идеально иерархичную структуру программы. Второй — создавал путаницу с областями видимости имён.

Поддерживались и все основные типы данных. За рамками остались только беззнаковые целые числа, множества, перечисления и вариантные записи — однако всё это явно не предметы первой необходимости. Тем не менее, я не мог отказать себе в удовольствии от чисел с плавающей точкой и их арифметики на сопроцессоре 8087 — тут сказалась профессиональная склонность к инженерным расчётам.

При реализации процедур и функций я опасался, что большой проблемой окажутся рекурсия и хранение локальных переменных в стеке. Однако настоящая трудность, специфичная для Паскаля, подстерегала совсем в другом месте — в работе с вложенными процедурами. Может возникнуть совершенно невинная надобность обратиться к локальной переменной внешней процедуры из внутренней. Однако во внутренней процедуре нет адреса стекового кадра внешней процедуры — внутренняя процедура не знает, от чего отсчитывать адрес искомой переменной. Этот адрес приходится всякий раз передавать во внутреннюю процедуру через дополнительный скрытый параметр. Подозреваю, что именно это осложнение заставило разработчиков C вовсе отказаться от вложения функций. Однако в Паскале они есть, и с этим приходится считаться.

Генератор кода создавал самые простые исполняемые файлы COM для реального режима MS-DOS. Машинный код генерировался напрямую, без помощи внешнего ассемблера или компоновщика. Для данных я использовал 32-битные регистры архитектуры 80386, а адресация осталась 16-битной, в виде пары сегмент-смещение.

Модель памяти примерно соответствовала «малой» (если кто-то ещё помнит эту терминологию 16-битной эпохи): для кода, глобальных данных и стека выделялось по одному сегменту размером 64 кб.

image
Использование памяти

Генерация файлов EXE и переключение сегментов на лету казались чересчур сложным делом, и тесные рамки «малой» модели заставили меня распрощаться с идеей самокомпиляции. Конечно, мне встречались самокомпилируемые компиляторы, код которых целиком умещался в одном сегменте (например, Context [7]). Однако они редко умели делать хоть что-то полезное кроме этой самокомпиляции. Я же хотел сделать свой компилятор хоть немного пригодным для численных расчётов и вывода графики. Поэтому среди примеров программ появились фракталы, решение линейных уравнений по Гауссу, быстрое преобразование Фурье и даже оценивание фильтром Калмана ошибок инерциальной навигационной системы.

image
Фрагмент множества Мандельброта

image
Быстрое преобразование Фурье

image
Оценивание погрешностей инерциальной навигационной системы

То, что у меня получилось в итоге, больше всего напоминало древний как мир Turbo Pascal 3.0 (ещё без ООП) и любительский BeRo Tiny Pascal [8]. Автор последнего совладал с самокомпиляцией под Windows, однако пожертвовал арифметикой с плавающей точкой и многими тонкостями грамматики, которые мне хотелось соблюсти. Из более современных особенностей в моём XD Pascal появились позаимствованные из Delphi однострочные комментарии (//) и автопеременная Result.

Впрочем, ещё с самого своего рождения мой компилятор был отмечен печатью смерти. Паскаль уже необратимо выходил из моды, а MS-DOS давно стал архаикой. В тот день, когда я перешёл с 32-битной Windows XP на 64-битную Windows 7 без виртуальной машины DOS, я мысленно похоронил свой проект.

Возрождение

Затем произошло странное. После трёх лет полного забвения некая группа польских энтузиастов ретрокомпьютинга и любителей Atari отыскала мой компилятор. Судя по всему, абстрактные проблемы самокомпилируемости и строгости реализации грамматики их волновали мало. Им просто нужен был удобный инструмент программирования их любимой машины. Из моего проекта они сделали собственный компилятор Mad Pascal [9] для архитектуры 6502. Грамматика языка разрослась, появилась поддержка модулей с секциями интерфейса и реализации, оператора goto, беззнаковых целых чисел, множеств и перечислений, ассемблерных вставок. Вместо машинного кода теперь генерировался ассемблерный код. Его финальная трансляция делалась ассемблером собственной разработки.

Внешне язык стал заметно ближе к фактическому стандарту Паскаля. Внутри компилятор выглядит несколько устрашающе, зарезервированные слова перемешаны с именами стандартных процедур, однако это авторов нисколько не смущает. Как бы оно ни выглядело, но дело оказалось на удивление живучим: вот уже три года Mad Pascal регулярно обновляется, на нём написано немало игр, авторы ежегодно выступают на ретроконференции Silly Venture [10] (ссылка требует VPN). Возникает ощущение, что в Польше вообще очень сильны традиции почитания Atari.

Весной 2018 года произошло событие, весьма примечательное для польской тусовки поклонников Atari: вышла книга «Robbo. Solucja» [11] («Роббо. Прохождение») в жанре экспериментальной литературы. Здесь надо сказать, что сама игра Robbo [12] для Atari, изданная 30 лет назад, до сих пор волнует сердца поляков старшего поколения и наполняет их патриотическим восторгом. В общем, неудивительно, что появилась посвящённая игре книжка. Забавно лишь то, что она, по словам авторов, на 60 % состоит из инструкций по прохождению игры, сгенерированных самим компьютером Atari. Программа генерации написана на том самом Mad Pascal.

image
graczpospolita.pl

И кажется, некоторые [13] восприняли книгу как достойный образец современного искусства:

Было бы неверно относиться к книге только как к предмету коллекционирования для поклонников Robbo или, в более общем смысле, для поклонников Atari. Нам приходится иметь дело с редким случаем столкновения культуры видеоигр с литературой (в данном случае электронной), когда отправной точкой является «игра», а не «литература». Для некоторых это бессмысленное искусство ради искусства. Для других подобное скрещивание несёт совершенно новые возможности и опыт. Ничто не мешает вам создать версию Robbo, которую вы можете закончить с помощью «прохождения» из книги. Книга хорошо согласуется с моим взглядом на игры как на искусство. Искусство, в котором игрок может быть как воспринимающим, так и творящим — если во время «игры» присутствует «аудитория», наблюдающая за игроком, создающим свою собственную историю «игры». Содержание книги можно адаптировать для перформанса с игроком, проходящим Robbo, используя элементы «пошаговых инструкций» из книги. Чтобы не оставаться голословным: перформанс по мотивам «Robbo. Solucja» состоялся 11 мая 2018 года в галерее современного искусства «Бункер» в Кракове, во время презентации книги в рамках выставки «Неисчерпаемость».

Перформанс в Кракове. Ради этого стоило написать компилятор.

Автор: Tereshkov

Источник [14]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/delphi/305795

Ссылки в тексте:

[1] мозгу: http://www.braintools.ru

[2] PL/0: https://en.wikipedia.org/wiki/PL/0

[3] Compiler Construction: http://www.ethoberon.ethz.ch/WirthPubl/CBEAll.pdf

[4] яков: https://en.wikipedia.org/wiki/Yacc

[5] бизонов: https://en.wikipedia.org/wiki/GNU_Bison

[6] XD Pascal: https://sourceforge.net/projects/xdpascal/

[7] Context: http://www.avhohlov.narod.ru/p9800ru.htm

[8] BeRo Tiny Pascal: https://github.com/BeRo1985/berotinypascal

[9] Mad Pascal: http://mads.atari8.info/

[10] Silly Venture: http://www.sillyventure.eu/pl/

[11] «Robbo. Solucja»: http://www.ha.art.pl/wydawnictwo/nowe-ksiazki/5330-robbo-solucja.html

[12] Robbo: https://en.wikipedia.org/wiki/Robbo_(video_game)

[13] некоторые: http://retroage.net/recenzje-prasyksiazek/robbo-solucja

[14] Источник: https://habr.com/ru/post/436694/?utm_campaign=436694