bmstu-iu9 / bmstu-iu9/refal-5-lambda
Удалить $SCOPEID
- Dominant language
- C++
- Stars
- 97
- Forks
- 40
- PR merge metrics
- No merged PRs in 30d
Description
Задача-минимум — удалить ключевое слово
==============================
Ключевое слово `$SCOPEID` заменяется на две макроцифры — идентификатор области видимости, который вычисляется как хэш из содержимого области видимости файла. Исходно это ключевое слово использовалось при реализации метафункции `Mu`, но сейчас у неё есть другая, лучшая реализация.
Идентификатор области видимости используется функциями `Module-Mu`, `Module-LookupFunction` и `Module-FunctionPtr`, причём параметр идентификатора области видимости у них опциональный. Если в соответствующей позиции аргумента двух чисел нет, подразумевается `0 0`, т.е. entry-функция.
Из этих трёх функций в рабочем коде используется только `Module-LookupFunction` в интерпретаторе, чтобы вызывать `Go`, идентификатор области видимости ей не передаётся.
Так что если удалить синтаксическую поддержку этого ключевого слова, придётся переписать только ограниченное число автотестов.
Реализация ключевого слова в синтаксическом дереве имеет свои проблемы. Ключевое слово транслируется в пару символов-чисел, значение которых записывается как `Cookie1` и `Cookie2`. Во-первых, нужно выполнять дополнительный проход в `LowLexerRASL.ref` для того, чтобы заменить их на актуальные числа (их расстановка требует ≈1 % работы программы). Во-вторых, планируемый оптимизатор интринсиков (#260) будет немало удивлён (вылетит), увидев ``. Однако, прогонщика и специализатора они не смущают.
Так что удаление `$SCOPEID` несколько упростит и выпрямит компилятор.
Любая локальная функция содержит в своём дескрипторе имя, а оно содержит идентификатор области видимости. Так что можно определить встроенную функцию `ScopeId`, которая принимает указатель на локальную функцию и возвращает scope id. Простейшим способом её использования будет ``.
В образцовых выражениях `$SCOPEID` как константа бессмысленно (во всяком случае я не нахожу подходящих сценариев использования). В результатных выражениях его можно заменить на ``.
Задача-максимум — вообще убрать хеши областей видимости из компилятора
======================================================
Это потребует гораздо больше возни, поскольку эти хеши глубоко въелись в рантайм.
Исходная причина введения хешей была в том, что надо было (а) обеспечить работающую инкапсуляцию, (б) поместить все функции в глобальную область видимости. Этого удалось добиться путём приписывания уникальных ключей к именам локальных функций. Использование для этой цели хеша позволяет с одной стороны обеспечить уникальность (для разных файлов — разные), с другой — что при компиляции одного и того же файла будет создаваться один тот же «ключ».
Заявки, которые внесли эти куки: #63, #66.
Другим бонусом использования этих кук стала возможность написания локальных нативных функций. Основной код файла может быть откомпилирован в RASL, нативная функция — в C++, и благодаря кукам они найдут друг друга. Но это артефакт имеющегося подхода к реализации нативных функций.
Если не рассматривать локальные нативные функции, то от куков в API и формате RASL’а можно отказаться.
* В формате RASL’а требуется, чтобы описания функций располагались после таблицы констант, соответствующей единице трансляции. Таким образом, таблица констант становится естественным контейнером инкапсуляции: локальные функции разрешаются внутри неё, внешние — среди entry-функций сначала модуля, а потом уже и всей программы.
Функция содержит ссылку на таблицу констант (которую в этом случае разумнее называть описателем единицы трансляции), та — на модуль. При разрешении ссылки поиск осуществляется сначала в описателе единицы трансляции, потом модуля, потом программы.
* Из API `Module-***` можно просто выкинуть идентификатор области видимости — сценарии поиска локальных функций мне пока не очевидны. Для отображения имён именованных функций в указатели есть метатаблицы. Функции после рассахаривания для вызова пользователем не предназначены. Потребность во всякой хитрой рефлексии я пока не вижу.
* Для кода прямой кодогенерации и исходных файлов со вставками нативного кода можно имитировать описатель модуля на C/C++, как описано в заявке #197 (про переход на Си). Ограничением будет то, что если в файле есть хотя бы одна нативная вставка, весь файл принудительно будет компилироваться в режиме прямой кодогенерации — смешанная компиляция уже доступна не будет (да и не нужна, честно говоря).
**UPD:** нативные вставки сами по себе предлагаются к удалению: https://github.com/bmstu-iu9/refal-5-lambda/issues/318#native.
Вывод
====
Имеет смысл ориентироваться на программу-максимум, поскольку куки устарели — решают давно не актуальную задачу. Но это потребует масштабной переделки всего рантайма и частично кодогенератора.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.