-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Мотивация
Некоторые возможности рантайма проще выражать на Рефале, нежели на C++ или в сгенерированном коде. На данный момент — это вызов инициализаторов и финализаторов. Во всех трёх back-end’ах он реализован по-разному, с разной степенью кривизны. Наиболее красивая реализация инициализаторов и финализаторов — в Простом Рефале, наиболее кривая — в C++/SR. Если бы был глобальный модуль рантайма, написанный на Модульном Рефале, можно было бы определить в нём статический ящик, куда будут складываться финализаторы + функции регистрации и раскрутки финализаторов.
В дальнейшем (см. TODOs.txt) планируется добавить вложенные функции как подкласс некоторого встроенного класса. Как написано по предыдущей ссылке, такой класс можно описать и на Рефале:
Первое, что мне пришло в голову — создать библиотечный модуль с определением виртуальной
функции вроде такого:
$MODULE RUNTIME;
$VIRTUAL CALL {
s.Func e.Arg = <s.Func e.Arg>;
$DATA e.Arg;
}
$END RUNTIME.
Тогда, если модуль содержит вызовы <t.Func ...>, то он неявно импортирует модуль RUNTIME,
а сами вызовы заменяются на вызов <RUNTIME::CALL ...>. При этом пользователь может явно
импортировать этот модуль и расширить RUNTIME.CALL для своих АТД.
Возможно, в дальнейшем отыщутся и другие причины иметь рантайм, написанный на Модульном Рефале.
Реализация
Компилятор Рефала знает два модуля с предопределёнными именами: RUNTIME и RUNTIME-CORE. Оба модуля запрещено импортировать явно во всех остальных модулях, за исключением RUNTIME-CORE, который можно импортировать из RUNTIME. А может, и не запрещено. А просто не рекомендуется.
Первый модуль RUNTIME неявно импортируется из каждого модуля, где используется соответствующая функциональность рантайма (финализаторы, вложенные функции и <t.Func …>), либо импортируется неявно любыми модулями. Второй RUNTIME-CORE явно импортируется из RUNTIME.
Модуль RUNTIME содержит универсальные средства, не зависит от выбранного back-end’а. Второй содержит платформенно-зависимый код, поэтому для каждого back-end’а свой.
Комментарии
В TODOs.txt есть такое замечание:
(-) Решение противоречит идеологии Модульного Рефала: встроенные средства языка не должны быть
привязаны к пользовательским определениям. Например, пользователь может переопределить модуль
RUNTIME в котором функция CALL может остутствовать, и вся механика разрушится.
Дескать, оно противоречит идеологии. Но это только на первый взгляд. Точно также, как пользователь может подменить RUNTIME.mref, он может подменить и refalrts.h/refalrts.cpp с тем же эффектом.