flang компилятор доказывает, что программа не зациклится 0.7.29 GitHub English

К README · Указатель документации

Развитие языка

Компилятор один, написан на самом flang и собирается в двоичный файл. Работа над ним идёт в клоне, и ставить в нём нечего: зависимостей у пакета нет, поэтому команды запускаются сразу после git clone.

Правка компилятора в flang/self/ обязана перепечатать точку раскрутки тем же коммитом, иначе bootstrap/ начнёт собирать прошлый компилятор молча:

sh scripts/bootstrap-reprint.sh           # перепечатать bootstrap/ (часы)
sh scripts/bootstrap-reprint.sh --check   # сверить с исходниками побайтово, код 1 при расхождении
sh scripts/bootstrap-reprint.sh --stroki  # меньше секунды: все строковые литералы рантайма C закрыты

Печатает эти байты сам двоичный компилятор (bootstrap/flang emit … --target c); если двоичного нет, скрипт сначала соберёт его из bootstrap/.

Сверка печатает заново и стоит столько же, сколько печать (часы), плюс make, если двоичный не собран. Зовите --check перед слиянием правки в flang/self/ или flang/src/emit/c/, а не на каждое сохранение.

Чтобы прогнать правленый исходник компилятора на одной программе до печати, пусть собранный двоичный истолкует исходники: flang/self/bootstrap/check-with-source-compiler.flang проверяет ими один файл и печатает отчёт о доказательствах словами и запись доказательства. --trust пропускает проверку доказательств по самому компилятору; маленькая программа стоит около десяти минут и 12 ГиБ:

bootstrap/flang run flang/self/bootstrap/check-with-source-compiler.flang \
  --function 'Проверить исходным компилятором' --trust --max-steps 2000000000 \
  --args "$(jq -n --arg path FILE --rawfile text FILE '{"путь": $path, "текст": $text}')"

Порядок ввоза в этом модуле значим: связывание берёт объявления модуля через того, кто ввёз его первым, вместе с его списком только, поэтому «Compiler flang» стоит первым, как в compiler.flang. С «Печать в C» на первом месте проверяемая программа с требует останавливается на FLANG_UNKNOWN_NAME о «Печать значения».

Команды, на которые язык отвечает:

# разобрать, проверить типы, доказать тотальность
flang check docs/examples/leetcode/035-search-insert-position.flang --pretty

# прогнать примеры, объявленные внутри функций
flang test docs/examples/leetcode/035-search-insert-position.flang --pretty

# то же по КОРПУСУ: каталог или маска вместо файла (только у двоичного).
# Печатается каждый не прошедший пример и каждый не взятый файл, прошедшие —
# числом; код возврата 0 — чисто, 1 — упало или файл не взят, 2 — кривой вызов.
flang test flang/stdlib/
flang test 'docs/examples/**/*.flang' --json

# вызвать функцию: --args берёт ПЛОСКИЙ объект скаляров, список туда не подать
flang run docs/examples/leetcode/035-search-insert-position.flang \
  --function "Место вставки" --args '{"цель":2}'
# функции со списочным доводом зовутся своими примерами: flang test <файл>

# напечатать — цели: c | cpp | csharp | elixir | go | java | js | python | rust | ts
flang emit docs/examples/leetcode/035-search-insert-position.flang \
  --target python --out ./out-python

Проверки:

sh flang/test/обход.sh          # проверки обходчика двоичным
sh flang/test/обход-примеров.sh # все примеры дерева
sh scripts/bootstrap-reprint.sh --check  # семя против того, что печатают исходники
bootstrap/flang run-script                                  # список всех проверок дерева с пояснением к каждой
bootstrap/flang run-script tests                            # весь набор разом

Отдельная проверка зовётся по имени из этого списка: bootstrap/flang run-script specs:check, bootstrap/flang run-script links:check, bootstrap/flang run-script site:check. У каждой свой код возврата: 0 — чисто, ненулевой — назван виновник.

Каждая команда пишет JSON в stdout, диагностику в stderr и возвращает ненулевой код при отказе — один и тот же контракт везде, и именно он делает всё это пригодным для CI, редакторов и агентов. Единственное исключение — flang repl, который разговаривает с человеком.