refal-5-lambda
refal-5-lambda copied to clipboard
Добавить предупреждение «не определена точка входа»
В случае, если в исходнике отсутствует функция, помеченная как $ENTRY
и при этом отсутствуют нативные вставки на верхнем уровне, следует выдавать ошибку.
Иначе говоря, надо выдавать ошибку, если в исходнике нет ни нативных вставок верхнего уровня, ни функций, помеченных как $ENTRY
.
Нативные вставки верхнего уровня роли не играют, потому что согласно #163 глобальных переменных с конструкторами быть не должно.
Но, с другой стороны, согласно #164 в модуле могут быть локальные функции INIT
и FINAL
, которые вызываются рантаймом. Поэтому их надо рассматривать отдельно.
Иногда удобно описывать пустые файлы вида
*$FROM Hash
*$FROM LibraryEx
*$FROM GetOpt
*$FROM refalrts-main
Их смысл — собирать проект при помощи srmake
. Разумно их сохранить как идиому (не выдавать на них warning), либо запретить их, добавив особые «проектные» файлы для srmake
.
После выполнения #273 в компиляторе появится поддержка предупреждений. А отсутствие точки входа как раз логичнее трактовать как предупреждение, а не ошибку.
@nexterot, добавлять поддержку механизма предупреждений (#273) ради одного предупреждения немного странно (на первый взгляд). Поэтому вместе с задачей #273 добавьте поддержку предупреждения -Wmissing-entry-point
, которое будет включено по умолчанию.
Для его поддержки нужно будет в Checker.ref
проверять, что в дереве есть хотя бы одна entry-функция или функция с именем INIT
или FINAL
.
По-хорошему, нужно также выдавать предупреждение (-Winit-final-is-entry
), если функции INIT
или FINAL
определены как $ENTRY
, но это на Ваше усмотрение. Добавить его проще, чем -Wmissing-entry-point
.
Просто если добавить поддержку предупреждений (ключи командной строки + изменения внутренних структур данных) и не добавить поддержку хотя бы одного простого предупреждения, то для #273 нельзя будет написать автотест.
Уточнение. У предупреждения должна быть координата ошибки. Но какую координату выдавать для чего-то отсутствующего? Более того, файл может быть пустым, и дерево у него тоже может быть пустым (или непустым, поскольку для .ref
подключается прелюдия).
Предлагается добавить в синтаксическое дерево до рассахаривателя узел (EOF t.SrcPos)
, смысл которого в сохранении координаты конца файла (для этого предупреждения или каких-то ещё в будущем). И выдавать координату из этого узла. Для этого потребуется научить файлы SR-Parser.sref
и R5-Parser.ref
добавлять в дерево соответствующий узел, Engine.ref
и Checker.ref
не спотыкаться об него, Desugaring.ref
удалять его на самом первом проходе (Pass-RemovePos
).
@nexterot, узел (EOF t.SrcPos)
— ненужная возня, не имеющая отношения к диплому. Добавить -Wmissing-entry-point
недолго (не более 2 часов работы), но, чтобы не отвлекаться, снимаю с Вас эту заявку.
Добавьте лучше -Winit-final-entry
как описано в комментарии выше. У этих предупреждений координата предупреждения совпадает с координатой самой функции.
Поясню. Функции INIT
и FINAL
запускаются, соответственно, после загрузки или перед выгрузкой (включая завершение программы) единицы трансляции. Используются для начальной инициализации глобальных переменных и освобождения памяти (актуально для библиотек, написанных на C++). Каждая единица трансляции образует свою область видимости (идентифицируемую парой 32-разрядных чисел), рантайм при загрузке просто проходится по всем областям видимости и дёргает в них функции INIT
(при выгрузке FINAL
), если они там есть. Область видимости entry-функции глобальная, поэтому эти $ENTRY INIT
и $ENTRY FINAL
просто не будут вызваны. Более того, в скомпилированном модуле не может быть несколько entry-функций с одинаковыми именами.
Коммиту выше не верить. Он вообще удалён с сервера и ни в какую ветку не входит.