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-функций с одинаковыми именами.
Коммиту выше не верить. Он вообще удалён с сервера и ни в какую ветку не входит.