diff --git a/.flangrc b/.flangrc index f35929d31..48d91c0dd 100644 --- a/.flangrc +++ b/.flangrc @@ -200,6 +200,12 @@ script.releases:page = bootstrap/flang io scripts/site/releases-page.fscript --m script.releases:page:check = bootstrap/flang io scripts/site/releases-page-verify.fscript --max-steps 80000000 --на-веру script.registry:page = bootstrap/flang io scripts/site/registry-page.fscript --plan 'Напечатать страницу реестра' script.registry:publish = bootstrap/flang io scripts/site/registry-page.fscript --plan 'Выложить ведомость' +script.registry-resolution:check = bootstrap/flang io scripts/guards/registry-resolution-guard.fscript --plan Check +script.registry-resolution:forgery = bootstrap/flang io scripts/guards/registry-resolution-guard.fscript --plan Forgery +script.registry-resolution:measure = bootstrap/flang io scripts/guards/registry-resolution-guard.fscript --plan Measure +script.registry-prints:check = bootstrap/flang io scripts/registry-tool.fscript --plan 'Сверить отпечатки' +script.lock-forms:check = bootstrap/flang io scripts/guards/lock-closes-every-form.fscript --plan Check +script.lock-forms:forgery = bootstrap/flang io scripts/guards/lock-closes-every-form.fscript --plan Forgery script.reprint = sh scripts/bootstrap-reprint.sh script.reprint:check = sh scripts/bootstrap-reprint.sh --check script.bootstrap-point:check = bootstrap/flang io scripts/seed/bootstrap-point-by-binary.fscript --timeout 2400000 --на-веру diff --git a/.githooks/pre-push.fscript b/.githooks/pre-push.fscript index 94ddba505..53b35740e 100644 --- a/.githooks/pre-push.fscript +++ b/.githooks/pre-push.fscript @@ -16,8 +16,11 @@ тотальная функция «Checks» возвращает список «Check» - обеспечивает «there are exactly twenty-one checks» (длина результат) равен 21 + обеспечивает «there are exactly twenty-four checks» (длина результат) равен 24 [запись «Check» с «name» равным "prose-numbers-guard" и «command» равным "bootstrap/flang io scripts/guards/prose-numbers-guard.fscript --plan Check", + запись «Check» с «name» равным "registry" и «command» равным "bootstrap/flang run-script registry-resolution:check", + запись «Check» с «name» равным "prints" и «command» равным "bootstrap/flang run-script registry-prints:check", + запись «Check» с «name» равным "lock-forms" и «command» равным "bootstrap/flang run-script lock-forms:check", запись «Check» с «name» равным "seed-runtime-is-source" и «command» равным "bootstrap/flang io scripts/seed/seed-runtime-is-source.fscript --plan Check", запись «Check» с «name» равным "seed-refresh" и «command» равным "bootstrap/flang io scripts/seed/seed-refresh.fscript --plan Check", запись «Check» с «name» равным "version-derivations-guard" и «command» равным "bootstrap/flang io scripts/guards/version-derivations-guard.fscript --plan Проверка", @@ -318,7 +321,7 @@ тотальная функция «Leftovers» принимает directory: строка возвращает список строки - обеспечивает «one file for every check and the directory itself» (длина результат) равен 22 + обеспечивает «one file for every check and the directory itself» (длина результат) равен 25 добавить directory к (отобразить («Checks») как check → («Output path» от directory и check)) тотальная функция «Remove files» diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 895644092..4c6d90a59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1913,3 +1913,86 @@ jobs: env: FLANG_TMP: ${{ runner.temp }} + + registry-resolution: + name: registry-resolution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - name: Check verdict cache + uses: ./.github/actions/release-without-cache + - run: make -C bootstrap -j"$(nproc)" + - name: Probe registry resolution by a forged corpus + run: | + if bootstrap/flang run-script registry-resolution:forgery; then + echo "the guard stayed green on a forged corpus" >&2 + exit 1 + fi + - name: Probe registry resolution by a cut ledger + run: | + ledger=packaging/registry/cases/ledger.list + cp "$ledger" "$RUNNER_TEMP/ledger.list" + grep -v '^Логика | 1.2.0' "$RUNNER_TEMP/ledger.list" > "$ledger" + if cmp -s "$ledger" "$RUNNER_TEMP/ledger.list"; then + cp "$RUNNER_TEMP/ledger.list" "$ledger" + echo "the row was not cut, nothing to probe" >&2 + exit 1 + fi + if bootstrap/flang run-script registry-resolution:check > "$RUNNER_TEMP/cut.out" 2>&1; then + cp "$RUNNER_TEMP/ledger.list" "$ledger" + cat "$RUNNER_TEMP/cut.out" >&2 + echo "the guard stayed green with a chosen version cut out" >&2 + exit 1 + fi + cp "$RUNNER_TEMP/ledger.list" "$ledger" + cmp "$ledger" "$RUNNER_TEMP/ledger.list" + - name: Check registry resolution + run: bootstrap/flang run-script registry-resolution:check + - name: Probe registry fingerprints + run: | + ledger=scripts/registry-example/registry.list + cp "$ledger" "$RUNNER_TEMP/registry.list" + sed -i '2s/| 1dc6/| Xdc6/' "$ledger" + if cmp -s "$ledger" "$RUNNER_TEMP/registry.list"; then + cp "$RUNNER_TEMP/registry.list" "$ledger" + echo "the forged fingerprint did not land, nothing to probe" >&2 + exit 1 + fi + if bootstrap/flang run-script registry-prints:check > "$RUNNER_TEMP/probe.out" 2>&1; then + cp "$RUNNER_TEMP/registry.list" "$ledger" + cat "$RUNNER_TEMP/probe.out" >&2 + echo "the guard stayed green on a bent fingerprint" >&2 + exit 1 + fi + cp "$RUNNER_TEMP/registry.list" "$ledger" + cmp "$ledger" "$RUNNER_TEMP/registry.list" + - name: Check registry fingerprints + run: bootstrap/flang run-script registry-prints:check + - name: Probe lock forms by a forged measurement + run: | + if bootstrap/flang run-script lock-forms:forgery; then + echo "the guard stayed green on a forged measurement" >&2 + exit 1 + fi + - name: Probe lock forms by the old binary + run: | + cp bootstrap/flang_repl.c "$RUNNER_TEMP/flang_repl.c" + sed -i 's/wanted_bytes != 0/wanted_bytes == 0/' bootstrap/flang_repl.c + if cmp -s bootstrap/flang_repl.c "$RUNNER_TEMP/flang_repl.c"; then + cp "$RUNNER_TEMP/flang_repl.c" bootstrap/flang_repl.c + echo "the old behaviour did not land in the seed, nothing to probe" >&2 + exit 1 + fi + make -C bootstrap -j"$(nproc)" + if bootstrap/flang run-script lock-forms:check > "$RUNNER_TEMP/old.out" 2>&1; then + cp "$RUNNER_TEMP/flang_repl.c" bootstrap/flang_repl.c + make -C bootstrap -j"$(nproc)" + cat "$RUNNER_TEMP/old.out" >&2 + echo "the guard stayed green on the old lock behaviour" >&2 + exit 1 + fi + cp "$RUNNER_TEMP/flang_repl.c" bootstrap/flang_repl.c + cmp bootstrap/flang_repl.c "$RUNNER_TEMP/flang_repl.c" + make -C bootstrap -j"$(nproc)" + - name: Check lock forms + run: bootstrap/flang run-script lock-forms:check diff --git a/bootstrap/flang_repl.c b/bootstrap/flang_repl.c index b7ad01558..d9d5e7c5c 100644 --- a/bootstrap/flang_repl.c +++ b/bootstrap/flang_repl.c @@ -19421,6 +19421,26 @@ static bool lock_scan(const char *full, const char *text, size_t bytes, char **n char *relative = NULL; char *target = NULL; if (!zn_field_text(imports[inner], "from", &from, &from_bytes)) { + const char *wanted = NULL; + size_t wanted_bytes = 0; + if (zn_field_text(imports[inner], "category", &wanted, &wanted_bytes) && wanted_bytes != 0) { + repl_strings found; + char *asked = repl_dup(wanted, wanted_bytes); + size_t place = 0; + strings_init(&found); + repl_find_module(full, asked, &found); + for (place = 0; place < found.count; place += 1) { + const char *target = found.items[place]; + if (strings_has(seen, target, strlen(target))) { + continue; + } + strings_say(seen, target); + strings_say(queue_paths, target); + strings_add(queue_names, wanted, wanted_bytes); + } + strings_free(&found); + free(asked); + } continue; } relative = repl_dup(from, from_bytes); @@ -19444,6 +19464,9 @@ static bool lock_scan(const char *full, const char *text, size_t bytes, char **n return true; } +static bool pkg_is_package(const char *path); +static bool pkg_take_nested(const char *file, const char *root, lock_modules *out); + /* * Обход замыкания «использует» с чтением файлов — то же, что делает * `собратьЗамок` свидетеля, и в том же порядке: очередь в ширину от входа, @@ -19472,7 +19495,12 @@ static bool lock_collect(const char *entry, const char *root, const char *entry_ char *name = NULL; size_t functions = 0; size_t bytes = 0; - char *text = repl_read_file(file, &bytes); + char *text = NULL; + if (at > 0 && pkg_is_package(file)) { + ok = pkg_take_nested(file, root, out); + continue; + } + text = repl_read_file(file, &bytes); if (text == NULL) { fprintf(stderr, "FLANG_CLI: не прочитан файл %s\n", file); ok = false; diff --git a/docs/DESCRIPTION.md b/docs/DESCRIPTION.md index a4d548583..60e15295f 100644 --- a/docs/DESCRIPTION.md +++ b/docs/DESCRIPTION.md @@ -1440,8 +1440,9 @@ $ flang io доводы.flang -- раз два три Модули стандартной библиотеки импортируются по имени, например `использует «Lists»`. -`flang lock` печатает lock-файл — JSON с исходниками модулей, импортированных -формой `из "путь"`, и sha256 каждого. Если файл `flang.lock` лежит рядом с +`flang lock` печатает lock-файл — JSON с исходниками всех модулей замыкания и +sha256 каждого: и названных формой `из "путь"`, и найденных по имени, и +привезённых пакетом `.flang-package`. Если файл `flang.lock` лежит рядом с программой, команды берут эти модули из него, и исходники на диске не нужны. `flang package` печатает пакет: тот же JSON с именем и версией из файла @@ -1670,8 +1671,6 @@ script.site:build = node docs/site/build.mjs не полностью: `flang check` отвечает кодом 2, `flang emit` на программе с морфизмами, моноидами или монадами — кодом 3. На программе с процессами `flang check --proof` отвечает кодом 0, хотя `flang check` — кодом 2. -- В lock-файл `flang lock` попадают только модули, импортированные формой - `из "путь"`; модуль, найденный по имени, в него не записывается. - Независимый checker перепроверяет не каждое доказательство: часть мест он принимает со слов ядра и называет их в отчёте. На пробе [`step-by-restricted-postcondition.flang`](../flang/proof/checker/tests/families/citation/step-by-restricted-postcondition.flang) diff --git a/docs/adr/0059-the-registry-is-a-ledger-of-names-not-a-store-of-code.md b/docs/adr/0059-the-registry-is-a-ledger-of-names-not-a-store-of-code.md index 803fde731..70a11006a 100644 --- a/docs/adr/0059-the-registry-is-a-ledger-of-names-not-a-store-of-code.md +++ b/docs/adr/0059-the-registry-is-a-ledger-of-names-not-a-store-of-code.md @@ -93,6 +93,13 @@ ADR-0021 обещает воспроизводимость: «После уст двоичным. Пакет из реестра рядом с двоичным не лежит, и для него тот же прогон даст отказ. +**Замок после правки задачи 2031.** `flang lock` замыкает все три формы: по +имени — код 0, **модулей 3**; `из "путь"` на `.flang` — код 0, **модулей 3** +(замыкание `hmac.flang` само ввозит модули по имени); пакет по пути — **код 0**, +модулей 1. У каждой формы модулей ровно «файлов вместе с импортами» минус +входной файл. Сторож — `scripts/guards/lock-closes-every-form.fscript` +(`lock-forms:check`). + **Дерево после прогонов.** План `«Собрать реестр»` из `scripts/registry-tool.fscript` пишет в `scripts/registry-example/registry.list` и во время замера его перезаписал (4 строки из 7); файл возвращён @@ -212,19 +219,32 @@ ADR-0021 обещает воспроизводимость: «После уст ## 7. Как разрешение сдаётся прибором, а не обещанием -Четыре прогона, у каждого своя подделка. Прибор кладёт задача 4909; корпус -случаев — `packaging/registry/cases/`, сторож — `scripts/guards/`. +Четыре прогона, у каждого своя подделка. Корпус +случаев — `packaging/registry/cases/`, сторож — +`scripts/guards/registry-resolution-guard.fscript`, работа CI — +`registry-resolution` в `.github/workflows/ci.yml`. -| что проверяется | прогон | подделка, на которой сторож ОБЯЗАН покраснеть | состояние 4 октября 2026 | +| что проверяется | прогон | подделка, на которой сторож ОБЯЗАН покраснеть | состояние | |---|---|---|---| -| ответ не зависит от порядка строк ведомости | разрешение на N перестановок, ответы сверяются побайтово | убрать из ведомости версию, которая выбиралась: ответ обязан измениться | измерено руками: 7 порядков → 1 ответ; подделка меняет ответ. Сторожа нет | -| ведомость согласна с файлами | пересчёт `sha256` каждого адреса против поля `отпечаток` | подкрутить один знак отпечатка | план есть, **краснеет сегодня: 3 из 7** (§4). CI его не зовёт | -| отказ назван, а не проглочен | четыре запроса из таблицы §5 | снять причину из текста отказа — сторож сверяет код И текст | измерено руками, четыре кода. Сторожа нет | -| замок замыкает поставленное | поставить пакет, собрать замок, собрать программу в пустом каталоге | тот же каталог без замка обязан отказать | **невозможно сегодня** (§3). Задача 2031 | +| ответ не зависит от порядка строк ведомости | разрешение на N перестановок, ответы сверяются побайтово | убрать из ведомости версию, которая выбиралась: ответ обязан измениться | **сдано прибором** (`registry-resolution:check`): случаев 6, порядков ведомости 20, снятых выбранных записей 4, код 0. Снятие `Логика 1.2.0` краснит сторожа кодом 1 | +| ведомость согласна с файлами | пересчёт `sha256` каждого адреса против поля `отпечаток` | подкрутить один знак отпечатка | **сошлось: 7 из 7** (`registry-prints:check`, код 0). Подкрученный знак — «не сошлось: 1, сошлось 6», код 1. CI зовёт работой `registry-resolution` | +| отказ назван, а не проглочен | четыре запроса из таблицы §5 | снять причину из текста отказа — сторож сверяет код И текст | **сдано прибором**: четыре кода и четыре текста знак в знак; план `Forgery` краснит все 6 случаев кодом 1 | +| замок замыкает поставленное | поставить пакет, собрать замок, собрать программу в пустом каталоге | тот же каталог без замка обязан отказать | **сдано прогоном** (задача 2031): `flang lock` над `shop.flang` — код 0, в пустом каталоге `flang check` код 0 и «файлов вместе с импортами 2», без замка — `FLANG_PACKAGE`, код 1. Сторож `lock-forms:check` держит все три формы | Первая строка — та, ради которой §5 несёт подделку. Сверка «ответ один на всех перестановках» без неё зеленеет и на приборе, который вовсе не читает ведомость. +Корпус — два файла. `ledger.list` — своя копия ведомости в формате реестра: +корпус отвечает одно и то же, когда ведомость примера меняют. `resolution.cases` +— случаи, по строке «ключ = значение» на поле, значение режется по первому +«=». Случай начинается ключом `случай` (имя, которым его называет сторож) и +кончается перед следующим `случай`. `род` — `выбор` или `отказ`; `нужды` — +запрос, как его пишут в `request.needs`; `строчка` — лишняя строка ведомости +для случаев порчи самой ведомости; `ответ` — одна выбранная запись «имя версия +адрес», строк столько, сколько пакетов в ответе, и порядок строк значим; `код` +и `причина` — код и текст отказа, знак в знак. Пути поручений `flang io` считает +от каталога плана, поэтому сторож называет корпус путём от своего каталога. + ## 8. ADR-0012 не задет — и вот чем это снято Запрет, который легко спутать с этим решением, лежит **не в ADR-0012.** diff --git a/docs/tasks/2031-no-form-of-dependency-a-registry-delivers-reaches-the-lock.md b/docs/tasks/2031-no-form-of-dependency-a-registry-delivers-reaches-the-lock.md index 4a62c5ddc..b11e9510a 100644 --- a/docs/tasks/2031-no-form-of-dependency-a-registry-delivers-reaches-the-lock.md +++ b/docs/tasks/2031-no-form-of-dependency-a-registry-delivers-reaches-the-lock.md @@ -1,10 +1,10 @@ --- номер: 2031 заголовок: Замок не записывает ни одну форму зависимости, которую умеет доставить реестр: по имени — ноль модулей, на пакет — FLANG_PARSE -статус: свободна +статус: сделана — обе формы попадают в замок: по имени модулей 3 при «файлах вместе с импортами 4», пакет по пути отвечает кодом 0; сквозной опыт в пустом каталоге прогнан (с замком код 0 и «файлов вместе с импортами 2», без замка FLANG_PACKAGE и код 1); сторож lock-forms:check держит все три формы, подлог краснит его кодом 1; правка легла ТОЛЬКО в flang/src/emit/c — быстрый пересев семени, не перепечатка приоритет: P1 -исполнитель: — -ветка: — +исполнитель: a +ветка: a/the-registry-properties-and-the-js-twin команда: любая карта: Что мешает больше всего рядом: 3401, 3402, 3403, 4909, 6990 @@ -68,6 +68,64 @@ $ bootstrap/flang lock flang/stdlib/hmac.flang | wc -c имён, и от пакетов. Для зависимости, приехавшей из реестра, обхода нет: её код лежит в `.flang-package`, а эту форму замок отвергает. +## Что сделано + +**Две правки, обе в `flang/src/emit/c/flang_repl.c`.** + +1. `lock_scan`: у ввоза БЕЗ ключа `"from"` (`использует «Списки»`) стояло + `continue` — имя просто выбрасывалось. Теперь оно разрешается тем же + `repl_find_module`, которым пользуется загрузчик: свой список мест означал бы, + что замок пишет не тот файл, который соберётся. +2. `lock_collect`: встреченный `.flang-package` раскрывается целиком через + `pkg_take_nested` — то же тело, что у пакета над пакетом, — а не отдаётся + разбору flang. Два объявления (`pkg_is_package`, `pkg_take_nested`) вынесены + вперёд: замок встречает пакет раньше, чем они определены. + +**Прогон 4 октября 2026 после правки, двоичный 0.7.24:** + +``` +$ bootstrap/flang lock docs/examples/web/orders-api.flang | wc -c +109766 код 0 + модули: 3 записи — Dictionary, String sets, Strings + flang check над тем же файлом: «файлов вместе с импортами 4» — сходится + +$ bootstrap/flang lock docs/examples/package/shop/shop.flang + код 0 + модули: 1 запись, «Скидка», ./discount.flang-package + +$ bootstrap/flang lock flang/stdlib/hmac.flang | wc -c +168237 код 0 + модули: 3 записи — Numbers, SHA-256, UTF-8 (было 1) +``` + +Третья строка — контроль, и он тоже сдвинулся: у `hmac.flang` замыкание шло +через `sha256.flang`, который ввозит `Numbers` и `UTF-8` ПО ИМЕНИ, и эти два +модуля терялись молча. То есть «модулей 1» в прежнем замере было не границей +формы `из "путь"`, а тем же дефектом внутри неё. + +**Сквозной опыт в пустом каталоге прогнан целиком:** + +``` +$ bootstrap/flang lock docs/examples/package/shop/shop.flang > /вне-дерева/flang.lock + код 0 +$ ls /вне-дерева # flang.lock и shop.flang +$ cd /вне-дерева && flang check shop.flang + код 0, «файлов вместе с импортами 2» +$ rm flang.lock && flang check shop.flang + FLANG_PACKAGE: пакет …/discount.flang-package не прочитан, код 1 +``` + +**Прибор.** `scripts/guards/lock-closes-every-form.fscript` +(`lock-forms:check`) над всеми тремя формами сверяет длину списка `модули` с +числом «файлов вместе с импортами» минус входной файл. Прогон: «форм 3; по имени +— модулей 3 при файлах 4; пакет — модулей 1 при файлах 2; из пути — модулей 3 +при файлах 4», код 0. Цена — 9 с: `flang check --fast` даёт то же число файлов, +что полная проверка, но 3,5 с против 149 с на `hmac.flang`. +Подлог (план `Forgery`) подменяет измеренную длину нулём — прежним поведением +замка на форме по имени: код 1, краснеют все три формы, каждая названа вместе с +обоими числами. Сторожа зовут работа CI `registry-resolution` и +`.githooks/pre-push.fscript` (проверок стало 24). + ## Когда задача сделана Сквозной прогон с контрольным опытом, оба обязательны: @@ -99,7 +157,12 @@ $ rm flang.lock && flang check shop.flang `flang/src/emit/c/flang_repl.c`, `lock_print`. Разбор `.flang-package` как источника модуля живёт рядом со связыванием (`flang/self/link.flang`). -**Доставка правки.** Если правка ложится только в `flang/src/emit/c/**` — быстрый -пересев семени. Если в `flang/self/**` — полная перепечатка; по карте ADR-0021 -это «4 ч 41 мин и 36,3 ГиБ» (число оттуда, в этой задаче не перемерено). -Которая из двух — выяснить первым делом и записать здесь числом. +**Доставка правки. ВЫЯСНЕНО 4 октября 2026: БЫСТРЫЙ ПЕРЕСЕВ.** Правка легла +ТОЛЬКО в `flang/src/emit/c/flang_repl.c` — `flang/self/**` не тронут ни строкой. +`flang/self/cli.flang:400`, названный выше, оказался не тем местом: там стоит +разбор ТЕМЫ СПРАВКИ (`если «команда» равен "lock" то «Справка замка»`), а +решение «класть модуль в замок» принимается в C — `lock_scan` и `lock_collect`. +Пересев: `bootstrap/flang run-script seed:refresh` — «шапка 9 строк + источник +21 460 строк», заслоны `--telo` и `seed-runtime-is-source` зелены, двоичный +собран, версия `flang 0.7.24`. Полная перепечатка (по карте ADR-0021 «4 ч 41 мин +и 36,3 ГиБ») НЕ ПОНАДОБИЛАСЬ. diff --git a/docs/tree-inventory.md b/docs/tree-inventory.md index 1a3ce84a9..91c1acf44 100644 --- a/docs/tree-inventory.md +++ b/docs/tree-inventory.md @@ -83,7 +83,7 @@ $ bootstrap/flang io scripts/guards/tree-inventory.fscript --max-steps 50000000 | язык | файлов | строк | долг файлов | долг строк | |---|---:|---:|---:|---:| | оболочка | 46 | 8 359 | 41 | 4 129 | -| C | 45 | 914 847 | 1 | 107 | +| C | 45 | 914 903 | 1 | 107 | | C++ | 2 | 511 | 1 | 107 | | Python | 5 | 3 068 | 0 | 0 | | HTML | 6 | 412 | 0 | 0 | @@ -168,8 +168,8 @@ flang в C. | довод | что под ним | файлов | строк | |---|---|---:|---:| -| напечатано самим компилятором | `bootstrap/**` — шесть файлов на C, вывод печати | 6 | 859 483 | -| рантайм цели печати | `flang/src/emit/{c,cpp,python,java,csharp,elixir,go,rust}/**` — уезжает в напечатанную программу дословно | 29 | 55 797 | +| напечатано самим компилятором | `bootstrap/**` — шесть файлов на C, вывод печати | 6 | 859 511 | +| рантайм цели печати | `flang/src/emit/{c,cpp,python,java,csharp,elixir,go,rust}/**` — уезжает в напечатанную программу дословно | 29 | 55 825 | | замеряемый материал | `benchmarks/**` без оболочки и без оснастки на Python (`tasks.py` — набор задач замера, он материал) плюс `flang/concurrency/bench/beam.erl` — это то, с чем сравнивают | 12 | 3 217 | | проба рантайма C | `flang/test/oblast/*.c` и `flang/concurrency/bench/sizes.c` — двенадцать проб памяти, их заголовок и размеры записей; на flang они проверяли бы не рантайм, а себя. Гоняет их `scripts/targets/region-in-c-target.flang`, уже написанный на flang | 14 | 674 | | чужая среда: редактор | `docs/editors/vim/**` — vim и neovim грузят только vimscript и Lua | 11 | 619 | diff --git a/flang/src/emit/c/flang_repl.c b/flang/src/emit/c/flang_repl.c index 0499ecbea..a30827aa4 100644 --- a/flang/src/emit/c/flang_repl.c +++ b/flang/src/emit/c/flang_repl.c @@ -19412,6 +19412,26 @@ static bool lock_scan(const char *full, const char *text, size_t bytes, char **n char *relative = NULL; char *target = NULL; if (!zn_field_text(imports[inner], "from", &from, &from_bytes)) { + const char *wanted = NULL; + size_t wanted_bytes = 0; + if (zn_field_text(imports[inner], "category", &wanted, &wanted_bytes) && wanted_bytes != 0) { + repl_strings found; + char *asked = repl_dup(wanted, wanted_bytes); + size_t place = 0; + strings_init(&found); + repl_find_module(full, asked, &found); + for (place = 0; place < found.count; place += 1) { + const char *target = found.items[place]; + if (strings_has(seen, target, strlen(target))) { + continue; + } + strings_say(seen, target); + strings_say(queue_paths, target); + strings_add(queue_names, wanted, wanted_bytes); + } + strings_free(&found); + free(asked); + } continue; } relative = repl_dup(from, from_bytes); @@ -19435,6 +19455,9 @@ static bool lock_scan(const char *full, const char *text, size_t bytes, char **n return true; } +static bool pkg_is_package(const char *path); +static bool pkg_take_nested(const char *file, const char *root, lock_modules *out); + /* * Обход замыкания «использует» с чтением файлов — то же, что делает * `собратьЗамок` свидетеля, и в том же порядке: очередь в ширину от входа, @@ -19463,7 +19486,12 @@ static bool lock_collect(const char *entry, const char *root, const char *entry_ char *name = NULL; size_t functions = 0; size_t bytes = 0; - char *text = repl_read_file(file, &bytes); + char *text = NULL; + if (at > 0 && pkg_is_package(file)) { + ok = pkg_take_nested(file, root, out); + continue; + } + text = repl_read_file(file, &bytes); if (text == NULL) { fprintf(stderr, "FLANG_CLI: не прочитан файл %s\n", file); ok = false; diff --git a/packaging/registry/cases/ledger.list b/packaging/registry/cases/ledger.list new file mode 100644 index 000000000..9b633e4d6 --- /dev/null +++ b/packaging/registry/cases/ledger.list @@ -0,0 +1,8 @@ +# реестр flang, схема 1: имя | версия | отпечаток sha256 | адрес | нужды +Логика | 1.0.0 | 1dc6da94a777a731150d896e28d9b20ce0afd6ca876b0cafe1c0d0d3d0b4c864 | registry-example/logic-1.0.0.flang-package | +Логика | 1.2.0 | b2bda19546f5cbb2b7642a80f54458197bca3dfde517983356080a11c62870d2 | registry-example/logic-1.2.0.flang-package | +Логика | 2.0.0 | 5374735fb59ebaf5e374ffa1e4a985a8b66616f35a45f4cd35244697ed91c965 | registry-example/logic-2.0.0.flang-package | +Списки | 1.4.2 | 802d716b62ea8918ded9cdda7ed2fd04c16aa97da4d519381e3c98e4e3f5ccc9 | registry-example/lists-1.4.2.flang-package | Логика: не ниже 1.0.0 +Множество строк | 1.0.0 | cf3a1697ccc1e7c2fa4fd72b3210ad5372590c0844f13e07119fa290a1f69931 | registry-example/sets-1.0.0.flang-package | Логика: не ниже 1.0.0 +Множество строк | 1.1.0 | a9a776e153d9789c7e29f8c66ad92df36a834f21630c6388b41ebd4f8d2effc2 | registry-example/sets-1.1.0.flang-package | Списки: в пределах 1.x; Логика: в пределах 1.x +Опциональное значение | 0.9.0 | 17eac86ce77be366094d22be0f537d4bab5bb00958fb41df3bd7353060957c7d | registry-example/optional-0.9.0.flang-package | Логика: ровно 2.0.0 diff --git a/packaging/registry/cases/resolution.cases b/packaging/registry/cases/resolution.cases new file mode 100644 index 000000000..0f2ce8804 --- /dev/null +++ b/packaging/registry/cases/resolution.cases @@ -0,0 +1,36 @@ +случай = ромб поднимается до старшей годной +род = выбор +нужды = Множество строк: не ниже 1.1 +ответ = Множество строк 1.1.0 registry-example/sets-1.1.0.flang-package +ответ = Списки 1.4.2 registry-example/lists-1.4.2.flang-package +ответ = Логика 1.2.0 registry-example/logic-1.2.0.flang-package + +случай = одна нужда на одно имя разрешается прямо +род = выбор +нужды = Логика: ровно 2.0.0 +ответ = Логика 2.0.0 registry-example/logic-2.0.0.flang-package + +случай = три диапазона на одно имя вместе не выполнимы +род = отказ +нужды = Множество строк: не ниже 1.1; Опциональное значение: любая +код = FLANG_REESTR_KONFLIKT +причина = пакет «Логика»: требования «в пределах 1.x» (от «Множество строк» 1.1.0) и «ровно 2.0.0» (от «Опциональное значение» 0.9.0) и «не ниже 1.0.0» (от «Списки» 1.4.2) вместе не выполнимы; реестр знает версии: 1.0.0, 1.2.0, 2.0.0 + +случай = имени нет в ведомости вовсе +род = отказ +нужды = Нетакого: любая +код = FLANG_REESTR_KONFLIKT +причина = пакет «Нетакого»: требования «любая» (от запрос) вместе не выполнимы; реестр знает версии: ни одной + +случай = диапазон записан не той формой +род = отказ +нужды = Логика: в пределах 1.2 +код = FLANG_REESTR_ZAPROS +причина = нужда «Логика: в пределах 1.2»: «в пределах 1.2»: ждали «1.x» или «1.2.x» — последней частью обязан стоять «x» + +случай = строка ведомости короче пяти полей +род = отказ +нужды = Логика: любая +строчка = Логика | 1.0.0 +код = FLANG_REESTR_STROKA +причина = строка «Логика | 1.0.0»: ждали «имя | версия | отпечаток | адрес | нужды», а полей 2 diff --git a/scripts/guards/lock-closes-every-form.fscript b/scripts/guards/lock-closes-every-form.fscript new file mode 100644 index 000000000..a93b5efce --- /dev/null +++ b/scripts/guards/lock-closes-every-form.fscript @@ -0,0 +1,306 @@ +модуль «Lock closes every form» + +примечание "СТОРОЖ ЗАМКА: записал ли он столько модулей, сколько насчитал импортами check." +примечание " bootstrap/flang run-script lock-forms:check сверка трёх форм, код 1 при беде" +примечание " bootstrap/flang run-script lock-forms:forgery подлог: сторож обязан покраснеть" + +примечание "ЗАЧЕМ. ADR-0021 п. 4 обещает, что после установки зовётся готовый flang lock, а" +примечание "ADR-0059 §6 п. 4 делает условием приёмки реестра замыкание замка. 4 октября 2026" +примечание "замок не записывал НИ ОДНУ форму зависимости, которую умеет доставить реестр:" +примечание "по имени он писал модули: [] при четырёх файлах у check, а пакет по пути отдавал" +примечание "разбору flang и отвечал FLANG_PARSE. Задача 2031." + +примечание "ЧТО СВЕРЯЕТСЯ. Над каждой из трёх форм гоняются два прогона двоичного: flang" +примечание "lock даёт длину списка модули, flang check --fast даёт «файлов вместе с импортами" +примечание "N». Длина обязана быть N минус один: входной файл в груз замка не едет. Ключ" +примечание "--fast взят не для скорости ради скорости: без него тот же замер стоит 149 с на" +примечание "одной форме (hmac) против 3,5 с, а число файлов обе формы команды печатают одно" +примечание "и то же. Код возврата 4 у --fast законен — он и значит «часть проверок не" +примечание "запускалась»." + +примечание "ПОДЛОГ. План Forgery подменяет ИЗМЕРЕННУЮ длину списка нулём — ровно прежним" +примечание "поведением замка на форме по имени. Сторож обязан покраснеть и назвать форму и" +примечание "оба числа; молчание значит, что сверка смотрит не туда." + +объект «Form» + «name»: строка + «path»: строка + +объект «Found» + «name»: строка + «modules»: число + «files»: число + +тип «Step» + вариант «Locking» содержит bad: признак, rest: список «Form», got: список «Found» + вариант «Checking» содержит bad: признак, now: «Form», took: число, rest: список «Form», got: список «Found» + +тотальная функция «Binary» + возвращает строка + пример «Двоичный назван путём от каталога сторожа» + ожидается "../../bootstrap/flang" + "../../bootstrap/flang" + +тотальная функция «Forms» + возвращает список «Form» + обеспечивает «форм ровно три» (длина результат) равен 3 + [(запись «Form» с «name» равным "по имени" и «path» равным "../../docs/examples/web/orders-api.flang"), + (запись «Form» с «name» равным "пакет" и «path» равным "../../docs/examples/package/shop/shop.flang"), + (запись «Form» с «name» равным "из пути" и «path» равным "../../flang/stdlib/hmac.flang")] + +тотальная функция «Module mark» + возвращает строка + пример «Запись груза открывается полем имени» + ожидается "{\"имя\":" + "{\"имя\":" + +тотальная функция «Files mark» + возвращает строка + пример «Число файлов стоит за этими словами» + ожидается "файлов вместе с импортами " + "файлов вместе с импортами " + +тотальная функция «Count of» + принимает text: строка, mark: строка + возвращает число + пример «Две записи» + дано text равно "[{\"имя\":1},{\"имя\":2}]" + дано mark равно "{\"имя\":" + ожидается 2 + пример «Ни одной записи» + дано text равно "[]" + дано mark равно "{\"имя\":" + ожидается 0 + (длина (разделить text по mark)) минус 1 + +тотальная функция «Before mark» + принимает text: строка, mark: строка + возвращает строка + пример «До первой метки» + дано text равно "раз\nдва" + дано mark равно "\n" + ожидается "раз" + голова (разделить text по mark) + +тотальная функция «After mark» + принимает text: строка, mark: строка + возвращает строка + пример «За меткой — остаток» + дано text равно "а: 4\nб" + дано mark равно "а: " + ожидается "4\nб" + соединить (хвост (разделить text по mark)) по mark + +тотальная функция «Number of» + принимает text: строка + возвращает число + пример «Число из цифр» + дано text равно "12" + ожидается 12 + пример «Не число — минус один» + дано text равно "х" + ожидается -1 + разбор (к числу или беда text) + случай вариант «Разобрано» с значение как value + то value + случай вариант «Не разобрано» с код как code и сообщение как words + то -1 + +тотальная функция «Files said» + принимает text: строка + возвращает число + пример «Число файлов стоит в конце строки сводки» + дано text равно "модуль «А»: типов 4; файлов вместе с импортами 4\nа: проверено\n" + ожидается 4 + пример «Строки сводки нет — минус один» + дано text равно "а: не проверено\n" + ожидается -1 + если не (text содержит («Files mark»)) + то -1 + иначе «Number of» от («Before mark» от («After mark» от text и («Files mark»)) и "\n") + +тотальная функция «Lock order» + принимает form: «Form» + возвращает «Поручение» + пример «Замок строится двоичным дерева» + дано form равно (запись «Form» с «name» равным "а" и «path» равным "п") + ожидается вариант «Запустить процесс» с программа равным "../../bootstrap/flang" и аргументы равным ["lock", "п"] + вариант «Запустить процесс» с программа равным («Binary») и аргументы равным ["lock", (form.«path»)] + +тотальная функция «Fast keys» + принимает path: строка + возвращает список строки + пример «Проверка идёт быстрым ключом» + дано path равно "п" + ожидается ["check", "--fast", "п"] + ["check", "--fast", path] + +тотальная функция «Check order» + принимает form: «Form» + возвращает «Поручение» + вариант «Запустить процесс» с программа равным («Binary») и аргументы равным («Fast keys» от (form.«path»)) + +тотальная функция «Doing» + принимает order: «Поручение», onward: «Step» + возвращает «Продолжение» + вариант «Сделать» с поручение равным order и потом равным onward + +тотальная функция «Broke» + принимает form: «Form», words: строка + возвращает «Продолжение» + пусть said равно (соединить ["замок по формам: форма «", (form.«name»), "»: ", words] по "") + вариант «Не проверено» с код равным "FLANG_LOCK_FORMS_NOT_JUDGED" и сообщение равным said + +тотальная функция «Faulted» + принимает one: «Found» + возвращает список строки + пример «Сошедшаяся форма беды не даёт» + дано one равно (запись «Found» с «name» равным "а" и «modules» равным 3 и «files» равным 4) + ожидается пустой список + пусть words равно (соединить ["форма «", (one.«name»), "»: в замке модулей ", (к строке (one.«modules»)), + ", а check насчитал файлов вместе с импортами ", (к строке (one.«files»)), " — ждали ", + (к строке ((one.«files») минус 1))] по "") + если (one.«modules») равен ((one.«files») минус 1) + то пустой список + иначе [words] + +тотальная функция «Faults step» + принимает found: список строки, one: «Found» + возвращает список строки + пусть mine равно («Faulted» от one) + свёртка mine начиная с found как kept и words → добавить words к kept + +тотальная функция «Faults» + принимает got: список «Found» + возвращает список строки + свёртка got начиная с (пустой список) как found и one → «Faults step» от found и one + +тотальная функция «Numbers» + принимает got: список «Found» + возвращает строка + пусть said равно (отобразить got как one → соединить [(one.«name»), " — модулей ", + (к строке (one.«modules»)), " при файлах ", (к строке (one.«files»))] по "") + соединить ["замок по формам: форм ", (к строке (длина got)), "; ", (соединить said по "; ")] по "" + +тотальная функция «Verdict of run» + принимает got: список «Found» + возвращает «Продолжение» + пусть found равно («Faults» от got) + пусть said равно (соединить (приписать («Numbers» от got) к found) по "\n · ") + если (длина found) равен 0 + то вариант «Конец работы» с значение равным («Numbers» от got) + иначе вариант «Провал» с код равным "FLANG_LOCK_FORMS" и сообщение равным said + +тотальная функция «Forged took» + принимает bad: признак, took: число + возвращает число + пример «Подлог возвращает прежнее поведение замка» + дано bad равно да + дано took равно 3 + ожидается 0 + если bad то 0 иначе took + +тотальная функция «Wait check» + принимает bad: признак, now: «Form», took: число, rest: список «Form», got: список «Found» + возвращает «Step» + вариант «Checking» с bad равным bad и now равным now и took равным took и rest равным rest и got равным got + +тотальная функция «Onward from lock» + принимает bad: признак, rest: список «Form», got: список «Found», output: строка + возвращает «Продолжение» + разбор rest + случай пусто + то «Verdict of run» от got + случай голова и хвост + то пусть counted равно («Forged took» от bad и («Count of» от output и («Module mark»))) + «Doing» от («Check order» от голова) и («Wait check» от bad и голова и counted и хвост и got) + +тотальная функция «After lock» + принимает bad: признак, rest: список «Form», got: список «Found», reply: «Отклик» + возвращает «Продолжение» + разбор reply + случай вариант «Пока ничего» + то «Start locking» от bad и rest и got + случай вариант «Процесс завершён» с код как code и вывод как output и ошибки как errors + то если code равен 0 + то «Onward from lock» от bad и rest и got и output + иначе «Broke» от («Head form» от rest) и (соединить ["flang lock ответил кодом ", + (к строке code), ": ", errors] по "") + случай любое + то вариант «Провал» с код равным "FLANG_IO_ORDER" и сообщение равным "ждали ответ flang lock" + +тотальная функция «Head form» + принимает rest: список «Form» + возвращает «Form» + пример «Пустой список формы не несёт» + дано rest равно пустой список + ожидается запись «Form» с «name» равным "" и «path» равным "" + разбор rest + случай пусто + то запись «Form» с «name» равным "" и «path» равным "" + случай голова и хвост + то голова + +тотальная функция «Wait lock» + принимает bad: признак, rest: список «Form», got: список «Found» + возвращает «Step» + вариант «Locking» с bad равным bad и rest равным rest и got равным got + +тотальная функция «Start locking» + принимает bad: признак, rest: список «Form», got: список «Found» + возвращает «Продолжение» + разбор rest + случай пусто + то «Verdict of run» от got + случай голова и хвост + то «Doing» от («Lock order» от голова) и («Wait lock» от bad и rest и got) + +тотальная функция «Onward from check» + принимает bad: признак, now: «Form», took: число, rest: список «Form», got: список «Found», output: строка + возвращает «Продолжение» + пусть seen равно («Files said» от output) + пусть one равно (запись «Found» с «name» равным (now.«name») и «modules» равным took и «files» равным seen) + если seen не больше 0 + то «Broke» от now и "flang check не назвал числа файлов вместе с импортами" + иначе «Start locking» от bad и rest и (добавить one к got) + +тотальная функция «After check» + принимает bad: признак, now: «Form», took: число, rest: список «Form», got: список «Found», reply: «Отклик» + возвращает «Продолжение» + разбор reply + случай вариант «Процесс завершён» с код как code и вывод как output и ошибки как errors + то если (code равен 0) или (code равен 4) + то «Onward from check» от bad и now и took и rest и got и output + иначе «Broke» от now и (соединить ["flang check ответил кодом ", (к строке code), ": ", + errors] по "") + случай любое + то вариант «Провал» с код равным "FLANG_IO_ORDER" и сообщение равным "ждали ответ flang check" + +тотальная функция «Begin check» + возвращает «Step» + обеспечивает «сверка начинается без подлога» результат равен («Wait lock» от нет и («Forms») и пустой список) + «Wait lock» от нет и («Forms») и пустой список + +тотальная функция «Begin forgery» + возвращает «Step» + обеспечивает «подлог начинается так же, но с подменой» результат равен («Wait lock» от да и («Forms») и пустой список) + «Wait lock» от да и («Forms») и пустой список + +тотальная функция «Onward» + принимает step: «Step», reply: «Отклик» + возвращает «Продолжение» + разбор step + случай вариант «Locking» с bad как bad и rest как rest и got как got + то «After lock» от bad и rest и got и reply + случай вариант «Checking» с bad как bad и now как now и took как took и rest как rest и got как got + то «After check» от bad и now и took и rest и got и reply + +план «Check» + состояние «Step» + начинает с «Begin check» + обрабатывает «Onward» + +план «Forgery» + состояние «Step» + начинает с «Begin forgery» + обрабатывает «Onward» diff --git a/scripts/guards/registry-resolution-guard.fscript b/scripts/guards/registry-resolution-guard.fscript new file mode 100644 index 000000000..b3b4c5389 --- /dev/null +++ b/scripts/guards/registry-resolution-guard.fscript @@ -0,0 +1,688 @@ +модуль «Registry resolution guard» + использует «Registry» из "../../flang/stdlib/registry.flang" + +примечание "СТОРОЖ РАЗРЕШЕНИЯ ВЕРСИЙ: свойства 2 и 3 из ADR-0059 §7. Зовут тремя ярлыками:" +примечание " bootstrap/flang run-script registry-resolution:check сверка корпуса, код 1 при беде" +примечание " bootstrap/flang run-script registry-resolution:forgery подлог: сторож обязан покраснеть" +примечание " bootstrap/flang run-script registry-resolution:measure что прибор отвечает на каждый случай" + +примечание "СВОЙСТВО 2 — ответ не зависит от порядка строк ведомости. Каждый случай рода" +примечание "выбор гоняется на всех прокрутах ведомости и на обратном порядке, ответы" +примечание "сверяются побайтово. Семь записей дают восемь порядков." + +примечание "СВОЙСТВО 3 — отказ назван, а не проглочен. У случая рода отказ сверяется И код," +примечание "И текст причины, знак в знак: код без текста зеленел бы на отказе, который" +примечание "перестал называть диапазоны." + +примечание "ОТРИЦАТЕЛЬНЫЙ КОНТРОЛЬ ЖИВЁТ ВНУТРИ СВЕРКИ, а не рядом с ней. Один ответ на" +примечание "восемь порядков зеленеет и на приборе, который ведомость вовсе не читает —" +примечание "ровно та ошибка, в которую замер однажды упал. Поэтому на каждом случае выбора" +примечание "снимается по одной ВЫБРАННОЙ записи, и ответ ОБЯЗАН измениться; не изменился —" +примечание "сторож красен и называет снятую запись." + +примечание "КОРПУС лежит в packaging/registry/cases и назван путём от каталога сторожа:" +примечание "flang io считает пути поручений от каталога ПЛАНА, а не от текущего каталога." + +объект «Case» + «name»: строка + «lines»: список строки + +объект «Verdict» + «code»: строка + «text»: строка + «lines»: список строки + +тип «Step» + вариант «Awaiting ledger» содержит forged: признак, mode: строка + вариант «Awaiting probes» содержит forged: признак, mode: строка, ledger: строка + +тотальная функция «Ledger path» + возвращает строка + пример «Ведомость корпуса названа путём от каталога сторожа» + ожидается "../../packaging/registry/cases/ledger.list" + "../../packaging/registry/cases/ledger.list" + +тотальная функция «Cases path» + возвращает строка + пример «Случаи корпуса названы путём от каталога сторожа» + ожидается "../../packaging/registry/cases/resolution.cases" + "../../packaging/registry/cases/resolution.cases" + +тотальная функция «Fuel» + возвращает число + пример «Топлива столько же, сколько у постановщика» + ожидается 32 + 32 + +тотальная функция «Joined» от «А» + принимает left: список «А», right: список «А» + возвращает список «А» + пример «Два списка подряд» + дано left равно [1] + дано right равно [2] + ожидается [1, 2] + свёртка right начиная с left как kept и one → добавить one к kept + +тотальная функция «Dropped» от «А» + принимает items: список «А», count: число + возвращает список «А» + пример «Отбросить два» + дано items равно [1, 2, 3, 4] + дано count равно 2 + ожидается [3, 4] + пример «Отбросить больше длины» + дано items равно [1] + дано count равно 5 + ожидается пустой список + разбор items + случай пусто + то пустой список + случай голова и хвост + если count не больше 0 + то items + иначе «Dropped» от хвост и (count минус 1) + +тотальная функция «Counts to» + принимает limit: число + возвращает список числа + пример «От одного до трёх» + дано limit равно 3 + ожидается [1, 2, 3] + пример «Ноль даёт пусто» + дано limit равно 0 + ожидается пустой список + если limit не больше 0 + то пустой список + иначе добавить limit к («Counts to» от (limit минус 1)) + +тотальная функция «Backwards» от «А» + принимает items: список «А» + возвращает список «А» + пример «Три элемента наоборот» + дано items равно [1, 2, 3] + ожидается [3, 2, 1] + свёртка items начиная с (пустой список) как kept и one → «Joined» от [one] и kept + +тотальная функция «Up to» от «А» + принимает items: список «А», count: число + возвращает список «А» + пример «Первые два» + дано items равно [1, 2, 3, 4] + дано count равно 2 + ожидается [1, 2] + пример «Ноль первых — пусто» + дано items равно [1, 2] + дано count равно 0 + ожидается пустой список + пусть tail равно («Dropped» от («Backwards» от items) и ((длина items) минус count)) + «Backwards» от tail + +тотальная функция «First of» + принимает texts: список строки + возвращает строка + пример «Первый из двух» + дано texts равно ["а", "б"] + ожидается "а" + пример «Из пустого — пусто» + дано texts равно пустой список + ожидается "" + разбор texts + случай пусто + то "" + случай голова и хвост + то голова + +тотальная функция «Before mark» + принимает text: строка, sign: строка + возвращает строка + пример «До первой метки» + дано text равно "раз;два" + дано sign равно ";" + ожидается "раз" + голова (разделить text по sign) + +тотальная функция «Live lines» + принимает text: строка + возвращает список строки + пример «Пустые строки и примечания выброшены» + дано text равно "# шапка\nа = раз\n\nб = два\n" + ожидается ["а = раз", "б = два"] + пусть trimmed равно (отобразить (разделить text по "\n") как line → «Обрезать» от line) + отфильтровать trimmed где line → (не (line равен "")) и притом (не (line начинается с "#")) + +тотальная функция «Key of» + принимает line: строка + возвращает строка + пример «Ключ стоит до первого равенства» + дано line равно "нужды = Логика: ровно 2.0.0" + ожидается "нужды" + пример «Строка без равенства ключа не несёт» + дано line равно "нужды" + ожидается "" + если не (line содержит "=") + то "" + иначе «Обрезать» от («Before mark» от line и "=") + +тотальная функция «Value of» + принимает line: строка + возвращает строка + пример «Значение стоит после первого равенства и хранит следующие» + дано line равно "причина = ждали а = б" + ожидается "ждали а = б" + пример «Строка без равенства значения не несёт» + дано line равно "нужды" + ожидается "" + если не (line содержит "=") + то "" + иначе «Обрезать» от («После метки» от line и "=") + +тотальная функция «With line» + принимает probe: «Case», line: строка + возвращает «Case» + пример «Строка дописывается в конец, а не замещает» + дано probe равно (запись «Case» с «name» равным "раз" и «lines» равным ["а"]) + дано line равно "б" + ожидается (запись «Case» с «name» равным "раз" и «lines» равным ["а", "б"]) + запись «Case» с «name» равным (probe.«name») и «lines» равным (добавить line к (probe.«lines»)) + +тотальная функция «Into last» + принимает probes: список «Case», line: строка + возвращает список «Case» + пример «Строка ложится в последний заведённый случай» + дано probes равно [(запись «Case» с «name» равным "раз" и «lines» равным пустой список)] + дано line равно "род = отказ" + ожидается [(запись «Case» с «name» равным "раз" и «lines» равным ["род = отказ"])] + разбор («Backwards» от probes) + случай пусто + то пустой список + случай голова и хвост + то добавить («With line» от голова и line) к («Backwards» от хвост) + +тотальная функция «Fresh case» + принимает name: строка + возвращает «Case» + пример «Новый случай знает только своё имя» + дано name равно "раз" + ожидается (запись «Case» с «name» равным "раз" и «lines» равным пустой список) + запись «Case» с «name» равным name и «lines» равным пустой список + +тотальная функция «Take line» + принимает probes: список «Case», line: строка + возвращает список «Case» + пример «Ключ случая заводит новый случай в конце списка» + дано probes равно пустой список + дано line равно "случай = раз" + ожидается [(запись «Case» с «name» равным "раз" и «lines» равным пустой список)] + пример «Поле без заведённого случая пропадает» + дано probes равно пустой список + дано line равно "род = выбор" + ожидается пустой список + если («Key of» от line) равен "случай" + то добавить («Fresh case» от («Value of» от line)) к probes + иначе «Into last» от probes и line + +тотальная функция «Cases of» + принимает text: строка + возвращает список «Case» + пример «Два случая разбираются по порядку» + дано text равно "случай = раз\nрод = выбор\n\nслучай = два\nкод = К\n" + ожидается [(запись «Case» с «name» равным "раз" и «lines» равным ["род = выбор"]), + (запись «Case» с «name» равным "два" и «lines» равным ["код = К"])] + свёртка («Live lines» от text) начиная с (пустой список) как probes и line → «Take line» от probes и line + +тотальная функция «Fields» + принимает probe: «Case», key: строка + возвращает список строки + пример «Все значения одного ключа по порядку» + дано probe равно (запись «Case» с «name» равным "раз" и «lines» равным ["ответ = а", "ответ = б"]) + дано key равно "ответ" + ожидается ["а", "б"] + пусть kept равно (отфильтровать (probe.«lines») где line → («Key of» от line) равен key) + отобразить kept как line → «Value of» от line + +тотальная функция «Field» + принимает probe: «Case», key: строка + возвращает строка + пример «Ключа нет — пусто» + дано probe равно (запись «Case» с «name» равным "раз" и «lines» равным пустой список) + дано key равно "род" + ожидается "" + «First of» от («Fields» от probe и key) + +тотальная функция «Entry line» + принимает row: «Запись реестра» + возвращает строка + соединить [(row.«имя»), " ", («Версия строкой» от (row.«версия»)), " ", (row.«адрес»)] по "" + +тотальная функция «Chosen line» + принимает pick: «Выбор» + возвращает строка + соединить [(pick.«имя»), " ", («Версия строкой» от (pick.«версия»)), " ", (pick.«адрес»)] по "" + +тотальная функция «Resolved» + принимает picks: список «Выбор» + возвращает «Verdict» + пусть lines равно (отобразить picks как pick → «Chosen line» от pick) + запись «Verdict» с «code» равным "" и «text» равным "" и «lines» равным lines + +тотальная функция «Refused» + принимает code: строка, text: строка + возвращает «Verdict» + пример «Отказ несёт код и текст, а выбора не несёт» + дано code равно "К" + дано text равно "П" + ожидается (запись «Verdict» с «code» равным "К" и «text» равным "П" и «lines» равным пустой список) + запись «Verdict» с «code» равным code и «text» равным text и «lines» равным пустой список + +тотальная функция «Verdict text» + принимает verdict: «Verdict» + возвращает строка + пример «Отказ читается кодом и причиной» + дано verdict равно (запись «Verdict» с «code» равным "К" и «text» равным "П" и «lines» равным пустой список) + ожидается "К: П" + если (verdict.«code») равен "" + то соединить (verdict.«lines») по "\n" + иначе соединить [(verdict.«code»), ": ", (verdict.«text»)] по "" + +тотальная функция «Judge needs» + принимает rows: список «Запись реестра», needs: строка + возвращает «Verdict» + пусть gathered равно («Разобрать нужды» от needs и "запрос") + если не ((gathered.«беда») равен "") + то «Refused» от "FLANG_REESTR_ZAPROS" и (gathered.«беда») + иначе разбор («Разрешить» от rows и (gathered.«нужды») и («Fuel»)) + случай вариант «Не разрешено» с причина как why + то «Refused» от "FLANG_REESTR_KONFLIKT" и why + случай вариант «Разрешено» с выбор как picks + то «Resolved» от picks + +тотальная функция «Ledger of» + принимает ledger: строка, row: строка + возвращает «Реестр» + если row равен "" + то «Разобрать реестр» от ledger + иначе «Разобрать реестр» от (соединить [ledger, "\n", row] по "") + +тотальная функция «Rows of» + принимает ledger: строка, probe: «Case» + возвращает список «Запись реестра» + («Ledger of» от ledger и («Field» от probe и "строчка")).«записи» + +тотальная функция «Judge» + принимает ledger: строка, probe: «Case» + возвращает «Verdict» + пусть registry равно («Ledger of» от ledger и («Field» от probe и "строчка")) + если (длина (registry.«беды»)) больше 0 + то «Refused» от "FLANG_REESTR_STROKA" и («First of» от (registry.«беды»)) + иначе «Judge needs» от (registry.«записи») и («Field» от probe и "нужды") + +тотальная функция «Answer text» + принимает rows: список «Запись реестра», needs: строка + возвращает строка + «Verdict text» от («Judge needs» от rows и needs) + +тотальная функция «Rotated» + принимает rows: список «Запись реестра», turn: число + возвращает список «Запись реестра» + «Joined» от («Dropped» от rows и turn) и («Up to» от rows и turn) + +тотальная функция «Answers over orders» + принимает rows: список «Запись реестра», needs: строка + возвращает список строки + пусть turns равно (отобразить («Counts to» от (длина rows)) как turn → «Rotated» от rows и turn) + пусть orders равно (добавить («Backwards» от rows) к turns) + отобразить orders как order → «Answer text» от order и needs + +тотальная функция «Without» + принимает rows: список «Запись реестра», line: строка + возвращает список «Запись реестра» + отфильтровать rows где row → не ((«Entry line» от row) равен line) + +тотальная функция «About» + принимает probe: «Case», words: строка + возвращает строка + пример «Находка называет случай» + дано probe равно (запись «Case» с «name» равным "раз" и «lines» равным пустой список) + дано words равно "ответ разошёлся" + ожидается "раз: ответ разошёлся" + соединить [(probe.«name»), ": ", words] по "" + +тотальная функция «Said and measured» + принимает what: строка, said: строка, measured: строка + возвращает строка + пример «Расхождение называет обе стороны» + дано what равно "код" + дано said равно "А" + дано measured равно "Б" + ожидается "код разошёлся\n в корпусе: А\n прибор: Б" + соединить [what, " разошёлся\n в корпусе: ", said, "\n прибор: ", measured] по "" + +тотальная функция «Code faults» + принимает probe: «Case», verdict: «Verdict» + возвращает список строки + пусть said равно («Field» от probe и "код") + пусть words равно («Said and measured» от "код" и said и (verdict.«code»)) + если (verdict.«code») равен said + то пустой список + иначе [«About» от probe и words] + +тотальная функция «Reason faults» + принимает probe: «Case», verdict: «Verdict» + возвращает список строки + пусть said равно («Field» от probe и "причина") + пусть words равно («Said and measured» от "причина" и said и (verdict.«text»)) + если (verdict.«text») равен said + то пустой список + иначе [«About» от probe и words] + +тотальная функция «Refusal faults» + принимает probe: «Case», verdict: «Verdict» + возвращает список строки + пример «Сошедшийся отказ бед не даёт» + дано probe равно (запись «Case» с «name» равным "а" и «lines» равным ["код = К", "причина = П"]) + дано verdict равно (запись «Verdict» с «code» равным "К" и «text» равным "П" и «lines» равным пустой список) + ожидается пустой список + «Joined» от («Code faults» от probe и verdict) и («Reason faults» от probe и verdict) + +тотальная функция «Answer faults» + принимает probe: «Case», verdict: «Verdict» + возвращает список строки + пример «Сошедшийся выбор бед не даёт» + дано probe равно (запись «Case» с «name» равным "а" и «lines» равным ["ответ = а"]) + дано verdict равно (запись «Verdict» с «code» равным "" и «text» равным "" и «lines» равным ["а"]) + ожидается пустой список + пусть said равно (соединить («Fields» от probe и "ответ") по "\n") + пусть got равно («Verdict text» от verdict) + пусть words равно («Said and measured» от "ответ" и said и got) + если got равен said + то пустой список + иначе [«About» от probe и words] + +тотальная функция «Order fault» + принимает probe: «Case», one: строка, other: строка + возвращает список строки + пусть words равно (соединить ["ПОРЯДОК СТРОК ПОВЛИЯЛ НА ОТВЕТ\n порядок один: ", one, + "\n порядок другой: ", other] по "") + если other равен one + то пустой список + иначе [«About» от probe и words] + +тотальная функция «Order step» + принимает probe: «Case», one: строка, found: список строки, other: строка + возвращает список строки + «Joined» от found и («Order fault» от probe и one и other) + +тотальная функция «Order faults» + принимает probe: «Case», answers: список строки + возвращает список строки + пример «Один ответ на все порядки бед не даёт» + дано probe равно (запись «Case» с «name» равным "а" и «lines» равным пустой список) + дано answers равно ["а", "а"] + ожидается пустой список + пусть one равно («First of» от answers) + свёртка answers начиная с (пустой список) как found и other → «Order step» от probe и one и found и other + +тотальная функция «Removal fault» + принимает probe: «Case», rows: список «Запись реестра», base: строка, line: строка + возвращает список строки + пусть needs равно («Field» от probe и "нужды") + пусть words равно (соединить ["ВЕДОМОСТЬ НЕ ПРОЧИТАНА: снял выбранную запись ", line, + ", а ответ не изменился"] по "") + если не ((«Answer text» от («Without» от rows и line) и needs) равен base) + то пустой список + иначе [«About» от probe и words] + +тотальная функция «Removal step» + принимает probe: «Case», rows: список «Запись реестра», base: строка, found: список строки, line: строка + возвращает список строки + «Joined» от found и («Removal fault» от probe и rows и base и line) + +тотальная функция «Removal faults» + принимает probe: «Case», rows: список «Запись реестра», base: строка, lines: список строки + возвращает список строки + свёртка lines начиная с (пустой список) как found и line → «Removal step» от probe и rows и base и found и line + +тотальная функция «Pick faults» + принимает probe: «Case», ledger: строка + возвращает список строки + пусть rows равно («Rows of» от ledger и probe) + пусть verdict равно («Judge» от ledger и probe) + пусть needs равно («Field» от probe и "нужды") + пусть orders равно («Order faults» от probe и («Answers over orders» от rows и needs)) + пусть base равно («Answer text» от rows и needs) + пусть removals равно («Removal faults» от probe и rows и base и (verdict.«lines»)) + пусть answers равно («Answer faults» от probe и verdict) + «Joined» от («Joined» от answers и orders) и removals + +тотальная функция «Case faults» + принимает probe: «Case», ledger: строка + возвращает список строки + если («Field» от probe и "род") равен "отказ" + то «Refusal faults» от probe и («Judge» от ledger и probe) + иначе если («Field» от probe и "род") равен "выбор" + то «Pick faults» от probe и ledger + иначе [«About» от probe и "род не назван словом выбор или отказ"] + +тотальная функция «Faults step» + принимает ledger: строка, found: список строки, probe: «Case» + возвращает список строки + «Joined» от found и («Case faults» от probe и ledger) + +тотальная функция «Faults» + принимает ledger: строка, probes: список «Case» + возвращает список строки + свёртка probes начиная с (пустой список) как found и probe → «Faults step» от ledger и found и probe + +тотальная функция «Orders counted» + принимает ledger: строка, probe: «Case» + возвращает число + если («Field» от probe и "род") равен "выбор" + то (длина («Rows of» от ledger и probe)) плюс 1 + иначе 1 + +тотальная функция «Removals counted» + принимает ledger: строка, probe: «Case» + возвращает число + если («Field» от probe и "род") равен "выбор" + то длина ((«Judge» от ledger и probe).«lines») + иначе 0 + +тотальная функция «Sum of» + принимает numbers: список числа + возвращает число + пример «Сумма трёх» + дано numbers равно [1, 2, 3] + ожидается 6 + свёртка numbers начиная с 0 как total и each → total плюс each + +тотальная функция «Numbers» + принимает ledger: строка, probes: список «Case» + возвращает строка + пусть orders равно («Sum of» от (отобразить probes как probe → «Orders counted» от ledger и probe)) + пусть taken равно («Sum of» от (отобразить probes как probe → «Removals counted» от ledger и probe)) + соединить ["разрешение реестра: случаев ", (к строке (длина probes)), ", порядков ведомости ", + (к строке orders), ", снятых выбранных записей ", (к строке taken)] по "" + +тотальная функция «Stripped» + принимает text: строка + возвращает строка + пример «Из текста отказа снят перечень диапазонов и версий» + дано text равно "пакет: требования ровно вместе не выполнимы; реестр знает версии: 1.0.0" + ожидается "пакет: вместе не выполнимы" + пример «Из прочих отказов снято всё названное в ёлочках» + дано text равно "нужда «а»: ждали «x»" + ожидается "нужда " + если не (text содержит ": требования ") + то «Before mark» от text и "«" + иначе соединить [(«Before mark» от text и ": требования "), ": вместе не выполнимы"] по "" + +тотальная функция «Forged line» + принимает line: строка + возвращает строка + пример «Строке ответа дописан подлог» + дано line равно "ответ = а" + ожидается "ответ = а ПОДЛОГ" + пример «Из причины снят перечень» + дано line равно "причина = пакет: требования ровно вместе не выполнимы" + ожидается "причина = пакет: вместе не выполнимы" + если («Key of» от line) равен "ответ" + то соединить [line, " ПОДЛОГ"] по "" + иначе если («Key of» от line) равен "причина" + то соединить ["причина = ", («Stripped» от («Value of» от line))] по "" + иначе line + +тотальная функция «Forged case» + принимает probe: «Case» + возвращает «Case» + пусть lines равно (отобразить (probe.«lines») как line → «Forged line» от line) + запись «Case» с «name» равным (probe.«name») и «lines» равным lines + +тотальная функция «Corpus» + принимает forged: признак, text: строка + возвращает список «Case» + если forged + то отобразить («Cases of» от text) как probe → «Forged case» от probe + иначе «Cases of» от text + +тотальная функция «Measured line» + принимает ledger: строка, probe: «Case» + возвращает строка + пусть verdict равно («Judge» от ledger и probe) + если (verdict.«code») равен "" + то соединить ["случай = ", (probe.«name»), "\n ответ = ", + (соединить (verdict.«lines») по "\n ответ = ")] по "" + иначе соединить ["случай = ", (probe.«name»), "\n код = ", (verdict.«code»), "\n причина = ", + (verdict.«text»)] по "" + +тотальная функция «Measured» + принимает ledger: строка, probes: список «Case» + возвращает строка + соединить (отобразить probes как probe → «Measured line» от ledger и probe) по "\n\n" + +тотальная функция «Clean words» + принимает ledger: строка, probes: список «Case» + возвращает строка + соединить [(«Numbers» от ledger и probes), + "свойство 2: ответ один на всех порядках ведомости — сходится", + "свойство 3: отказ назван кодом и текстом — сходится"] по "\n" + +тотальная функция «Fault words» + принимает ledger: строка, probes: список «Case», found: список строки + возвращает строка + пусть said равно [(«Numbers» от ledger и probes), + (соединить ["находок ", (к строке (длина found))] по "")] + соединить («Joined» от said и found) по "\n · " + +тотальная функция «Verdict of run» + принимает ledger: строка, probes: список «Case» + возвращает «Продолжение» + пусть found равно («Faults» от ledger и probes) + пусть words равно («Fault words» от ledger и probes и found) + если (длина found) равен 0 + то вариант «Конец работы» с значение равным («Clean words» от ledger и probes) + иначе вариант «Провал» с код равным "FLANG_REESTR_RAZRESHENIE" и сообщение равным words + +тотальная функция «No corpus» + принимает path: строка, words: строка + возвращает «Продолжение» + пусть said равно (соединить ["разрешение реестра: ", path, ": ", words] по "") + вариант «Не проверено» с код равным "FLANG_REESTR_RAZRESHENIE_PUSTO" и сообщение равным said + +тотальная функция «Judge corpus» + принимает forged: признак, mode: строка, ledger: строка, text: строка + возвращает «Продолжение» + пусть probes равно («Corpus» от forged и text) + если (длина probes) равен 0 + то «No corpus» от («Cases path») и "случаев в корпусе НЕТ — сверять нечем" + иначе если mode равен "measure" + то вариант «Конец работы» с значение равным («Measured» от ledger и probes) + иначе «Verdict of run» от ledger и probes + +тотальная функция «Read» + принимает path: строка + возвращает «Поручение» + пример «Поручение читает названный файл» + дано path равно "а" + ожидается вариант «Прочитать файл» с путь равным "а" + вариант «Прочитать файл» с путь равным path + +тотальная функция «Wait ledger» + принимает forged: признак, mode: строка + возвращает «Step» + вариант «Awaiting ledger» с forged равным forged и mode равным mode + +тотальная функция «Wait probes» + принимает forged: признак, mode: строка, ledger: строка + возвращает «Step» + вариант «Awaiting probes» с forged равным forged и mode равным mode и ledger равным ledger + +тотальная функция «Doing» + принимает order: «Поручение», onward: «Step» + возвращает «Продолжение» + вариант «Сделать» с поручение равным order и потом равным onward + +тотальная функция «After ledger» + принимает forged: признак, mode: строка, reply: «Отклик» + возвращает «Продолжение» + разбор reply + случай вариант «Пока ничего» + то «Doing» от («Read» от («Ledger path»)) и («Wait ledger» от forged и mode) + случай вариант «Прочитано» с содержимое как text + то «Doing» от («Read» от («Cases path»)) и («Wait probes» от forged и mode и text) + случай вариант «Сбой» с код как code и сообщение как words + то «No corpus» от («Ledger path») и words + случай любое + то вариант «Провал» с код равным "FLANG_IO_ORDER" и сообщение равным "ждали ведомость корпуса" + +тотальная функция «After probes» + принимает forged: признак, mode: строка, ledger: строка, reply: «Отклик» + возвращает «Продолжение» + разбор reply + случай вариант «Прочитано» с содержимое как text + то «Judge corpus» от forged и mode и ledger и text + случай вариант «Сбой» с код как code и сообщение как words + то «No corpus» от («Cases path») и words + случай любое + то вариант «Провал» с код равным "FLANG_IO_ORDER" и сообщение равным "ждали случаи корпуса" + +тотальная функция «Begin check» + возвращает «Step» + пример «Сверка начинается с ведомости корпуса» + ожидается вариант «Awaiting ledger» с forged равным нет и mode равным "check" + вариант «Awaiting ledger» с forged равным нет и mode равным "check" + +тотальная функция «Begin forgery» + возвращает «Step» + пример «Подлог начинается так же» + ожидается вариант «Awaiting ledger» с forged равным да и mode равным "check" + вариант «Awaiting ledger» с forged равным да и mode равным "check" + +тотальная функция «Begin measure» + возвращает «Step» + пример «Замер начинается так же» + ожидается вариант «Awaiting ledger» с forged равным нет и mode равным "measure" + вариант «Awaiting ledger» с forged равным нет и mode равным "measure" + +тотальная функция «Next» + принимает step: «Step», reply: «Отклик» + возвращает «Продолжение» + разбор step + случай вариант «Awaiting ledger» с forged как forged и mode как mode + то «After ledger» от forged и mode и reply + случай вариант «Awaiting probes» с forged как forged и mode как mode и ledger как ledger + то «After probes» от forged и mode и ledger и reply + +план «Check» + состояние «Step» + начинает с «Begin check» + обрабатывает «Next» + +план «Forgery» + состояние «Step» + начинает с «Begin forgery» + обрабатывает «Next» + +план «Measure» + состояние «Step» + начинает с «Begin measure» + обрабатывает «Next» diff --git a/scripts/ledgers/file-name-words.txt b/scripts/ledgers/file-name-words.txt index d524e1836..4afc62164 100644 --- a/scripts/ledgers/file-name-words.txt +++ b/scripts/ledgers/file-name-words.txt @@ -1420,6 +1420,7 @@ requires reseed reserved resets +resolution resolving rest restores diff --git a/scripts/ledgers/proved-share-ledger.txt b/scripts/ledgers/proved-share-ledger.txt index ccc483313..b6e2b710a 100644 --- a/scripts/ledgers/proved-share-ledger.txt +++ b/scripts/ledgers/proved-share-ledger.txt @@ -1559,6 +1559,7 @@ b00f9a812077e3b8497c15864acff995|11|7|3|0|0|scripts/guards/io-dictionary-copies- ea1518a801b7e78ee25788b065921aff|23|11|2|3|0|scripts/guards/kernel-abilities-guard.fscript 5ab01492f40c7c4a19b89433856c1786|6|6|0|0|0|scripts/guards/license-guard.fscript b162a51d6ae08b12527da153f5957d56|85|37|48|0|0|scripts/guards/link-guard.fscript +d3c200fe9be648a3eb699ba7d7fb237d|3|3|0|0|0|scripts/guards/lock-closes-every-form.fscript 3eea8a647996e57cc3e492c8f4e4763e|15|13|2|0|0|scripts/guards/manpage-guard.fscript f8e01fecff7e47ed055e836a42195ee0|15|15|0|0|0|scripts/guards/module-name-guard.fscript a63d8465a17432a9e21c55efe890d510|27|26|0|1|0|scripts/guards/name-collision-guard.fscript diff --git a/scripts/seed-fingerprint b/scripts/seed-fingerprint index ef6b47ed0..c4e3047e9 100644 --- a/scripts/seed-fingerprint +++ b/scripts/seed-fingerprint @@ -4,7 +4,7 @@ предел-глубины 20000 вход flang/self/bootstrap/compiler.flang ключи --cli --repl -коммит 60751a21598481463a64a7dc0434621a4de3b37a +коммит c8ef66ddf3ecb2291c0f63fb71fe2d09339310ef e200119e04672d9c574cd22cb41f6358a9508a1810f8a4f43ad287a8add8f923 flang/core/evaluate.flang 363ef4fdf66c10a13853083b3aa4aea6b6308c21045171cf5196e02c7871991f flang/core/json.flang 1767bca675dfeb0e4366b5f3a015a2520500fb8d3ab011ab25ca4d8890e134b8 flang/self/bootstrap/compiler.flang @@ -47,7 +47,7 @@ f3801c9cdf81f51473312656ee84578e4dfa9ed322fef67b925961836aefb8e8 flang/self/pro ce2dc6c1920ee099b4ad91a0f57a8bd1993d832fd80a389b3005fabd022056cd flang/self/totality.flang 75f2fd823c6d414878cfa6d837467d4b41a3c3297481aff6f0f4c5efaf4ff177 flang/self/types.flang bd13b337adbf0de4123296db3d3a810f16cb433181b75bceddf5a8146b265b8d flang/src/emit/c/flang_cli.c -a1cdb3b4294380839fd5b7347a9d36dfcc8a1cdf63fb99e08c105e54dabca194 flang/src/emit/c/flang_repl.c +41b967d5f93932f66f3bc4ec3c7599c92ed5a890ec571b1fe6fa010b230ffc6d flang/src/emit/c/flang_repl.c d61423f0037fc933e67d29d6bea2723332313635cfdf0d36fa818db9f3c3679a flang/src/emit/c/flang_runtime.c a01ffd2be6ef948565119446d1a36da0538377a6b1695103ef7dea5c88b99603 flang/src/emit/c/flang_runtime.h 7bd6e6f32172728767ea9b7a1493638d11c91f349e033769d182fc4d04edbec8 flang/stdlib/hashmap.flang @@ -62,6 +62,6 @@ a01ffd2be6ef948565119446d1a36da0538377a6b1695103ef7dea5c88b99603 flang/src/emit ab826382e96a9cc483f1ef8cd7dd260a912c02bb82a6ae1cee453cdedc660aab bootstrap/compiler_flang.c a0cf58d8b82014696de8ea3ef39d11b09331bf23043b6f55395c69dccb8e2996 bootstrap/compiler_flang.h bc7cf10d951d73fd05a8a922022dc4079d542100aa30e621c3b4859aba4efb36 bootstrap/flang_cli.c -faabc53ec91460d916c8e9d2f7402dcb7f9b2c67b4f13f20fe3b7d5514ef81eb bootstrap/flang_repl.c +609b949e93f030fe60ea819e42d39392fc71eabeedde3a98621bcafeb2a6d435 bootstrap/flang_repl.c 99de7541f21670ec2535093e3d28d22bcf3553a8a50bc447c4a6277c7ca41afb bootstrap/flang_runtime.c 085dd61e2eeb6484993bd06cc6f2cfca584fd4fb307962c7744e7a3f36d3df2f bootstrap/flang_runtime.h