refal-5-lambda icon indicating copy to clipboard operation
refal-5-lambda copied to clipboard

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

Open Mazdaywik opened this issue 5 years ago • 1 comments

Последняя (непубличная) версия 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.

Mazdaywik avatar Mar 14 '19 14:03 Mazdaywik

Не смотря на то, что код уже в ветке master и вообще в релизе, заявку не закрываю. Возможно, я потом глубже интегрирую декомпилятор в компилятор — варианты 2–4 в тексте выше.

Mazdaywik avatar Mar 20 '19 14:03 Mazdaywik