Closed Mazdaywik closed 5 years ago
Речь идёт о том же, о чём написано в bmstu-iu9/refal-5-lambda#46. Причём в случае языка Си ситуация упрощается: их предобъявления просто определяются как static
. Язык Си допускает наличие нескольких переменных в одном файле с одним именем (но инициализироваться может только одна).
Выделено в подзадачу: #14.
Предлагается по возможности не использовать typedef
’ы. Например, struct r05_Node*
вместо refalrts::Iter
. Исключение — типы указателей на функции.
Пространств имён в чистом Си нет, вместо них принято использовать префиксы. Предлагаются следующие префиксы
r05_
— для всех сущностей рантайма: r05_Node
, r05_alloc_char
, r05_cDataNumber
. Заменяет refalrts::
.r05f_
— для дескрипторов функций. Дескрипторы функций могут быть как статическими, так и со внешней компоновкой.r05c_
— для самих функций (кода). Эти функции могут быть только статическими.Пример:
static r05_FnResult r05c_Foo(struct r05_Node *arg_begin, struct r05_Node *arg_end);
r05_Function r05f_Foo = { r05c_Foo, "Foo" };
static r05_FnResult r05c_Foo(struct r05_Node *arg_begin, struct r05_Node *arg_end) {
. . .
}
Выделено в подзадачу: #15.
Предлагается функции рантайма, распределяющие память, сделать «безотказными». Если памяти не хватает, сами эти функции должны выводить дамп и завершать программу (вызовом exit
или abort
).
Обоснование: сложно представить себе ситуацию, когда эти ошибки корректно обрабатываются и продолжается выполнение. Функции, написанные на Рефале, могут только упасть.
Нативная функция, что она может сделать? Какая-нибудь функция, которая может загрузить чего-то очень много (например, прочитать длинный файл) может при недостатке памяти вернуть только часть и продолжить работу, надеясь, что к следующему запуску часть памяти освободится. Но из соображений минимализма в этом репозитории я таких функций писать не буду.
Так что единственная реакция любой разумной функции на ошибку аллокации — вернуть cNoMemory
, после чего рефал-машина просто остановится с ошибкой. Дабы упростить и генерируемый код, и нативные функции, предлагается поэтому сделать их безотказными. Побочным результатом будет повышение быстродействия, поскольку будет выполняться на одну проверку меньше. Но быстродействие нас не интересует.
Выделено в подзадачу: #16.
Предлагается сделать примерно так, как это сделано сейчас в Модульном Рефале. Распределяемые объекты (скобки, символы, копии переменных) последовательно размещаются в списке свободных узлов. Для переносимых переменных сохраняется позиция после вставляемого элемента.
Преимущества:
Выделено в подзадачу: #17.
Эта задача — подзадача для #1.
Простой Рефал, особенно его ранние версии, компилируется в C++, однако C++ почти не использует. Поэтому из соображений минимализма следует перейти на подмножество — на C.
Язык Си более переносим: скорее всего придётся обходить меньше ошибок в Watcom, существуют компиляторы C, которые не поддерживают C++ (например, Tiny C, PCC).
По моим ощущениям язык C менее располагает к нагромождению абстракций, чем C++, а значит, играет некоторую воспитательную и ограничивающую функцию. И это тоже способствует минимализму.
В Простом Рефале C++ был необходим для простой реализации идентификаторов. Благодаря трюку с шаблонами компоновщик C++ устранял дубликаты, обеспечивая тем самым глобальность указателей. В Рефале-5λ C++ обеспечивает инициализацию глобальных переменных в нативных файлах и упрощает написание рантайма (без STL и RAII написать динамическую загрузку было бы сложнее). На чистый C переписать можно, но пока такой цели не стоит.
В Рефале-05 идентификаторов не будет (#4), для глобальных переменных будет достаточно только статической инициализации. Поэтому технически C++ не нужен. Идеологическое обоснование ненужности дано выше.
Подзадачи: