bmstu-iu9 / bmstu-iu9/refal-5-lambda

Интегрировать в компилятор декомпилятор .rsl

Open
#202 1 comment 0 reactions 1 assignee Claimed by @Mazdaywik View on GitHub
task
Dominant language
C++
Stars
97
Forks
40
PR merge metrics
No merged PRs in 30d

Description

Последняя (непубличная) версия SCP4 имеет в своём составе компоненты, распространяемые в скомпилированном виде (в частности, `crefal.rsl`, `prefal.rsl`…), из-за чего уже не может быть скомпилированной Рефалом-5λ. Ради того, чтобы её всё-таки иметь возможность собрать, я написал декомпилятор rsl’ек, правда, в отдельном репозитории:

https://github.com/Mazdaywik/rsl-decompiler

Предлагается, используя этот проект, внедрить в Рефал-5λ поддержку .rsl-файлов как исходных текстов.

Интеграцию можно сделать несколькими способами:
1. Декомпилятор является отдельным исполнимым модулем, который вызывается из компилятора функцией `System`, результат декомпиляции обрабатывается как обычный исходный файл.
2. Декомпилятор встроен в компилятор, порождает текст, который обрабатывается лексером.
3. Декомпилятор порождает лексическую свёртку, подаваемую на вход парсера.
4. Декомпилятор порождает синтаксическое дерево.
5. Декомпилятор порождает язык сборки.

Дальше продвинуть декомпилятор уже нельзя — дальше уже время выполнения и придётся говорить об альтернативном загрузчике и интерпретаторе, код декомпилятора на Рефале становится не нужен.

Вариант 1 предполагает максимум накладных расходов на взаимодействие между программами — нужно реконструировать исходный текст как файл на диске и заново его разобрать. Вариант 5 предполагает как бы минимум вспомогательных проходов, но он не реалистичен.

Почему нереалистичен вариант 5. Во-первых, языки сборки Рефала-5 и Рефала-5λ существенно различаются, проще реконструировать соответствующие конструкты и заново их разобрать (вариант 4). Во-вторых, между загрузкой синтаксического дерева и порождением языка сборки присутствует проход разрешения `$INCLUDE`’ов, а встроенные функции Рефала-5 реализуются как неявное подключение прелюдии. Кроме того, даже если дословно реализовать трансляцию языка сборки, пропадёт возможность оптимизаций, выполняемых Рефалом-5λ.

Кодовая база декомпилятора во многом «быстрая и грязная». В ней осталось много отладочных артефактов, в частности, для некорректных опкодов и неразобранных конструкций в целевой файл просто вываливаются промежуточные структуры данных. Не предусмотрена проверка на ошибки на ряде этапов разбора (например, списка имён extern- и entry-функций, списка составных символов). Контроль инвариантов осуществляется сопоставлением с повторными переменными _в присваиваниях._ Поэтому при некорректном файле на входе декомпилятор может или упасть, или вывалить ерунду в целевой файл.

Таким образом варианты со 2 по 4 будут подразумевать доработку контроля ошибок в самом декомпиляторе, что может сказаться на его быстродействии. Внести контроль сравнительно минимальными правками можно будет только после реализации исключений (#180).

Поэтому предлагается реализовать вариант 1 — вызов внешней программы. Вызывается декомпилятор и порождает файл `имяфайла-decompiled.ref`. Если файл отсутствует или код возврата ненулевой — выдаётся сообщение об ошибке. Иначе — парсим. Если файл разобрался без ошибок — Рефал-5λ удаляет `имяфайла-decompiled.ref` и продолжает компиляцию. Иначе — выдаёт сообщения о синтаксических ошибках и файл не удаляет. Пользователь в этом случае получает возможность понять, что же за фигню написал декомпилятор.

Реализация такого базового варианта уже позволит собрать новую версию SCP4 (специально для @madina9997 😉). В дальнейшем можно будет осуществить рефакторинг к любому из вариантов 2–4.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.