diff --git a/.flangrc b/.flangrc index c99e8019b..2e798d6a5 100644 --- a/.flangrc +++ b/.flangrc @@ -193,8 +193,9 @@ 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 --на-веру script.seed-lines:check = sh scripts/bootstrap-reprint.sh --stroki script.guards:check = bootstrap/flang io flang/scripts/guards-start.fscript --на-веру -script.hand-written-lists:census = sh scripts/guards/hand-written-lists.sh -script.hand-written-lists:check = sh scripts/guards/hand-written-lists.sh --check +script.hand-written-lists:census = bootstrap/flang io scripts/guards/hand-written-lists.fscript --plan Census --max-steps 4000000000 +script.hand-written-lists:check = bootstrap/flang io scripts/guards/hand-written-lists.fscript --plan Check --max-steps 4000000000 +script.hand-written-lists:forgery = bootstrap/flang io scripts/guards/hand-written-lists.fscript --plan Forgery --timeout 5400000 script.what-blocks:check = bootstrap/flang io scripts/guards/what-blocks-inventory-guard.fscript --plan Проверка script.what-blocks:forgery = bootstrap/flang io scripts/guards/what-blocks-inventory-guard.fscript --plan Подлог script.criterion:score = bootstrap/flang io scripts/guards/criterion-score-guard.fscript -- diff --git a/.github/workflows/binary.yml b/.github/workflows/binary.yml index 22bfe3903..1b228d7df 100644 --- a/.github/workflows/binary.yml +++ b/.github/workflows/binary.yml @@ -394,9 +394,9 @@ jobs: # # Счётчиков долга в дереве было три — раздел «Вне языка» в docs/ROADMAP.md, # docs/javascript-inventory.md и числа сайта, — и все три считали ОДИН - # язык: JavaScript. Оболочка (46 файлов, 8886 строк), HTML, CSS, пробы на - # СНЯТО 2026-10-07 файлов *.sh = 46 (перенос scripts/guards/proved-share-vs-tree.sh и guards-without-forgery-probe.sh на планы снял два файла оболочки; до них 49, снято 2026-10-04) (перенос flang/translation/run.sh на план flang/translation/run.fscript снял один файл оболочки; до него 50, снято 2026-10-04) (задачи 0049 и 5821: сняты flang/scripts/word-occupancy.mjs, scripts/seed/seed-freshness.sh и scripts/guards/version-derivations-guard.sh — у каждого двойник на flang доказан прогоном; до них 52, снято 2026-10-04) (задача 5821: семь скриптов scripts/** переехали с оболочки на flang; до них 101, снято 2026-09-17) - # СНЯТО 2026-10-07 строк-в *.sh = 8886 (перенос scripts/guards/proved-share-vs-tree.sh и guards-without-forgery-probe.sh на планы снял 414 строк оболочки; до них 9344, снято 2026-10-04) (перенос flang/translation/run.sh на план flang/translation/run.fscript снял 214 строк оболочки; до него 9558, снято 2026-10-04) (задачи 0049 и 5821: сняты flang/scripts/word-occupancy.mjs, scripts/seed/seed-freshness.sh и scripts/guards/version-derivations-guard.sh — у каждого двойник на flang доказан прогоном; до них 9756, снято 2026-10-04) (задачи 1426 и 8567: поиск коммита отпечатка по содержимому прибавил 135 строк в scripts/bootstrap-reprint.sh, а отменённая хронология предела шагов убрала 141; до них 9762, снято 2026-09-17) (задача 1400: девять проб на подлог и две честные под правила Н6 и О9 прибавили 42 строки в flang/proof/checker/tests/run.sh) (задача 1416: четырнадцать объявлений ярлыков заведены в скриптах и зов «Сбора» — в хуке; до них 23372, снято 2026-09-17) (задача 5821: семь скриптов scripts/** переехали с оболочки на flang; до них 23980, снято 2026-09-22) (ADR-0046: довод в шапках двух сторожей имён — сперва почему flang/proof не судится, потом почему вошёл в область — прибавил 9 строк; до него 23971, снято 2026-09-17) + # язык: JavaScript. Оболочка (45 файлов, 8510 строк), HTML, CSS, пробы на + # СНЯТО 2026-10-07 файлов *.sh = 45 (перенос scripts/guards/proved-share-vs-tree.sh и guards-without-forgery-probe.sh на планы снял два файла оболочки; до них 49, снято 2026-10-04) (перенос flang/translation/run.sh на план flang/translation/run.fscript снял один файл оболочки; до него 50, снято 2026-10-04) (задачи 0049 и 5821: сняты flang/scripts/word-occupancy.mjs, scripts/seed/seed-freshness.sh и scripts/guards/version-derivations-guard.sh — у каждого двойник на flang доказан прогоном; до них 52, снято 2026-10-04) (задача 5821: семь скриптов scripts/** переехали с оболочки на flang; до них 101, снято 2026-09-17) + # СНЯТО 2026-10-07 строк-в *.sh = 8510 (перенос scripts/guards/proved-share-vs-tree.sh и guards-without-forgery-probe.sh на планы снял 414 строк оболочки; до них 9344, снято 2026-10-04) (перенос flang/translation/run.sh на план flang/translation/run.fscript снял 214 строк оболочки; до него 9558, снято 2026-10-04) (задачи 0049 и 5821: сняты flang/scripts/word-occupancy.mjs, scripts/seed/seed-freshness.sh и scripts/guards/version-derivations-guard.sh — у каждого двойник на flang доказан прогоном; до них 9756, снято 2026-10-04) (задачи 1426 и 8567: поиск коммита отпечатка по содержимому прибавил 135 строк в scripts/bootstrap-reprint.sh, а отменённая хронология предела шагов убрала 141; до них 9762, снято 2026-09-17) (задача 1400: девять проб на подлог и две честные под правила Н6 и О9 прибавили 42 строки в flang/proof/checker/tests/run.sh) (задача 1416: четырнадцать объявлений ярлыков заведены в скриптах и зов «Сбора» — в хуке; до них 23372, снято 2026-09-17) (задача 5821: семь скриптов scripts/** переехали с оболочки на flang; до них 23980, снято 2026-09-22) (ADR-0046: довод в шапках двух сторожей имён — сперва почему flang/proof не судится, потом почему вошёл в область — прибавил 9 строк; до него 23971, снято 2026-09-17) # C, Python, awk и Erlang не считались нигде и ни в одной проверке. Долг, # которого никто не считает, не убывает: его не видно ни в отчёте, ни в # ленте, и растёт он молча. @@ -407,9 +407,9 @@ jobs: # оболочке или на Python останавливает работу в тот же день. # # Замер на этом дереве: 17,7 с и 471 МБ, двоичному хватает `git` и `wc`. - # Предел шагов поднят с умолчания (10 млн): опись обходит 203 файлов и + # Предел шагов поднят с умолчания (10 млн): опись обходит 202 файлов и # семнадцать языков, и в умолчание не укладывается. - # СНЯТО 2026-10-07 файлов *.sh,*.c,*.h,*.py,*.html,*.css,*.awk,*.erl,*.js,*.mjs,*.java,*.cs,*.ex,*.go,*.rs,*.lua,*.vim,*.rb,*.cpp,*.cc,*.hpp,*.hh,ярлык,packaging/asdf/bin/download,packaging/asdf/bin/install,packaging/asdf/bin/list-all,.githooks/pre-push,.githooks/commit-msg,.githooks/pre-commit = 203 (мера починена: правило «Язык пути» описи знает только *.ex, а водители пробы на .exs и .ts языком не считает, зато считает .githooks/commit-msg и .githooks/pre-commit — их в мере не было; по прежней мере вышло бы 198, снято 2026-10-04) (задача 1413: семь водителей пробы flang/proof/probes/exact-integer-in-targets/drivers/* на C, C++, Java, C#, Go, Rust и JS — судья, который считает десятичную запись точного целого на самой цели; до них 190, снято 2026-10-04) (перенос scripts/guards/proved-share-vs-tree.sh и guards-without-forgery-probe.sh на планы снял два файла вне flang; до них 192, снято 2026-10-04) (перенос flang/translation/run.sh на план flang/translation/run.fscript снял один файл вне flang; до него 193, снято 2026-10-04) (задачи 0049 и 5821: сняты flang/scripts/word-occupancy.mjs, scripts/seed/seed-freshness.sh и scripts/guards/version-derivations-guard.sh — у каждого двойник на flang доказан прогоном; до них 196, снято 2026-10-04) (две честные пары сличителя перевода: отбор по признаку и объявленная мера; до них 194, снято 2026-09-17) (задача 5821: семь проверок scripts/** стали планами; до них 251, снято 2026-09-27) (задача 5821: семь скриптов scripts/** переехали с оболочки на flang; до них 256, снято 2026-09-17) + # СНЯТО 2026-10-07 файлов *.sh,*.c,*.h,*.py,*.html,*.css,*.awk,*.erl,*.js,*.mjs,*.java,*.cs,*.ex,*.go,*.rs,*.lua,*.vim,*.rb,*.cpp,*.cc,*.hpp,*.hh,ярлык,packaging/asdf/bin/download,packaging/asdf/bin/install,packaging/asdf/bin/list-all,.githooks/pre-push,.githooks/commit-msg,.githooks/pre-commit = 202 (мера починена: правило «Язык пути» описи знает только *.ex, а водители пробы на .exs и .ts языком не считает, зато считает .githooks/commit-msg и .githooks/pre-commit — их в мере не было; по прежней мере вышло бы 198, снято 2026-10-04) (задача 1413: семь водителей пробы flang/proof/probes/exact-integer-in-targets/drivers/* на C, C++, Java, C#, Go, Rust и JS — судья, который считает десятичную запись точного целого на самой цели; до них 190, снято 2026-10-04) (перенос scripts/guards/proved-share-vs-tree.sh и guards-without-forgery-probe.sh на планы снял два файла вне flang; до них 192, снято 2026-10-04) (перенос flang/translation/run.sh на план flang/translation/run.fscript снял один файл вне flang; до него 193, снято 2026-10-04) (задачи 0049 и 5821: сняты flang/scripts/word-occupancy.mjs, scripts/seed/seed-freshness.sh и scripts/guards/version-derivations-guard.sh — у каждого двойник на flang доказан прогоном; до них 196, снято 2026-10-04) (две честные пары сличителя перевода: отбор по признаку и объявленная мера; до них 194, снято 2026-09-17) (задача 5821: семь проверок scripts/** стали планами; до них 251, снято 2026-09-27) (задача 5821: семь скриптов scripts/** переехали с оболочки на flang; до них 256, снято 2026-09-17) # # СКОЛЬКО ИЗ ЭТИХ ПЯТИДЕСЯТИ МИЛЛИОНОВ УХОДИТ, замер 29 августа 2026. # Меряно перебором самого предела: при 10 500 000 опись умирает diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 394a30bbb..a1fbb3a74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -213,8 +213,8 @@ jobs: # 31 августа 2026 в дереве нашлось 31 место в 14 файлах, где записанное рукой # число разошлось с тем, что лежит рядом: `docs/tree-inventory.md` считала # `seed-parses-sources-guard.sh` в 83 строки при 195, оболочку — в 66 файлов - # при 71 тогдашних — сегодня их 46; - # СНЯТО 2026-10-07 файлов *.sh = 46 (перенос scripts/guards/proved-share-vs-tree.sh и guards-without-forgery-probe.sh на планы снял два файла оболочки; до них 49, снято 2026-10-04) (перенос flang/translation/run.sh на план flang/translation/run.fscript снял один файл оболочки; до него 50, снято 2026-10-04) (задача 5821: scripts/guards/version-derivations-guard.sh снят — сверка производных версии стала планом scripts/guards/version-derivations-guard.fscript, приговор доказан ядром (13 из 13), хук зовёт план; до него 51, снято 2026-10-04) (задача 0049: scripts/seed/seed-freshness.sh снят — проверка давно живёт планом scripts/seed/seed-freshness.fscript, а переходник ещё и терял довод (exec без "$@"); до него 52, снято 2026-10-04) (задача 5821: семь скриптов scripts/** переехали с оболочки на flang; до них 101, снято 2026-09-21) `flang/cat/SPEC.md` обещала восемнадцать поручений при 22; + # при 71 тогдашних — сегодня их 45; + # СНЯТО 2026-10-07 файлов *.sh = 45 (перенос scripts/guards/proved-share-vs-tree.sh и guards-without-forgery-probe.sh на планы снял два файла оболочки; до них 49, снято 2026-10-04) (перенос flang/translation/run.sh на план flang/translation/run.fscript снял один файл оболочки; до него 50, снято 2026-10-04) (задача 5821: scripts/guards/version-derivations-guard.sh снят — сверка производных версии стала планом scripts/guards/version-derivations-guard.fscript, приговор доказан ядром (13 из 13), хук зовёт план; до него 51, снято 2026-10-04) (задача 0049: scripts/seed/seed-freshness.sh снят — проверка давно живёт планом scripts/seed/seed-freshness.fscript, а переходник ещё и терял довод (exec без "$@"); до него 52, снято 2026-10-04) (задача 5821: семь скриптов scripts/** переехали с оболочки на flang; до них 101, снято 2026-09-21) `flang/cat/SPEC.md` обещала восемнадцать поручений при 22; # `flang/PLAN.md` — пять вариантов «Поручение» при 22. Каждое из этих чисел # было ВЕРНО В ДЕНЬ ЗАПИСИ и солгало назавтра, и сторожа не было ни на одном. # diff --git a/docs/javascript-inventory.md b/docs/javascript-inventory.md index 74e55d465..ae2be0cbf 100644 --- a/docs/javascript-inventory.md +++ b/docs/javascript-inventory.md @@ -68,8 +68,8 @@ JavaScript стало 55, строк 29 733; в трёх каталогах о Эта опись считает ОДИН язык. Остальные шестнадцать — оболочка, C, C++, Python, HTML, CSS, awk, Erlang, Java, C#, Elixir, Go, Rust, Lua, vimscript, Ruby — -считает [`tree-inventory.md`](tree-inventory.md) (4 октября 2026: 203 файлов вне flang, - +считает [`tree-inventory.md`](tree-inventory.md) (4 октября 2026: 202 файлов вне flang, + долг вне JavaScript — **55 файлов, 5 607 строк при потолке 63**: храповик зелён, запас 8 файлов, разбор прежней красноты — задачи 4838 и 7405). Там же названы 569 строк JavaScript, лежащих ВНУТРИ файлов `.html`: счёт по именам файлов их не видит, и diff --git a/docs/tree-inventory.md b/docs/tree-inventory.md index fb4525f9e..c9882d87a 100644 --- a/docs/tree-inventory.md +++ b/docs/tree-inventory.md @@ -1,5 +1,5 @@ -# Опись дерева по языкам: 203 файлов вне flang, долг вне JavaScript — 55 при потолке 63 - +# Опись дерева по языкам: 202 файлов вне flang, долг вне JavaScript — 55 при потолке 63 + ⚠ **ХРАПОВИК ДОЛГА ЗЕЛЁН С 4 ОКТЯБРЯ 2026: долг 55 файлов при потолке 63, запас 8.** Прогон `bootstrap/flang run-script inventory:languages` **4 октября 2026** отвечает кодом 0: «ДОЛГ ВНЕ @@ -82,7 +82,7 @@ $ bootstrap/flang io scripts/guards/tree-inventory.fscript --max-steps 50000000 | язык | файлов | строк | долг файлов | долг строк | |---|---:|---:|---:|---:| -| оболочка | 52 | 9 203 | 47 | 4 973 | +| оболочка | 51 | 8 827 | 46 | 4 597 | | C | 45 | 893 973 | 1 | 107 | | C++ | 2 | 511 | 1 | 107 | | Python | 5 | 2 997 | 0 | 0 | diff --git a/scripts/guards/file-extensions.fscript b/scripts/guards/file-extensions.fscript index 7a9753c92..d1c5d29b6 100644 --- a/scripts/guards/file-extensions.fscript +++ b/scripts/guards/file-extensions.fscript @@ -145,7 +145,8 @@ запись «Место» с «путь» равным "scripts/guards/link-guard.fscript" и «нужно» равным "\"flang\", \"fscript\", \"md\"" и «нельзя» равным "\"flang\", \"md\"", запись «Место» с «путь» равным "scripts/guards/name-collision-guard.fscript" и «нужно» равным "'*.flang' '*.fscript' | while" и «нельзя» равным "'*.flang' | while", запись «Место» с «путь» равным "scripts/guards/name-splicing-guard.fscript" и «нужно» равным "\"ls-files\", \"*.flang\", \"*.fscript\"]" и «нельзя» равным "\"*.flang\"]", - запись «Место» с «путь» равным "scripts/guards/hand-written-lists.sh" и «нужно» равным "(flang|fscript|mjs|sh|js|py|awk)$" и «нельзя» равным "(flang|mjs|", + запись «Место» с «путь» равным (соединить ["scripts/guards/hand-written-lists", + ".fscript"] по "") и «нужно» равным "\".fscript\", \".mjs\"" и «нельзя» равным "\".flang\", \".mjs\"", запись «Место» с «путь» равным "scripts/guards/no-comments-guard.fscript" и «нужно» равным "ls-files -z '*.flang' '*.fscript'" и «нельзя» равным "ls-files -z '*.flang' |", запись «Место» с «путь» равным "scripts/guards/what-blocks-inventory-guard.fscript" и «нужно» равным "\".flang\", \".fscript\"" и «нельзя» равным "\".flang\", \".tsv\"", запись «Место» с «путь» равным "scripts/guards/module-origin-guard.sh" и «нужно» равным "i.endswith((\".flang\", \".fscript\"))" и «нельзя» равным "", diff --git a/scripts/guards/hand-written-lists.fscript b/scripts/guards/hand-written-lists.fscript new file mode 100644 index 000000000..cb44a5f6e --- /dev/null +++ b/scripts/guards/hand-written-lists.fscript @@ -0,0 +1,2558 @@ +модуль «Hand-written lists guard» + +тотальная функция «Код знака» + принимает знак: строка + возвращает число + пример «Код латинской буквы» + дано знак равно "a" + ожидается 97 + пример «У пустоты кода нет — ноль» + дано знак равно "" + ожидается 0 + если знак равен "" + то 0 + иначе код символа знак + +тотальная функция «Латинская ли» + принимает код: число + возвращает признак + пример «Строчная» + дано код равно 97 + ожидается да + пример «Заглавная» + дано код равно 65 + ожидается да + пример «Цифра буквой не является» + дано код равно 48 + ожидается нет + ((код не меньше 65) и притом (код не больше 90)) или ((код не меньше 97) и притом (код не больше 122)) + +тотальная функция «Цифра ли» + принимает код: число + возвращает признак + пример «Ноль» + дано код равно 48 + ожидается да + пример «Точка цифрой не является» + дано код равно 46 + ожидается нет + (код не меньше 48) и притом (код не больше 57) + +тотальная функция «Строчная ли» + принимает код: число + возвращает признак + пример «Строчная латинская» + дано код равно 122 + ожидается да + пример «Заглавная строчной не является» + дано код равно 90 + ожидается нет + (код не меньше 97) и притом (код не больше 122) + +тотальная функция «Заглавная ли» + принимает код: число + возвращает признак + пример «Заглавная латинская» + дано код равно 65 + ожидается да + пример «Строчная заглавной не является» + дано код равно 97 + ожидается нет + (код не меньше 65) и притом (код не больше 90) + +тотальная функция «Кириллица ли» + принимает код: число + возвращает признак + пример «Буква А» + дано код равно 1040 + ожидается да + пример «Буква ё стоит отдельно от основного ряда» + дано код равно 1105 + ожидается да + пример «Латиница кириллицей не является» + дано код равно 97 + ожидается нет + ((код не меньше 1040) и притом (код не больше 1103)) или ((код равен 1025) или (код равен 1105)) + +тотальная функция «Знак начала ли» + принимает знак: строка + возвращает признак + пример «Буква начинает имя» + дано знак равно "d" + ожидается да + пример «Подчёркивание начинает имя» + дано знак равно "_" + ожидается да + пример «Точка имя не начинает» + дано знак равно "." + ожидается нет + пусть код равно («Код знака» от знак) + («Латинская ли» от код) или (((«Цифра ли» от код) или (код равен 95))) + +тотальная функция «Знак слова ли» + принимает знак: строка + возвращает признак + пример «Дефис внутри слова» + дано знак равно "-" + ожидается да + пример «Точка слово рвёт» + дано знак равно "." + ожидается нет + пример «Пустота слова не продолжает» + дано знак равно "" + ожидается нет + («Знак начала ли» от знак) или (знак равен "-") + +тотальная функция «Знак середины ли» + принимает знак: строка + возвращает признак + пример «Точка в середине имени» + дано знак равно "." + ожидается да + пример «Косая черта в середину не входит» + дано знак равно "/" + ожидается нет + («Знак слова ли» от знак) или (знак равен ".") + +тотальная функция «Знак отрезка ли» + принимает знак: строка + возвращает признак + пример «Кириллица в отрезке пути» + дано знак равно "я" + ожидается да + пример «Косая черта отрезок кончает» + дано знак равно "/" + ожидается нет + («Знак середины ли» от знак) или («Кириллица ли» от («Код знака» от знак)) + +тотальная функция «Знак заглавного ли» + принимает знак: строка + возвращает признак + пример «Заглавная буква» + дано знак равно "Z" + ожидается да + пример «Цифра в имени переменной» + дано знак равно "7" + ожидается да + пример «Строчная сюда не входит» + дано знак равно "z" + ожидается нет + пусть код равно («Код знака» от знак) + («Заглавная ли» от код) или ((«Цифра ли» от код) или (знак равен "_")) + +тотальная функция «Знак номер» + принимает текст: строка, номер: число + возвращает строка + пример «Второй знак» + дано текст равно "аб" + дано номер равно 2 + ожидается "б" + пример «За краем знака нет» + дано текст равно "аб" + дано номер равно 9 + ожидается "" + пример «Нулевого знака нет» + дано текст равно "аб" + дано номер равно 0 + ожидается "" + если (номер меньше 1) или (номер больше (длина текст)) + то "" + иначе символ номер в текст + +тотальная функция «Последний знак» + принимает текст: строка + возвращает строка + пример «Последний знак слова» + дано текст равно "путь" + ожидается "ь" + пример «У пустоты последнего знака нет» + дано текст равно "" + ожидается "" + «Знак номер» от текст и (длина текст) + +тотальная функция «Первый знак» + принимает текст: строка + возвращает строка + пример «Первый знак слова» + дано текст равно "путь" + ожидается "п" + пример «У пустоты первого знака нет» + дано текст равно "" + ожидается "" + «Знак номер» от текст и 1 + +тотальная функция «Кончается на» + принимает текст: строка, хвостик: строка + возвращает признак + пример «Кончается» + дано текст равно "проба.md" + дано хвостик равно ".md" + ожидается да + пример «Хвостик в середине не считается» + дано текст равно "a.md.txt" + дано хвостик равно ".md" + ожидается нет + пусть куски равно (разделить текст по хвостик) + ((длина куски) не меньше 2) и притом ((элемент (длина куски) в куски) равен "") + +тотальная функция «До метки» + принимает текст: строка, метка: строка + возвращает строка + пример «До первой метки» + дано текст равно "раз|два" + дано метка равно "|" + ожидается "раз" + пример «Метки нет — весь текст» + дано текст равно "раз" + дано метка равно "|" + ожидается "раз" + голова (разделить текст по метка) + +тотальная функция «После метки» + принимает текст: строка, метка: строка + возвращает строка + пример «После первой метки — весь остаток» + дано текст равно "раз|два|три" + дано метка равно "|" + ожидается "два|три" + пример «Метки нет — пусто» + дано текст равно "раз" + дано метка равно "|" + ожидается "" + разбор (разделить текст по метка) + случай пусто + то "" + случай голова и хвост + то соединить хвост по метка + +тотальная функция «Переводов» + принимает текст: строка + возвращает число + пример «Два перевода строки» + дано текст равно "раз\nдва\n" + ожидается 2 + пример «Без переводов — ноль» + дано текст равно "раз" + ожидается 0 + (длина (разделить текст по "\n")) минус 1 + +тотальная функция «Непустые» + принимает строки: список строки + возвращает список строки + пример «Пустые выброшены» + дано строки равно ["раз", "", "два"] + ожидается ["раз", "два"] + отфильтровать строки где строчка → (не (строчка равен "")) + +тотальная функция «Подменить» + принимает текст: строка, что: строка, чем: строка + возвращает строка + пример «Все вхождения заменены» + дано текст равно "а-б-в" + дано что равно "-" + дано чем равно "+" + ожидается "а+б+в" + пример «Нечего заменять» + дано текст равно "абв" + дано что равно "-" + дано чем равно "+" + ожидается "абв" + соединить (разделить текст по что) по чем + +тотальная функция «Строчки» + принимает текст: строка + возвращает список строки + пример «Хвостовой перевод не даёт пустой строки» + дано текст равно "раз\nдва\n" + ожидается ["раз", "два"] + «Непустые» от (разделить текст по "\n") + +объект «Помин» + «строка»: число + «имя»: строка + +объект «Поиск слова» + «есть»: признак + «левое»: строка + «первый»: признак + +тотальная функция «Поиск слова с» + принимает есть: признак, левое: строка, первый: признак + возвращает «Поиск слова» + запись «Поиск слова» с «есть» равным есть и «левое» равным левое и «первый» равным первый + +тотальная функция «Знак перед хвостом» + принимает текст: строка, сколько: число + возвращает строка + пример «Знак перед пятизначным хвостом» + дано текст равно "xemit-" + дано сколько равно 5 + ожидается "x" + пример «Хвост занял всё — слева край строки» + дано текст равно "emit-" + дано сколько равно 5 + ожидается "" + «Знак номер» от текст и ((длина текст) минус сколько) + +тотальная функция «Через emit» + принимает левое: строка + возвращает признак + пример «Приставка стоит у края» + дано левое равно "emit-" + ожидается да + пример «Приставка после косой черты» + дано левое равно "flang/self/emit-" + ожидается да + пример «Приставка приклеена к слову — не она» + дано левое равно "pre-emit-" + ожидается нет + пример «Приставки нет вовсе» + дано левое равно "цель " + ожидается нет + («Кончается на» от левое и "emit-") и притом (не («Знак слова ли» от («Знак перед хвостом» от левое и 5))) + +тотальная функция «Начало слова ли» + принимает левое: строка + возвращает признак + пример «Слева пробел» + дано левое равно "цель " + ожидается да + пример «Слева край строки» + дано левое равно "" + ожидается да + пример «Слева буква — слово не начинается» + дано левое равно "mi" + ожидается нет + пример «Слева приставка печати» + дано левое равно " emit-" + ожидается да + если не («Знак слова ли» от («Последний знак» от левое)) + то да + иначе «Через emit» от левое + +тотальная функция «Слово ли» + принимает левое: строка, правое: строка + возвращает признак + пример «Имя стоит отдельным словом» + дано левое равно "цель " + дано правое равно " печатает" + ожидается да + пример «Справа буква — не слово» + дано левое равно " " + дано правое равно "de" + ожидается нет + пример «Оба края пусты — всё строка и есть слово» + дано левое равно "" + дано правое равно "" + ожидается да + если («Знак слова ли» от («Первый знак» от правое)) + то нет + иначе «Начало слова ли» от левое + +тотальная функция «Левое дальше» + принимает кусок: строка, цель: строка, первый: признак + возвращает строка + пример «Непустой кусок идёт слева как он есть» + дано кусок равно "цель " + дано цель равно "go" + дано первый равно нет + ожидается "цель " + пример «Пустой кусок у края строки оставляет край» + дано кусок равно "" + дано цель равно "go" + дано первый равно да + ожидается "" + пример «Пустой кусок внутри значит, что слева стоит сама цель» + дано кусок равно "" + дано цель равно "go" + дано первый равно нет + ожидается "go" + если не (кусок равен "") + то кусок + иначе (если первый то "" иначе цель) + +тотальная функция «Шаг поиска слова» + принимает ход: «Поиск слова», кусок: строка, цель: строка + возвращает «Поиск слова» + пусть было равно ((не (ход.«первый»)) и притом («Слово ли» от (ход.«левое») и кусок)) + пусть левое равно («Левое дальше» от кусок и цель и (ход.«первый»)) + «Поиск слова с» от ((ход.«есть») или было) и левое и нет + +тотальная функция «Поиск по кускам» + принимает куски: список строки, цель: строка + возвращает признак + пусть начало равно («Поиск слова с» от нет и "" и да) + (свёртка куски начиная с начало как ход и кусок → («Шаг поиска слова» от ход и кусок и цель)).«есть» + +тотальная функция «Слово в строчке ли» + принимает строчка: строка, цель: строка + возвращает признак + пример «Цель названа отдельным словом» + дано строчка равно "цель go печатает" + дано цель равно "go" + ожидается да + пример «Имя внутри слова перечнем не считается» + дано строчка равно "algorithm" + дано цель равно "go" + ожидается нет + пример «Приставка печати снимается» + дано строчка равно "for m in emit-go emit-rust" + дано цель равно "go" + ожидается да + пример «Цели в строке нет вовсе» + дано строчка равно "ничего" + дано цель равно "go" + ожидается нет + если не (строчка содержит цель) + то нет + иначе «Поиск по кускам» от (разделить строчка по цель) и цель + +объект «Ход строк» + «стр»: число + «места»: список «Помин» + +тотальная функция «Помин для» + принимает стр: число, имя: строка + возвращает «Помин» + запись «Помин» с «строка» равным стр и «имя» равным имя + +тотальная функция «Цели строчки» + принимает строчка: строка, свои: список строки + возвращает список строки + пример «Две цели в одной строке» + дано строчка равно "VSE=\"c go\"" + дано свои равно ["c", "go"] + ожидается ["c", "go"] + отфильтровать свои где цель → («Слово в строчке ли» от строчка и цель) + +тотальная функция «Шаг строчки кода» + принимает ход: «Ход строк», строчка: строка, свои: список строки + возвращает «Ход строк» + пусть стр равно ((ход.«стр») плюс 1) + пусть имена равно («Цели строчки» от строчка и свои) + пусть места равно (свёртка имена начиная с (ход.«места») как акк и имя → (приписать («Помин для» от стр и имя) к акк)) + запись «Ход строк» с «стр» равным стр и «места» равным места + +тотальная функция «Помины строк» + принимает строчки: список строки, свои: список строки + возвращает список «Помин» + пусть начало равно (запись «Ход строк» с «стр» равным 0 и «места» равным (пустой список)) + пусть итог равно (свёртка строчки начиная с начало как ход и строчка → («Шаг строчки кода» от ход и строчка и свои)) + «Обратить помины» от (итог.«места») + +тотальная функция «Помины кода» + принимает текст: строка, цели: список строки + возвращает список «Помин» + пример «Цель помянута во второй строке» + дано текст равно "первая\nцель go печатает\n" + дано цели равно ["c", "go"] + ожидается [запись «Помин» с «строка» равным 2 и «имя» равным "go"] + пример «Целей в тексте нет вовсе» + дано текст равно "ничего\n" + дано цели равно ["go"] + ожидается пустой список + пусть свои равно (отфильтровать цели где цель → (текст содержит цель)) + если (длина свои) равен 0 + то пустой список + иначе «Помины строк» от (разделить текст по "\n") и свои + +объект «Ход кавычек» + «номер»: число + «строка»: число + «пропуск»: признак + «места»: список «Помин» + +тотальная функция «Пустой ход кавычек» + возвращает «Ход кавычек» + запись «Ход кавычек» с «номер» равным 0 и «строка» равным 1 и «пропуск» равным нет и «места» равным (пустой список) + +тотальная функция «Все строчные» + принимает текст: строка + возвращает признак + пример «Слово из строчных» + дано текст равно "python" + ожидается да + пример «Пробел рвёт слово» + дано текст равно "a b" + ожидается нет + пример «Заглавная сюда не входит» + дано текст равно "Go" + ожидается нет + разбор текст + случай пусто + то да + случай голова и хвост + то если («Строчная ли» от («Код знака» от голова)) + то «Все строчные» от хвост + иначе нет + +тотальная функция «Находка кавычек ли» + принимает отрезок: строка, кандидат: признак + возвращает признак + пример «Непустой строчный отрезок между кавычками» + дано отрезок равно "go" + дано кандидат равно да + ожидается да + пример «Пустой отрезок находкой не бывает» + дано отрезок равно "" + дано кандидат равно да + ожидается нет + пример «Не кандидат — и не находка» + дано отрезок равно "go" + дано кандидат равно нет + ожидается нет + (кандидат и притом (не (отрезок равен ""))) и притом («Все строчные» от отрезок) + +тотальная функция «Кандидат ли» + принимает номер: число, предел: число, пропуск: признак + возвращает признак + пример «Отрезок в середине» + дано номер равно 1 + дано предел равно 3 + дано пропуск равно нет + ожидается да + пример «Отрезок до первой кавычки» + дано номер равно 0 + дано предел равно 3 + дано пропуск равно нет + ожидается нет + пример «Отрезок за последней кавычкой закрывающей не имеет» + дано номер равно 4 + дано предел равно 3 + дано пропуск равно нет + ожидается нет + пример «Погашенный предыдущей находкой» + дано номер равно 2 + дано предел равно 3 + дано пропуск равно да + ожидается нет + ((номер не меньше 1) и притом (номер не больше предел)) и притом (не пропуск) + +тотальная функция «Ход кавычек дальше» + принимает ход: «Ход кавычек», отрезок: строка, находка: признак, места: список «Помин» + возвращает «Ход кавычек» + пусть номер равно ((ход.«номер») плюс 1) + пусть строка равно ((ход.«строка») плюс («Переводов» от отрезок)) + запись «Ход кавычек» с «номер» равным номер и «строка» равным строка и «пропуск» равным находка и «места» равным места + +тотальная функция «Шаг отрезка» + принимает ход: «Ход кавычек», отрезок: строка, предел: число, цели: список строки + возвращает «Ход кавычек» + пусть кандидат равно («Кандидат ли» от (ход.«номер») и предел и (ход.«пропуск»)) + пусть находка равно («Находка кавычек ли» от отрезок и кандидат) + пусть помин равно (запись «Помин» с «строка» равным (ход.«строка») и «имя» равным отрезок) + пусть взято равно (находка и притом (цели содержит отрезок)) + пусть места равно (если взято то (приписать помин к (ход.«места»)) иначе (ход.«места»)) + «Ход кавычек дальше» от ход и отрезок и находка и места + +тотальная функция «Куски по» + принимает акк: список строки, часть: строка, знак: строка + возвращает список строки + свёртка (разделить часть по знак) начиная с акк как собрано и кусок → (приписать кусок к собрано) + +тотальная функция «Обратить от строк» + принимает части: список строки + возвращает список строки + пример «Порядок обращён» + дано части равно ["а", "б"] + ожидается ["б", "а"] + свёртка части начиная с (пустой список) как собрано и часть → (приписать часть к собрано) + +тотальная функция «Сложить строки» + принимает первые: список строки, вторые: список строки + возвращает список строки + пример «Два ряда в один» + дано первые равно ["а", "б"] + дано вторые равно ["в"] + ожидается ["а", "б", "в"] + свёртка («Обратить от строк» от первые) начиная с вторые как собрано и часть → (приписать часть к собрано) + +объект «Отбор» + «счёт»: число + «взято»: список строки + +тотальная функция «Отбор с» + принимает счёт: число, взято: список строки + возвращает «Отбор» + запись «Отбор» с «счёт» равным счёт и «взято» равным взято + +тотальная функция «Шаг начала» + принимает ход: «Отбор», часть: строка, сколько: число + возвращает «Отбор» + пусть счёт равно ((ход.«счёт») плюс 1) + если счёт больше сколько + то «Отбор с» от счёт и (ход.«взято») + иначе «Отбор с» от счёт и (приписать часть к (ход.«взято»)) + +тотальная функция «Взять начало» + принимает части: список строки, сколько: число + возвращает список строки + пример «Первые два куска» + дано части равно ["а", "б", "в"] + дано сколько равно 2 + ожидается ["а", "б"] + пример «Больше, чем есть — всё» + дано части равно ["а"] + дано сколько равно 9 + ожидается ["а"] + пусть пуск равно («Отбор с» от 0 и (пустой список)) + пусть итог равно (свёртка части начиная с пуск как ход и часть → («Шаг начала» от ход и часть и сколько)) + «Обратить от строк» от (итог.«взято») + +тотальная функция «Шаг остатка» + принимает ход: «Отбор», часть: строка, сколько: число + возвращает «Отбор» + пусть счёт равно ((ход.«счёт») плюс 1) + если счёт не больше сколько + то «Отбор с» от счёт и (ход.«взято») + иначе «Отбор с» от счёт и (приписать часть к (ход.«взято»)) + +тотальная функция «Без начала» + принимает части: список строки, сколько: число + возвращает список строки + пример «Без первого куска» + дано части равно ["а", "б", "в"] + дано сколько равно 1 + ожидается ["б", "в"] + пусть пуск равно («Отбор с» от 0 и (пустой список)) + пусть итог равно (свёртка части начиная с пуск как ход и часть → («Шаг остатка» от ход и часть и сколько)) + «Обратить от строк» от (итог.«взято») + +тотальная функция «Шаг без повтора» + принимает собрано: список строки, часть: строка + возвращает список строки + если собрано содержит часть + то собрано + иначе приписать часть к собрано + +тотальная функция «Без повторов» + принимает части: список строки + возвращает список строки + пример «Повтор снят, порядок первых вхождений цел» + дано части равно ["б", "а", "б"] + ожидается ["б", "а"] + пусть итог равно (свёртка части начиная с (пустой список) как сбор и часть → («Шаг без повтора» от сбор и часть)) + «Обратить от строк» от итог + +тотальная функция «Разнять» + принимает части: список строки, знак: строка + возвращает список строки + пример «Каждая часть рассечена знаком, порядок обращён» + дано части равно ["a'b", "c"] + дано знак равно "'" + ожидается ["c", "b", "a"] + свёртка части начиная с (пустой список) как акк и часть → («Куски по» от акк и часть и знак) + +тотальная функция «Отрезки по кавычкам» + принимает текст: строка + возвращает список строки + пример «Отрезки между соседними кавычками любого вида» + дано текст равно "'c' и `go`" + ожидается ["", "c", " и ", "go", ""] + пример «Кавычек нет — отрезок один» + дано текст равно "слово" + ожидается ["слово"] + пусть двойные равно (разделить текст по "\"") + пусть одни равно («Обратить от строк» от («Разнять» от двойные и "'")) + «Обратить от строк» от («Разнять» от одни и "`") + +тотальная функция «Места прозы» + принимает отрезки: список строки, предел: число, цели: список строки + возвращает список «Помин» + пусть исход равно («Пустой ход кавычек») + (свёртка отрезки начиная с исход как ход и отрезок → («Шаг отрезка» от ход и отрезок и предел и цели)).«места» + +тотальная функция «Помины прозы» + принимает текст: строка, цели: список строки + возвращает список «Помин» + пример «Две цели в кавычках на второй строке» + дано текст равно "первая\n`go` и `rust`\n" + дано цели равно ["go", "rust"] + ожидается [запись «Помин» с «строка» равным 2 и «имя» равным "go", + запись «Помин» с «строка» равным 2 и «имя» равным "rust"] + пример «Съеденная кавычка прячет следующее имя» + дано текст равно "\"it's go\"\n" + дано цели равно ["go"] + ожидается пустой список + пример «Без кавычек проза перечнем не бывает» + дано текст равно "цель go печатает\n" + дано цели равно ["go"] + ожидается пустой список + пусть отрезки равно («Отрезки по кавычкам» от текст) + пусть предел равно ((длина отрезки) минус 2) + если предел меньше 1 + то пустой список + иначе «Обратить помины» от («Места прозы» от отрезки и предел и цели) + +объект «Находка» + «род»: строка + «где»: строка + «стр»: строка + «мера»: строка + «речь»: строка + +объект «Уклад» + «цели»: список строки + «посев»: список строки + «порядок»: список строки + «порог»: число + +тотальная функция «Порог» + принимает всего: число + возвращает число + пример «Две трети от девяти — шесть» + дано всего равно 9 + ожидается 6 + пример «Две трети от десяти — тоже шесть» + дано всего равно 10 + ожидается 6 + пример «Меньше трёх порог не бывает» + дано всего равно 2 + ожидается 3 + пусть двое равно (всего умножить на 2) + пусть целых равно ((двое минус (двое остаток от 3)) делить на 3) + если целых меньше 3 + то 3 + иначе целых + +тотальная функция «Перестановка gawk» + возвращает список числа + обеспечивает «мест ровно десять» (длина результат) равен 10 + пример «Места в порядке дерева, которые gawk обходил по очереди» + ожидается [7, 6, 2, 3, 9, 5, 1, 4, 10, 8] + [7, 6, 2, 3, 9, 5, 1, 4, 10, 8] + +тотальная функция «Порядок обхода» + принимает цели: список строки + возвращает список строки + обеспечивает «порядок не теряет и не добавляет имён» (длина результат) равен (длина цели) + пример «Десять целей дерева идут порядком хеш-таблицы gawk» + дано цели равно ["c", "cpp", "csharp", "elixir", "go", "java", "js", "python", "rust", "ts"] + ожидается ["js", "java", "cpp", "csharp", "rust", "go", "c", "elixir", "ts", "python"] + пример «Целей не десять — берётся порядок дерева» + дано цели равно ["c", "go"] + ожидается ["c", "go"] + если не ((длина цели) равен 10) + то цели + иначе отобразить («Перестановка gawk») как номер → (элемент номер в цели) + +тотальная функция «Ненайденные» + принимает порядок: список строки, имена: список строки + возвращает список строки + пример «Названо то, чего в череде нет» + дано порядок равно ["cpp", "c", "ts"] + дано имена равно ["c"] + ожидается ["cpp", "ts"] + отфильтровать порядок где цель → (не (имена содержит цель)) + +тотальная функция «Мера» + принимает сколько: число, всего: число + возвращает строка + пример «Восемь из десяти» + дано сколько равно 8 + дано всего равно 10 + ожидается "8 из 10" + соединить [(к строке сколько), " из ", (к строке всего)] по "" + +тотальная функция «Довод целей» + принимает ненайденные: список строки + возвращает строка + пример «Ненайденные перечисляются через запятую» + дано ненайденные равно ["cpp", "ts"] + ожидается "нет ни там, ни там: cpp,ts" + соединить ["нет ни там, ни там: ", (соединить ненайденные по ",")] по "" + +тотальная функция «Довод посева» + принимает сколько: число, ненайденные: список строки + возвращает строка + пример «Сказано, по чему сошлось и чего нет в исходнике» + дано сколько равно 9 + дано ненайденные равно ["cpp"] + ожидается "по семени (9 целей); в исходнике нет: cpp" + соединить ["по семени (", (к строке сколько), " целей); в исходнике нет: ", + (соединить ненайденные по ",")] по "" + +тотальная функция «Сошлось с посевом ли» + принимает уклад: «Уклад», имена: список строки + возвращает признак + пусть посев равно (уклад.«посев») + пусть мимо равно («Ненайденные» от посев и имена) + ((длина посев) больше 0) и притом (((длина мимо) равен 0) и притом ((длина имена) равен (длина посев))) + +тотальная функция «Сложить находку» + принимает род: строка, адрес: строка, стр: строка, мера: строка, речь: строка + возвращает «Находка» + запись «Находка» с «род» равным род и «где» равным адрес и «стр» равным стр и «мера» равным мера и «речь» равным речь + +тотальная функция «Неполная череда» + принимает адрес: строка, стр: строка, имена: список строки, уклад: «Уклад», мимо: список строки + возвращает «Находка» + пусть мера равно («Мера» от (длина имена) и (длина (уклад.«цели»))) + пусть речь равно («Довод посева» от (длина (уклад.«посев»)) и мимо) + если («Сошлось с посевом ли» от уклад и имена) + то «Сложить находку» от "ЦЕЛИ-СЕМЯ" и адрес и стр и мера и речь + иначе «Сложить находку» от "ЦЕЛИ" и адрес и стр и мера и («Довод целей» от мимо) + +тотальная функция «Находка череды целей» + принимает адрес: строка, стр: строка, имена: список строки, уклад: «Уклад» + возвращает «Находка» + пусть мимо равно («Ненайденные» от (уклад.«порядок») и имена) + пусть мера равно («Мера» от (длина имена) и (длина (уклад.«цели»))) + если (длина мимо) равен 0 + то «Сложить находку» от "ЦЕЛИ-ЦЕЛ" и адрес и стр и мера и "по исходнику" + иначе «Неполная череда» от адрес и стр и имена и уклад и мимо + +объект «Ход целей» + «нач»: число + «посл»: число + «имена»: список строки + «итог»: список «Находка» + +тотальная функция «Ход целей с» + принимает нач: число, посл: число, имена: список строки, итог: список «Находка» + возвращает «Ход целей» + запись «Ход целей» с «нач» равным нач и «посл» равным посл и «имена» равным имена и «итог» равным итог + +тотальная функция «Добавить цель» + принимает имена: список строки, имя: строка + возвращает список строки + пример «Повтор имени череду не удлиняет» + дано имена равно ["c"] + дано имя равно "c" + ожидается ["c"] + пример «Новое имя дописывается в конец» + дано имена равно ["c"] + дано имя равно "go" + ожидается ["c", "go"] + если имена содержит имя + то имена + иначе добавить имя к имена + +тотальная функция «Закрыть череду целей» + принимает ход: «Ход целей», адрес: строка, уклад: «Уклад» + возвращает список «Находка» + пусть имена равно (ход.«имена») + пусть стр равно (к строке (ход.«нач»)) + если (длина имена) меньше (уклад.«порог») + то (ход.«итог») + иначе приписать («Находка череды целей» от адрес и стр и имена и уклад) к (ход.«итог») + +тотальная функция «Начать череду целей» + принимает ход: «Ход целей», помин: «Помин», адрес: строка, уклад: «Уклад» + возвращает «Ход целей» + пусть итог равно («Закрыть череду целей» от ход и адрес и уклад) + пусть стр равно (помин.«строка») + «Ход целей с» от стр и стр и [(помин.«имя»)] и итог + +тотальная функция «Шаг помина» + принимает ход: «Ход целей», помин: «Помин», адрес: строка, уклад: «Уклад» + возвращает «Ход целей» + пусть стр равно (помин.«строка») + пусть рвётся равно (((длина (ход.«имена»)) равен 0) или ((стр минус (ход.«посл»)) больше 1)) + если рвётся + то «Начать череду целей» от ход и помин и адрес и уклад + иначе «Ход целей с» от (ход.«нач») и стр и («Добавить цель» от (ход.«имена») и (помин.«имя»)) и (ход.«итог») + +тотальная функция «Помины файла» + принимает путь: строка, текст: строка, цели: список строки + возвращает список «Помин» + если («Кончается на» от путь и ".md") + то «Помины прозы» от текст и цели + иначе «Помины кода» от текст и цели + +тотальная функция «Находки файла целей» + принимает найдено: список «Находка», путь: строка, текст: строка, уклад: «Уклад» + возвращает список «Находка» + пусть помины равно («Помины файла» от путь и текст и (уклад.«цели»)) + пусть начало равно («Ход целей с» от 0 и 0 и (пустой список) и найдено) + пусть итог равно (свёртка помины начиная с начало как ход и помин → («Шаг помина» от ход и помин и путь и уклад)) + «Закрыть череду целей» от итог и путь и уклад + +тотальная функция «Расширения пути» + возвращает список строки + обеспечивает «расширений ровно двадцать четыре» (длина результат) равен 24 + [".flang", ".fscript", ".mjs", ".md", ".sh", ".c", ".h", ".json", ".tsv", ".txt", + ".py", ".fts", ".yml", ".yaml", ".js", ".awk", ".ex", ".java", ".cs", ".vim", + ".html", ".hex", ".toml", ".lock"] + +тотальная функция «Корни пути» + возвращает список строки + обеспечивает «корней ровно одиннадцать» (длина результат) равен 11 + ["flang", "docs", "scripts", "tasks", "fspec", "examples", "benchmarks", + "bootstrap", "packaging", "editors", "web"] + +тотальная функция «Все заглавные» + принимает текст: строка + возвращает признак + пример «Имя переменной оболочки» + дано текст равно "KOREN" + ожидается да + пример «Строчная буква сюда не входит» + дано текст равно "Koren" + ожидается нет + разбор текст + случай пусто + то да + случай голова и хвост + то если («Знак заглавного ли» от голова) + то «Все заглавные» от хвост + иначе нет + +тотальная функция «Подстановкой ли» + принимает имя: строка + возвращает признак + пример «Переменная оболочки с путём» + дано имя равно "KOREN/scripts" + ожидается да + пример «Обычный путь дерева» + дано имя равно "docs/a.md" + ожидается нет + пусть первый равно («До метки» от имя и "/") + пусть знак равно («Первый знак» от первый) + («Заглавная ли» от («Код знака» от знак)) и притом («Все заглавные» от первый) + +тотальная функция «Основа» + принимает имя: строка + возвращает строка + пример «Основа после последней косой черты» + дано имя равно "docs/site/a.md" + ожидается "a.md" + пусть куски равно (разделить имя по "/") + элемент (длина куски) в куски + +тотальная функция «Основа одной буквы» + принимает имя: строка + возвращает признак + пример «Выдуманный пример пробы» + дано имя равно "docs/a.md" + ожидается да + пример «Настоящее имя файла» + дано имя равно "docs/abc.md" + ожидается нет + («Знак номер» от («Основа» от имя) и 2) равен "." + +тотальная функция «Основа примером ли» + принимает имя: строка + возвращает признак + пример «Одна буква и точка» + дано имя равно "docs/a.md" + ожидается да + пример «Две буквы перед точкой» + дано имя равно "docs/ab.md" + ожидается нет + пример «Подчёркивание в этот класс не входит» + дано имя равно "docs/_.md" + ожидается нет + пусть основа равно («Основа» от имя) + пусть код равно («Код знака» от («Первый знак» от основа)) + ((«Латинская ли» от код) или («Цифра ли» от код)) и притом («Основа одной буквы» от имя) + +тотальная функция «Расширение годное ли» + принимает имя: строка + возвращает признак + пример «Страница разметки» + дано имя равно "docs/a.md" + ожидается да + пример «Расширения нет в списке» + дано имя равно "docs/a.zip" + ожидается нет + свёртка («Расширения пути») начиная с нет как акк и хвостик → (акк или («Кончается на» от имя и хвостик)) + +тотальная функция «Корень годный ли» + принимает имя: строка + возвращает признак + пример «Путь от корня дерева» + дано имя равно "scripts/guards/x.zip" + ожидается да + пример «Корня нет в списке» + дано имя равно "etc/passwd" + ожидается нет + свёртка («Корни пути») начиная с нет как акк и корень → (акк или (имя начинается с (соединить [корень, "/"] по ""))) + +тотальная функция «Место дерева ли» + принимает имя: строка + возвращает признак + пример «Имя с годным расширением» + дано имя равно "a/b.md" + ожидается да + пример «Имя под годным корнем» + дано имя равно "docs/site" + ожидается да + пример «Ни расширения, ни корня» + дано имя равно "a/b" + ожидается нет + («Расширение годное ли» от имя) или («Корень годный ли» от имя) + +тотальная функция «Годное имя» + принимает имя: строка, пред: строка + возвращает признак + пример «Имя дерева годится» + дано имя равно "docs/a-b.md" + дано пред равно " " + ожидается да + пример «Слева подстановка оболочки» + дано имя равно "docs/a-b.md" + дано пред равно "$" + ожидается нет + пример «Переменная оболочки именем дерева не считается» + дано имя равно "KOREN/docs/a-b.md" + дано пред равно " " + ожидается нет + пример «Выдуманный пример пробы в счёт не идёт» + дано имя равно "docs/a.md" + дано пред равно " " + ожидается нет + если (не (пред равен "")) и притом ("$%{" содержит пред) + то нет + иначе «Годное имя дальше» от имя + +тотальная функция «Годное имя дальше» + принимает имя: строка + возвращает признак + пример «Имя дерева годится» + дано имя равно "docs/a-b.md" + ожидается да + пример «Подстановка в имени» + дано имя равно "KOREN/x.md" + ожидается нет + если («Подстановкой ли» от имя) или (не («Место дерева ли» от имя)) + то нет + иначе не («Основа примером ли» от имя) + +объект «Ищейка» + «поз»: число + «сост»: число + «нач»: число + «край»: число + «имена»: список строки + +тотальная функция «Ищейка с» + принимает поз: число, сост: число, нач: число, край: число, имена: список строки + возвращает «Ищейка» + запись «Ищейка» с «поз» равным поз и «сост» равным сост и «нач» равным нач и «край» равным край и «имена» равным имена + +тотальная функция «Пустая ищейка» + возвращает «Ищейка» + «Ищейка с» от 0 и 0 и 0 и 0 и (пустой список) + +тотальная функция «Знак перед именем» + принимает текст: строка, нач: число + возвращает строка + пример «Знак слева от имени» + дано текст равно " docs/a.md" + дано нач равно 2 + ожидается " " + пример «Имя стоит у края строки» + дано текст равно "docs/a.md" + дано нач равно 1 + ожидается "" + «Знак номер» от текст и (нач минус 1) + +тотальная функция «Имена с находкой» + принимает ход: «Ищейка», текст: строка + возвращает список строки + если (ход.«край») равен 0 + то (ход.«имена») + иначе «Имена с именем» от ход и текст + +тотальная функция «Имена с именем» + принимает ход: «Ищейка», текст: строка + возвращает список строки + пусть имя равно (подстрока текст с (ход.«нач») по (ход.«край»)) + пусть пред равно («Знак перед именем» от текст и (ход.«нач»)) + если («Годное имя» от имя и пред) + то приписать имя к (ход.«имена») + иначе (ход.«имена») + +тотальная функция «Сдать имя» + принимает ход: «Ищейка», поз: число, текст: строка + возвращает «Ищейка» + «Ищейка с» от поз и 0 и 0 и 0 и («Имена с находкой» от ход и текст) + +тотальная функция «Шаг вне имени» + принимает ход: «Ищейка», знак: строка, поз: число + возвращает «Ищейка» + если («Знак начала ли» от знак) + то «Ищейка с» от поз и 1 и поз и 0 и (ход.«имена») + иначе «Ищейка с» от поз и 0 и 0 и 0 и (ход.«имена») + +тотальная функция «Шаг первого отрезка» + принимает ход: «Ищейка», знак: строка, поз: число + возвращает «Ищейка» + если знак равен "/" + то «Ищейка с» от поз и 2 и (ход.«нач») и (ход.«край») и (ход.«имена») + иначе «Первый отрезок дальше» от ход и знак и поз + +тотальная функция «Первый отрезок дальше» + принимает ход: «Ищейка», знак: строка, поз: число + возвращает «Ищейка» + если («Знак середины ли» от знак) + то «Ищейка с» от поз и 1 и (ход.«нач») и (ход.«край») и (ход.«имена») + иначе «Ищейка с» от поз и 0 и 0 и 0 и (ход.«имена») + +тотальная функция «Шаг после черты» + принимает ход: «Ищейка», знак: строка, поз: число, текст: строка + возвращает «Ищейка» + если («Знак отрезка ли» от знак) + то «Ищейка с» от поз и 3 и (ход.«нач») и поз и (ход.«имена») + иначе «Сдать имя» от ход и поз и текст + +тотальная функция «Шаг отрезка пути» + принимает ход: «Ищейка», знак: строка, поз: число, текст: строка + возвращает «Ищейка» + если знак равен "/" + то «Ищейка с» от поз и 2 и (ход.«нач») и (ход.«край») и (ход.«имена») + иначе «Отрезок пути дальше» от ход и знак и поз и текст + +тотальная функция «Отрезок пути дальше» + принимает ход: «Ищейка», знак: строка, поз: число, текст: строка + возвращает «Ищейка» + если («Знак отрезка ли» от знак) + то «Ищейка с» от поз и 3 и (ход.«нач») и поз и (ход.«имена») + иначе «Сдать имя» от ход и поз и текст + +тотальная функция «Шаг после первого» + принимает ход: «Ищейка», знак: строка, поз: число, текст: строка + возвращает «Ищейка» + если (ход.«сост») равен 2 + то «Шаг после черты» от ход и знак и поз и текст + иначе «Шаг отрезка пути» от ход и знак и поз и текст + +тотальная функция «Шаг внутри имени» + принимает ход: «Ищейка», знак: строка, поз: число, текст: строка + возвращает «Ищейка» + если (ход.«сост») равен 1 + то «Шаг первого отрезка» от ход и знак и поз + иначе «Шаг после первого» от ход и знак и поз и текст + +тотальная функция «Шаг ищейки» + принимает ход: «Ищейка», знак: строка, текст: строка + возвращает «Ищейка» + пусть поз равно ((ход.«поз») плюс 1) + если (ход.«сост») равен 0 + то «Шаг вне имени» от ход и знак и поз + иначе «Шаг внутри имени» от ход и знак и поз и текст + +тотальная функция «Имена строчки» + принимает текст: строка + возвращает список строки + пример «Два имени в строке списка» + дано текст равно "- docs/a-b.md и scripts/guards/xy.sh" + ожидается ["docs/a-b.md", "scripts/guards/xy.sh"] + пример «Имя до конца строки» + дано текст равно "\"flang/self/emit-c.flang\"" + ожидается ["flang/self/emit-c.flang"] + пример «Обрубок с косой чертой на конце берётся без неё» + дано текст равно "\"flang/self/emit-*.flang\"" + ожидается ["flang/self/emit-"] + пример «Двойная косая черта имени не даёт» + дано текст равно "\"a//b\"" + ожидается пустой список + пусть знаки равно (разложить текст на символы) + пусть итог равно (свёртка знаки начиная с («Пустая ищейка») как ход и знак → («Шаг ищейки» от ход и знак и текст)) + «Обратить от строк» от («Имена с находкой» от итог и текст) + +тотальная функция «Строчка пути» + принимает текст: строка + возвращает строка + пример «Записанные переводы строк в тексте считаются пробелом» + дано текст равно "a\\ndocs/b.md" + ожидается "a docs/b.md" + пусть без-н равно («Подменить» от текст и "\\n" и " ") + пусть без-р равно («Подменить» от без-н и "\\r" и " ") + «Подменить» от без-р и "\\t" и " " + +тотальная функция «Отбивка ли» + принимает знак: строка + возвращает признак + пример «Пробел» + дано знак равно " " + ожидается да + пример «Буква отбивкой не бывает» + дано знак равно "a" + ожидается нет + (знак равен " ") или (знак равен "\t") + +тотальная функция «Без отступа» + принимает текст: строка + возвращает строка + пример «Отступ снят» + дано текст равно " - пункт" + ожидается "- пункт" + пример «Отступа нет» + дано текст равно "слово" + ожидается "слово" + разбор текст + случай пусто + то "" + случай голова и хвост + то если («Отбивка ли» от голова) + то «Без отступа» от хвост + иначе текст + +тотальная функция «Цифр впереди» + принимает текст: строка, счёт: число + возвращает число + пример «Две цифры и точка» + дано текст равно "12. пункт" + дано счёт равно 0 + ожидается 2 + пример «Цифр нет» + дано текст равно "пункт" + дано счёт равно 0 + ожидается 0 + разбор текст + случай пусто + то счёт + случай голова и хвост + то если («Цифра ли» от («Код знака» от голова)) + то «Цифр впереди» от хвост и (счёт плюс 1) + иначе счёт + +тотальная функция «Маркером ли» + принимает тело: строка + возвращает признак + пример «Пункт с дефисом» + дано тело равно "- пункт" + ожидается да + пример «Дефис без отбивки маркером не бывает» + дано тело равно "-пункт" + ожидается нет + пусть первый равно («Первый знак» от тело) + пусть маркер равно ((не (первый равен "")) и притом ("-*+" содержит первый)) + маркер и притом («Отбивка ли» от («Знак номер» от тело и 2)) + +тотальная функция «Номером ли» + принимает тело: строка + возвращает признак + пример «Нумерованный пункт» + дано тело равно "12) пункт" + ожидается да + пример «Число без точки и скобки» + дано тело равно "12 пункт" + ожидается нет + пусть цифр равно («Цифр впереди» от тело и 0) + пусть точка равно («Знак номер» от тело и (цифр плюс 1)) + пусть знак равно ((не (точка равен "")) и притом (".)" содержит точка)) + ((цифр больше 0) и притом знак) и притом («Отбивка ли» от («Знак номер» от тело и (цифр плюс 2))) + +тотальная функция «Кавычкой ли» + принимает текст: строка + возвращает признак + пример «Закавыченный литерал» + дано текст равно "VSE=\"docs/a.md\"" + ожидается да + пример «Без кавычек» + дано текст равно "слово" + ожидается нет + (текст содержит "\"") или ((текст содержит "'") или (текст содержит "`")) + +тотальная функция «Шапка ли» + принимает текст: строка + возвращает признак + пример «Пункт списка» + дано текст равно " - docs/a.md" + ожидается да + пример «Ячейка таблицы» + дано текст равно "| docs/a.md |" + ожидается да + пример «Проза пунктом не бывает» + дано текст равно "так лежит docs/a.md рядом" + ожидается нет + пусть тело равно («Без отступа» от текст) + пусть пункт равно ((«Маркером ли» от тело) или («Номером ли» от тело)) + (пункт или («Первый знак» от тело) равен "|") или («Кавычкой ли» от текст) + +тотальная функция «Имена пункта дальше» + принимает ровно: строка + возвращает список строки + если («Шапка ли» от ровно) и притом (не (ровно содержит "://")) + то «Имена строчки» от ровно + иначе пустой список + +тотальная функция «Имена пункта» + принимает текст: строка + возвращает список строки + пример «Пункт списка с именем дерева» + дано текст равно "- docs/a-b.md" + ожидается ["docs/a-b.md"] + пример «Строка без косой черты имени не несёт» + дано текст равно "- просто слова" + ожидается пустой список + пример «Адрес в сети именем дерева не считается» + дано текст равно "- \"https://example.org/docs/a.md\"" + ожидается пустой список + если не (текст содержит "/") + то пустой список + иначе «Имена пункта дальше» от («Строчка пути» от текст) + +объект «Ряд» + «где»: строка + «стр»: строка + «пары»: строка + +объект «Обход» + «стр»: число + «пом»: список «Помин» + «проб»: число + «ряды»: список «Ряд» + +тотальная функция «Обход с» + принимает стр: число, пом: список «Помин», проб: число, ряды: список «Ряд» + возвращает «Обход» + запись «Обход» с «стр» равным стр и «пом» равным пом и «проб» равным проб и «ряды» равным ряды + +тотальная функция «Пустой обход» + возвращает «Обход» + «Обход с» от 0 и (пустой список) и 0 и (пустой список) + +тотальная функция «Обратить помины» + принимает помины: список «Помин» + возвращает список «Помин» + пример «Порядок обращён» + дано помины равно [запись «Помин» с «строка» равным 1 и «имя» равным "a", + запись «Помин» с «строка» равным 2 и «имя» равным "b"] + ожидается [запись «Помин» с «строка» равным 2 и «имя» равным "b", + запись «Помин» с «строка» равным 1 и «имя» равным "a"] + свёртка помины начиная с (пустой список) как собрано и помин → (приписать помин к собрано) + +тотальная функция «Обратить находки» + принимает находки: список «Находка» + возвращает список «Находка» + обеспечивает «обращение не теряет и не добавляет находок» (длина результат) равен (длина находки) + свёртка находки начиная с (пустой список) как собрано и находка → (приписать находка к собрано) + +тотальная функция «Обратить ряды» + принимает ряды: список «Ряд» + возвращает список «Ряд» + обеспечивает «обращение не теряет и не добавляет рядов» (длина результат) равен (длина ряды) + свёртка ряды начиная с (пустой список) как собрано и ряд → (приписать ряд к собрано) + +тотальная функция «Сложить находки» + принимает первые: список «Находка», вторые: список «Находка» + возвращает список «Находка» + свёртка («Обратить находки» от первые) начиная с вторые как собрано и находка → (приписать находка к собрано) + +тотальная функция «Пара имени» + принимает помин: «Помин» + возвращает строка + пример «Имя и строка через двоеточие» + дано помин равно запись «Помин» с «строка» равным 17 и «имя» равным "docs/a.md" + ожидается "docs/a.md:17" + соединить [(помин.«имя»), ":", (к строке (помин.«строка»))] по "" + +тотальная функция «Добавить имя» + принимает пом: список «Помин», имя: строка, стр: число + возвращает список «Помин» + пусть было равно ((отобразить пом как помин → (помин.«имя»)) содержит имя) + если было + то пом + иначе приписать (запись «Помин» с «строка» равным стр и «имя» равным имя) к пом + +тотальная функция «Добавить имена» + принимает пом: список «Помин», имена: список строки, стр: число + возвращает список «Помин» + пример «Повтор имени второй записи не даёт» + дано пом равно пустой список + дано имена равно ["a/b.md", "a/b.md"] + дано стр равно 3 + ожидается [запись «Помин» с «строка» равным 3 и «имя» равным "a/b.md"] + свёртка имена начиная с пом как акк и имя → («Добавить имя» от акк и имя и стр) + +тотальная функция «Строка первого» + принимает пом: список «Помин» + возвращает число + пример «Строка первого помина» + дано пом равно [запись «Помин» с «строка» равным 4 и «имя» равным "a/b.md"] + ожидается 4 + пример «У пустого ряда первой строки нет» + дано пом равно пустой список + ожидается 0 + разбор пом + случай пусто + то 0 + случай голова и хвост + то (голова.«строка») + +тотальная функция «Ряд из помин» + принимает адрес: строка, пом: список «Помин» + возвращает «Ряд» + пример «Ряд несёт адрес, первую строку и все пары» + дано адрес равно "docs/a.md" + дано пом равно [запись «Помин» с «строка» равным 9 и «имя» равным "b/c.md", + запись «Помин» с «строка» равным 7 и «имя» равным "d/e.md"] + ожидается запись «Ряд» с «где» равным "docs/a.md" и «стр» равным "7" и «пары» равным "d/e.md:7 b/c.md:9" + пусть первые равно («Обратить помины» от пом) + пусть стр равно (к строке («Строка первого» от первые)) + пусть пары равно (соединить (отобразить первые как помин → («Пара имени» от помин)) по " ") + запись «Ряд» с «где» равным адрес и «стр» равным стр и «пары» равным пары + +тотальная функция «Сдать ряд» + принимает ход: «Обход», адрес: строка + возвращает «Обход» + пусть ряд равно («Ряд из помин» от адрес и (ход.«пом»)) + пусть годен равно ((длина (ход.«пом»)) не меньше 3) + пусть ряды равно (если годен то (приписать ряд к (ход.«ряды»)) иначе (ход.«ряды»)) + «Обход с» от (ход.«стр») и (пустой список) и 0 и ряды + +тотальная функция «Шаг молчания» + принимает ход: «Обход», адрес: строка + возвращает «Обход» + пусть проб равно ((ход.«проб») плюс 1) + если ((длина (ход.«пом»)) больше 0) и притом (проб больше 1) + то «Сдать ряд» от ход и адрес + иначе «Обход с» от (ход.«стр») и (ход.«пом») и проб и (ход.«ряды») + +тотальная функция «Шаг строчки пути» + принимает ход: «Обход», текст: строка, адрес: строка + возвращает «Обход» + пусть стр равно ((ход.«стр») плюс 1) + пусть имена равно («Имена пункта» от текст) + пусть шаг равно («Обход с» от стр и (ход.«пом») и (ход.«проб») и (ход.«ряды»)) + если (длина имена) равен 0 + то «Шаг молчания» от шаг и адрес + иначе «Обход с» от стр и («Добавить имена» от (ход.«пом») и имена и стр) и 0 и (ход.«ряды») + +тотальная функция «Ряды файла» + принимает ряды: список «Ряд», адрес: строка, текст: строка + возвращает список «Ряд» + пусть начало равно («Обход с» от 0 и (пустой список) и 0 и ряды) + пусть строчки равно (разделить текст по "\n") + пусть итог равно (свёртка строчки начиная с начало как ход и строчка → («Шаг строчки пути» от ход и строчка и адрес)) + («Сдать ряд» от итог и адрес).«ряды» + +объект «Сличение» + «поз»: число + «итог»: число + +тотальная функция «Сличение с» + принимает поз: число, итог: число + возвращает «Сличение» + запись «Сличение» с «поз» равным поз и «итог» равным итог + +тотальная функция «Сличение кодов» + принимает поз: число, свой: число, чужой: число + возвращает «Сличение» + если свой равен чужой + то «Сличение с» от поз и 0 + иначе «Сличение с» от поз и (если свой меньше чужой то 1 иначе 2) + +тотальная функция «Сличение знаков» + принимает поз: число, свой: строка, чужой: строка + возвращает «Сличение» + если чужой равен "" + то «Сличение с» от поз и 2 + иначе «Сличение кодов» от поз и (код символа свой) и (код символа чужой) + +тотальная функция «Шаг сличения» + принимает ход: «Сличение», знак: строка, вторая: строка + возвращает «Сличение» + пусть поз равно ((ход.«поз») плюс 1) + если не ((ход.«итог») равен 0) + то «Сличение с» от поз и (ход.«итог») + иначе «Сличение знаков» от поз и знак и («Знак номер» от вторая и поз) + +тотальная функция «Раньше ли» + принимает первая: строка, вторая: строка + возвращает признак + пример «Короткая раньше длинной с тем же началом» + дано первая равно "ПУТИ" + дано вторая равно "ПУТИ-ЦЕЛ" + ожидается да + пример «П раньше Ц» + дано первая равно "ПУТИ" + дано вторая равно "ЦЕЛИ" + ожидается да + пример «Равные друг раньше друга не бывают» + дано первая равно "a" + дано вторая равно "a" + ожидается нет + пример «Числа сравниваются как строки» + дано первая равно "100" + дано вторая равно "17" + ожидается да + пусть знаки равно (разложить первая на символы) + пусть пуск равно («Сличение с» от 0 и 0) + пусть итог равно (свёртка знаки начиная с пуск как ход и знак → («Шаг сличения» от ход и знак и вторая)) + если (итог.«итог») равен 0 + то (длина первая) меньше (длина вторая) + иначе (итог.«итог») равен 1 + +тотальная функция «Вставить по порядку строк» + принимает новая: строка, строки: список строки + возвращает список строки + пример «Вставка в середину» + дано новая равно "b" + дано строки равно ["a", "c"] + ожидается ["a", "b", "c"] + разбор строки + случай пусто + то [новая] + случай голова и хвост + то если («Раньше ли» от новая и голова) + то приписать новая к строки + иначе приписать голова к («Вставить по порядку строк» от новая и хвост) + +тотальная функция «Сортировать строки» + принимает строки: список строки + возвращает список строки + пример «Порядок по кодовым точкам» + дано строки равно ["ts", "c", "go"] + ожидается ["c", "go", "ts"] + свёртка строки начиная с (пустой список) как акк и строчка → («Вставить по порядку строк» от строчка и акк) + +тотальная функция «Разность рядов» + принимает первые: список строки, вторые: список строки + возвращает список строки + пример «Лишнее с первой стороны» + дано первые равно ["a", "b", "c"] + дано вторые равно ["b"] + ожидается ["a", "c"] + пример «Лишнего нет» + дано первые равно ["b"] + дано вторые равно ["a", "b"] + ожидается пустой список + «Сортировать строки» от (отфильтровать первые где ключ → (не (вторые содержит ключ))) + +объект «Рост» + «путь»: строка + «ряд»: список строки + +тотальная функция «Шаг роста» + принимает ход: «Рост», кусок: строка + возвращает «Рост» + пусть путь равно (если (ход.«путь») равен "" то кусок иначе (соединить [(ход.«путь»), "/", кусок] по "")) + запись «Рост» с «путь» равным путь и «ряд» равным (приписать путь к (ход.«ряд»)) + +тотальная функция «Шаг роста с хвоста» + принимает ход: «Рост», кусок: строка + возвращает «Рост» + пусть путь равно (если (ход.«путь») равен "" то кусок иначе (соединить [кусок, "/", (ход.«путь»)] по "")) + запись «Рост» с «путь» равным путь и «ряд» равным (приписать путь к (ход.«ряд»)) + +тотальная функция «Нарастающие с хвоста» + принимает куски: список строки + возвращает список строки + пример «Каждый хвост пути — своя строка» + дано куски равно ["a.md", "site", "docs"] + ожидается ["a.md", "site/a.md", "docs/site/a.md"] + пусть пуск равно (запись «Рост» с «путь» равным "" и «ряд» равным (пустой список)) + пусть итог равно (свёртка куски начиная с пуск как ход и кусок → («Шаг роста с хвоста» от ход и кусок)) + «Обратить от строк» от (итог.«ряд») + +тотальная функция «Нарастающие» + принимает куски: список строки + возвращает список строки + пример «Каждый шаг пути — своя строка» + дано куски равно ["docs", "site", "a.md"] + ожидается ["docs", "docs/site", "docs/site/a.md"] + пусть пуск равно (запись «Рост» с «путь» равным "" и «ряд» равным (пустой список)) + пусть итог равно (свёртка куски начиная с пуск как ход и кусок → («Шаг роста» от ход и кусок)) + «Обратить от строк» от (итог.«ряд») + +тотальная функция «Приставки» + принимает путь: строка + возвращает список строки + пример «Все надкаталоги пути» + дано путь равно "docs/site/build.mjs" + ожидается ["docs", "docs/site"] + пример «У имени без каталога надкаталогов нет» + дано путь равно "README.md" + ожидается пустой список + пусть куски равно (разделить путь по "/") + пусть все равно («Нарастающие» от куски) + «Взять начало» от все и ((длина все) минус 1) + +тотальная функция «Хвосты» + принимает путь: строка + возвращает список строки + пример «Все хвосты пути» + дано путь равно "docs/site/build.mjs" + ожидается ["build.mjs", "site/build.mjs"] + пример «У имени без каталога хвостов нет» + дано путь равно "README.md" + ожидается пустой список + пусть куски равно (разделить путь по "/") + пусть все равно («Нарастающие с хвоста» от («Обратить от строк» от куски)) + «Взять начало» от все и ((длина все) минус 1) + +тотальная функция «Все виды» + принимает путь: строка + возвращает список строки + пример «Сам путь, надкаталоги и хвосты» + дано путь равно "docs/a.md" + ожидается ["docs/a.md", "docs", "a.md"] + приписать путь к («Сложить строки» от («Приставки» от путь) и («Хвосты» от путь)) + +тотальная функция «Виды на диске» + принимает путь: строка + возвращает список строки + пример «Имя и каталоги над ним» + дано путь равно "bootstrap/flang" + ожидается ["bootstrap/flang", "bootstrap"] + приписать путь к («Приставки» от путь) + +тотальная функция «Шаг свода пути» + принимает собрано: список строки, кусок: строка + возвращает список строки + если кусок равен "." + то собрано + иначе «Шаг свода вверх» от собрано и кусок + +тотальная функция «Шаг свода вверх» + принимает собрано: список строки, кусок: строка + возвращает список строки + если не (кусок равен "..") + то приписать кусок к собрано + иначе «Отнять отрезок» от собрано + +тотальная функция «Отнять отрезок» + принимает собрано: список строки + возвращает список строки + разбор собрано + случай пусто + то [".."] + случай голова и хвост + то хвост + +тотальная функция «Свести путь» + принимает имя: строка + возвращает строка + пример «Точка выбрасывается» + дано имя равно "flang/scripts/./binary.fscript" + ожидается "flang/scripts/binary.fscript" + пример «Две точки съедают предыдущий отрезок» + дано имя равно "flang/scripts/../stdlib/json.flang" + ожидается "flang/stdlib/json.flang" + пример «Точка на конце даёт каталог» + дано имя равно "packaging/asdf/." + ожидается "packaging/asdf" + пример «Обычное имя не меняется» + дано имя равно "docs/a-b.md" + ожидается "docs/a-b.md" + пусть куски равно (разделить имя по "/") + пусть сведено равно (свёртка куски начиная с (пустой список) как сбор и кусок → («Шаг свода пути» от сбор и кусок)) + соединить («Обратить от строк» от сведено) по "/" + +тотальная функция «Имя пары» + принимает пара: строка + возвращает строка + пример «Имя до двоеточия» + дано пара равно "docs/a.md:17" + ожидается "docs/a.md" + «До метки» от пара и ":" + +тотальная функция «Имена ряда» + принимает ряд: «Ряд» + возвращает список строки + пример «Имена без строк» + дано ряд равно запись «Ряд» с «где» равным "a" и «стр» равным "1" и «пары» равным "x/y.md:1 z/w.md:2" + ожидается ["x/y.md", "z/w.md"] + отобразить (разделить (ряд.«пары») по " ") как пара → («Свести путь» от («Имя пары» от пара)) + +тотальная функция «Имена рядов» + принимает ряды: список «Ряд» + возвращает список строки + пусть все равно (свёртка ряды начиная с (пустой список) как акк и ряд → («Имена дальше» от акк и ряд)) + «Без повторов» от все + +тотальная функция «Имена дальше» + принимает акк: список строки, ряд: «Ряд» + возвращает список строки + «Сложить строки» от акк и («Имена ряда» от ряд) + +тотальная функция «Отметить вид» + принимает найдено: список строки, кандидаты: список строки, вид: строка + возвращает список строки + если кандидаты содержит вид + то приписать вид к найдено + иначе найдено + +тотальная функция «Отметить виды» + принимает найдено: список строки, кандидаты: список строки, виды: список строки + возвращает список строки + свёртка виды начиная с найдено как акк и вид → («Отметить вид» от акк и кандидаты и вид) + +тотальная функция «Отметить опись» + принимает найдено: список строки, кандидаты: список строки, опись: список строки + возвращает список строки + свёртка опись начиная с найдено как акк и путь → («Отметить виды» от акк и кандидаты и («Все виды» от путь)) + +тотальная функция «Отметить диск» + принимает найдено: список строки, кандидаты: список строки, лишние: список строки + возвращает список строки + свёртка лишние начиная с найдено как акк и путь → («Отметить виды» от акк и кандидаты и («Виды на диске» от путь)) + +тотальная функция «Доступные» + принимает опись: список строки, лишние: список строки, ряды: список «Ряд» + возвращает список строки + пусть кандидаты равно («Имена рядов» от ряды) + пусть по-описи равно («Отметить опись» от (пустой список) и кандидаты и опись) + «Отметить диск» от по-описи и кандидаты и лишние + +тотальная функция «Довод путей» + принимает мимо: список строки + возвращает строка + пример «Ненайденные имена с их строками» + дано мимо равно ["a/b.md:3", "c/d.md:9"] + ожидается "нет: a/b.md:3 c/d.md:9" + соединить ["нет: ", (соединить мимо по " ")] по "" + +тотальная функция «Лежит ли» + принимает пара: строка, найдено: список строки + возвращает признак + найдено содержит («Свести путь» от («Имя пары» от пара)) + +тотальная функция «Находка ряда» + принимает ряд: «Ряд», найдено: список строки + возвращает «Находка» + пусть пары равно (разделить (ряд.«пары») по " ") + пусть мимо равно (отфильтровать пары где пара → (не («Лежит ли» от пара и найдено))) + пусть мера равно («Мера» от (длина мимо) и (длина пары)) + если (длина мимо) равен 0 + то «Сложить находку» от "ПУТИ-ЦЕЛ" и (ряд.«где») и (ряд.«стр») и («Мера» от 0 и (длина пары)) и "-" + иначе «Сложить находку» от "ПУТИ" и (ряд.«где») и (ряд.«стр») и мера и («Довод путей» от мимо) + +тотальная функция «Находки рядов» + принимает ряды: список «Ряд», найдено: список строки + возвращает список «Находка» + отобразить ряды как ряд → («Находка ряда» от ряд и найдено) + +тотальная функция «Расширения переписи» + возвращает список строки + обеспечивает «расширений ровно двенадцать» (длина результат) равен 12 + [".flang", ".fscript", ".mjs", ".sh", ".js", ".py", ".awk", ".json", ".yml", ".yaml", + ".md", ".tsv"] + +тотальная функция «Расширения кода» + возвращает список строки + обеспечивает «расширений ровно семь» (длина результат) равен 7 + [".flang", ".fscript", ".mjs", ".sh", ".js", ".py", ".awk"] + +тотальная функция «Из набора ли» + принимает путь: строка, набор: список строки + возвращает признак + пример «Страница разметки числится» + дано путь равно "docs/a.md" + дано набор равно [".md"] + ожидается да + пример «Чужое расширение не числится» + дано путь равно "docs/a.png" + дано набор равно [".md"] + ожидается нет + свёртка набор начиная с нет как акк и хвостик → (акк или («Кончается на» от путь и хвостик)) + +тотальная функция «Печать ли» + принимает путь: строка + возвращает признак + пример «Слой печати» + дано путь равно "flang/self/emit-go.flang" + ожидается да + пример «Другой файл того же каталога» + дано путь равно "flang/self/parser.flang" + ожидается нет + (путь начинается с "flang/self/emit-") и притом («Кончается на» от путь и ".flang") + +тотальная функция «Из имени печати» + принимает путь: строка + возвращает строка + пример «Имя цели из имени слоя печати» + дано путь равно "flang/self/emit-go.flang" + ожидается "go" + «До метки» от («После метки» от путь и "emit-") и ".flang" + +тотальная функция «Цели дерева» + принимает опись: список строки + возвращает список строки + пример «Цели берутся из имён слоёв печати» + дано опись равно ["flang/self/emit-ts.flang", "docs/a.md", "flang/self/emit-c.flang"] + ожидается ["c", "ts"] + пусть слои равно (отфильтровать опись где путь → («Печать ли» от путь)) + «Сортировать строки» от (отобразить слои как путь → («Из имени печати» от путь)) + +тотальная функция «Пробег целей» + принимает текст: строка, собрано: строка + возвращает строка + пример «Берётся ряд строчных букв и чёрточек» + дано текст равно "c|go|ts\nи дальше" + дано собрано равно "" + ожидается "c|go|ts" + разбор текст + случай пусто + то собрано + случай голова и хвост + то если («Строчная ли» от («Код знака» от голова)) или (голова равен "|") + то «Пробег целей» от (хвост) и (соединить [собрано, голова] по "") + иначе собрано + +тотальная функция «Цели семени» + принимает вывод: строка + возвращает список строки + пример «Цели двоичного из строки помощи» + дано вывод равно "flang emit --target c|go|ts --out КАТАЛОГ\n" + ожидается ["c", "go", "ts"] + пример «Двоичный о целях не сказал» + дано вывод равно "flang emit --out КАТАЛОГ\n" + ожидается пустой список + если не (вывод содержит "--target ") + то пустой список + иначе «Цели семени дальше» от («После метки» от вывод и "--target ") + +тотальная функция «Цели семени дальше» + принимает хвостик: строка + возвращает список строки + пример «Ряд целей через чёрточку» + дано хвостик равно "c|go --out КАТАЛОГ" + ожидается ["c", "go"] + пусть ряд равно («Пробег целей» от хвостик и "") + «Сортировать строки» от («Непустые» от (разделить ряд по "|")) + +тотальная функция «Рода находок» + принимает находки: список «Находка», род: строка + возвращает число + длина (отфильтровать находки где находка → ((находка.«род») равен род)) + +тотальная функция «Семья находок» + принимает находки: список «Находка», приставка: строка + возвращает число + длина (отфильтровать находки где находка → ((находка.«род») начинается с приставка)) + +тотальная функция «Строчка расхождения» + принимает находка: «Находка» + возвращает строка + соединить [" ", (находка.«род»), "\t", (находка.«где»), ":", (находка.«стр»), "\t", + (находка.«мера»), "\t", (находка.«речь»), "\n"] по "" + +тотальная функция «Строчка посева» + принимает находка: «Находка» + возвращает строка + соединить [" ", (находка.«где»), ":", (находка.«стр»), "\t", (находка.«речь»), "\n"] по "" + +тотальная функция «Ключ находки» + принимает находка: «Находка» + возвращает строка + соединить [(находка.«род»), "\t", (находка.«где»), "\t", (находка.«стр»)] по "" + +тотальная функция «Строчка ключа» + принимает ключ: строка + возвращает строка + пример «Ключ печатается как род и место со строкой» + дано ключ равно "ЦЕЛИ\tdocs/a.md\t7" + ожидается " ЦЕЛИ\tdocs/a.md:7\n" + пусть части равно (разделить ключ по "\t") + если (длина части) меньше 3 + то соединить [" ", ключ, "\n"] по "" + иначе «Строчка частей» от части + +тотальная функция «Строчка частей» + принимает части: список строки + возвращает строка + соединить [" ", (элемент 1 в части), "\t", (элемент 2 в части), ":", (элемент 3 в части), + "\n"] по "" + +тотальная функция «Головка переписи» + принимает ствол: строка, уклад: «Уклад» + возвращает строка + пусть цели равно (уклад.«цели») + пусть посев равно (уклад.«посев») + соединить ["перепись перечней, набранных руками — ствол ", ствол, "\n", + "целей печати по исходнику flang/self/emit-*.flang: ", (к строке (длина цели)), + " (", (соединить цели по " "), " )\n", + "целей печати у двоичного bootstrap/flang: ", (к строке (длина посев)), + " (", (соединить посев по " "), " )\n\n"] по "" + +тотальная функция «Числа переписи» + принимает находки: список «Находка», режим: строка + возвращает строка + пусть цп равно («Семья находок» от находки и "ЦЕЛИ") + пусть цб равно («Рода находок» от находки и "ЦЕЛИ") + пусть цс равно («Рода находок» от находки и "ЦЕЛИ-СЕМЯ") + пусть пп равно («Семья находок» от находки и "ПУТИ") + пусть пб равно («Рода находок» от находки и "ПУТИ") + пусть всех равно (если режим равен "цели" то цп иначе (цп плюс пп)) + пусть плохих равно (если режим равен "цели" то цб иначе (цб плюс пб)) + соединить ["перечней набрано руками: ", (к строке всех), " (целей ", (к строке цп), + ", путей ", (к строке пп), ")\n", + "из них расходятся с деревом сегодня: ", (к строке плохих), " (целей ", (к строке цб), + ", путей ", (к строке пб), ")\n", + "перечней целей, сошедшихся с семенем, а не с исходником: ", (к строке цс), "\n\n"] по "" + +тотальная функция «Расхождения» + принимает находки: список «Находка», режим: строка + возвращает список «Находка» + пусть свои равно (если режим равен "цели" то ["ЦЕЛИ"] иначе ["ЦЕЛИ", "ПУТИ"]) + отфильтровать находки где находка → (свои содержит (находка.«род»)) + +тотальная функция «Блок посева» + принимает находки: список «Находка» + возвращает строка + пусть посев равно (отфильтровать находки где находка → ((находка.«род») равен "ЦЕЛИ-СЕМЯ")) + если (длина посев) равен 0 + то "" + иначе «Блок посева дальше» от посев + +тотальная функция «Блок посева дальше» + принимает посев: список «Находка» + возвращает строка + пусть строчки равно (соединить (отобразить посев как находка → («Строчка посева» от находка)) по "") + соединить ["перечни целей, сошедшиеся с ДВОИЧНЫМ, а не с исходником (отстают на девятую цель):\n", + строчки, "\n"] по "" + +тотальная функция «Блок расхождений» + принимает расхождения: список «Находка» + возвращает строка + если (длина расхождения) равен 0 + то "" + иначе «Блок расхождений дальше» от расхождения + +тотальная функция «Блок расхождений дальше» + принимает расхождения: список «Находка» + возвращает строка + пусть строчки равно (отобразить расхождения как находка → («Строчка расхождения» от находка)) + соединить ["расхождения:\n", (соединить строчки по ""), "\n"] по "" + +тотальная функция «Перепись текстом» + принимает ствол: строка, уклад: «Уклад», находки: список «Находка», режим: строка + возвращает строка + пусть головка равно («Головка переписи» от ствол и уклад) + пусть числа равно («Числа переписи» от находки и режим) + пусть посев равно («Блок посева» от находки) + соединить [головка, числа, посев, («Блок расхождений» от («Расхождения» от находки и режим))] по "" + +тотальная функция «Путь ведомости» + возвращает строка + обеспечивает «ведомость лежит у описей» результат содержит "ledgers/" + "scripts/ledgers/hand-written-lists-ledger.tsv" + +тотальная функция «Чтение ведомости» + возвращает строка + обеспечивает «читается та же ведомость» результат содержит "hand-written-lists-ledger" + "../ledgers/hand-written-lists-ledger.tsv" + +тотальная функция «Ключ строчки ведомости» + принимает строчка: строка + возвращает строка + пример «Берутся три первых поля» + дано строчка равно "ЦЕЛИ\tdocs/a.md\t7\tдовод" + ожидается "ЦЕЛИ\tdocs/a.md\t7" + соединить («Взять начало» от (разделить строчка по "\t") и 3) по "\t" + +тотальная функция «Ключи ведомости» + принимает текст: строка + возвращает список строки + пример «Примечания и пустые строки в ведомость не входят» + дано текст равно "# слово\nЦЕЛИ\tdocs/a.md\t7\tдовод\n\n" + ожидается ["ЦЕЛИ\tdocs/a.md\t7"] + пусть живые равно (отфильтровать («Строчки» от текст) где строчка → (не (строчка начинается с "#"))) + отобразить живые как строчка → («Ключ строчки ведомости» от строчка) + +тотальная функция «Строчка павшего» + принимает путь: строка + возвращает строка + соединить [" нет на диске\t", путь, "\n"] по "" + +тотальная функция «Блок павших дальше» + принимает павшие: список строки + возвращает строка + пусть строчки равно (соединить (отобразить павшие как путь → («Строчка павшего» от путь)) по "") + соединить ["ЧИСЛЯТСЯ В GIT, НО НЕ ЛЕЖАТ НА ДИСКЕ: ", (к строке (длина павшие)), + " — перепись снята БЕЗ них\n", строчки, + "красным это не делаем: посреди перебазирования так и бывает; но числа\n", + "ниже сняты с неполного набора, и на них нельзя ссылаться как на полные.\n\n"] по "" + +тотальная функция «Блок павших» + принимает павшие: список строки + возвращает строка + если (длина павшие) равен 0 + то "" + иначе «Блок павших дальше» от павшие + +тотальная функция «Блок новых дальше» + принимает новые: список строки + возвращает строка + пусть строчки равно (соединить (отобразить новые как ключ → («Строчка ключа» от ключ)) по "") + соединить ["НОВЫХ РАСХОЖДЕНИЙ: ", (к строке (длина новые)), " — их нет в ведомости ", + («Путь ведомости»), "\n", строчки, "\n"] по "" + +тотальная функция «Блок новых» + принимает новые: список строки + возвращает строка + если (длина новые) равен 0 + то "" + иначе «Блок новых дальше» от новые + +тотальная функция «Блок мёртвых дальше» + принимает мёртвые: список строки + возвращает строка + пусть строчки равно (соединить (отобразить мёртвые как ключ → («Строчка ключа» от ключ)) по "") + соединить ["МЁРТВЫХ ЗАПИСЕЙ ВЕДОМОСТИ: ", (к строке (длина мёртвые)), + " — расхождения нет, а запись стоит\n", + "ведомость, пережившая дерево, — та же болезнь; уберите строки:\n", строчки, "\n"] по "" + +тотальная функция «Блок мёртвых» + принимает мёртвые: список строки + возвращает строка + если (длина мёртвые) равен 0 + то "" + иначе «Блок мёртвых дальше» от мёртвые + +тотальная функция «Слово отказа» + принимает новых: число, мёртвых: число + возвращает строка + пример «Сказано, сколько новых и сколько мёртвых» + дано новых равно 3 + дано мёртвых равно 2 + ожидается "перепись: новых 3, мёртвых записей 2\n" + соединить ["перепись: новых ", (к строке новых), ", мёртвых записей ", (к строке мёртвых), + "\n"] по "" + +тотальная функция «Слово согласия» + принимает плохих: число + возвращает строка + пример «Сказано, сколько расхождений названо с доводом» + дано плохих равно 60 + ожидается "перепись сошлась с ведомостью: 60 расхождений, все названы с доводом\n" + соединить ["перепись сошлась с ведомостью: ", (к строке плохих), + " расхождений, все названы с доводом\n"] по "" + +объект «Списки» + «опись»: список строки + «лишние»: список строки + «павшие»: список строки + +объект «Основа» + «уклад»: «Уклад» + «ствол»: строка + «списки»: «Списки» + +объект «Ковш» + «основа»: «Основа» + «найдено»: список «Находка» + «ряды»: список «Ряд» + +тип «Ход» + вариант «Ждём опись» содержит режим: строка + вариант «Ждём лишние» содержит режим: строка, опись: список строки + вариант «Ждём павшие» содержит режим: строка, списки: «Списки» + вариант «Ждём посев» содержит режим: строка, списки: «Списки» + вариант «Ждём ствол» содержит режим: строка, списки: «Списки», посев: список строки + вариант «Ждём файл» содержит режим: строка, ковш: «Ковш», осталось: список строки + вариант «Ждём ведомость» содержит режим: строка, ковш: «Ковш» + вариант «Ждём подлог» + +тотальная функция «Начать перепись» + возвращает «Ход» + обеспечивает «перепись начинается с описи дерева» результат равен (вариант «Ждём опись» с режим равным "перепись") + вариант «Ждём опись» с режим равным "перепись" + +тотальная функция «Начать сверку» + возвращает «Ход» + обеспечивает «сверка начинается с описи дерева» результат равен (вариант «Ждём опись» с режим равным "сверка") + вариант «Ждём опись» с режим равным "сверка" + +тотальная функция «Начать цели» + возвращает «Ход» + обеспечивает «перечни целей начинаются с описи» результат равен (вариант «Ждём опись» с режим равным "цели") + вариант «Ждём опись» с режим равным "цели" + +тотальная функция «Начать подлог» + возвращает «Ход» + обеспечивает «подлог идёт своим ходом» результат равен (вариант «Ждём подлог») + вариант «Ждём подлог» + +тотальная функция «Доводы git» + принимает ключи: список строки + возвращает список строки + пример «К ключам приписан выход к корню дерева» + дано ключи равно ["ls-files"] + ожидается ["-C", "../..", "-c", "core.quotepath=false", "ls-files"] + «Сложить строки» от ["-C", "../..", "-c", "core.quotepath=false"] и ключи + +тотальная функция «Прогон git» + принимает ключи: список строки + возвращает «Поручение» + вариант «Запустить процесс» с программа равным "git" и аргументы равным («Доводы git» от ключи) + +тотальная функция «Прогон семени» + возвращает «Поручение» + вариант «Запустить процесс» с программа равным "../../bootstrap/flang" и аргументы равным ["emit", "--help"] + +тотальная функция «Шагом» + принимает поручение: «Поручение», ход: «Ход» + возвращает «Продолжение» + вариант «Сделать» с поручение равным поручение и потом равным ход + +тотальная функция «Чтением» + принимает путь: строка, ход: «Ход» + возвращает «Продолжение» + «Шагом» от (вариант «Прочитать файл» с путь равным путь) и ход + +тотальная функция «Нечем смотреть» + принимает слово: строка + возвращает «Продолжение» + вариант «Не проверено» с код равным "FLANG_HANDLISTS_NECHEM" и сообщение равным слово + +тотальная функция «Ждали текст» + принимает что: строка + возвращает «Продолжение» + «Нечем смотреть» от (соединить ["ждали ответа от «", что, "», пришёл другой отклик"] по "") + +тотальная функция «Слово о двоичном» + возвращает строка + соединить ["НЕ СУДИЛ: нет двоичного bootstrap/flang.\n", + "Список целей печати у двоичного берётся прогоном `flang emit --help`;\n", + "без него всякий перечень целей выглядит разошедшимся, и перепись\n", + "называет расхождения, которых нет.\n", + "Это не «перечни разошлись», это «сверять не с чем».\n", + "Соберите его: make -C bootstrap -j8\n"] по "" + +тотальная функция «Слово о ведомости» + возвращает строка + соединить ["НЕ СУДИЛ: ведомости ", («Путь ведомости»), " нет — сверять не с чем\n"] по "" + +тотальная функция «Списки с» + принимает опись: список строки, лишние: список строки, павшие: список строки + возвращает «Списки» + запись «Списки» с «опись» равным опись и «лишние» равным лишние и «павшие» равным павшие + +тотальная функция «Уклад из» + принимает цели: список строки, посев: список строки + возвращает «Уклад» + пусть порядок равно («Порядок обхода» от цели) + пусть порог равно («Порог» от (длина цели)) + запись «Уклад» с «цели» равным цели и «посев» равным посев и «порядок» равным порядок и «порог» равным порог + +тотальная функция «Основа из» + принимает уклад: «Уклад», ствол: строка, списки: «Списки» + возвращает «Основа» + запись «Основа» с «уклад» равным уклад и «ствол» равным ствол и «списки» равным списки + +тотальная функция «Ковш из» + принимает основа: «Основа», найдено: список «Находка», ряды: список «Ряд» + возвращает «Ковш» + запись «Ковш» с «основа» равным основа и «найдено» равным найдено и «ряды» равным ряды + +тотальная функция «Файлы переписи» + принимает списки: «Списки» + возвращает список строки + пусть числятся равно (отфильтровать (списки.«опись») где путь → («Из набора ли» от путь и («Расширения переписи»))) + отфильтровать числятся где путь → (не ((списки.«павшие») содержит путь)) + +тотальная функция «Ряды файла или нет» + принимает ряды: список «Ряд», путь: строка, текст: строка + возвращает список «Ряд» + если («Из набора ли» от путь и («Расширения кода»)) + то «Ряды файла» от ряды и путь и текст + иначе ряды + +тотальная функция «Шаг файла» + принимает ковш: «Ковш», путь: строка, текст: строка + возвращает «Ковш» + пусть уклад равно ((ковш.«основа»).«уклад») + пусть найдено равно («Находки файла целей» от (ковш.«найдено») и путь и текст и уклад) + пусть ряды равно («Ряды файла или нет» от (ковш.«ряды») и путь и текст) + «Ковш из» от (ковш.«основа») и найдено и ряды + +тотальная функция «Первая строчка» + принимает текст: строка + возвращает строка + пример «Первая строка без перевода» + дано текст равно "d27d0a7cb\n" + ожидается "d27d0a7cb" + пример «Пусто остаётся пустым» + дано текст равно "\n" + ожидается "" + разбор («Строчки» от текст) + случай пусто + то "" + случай голова и хвост + то (голова) + +тотальная функция «Все находки» + принимает ковш: «Ковш» + возвращает список «Находка» + пусть списки равно ((ковш.«основа»).«списки») + пусть ряды равно («Обратить ряды» от (ковш.«ряды»)) + пусть доступные равно («Доступные» от (списки.«опись») и (списки.«лишние») и ряды) + «Сложить находки» от («Обратить находки» от (ковш.«найдено»)) и («Находки рядов» от ряды и доступные) + +тотальная функция «Перепись ковша» + принимает ковш: «Ковш», режим: строка + возвращает строка + пусть основа равно (ковш.«основа») + «Перепись текстом» от (основа.«ствол») и (основа.«уклад») и («Все находки» от ковш) и режим + +тотальная функция «Ход ведомости» + принимает режим: строка, ковш: «Ковш» + возвращает «Ход» + вариант «Ждём ведомость» с режим равным режим и ковш равным ковш + +тотальная функция «Свести» + принимает режим: строка, ковш: «Ковш» + возвращает «Продолжение» + если режим равен "сверка" + то «Чтением» от («Чтение ведомости») и («Ход ведомости» от режим и ковш) + иначе вариант «Конец работы» с значение равным («Перепись ковша» от ковш и режим) + +тотальная функция «Ход файла» + принимает режим: строка, ковш: «Ковш», осталось: список строки + возвращает «Ход» + вариант «Ждём файл» с режим равным режим и ковш равным ковш и осталось равным осталось + +тотальная функция «Идти по файлам» + принимает режим: строка, ковш: «Ковш», осталось: список строки + возвращает «Продолжение» + разбор осталось + случай пусто + то «Свести» от режим и ковш + случай голова и хвост + то «Чтением» от (соединить ["../../", (голова)] по "") и («Ход файла» от режим и ковш и осталось) + +тотальная функция «Файл прочитан» + принимает режим: строка, ковш: «Ковш», путь: строка, хвостик: список строки, отклик: «Отклик» + возвращает «Продолжение» + разбор отклик + случай вариант «Прочитано» с содержимое как текст + то «Идти по файлам» от режим и («Шаг файла» от ковш и путь и текст) и хвостик + случай вариант «Сбой» с код как код и сообщение как сообщение + то «Нечем смотреть» от (соединить ["файл ", путь, " не прочитан: ", сообщение] по "") + случай любое + то «Ждали текст» от путь + +тотальная функция «После файла» + принимает режим: строка, ковш: «Ковш», осталось: список строки, отклик: «Отклик» + возвращает «Продолжение» + разбор осталось + случай пусто + то «Свести» от режим и ковш + случай голова и хвост + то «Файл прочитан» от режим и ковш и (голова) и (хвост) и отклик + +тотальная функция «Отказ сверки» + принимает начало: строка, новые: список строки, мёртвые: список строки + возвращает «Продолжение» + пусть тело равно (соединить [начало, («Блок новых» от новые), («Блок мёртвых» от мёртвые), + («Слово отказа» от (длина новые) и (длина мёртвые))] по "") + вариант «Провал» с код равным "FLANG_HANDLISTS_RAZOSHLIS" и сообщение равным тело + +тотальная функция «Приговор сверки» + принимает ковш: «Ковш», режим: строка, новые: список строки, мёртвые: список строки, плохих: число + возвращает «Продолжение» + пусть павшие равно (((ковш.«основа»).«списки»).«павшие») + пусть начало равно (соединить [(«Перепись ковша» от ковш и режим), («Блок павших» от павшие)] по "") + если ((длина новые) плюс (длина мёртвые)) равен 0 + то вариант «Конец работы» с значение равным (соединить [начало, («Слово согласия» от плохих)] по "") + иначе «Отказ сверки» от начало и новые и мёртвые + +тотальная функция «Судить ведомость» + принимает режим: строка, ковш: «Ковш», текст: строка + возвращает «Продолжение» + пусть беды равно («Расхождения» от («Все находки» от ковш) и режим) + пусть сейчас равно (отобразить беды как находка → («Ключ находки» от находка)) + пусть ведомость равно («Ключи ведомости» от текст) + пусть новые равно («Разность рядов» от сейчас и ведомость) + «Приговор сверки» от ковш и режим и новые и («Разность рядов» от ведомость и сейчас) и (длина беды) + +тотальная функция «После ведомости» + принимает режим: строка, ковш: «Ковш», отклик: «Отклик» + возвращает «Продолжение» + разбор отклик + случай вариант «Прочитано» с содержимое как текст + то «Судить ведомость» от режим и ковш и текст + случай вариант «Сбой» с код как код и сообщение как сообщение + то «Нечем смотреть» от («Слово о ведомости») + случай любое + то «Ждали текст» от («Путь ведомости») + +тотальная функция «Ход лишних» + принимает режим: строка, опись: список строки + возвращает «Ход» + вариант «Ждём лишние» с режим равным режим и опись равным опись + +тотальная функция «Ход павших» + принимает режим: строка, списки: «Списки» + возвращает «Ход» + вариант «Ждём павшие» с режим равным режим и списки равным списки + +тотальная функция «Ход посева» + принимает режим: строка, списки: «Списки» + возвращает «Ход» + вариант «Ждём посев» с режим равным режим и списки равным списки + +тотальная функция «Ход ствола» + принимает режим: строка, списки: «Списки», посев: список строки + возвращает «Ход» + вариант «Ждём ствол» с режим равным режим и списки равным списки и посев равным посев + +тотальная функция «Беда прогона» + принимает что: строка, код: число, ошибки: строка + возвращает «Продолжение» + «Нечем смотреть» от (соединить [что, " ответил кодом ", (к строке код), ": ", ошибки] по "") + +тотальная функция «Опись готова» + принимает режим: строка, код: число, вывод: строка, ошибки: строка + возвращает «Продолжение» + если не (код равен 0) + то «Беда прогона» от "git ls-files" и код и ошибки + иначе «Шагом» от («Прогон git» от ["ls-files", "--others"]) и («Ход лишних» от режим и («Строчки» от вывод)) + +тотальная функция «После описи» + принимает режим: строка, отклик: «Отклик» + возвращает «Продолжение» + разбор отклик + случай вариант «Пока ничего» + то «Шагом» от («Прогон git» от ["ls-files"]) и (вариант «Ждём опись» с режим равным режим) + случай вариант «Процесс завершён» с код как код и вывод как вывод и ошибки как ошибки + то «Опись готова» от режим и код и вывод и ошибки + случай вариант «Сбой» с код как код и сообщение как сообщение + то «Нечем смотреть» от (соединить ["git ls-files не запустился: ", сообщение] по "") + случай любое + то «Ждали текст» от "git ls-files" + +тотальная функция «Лишние готовы» + принимает режим: строка, опись: список строки, код: число, вывод: строка, ошибки: строка + возвращает «Продолжение» + пусть списки равно («Списки с» от опись и («Строчки» от вывод) и (пустой список)) + если не (код равен 0) + то «Беда прогона» от "git ls-files --others" и код и ошибки + иначе «Шагом» от («Прогон git» от ["ls-files", "--deleted"]) и («Ход павших» от режим и списки) + +тотальная функция «После лишних» + принимает режим: строка, опись: список строки, отклик: «Отклик» + возвращает «Продолжение» + разбор отклик + случай вариант «Процесс завершён» с код как код и вывод как вывод и ошибки как ошибки + то «Лишние готовы» от режим и опись и код и вывод и ошибки + случай вариант «Сбой» с код как код и сообщение как сообщение + то «Нечем смотреть» от (соединить ["git ls-files --others не запустился: ", сообщение] по "") + случай любое + то «Ждали текст» от "git ls-files --others" + +тотальная функция «Павшие готовы» + принимает режим: строка, списки: «Списки», код: число, вывод: строка, ошибки: строка + возвращает «Продолжение» + пусть полные равно («Списки с» от (списки.«опись») и (списки.«лишние») и («Строчки» от вывод)) + если не (код равен 0) + то «Беда прогона» от "git ls-files --deleted" и код и ошибки + иначе «Шагом» от («Прогон семени») и («Ход посева» от режим и полные) + +тотальная функция «После павших» + принимает режим: строка, списки: «Списки», отклик: «Отклик» + возвращает «Продолжение» + разбор отклик + случай вариант «Процесс завершён» с код как код и вывод как вывод и ошибки как ошибки + то «Павшие готовы» от режим и списки и код и вывод и ошибки + случай вариант «Сбой» с код как код и сообщение как сообщение + то «Нечем смотреть» от (соединить ["git ls-files --deleted не запустился: ", сообщение] по "") + случай любое + то «Ждали текст» от "git ls-files --deleted" + +тотальная функция «Спросить ствол» + принимает режим: строка, списки: «Списки», посев: список строки + возвращает «Продолжение» + пусть ход равно («Ход ствола» от режим и списки и посев) + «Шагом» от («Прогон git» от ["rev-parse", "--short", "HEAD"]) и ход + +тотальная функция «После посева» + принимает режим: строка, списки: «Списки», отклик: «Отклик» + возвращает «Продолжение» + разбор отклик + случай вариант «Процесс завершён» с код как код и вывод как вывод и ошибки как ошибки + то «Спросить ствол» от режим и списки и («Цели семени» от вывод) + случай вариант «Сбой» с код как код и сообщение как сообщение + то «Нечем смотреть» от («Слово о двоичном») + случай любое + то «Ждали текст» от "bootstrap/flang emit --help" + +тотальная функция «Ствол готов» + принимает режим: строка, списки: «Списки», посев: список строки, вывод: строка + возвращает «Продолжение» + пусть уклад равно («Уклад из» от («Цели дерева» от (списки.«опись»)) и посев) + пусть основа равно («Основа из» от уклад и («Первая строчка» от вывод) и списки) + пусть ковш равно («Ковш из» от основа и (пустой список) и (пустой список)) + «Идти по файлам» от режим и ковш и («Файлы переписи» от списки) + +тотальная функция «После ствола» + принимает режим: строка, списки: «Списки», посев: список строки, отклик: «Отклик» + возвращает «Продолжение» + разбор отклик + случай вариант «Процесс завершён» с код как код и вывод как вывод и ошибки как ошибки + то «Ствол готов» от режим и списки и посев и вывод + случай вариант «Сбой» с код как код и сообщение как сообщение + то «Нечем смотреть» от (соединить ["git rev-parse не запустился: ", сообщение] по "") + случай любое + то «Ждали текст» от "git rev-parse" + +тотальная функция «Корень подлога» + возвращает строка + обеспечивает «копия ведомости заводится вне дерева» результат содержит "handlists-forgery" + "COPY=${FLANG_TMP:-/srv/tmp}/handlists-forgery.$$" + +тотальная функция «Шаги подлога» + возвращает список строки + обеспечивает «шагов ровно девять» (длина результат) равен 9 + ["cd ../..", («Корень подлога»), "mkdir -p \"${FLANG_TMP:-/srv/tmp}\"", + "LEDGER=scripts/ledgers/hand-written-lists-ledger.tsv", "cp \"$LEDGER\" \"$COPY.bak\"", + "printf 'ПУТИ\\tподделка/нет.md\\t1\\tподлог пробы\\n' >> \"$LEDGER\"", + "bootstrap/flang run-script hand-written-lists:check > \"$COPY.out\" 2>&1; code=$?", + "cp \"$COPY.bak\" \"$LEDGER\"", + "echo \"код $code\"; echo '@@@'; cat \"$COPY.out\"; rm -f \"$COPY.bak\" \"$COPY.out\""] + +тотальная функция «Команда подлога» + возвращает строка + соединить («Шаги подлога») по " && " + +тотальная функция «Оболочкой подлога» + возвращает «Поручение» + вариант «Запустить процесс» с программа равным "sh" и аргументы равным ["-c", («Команда подлога»)] + +тотальная функция «Кусок номер» + принимает какой: число, куски: список строки + возвращает строка + пример «Второй кусок» + дано какой равно 2 + дано куски равно ["код 1", "беда"] + ожидается "беда" + пример «За краем — пусто» + дано какой равно 9 + дано куски равно ["код 1"] + ожидается "" + если какой больше (длина куски) + то "" + иначе элемент какой в куски + +тотальная функция «Строчки с отступом» + принимает текст: строка + возвращает строка + пример «Каждая строка сдвинута на два пробела» + дано текст равно "раз\nдва\n" + ожидается " раз\n два" + соединить (отобразить («Строчки» от текст) как строчка → (соединить [" ", строчка] по "")) по "\n" + +тотальная функция «Слово промолчал» + возвращает строка + соединить ["ПОДЛОГ НЕ ПОЙМАН: вписали в ведомость запись о месте, которого в дереве нет,", + " а сторож ответил кодом 0. Сторож, не краснеющий на подложенной записи, —", + " выключенный сторож."] по "" + +тотальная функция «Почему не единица» + возвращает строка + соединить ["сторож ответил кодом не 1 — это не «поймал подлог», ", + "это «не смог посмотреть»"] по "" + +тотальная функция «Почему не тем» + возвращает строка + "сторож покраснел не тем — про подложенную запись в выводе нет ни слова" + +тотальная функция «Холостая проба» + принимает почему: строка, тело: строка + возвращает «Продолжение» + пример «Названа причина холостоты и показан вывод» + дано почему равно "сторож ответил кодом не 1" + дано тело равно "сверка не начата\n" + ожидается вариант «Конец работы» с значение равным "ПРОБА ХОЛОСТА: сторож ответил кодом не 1\n сверка не начата" + пусть слово равно (соединить ["ПРОБА ХОЛОСТА: ", почему, "\n", («Строчки с отступом» от тело)] по "") + вариант «Конец работы» с значение равным слово + +тотальная функция «Судить код не единицу» + принимает слово: строка, тело: строка + возвращает «Продолжение» + если слово начинается с "код 0" + то вариант «Конец работы» с значение равным («Слово промолчал») + иначе «Холостая проба» от («Почему не единица») и тело + +тотальная функция «Слово пойман» + принимает тело: строка + возвращает строка + соединить ["подлог пойман: вписанную в ведомость запись о месте, которого в дереве нет,", + " сторож назвал мёртвой и ответил кодом 1\n", («Строчки с отступом» от тело)] по "" + +тотальная функция «Судить код единицу» + принимает тело: строка + возвращает «Продолжение» + если не (тело содержит "подделка/нет.md") + то «Холостая проба» от («Почему не тем») и тело + иначе вариант «Провал» с код равным "FLANG_HANDLISTS_FORGERY" и сообщение равным («Слово пойман» от тело) + +тотальная функция «Судить подлог» + принимает вывод: строка + возвращает «Продолжение» + пусть части равно (разделить вывод по "@@@\n") + пусть слово равно («Кусок номер» от 1 и части) + если не (слово начинается с "код 1") + то «Судить код не единицу» от слово и («Кусок номер» от 2 и части) + иначе «Судить код единицу» от («Кусок номер» от 2 и части) + +тотальная функция «После подлога» + принимает отклик: «Отклик» + возвращает «Продолжение» + разбор отклик + случай вариант «Пока ничего» + то «Шагом» от («Оболочкой подлога») и (вариант «Ждём подлог») + случай вариант «Процесс завершён» с код как код и вывод как вывод и ошибки как ошибки + то «Судить подлог» от вывод + случай вариант «Процесс убит» с сигнал как сигнал и вывод как вывод и ошибки как ошибки + то «Нечем смотреть» от (соединить ["оболочка убита сигналом ", сигнал] по "") + случай вариант «Сбой» с код как код и сообщение как сообщение + то «Нечем смотреть» от (соединить ["оболочка не запустилась: ", сообщение] по "") + случай любое + то «Ждали текст» от "ответ оболочки" + +тотальная функция «Дальше» + принимает ход: «Ход», отклик: «Отклик» + возвращает «Продолжение» + разбор ход + случай вариант «Ждём опись» с режим как режим + то «После описи» от режим и отклик + случай вариант «Ждём лишние» с режим как режим и опись как опись + то «После лишних» от режим и опись и отклик + случай вариант «Ждём павшие» с режим как режим и списки как списки + то «После павших» от режим и списки и отклик + случай вариант «Ждём посев» с режим как режим и списки как списки + то «После посева» от режим и списки и отклик + случай вариант «Ждём ствол» с режим как режим и списки как списки и посев как посев + то «После ствола» от режим и списки и посев и отклик + случай вариант «Ждём файл» с режим как режим и ковш как ковш и осталось как осталось + то «После файла» от режим и ковш и осталось и отклик + случай вариант «Ждём ведомость» с режим как режим и ковш как ковш + то «После ведомости» от режим и ковш и отклик + случай вариант «Ждём подлог» + то «После подлога» от отклик + +план «Census» + состояние «Ход» + начинает с «Начать перепись» + обрабатывает «Дальше» + +план «Check» + состояние «Ход» + начинает с «Начать сверку» + обрабатывает «Дальше» + +план «Targets» + состояние «Ход» + начинает с «Начать цели» + обрабатывает «Дальше» + +план «Forgery» + состояние «Ход» + начинает с «Начать подлог» + обрабатывает «Дальше» + +тотальная функция «Объявление короткой команды hand-written-lists:census» + возвращает строка + соединить ["bootstrap/flang io --plan Census --max-steps 4000000000 — ", + "сколько перечней в дереве набрано ", + "руками и сколько из них разошлось с деревом; оба числа своим прогоном"] по "" + +тотальная функция «Объявление короткой команды hand-written-lists:check» + возвращает строка + соединить ["bootstrap/flang io --plan Check --max-steps 4000000000 — ", + "новое расхождение перечня с деревом ", + "красит; запись ведомости, переставшая быть расхождением, красит тоже"] по "" + +тотальная функция «Объявление короткой команды hand-written-lists:forgery» + возвращает строка + соединить ["bootstrap/flang io --plan Forgery --timeout 5400000 — ", + "запись ведомости о месте, которого в ", + "дереве нет, краснит сторожа и названа им по имени"] по "" diff --git a/scripts/guards/hand-written-lists.sh b/scripts/guards/hand-written-lists.sh deleted file mode 100755 index 6753aa775..000000000 --- a/scripts/guards/hand-written-lists.sh +++ /dev/null @@ -1,376 +0,0 @@ -#!/bin/sh -# SPDX-FileCopyrightText: 2026 Digitable (Marat Zimnurov) -# SPDX-License-Identifier: BSD-2-Clause -# -# Перепись перечней, набранных руками, и сверка их с деревом. -# -# ── Зачем ──────────────────────────────────────────────────────────────────── -# Перечень имён, записанный в одном файле и описывающий вещи, живущие в другом, -# верен в день записи и лжёт назавтра: дерево меняется без него. Класс описан -# заметкой docs/zettel/a-hand-written-list-outlives-the-tree.md. До этого файла -# прибора, который считает такие перечни и спрашивает, разошлись ли они, в -# дереве не было — числа «105 перечней, 57 расходятся» назывались наизусть. -# -# ── Чем эта перепись НЕ является ───────────────────────────────────────────── -# Она не держит списка мест, куда смотреть: тогда она стала бы сто шестым -# перечнем и протухла бы ровно так же. Файлы берутся прогоном `git ls-files`, -# цели печати — из имён `flang/self/emit-*.flang`, оглавление дерева — оттуда же. -# Руками здесь набрано ровно одно: ПРАВИЛО, по которому строка признаётся -# перечнем, и оно записано ниже словами. -# -# ── Что считается перечнем ─────────────────────────────────────────────────── -# ЦЕЛИ. Связная череда строк, в которой стоит ШЕСТЬ и более из девяти имён целей -# печати. Шесть из девяти — это заявка на «вот они все»; три имени рядом («go, -# rust и java печатать отказываются») — правдивое высказывание о подмножестве, и -# перечнем оно не считается. Расхождение: цель дерева, которой в череде нет. -# -# ЧЕГО ЭТА ПЕРЕПИСЬ НЕ ВИДИТ, СКАЗАНО ПРЯМО: связная череда строк берётся как -# ОДИН перечень. Две соседние копии одного перечня (в примере и в теле функции -# рядом) сливаются в одну, и цель, вынутая ровно из одной копии, прячется за -# второй. Проверено подлогом: правка одной строки из двух ответа не меняет, -# правка обеих — краснеет. Разделять по строкам пробовал: перенос длинной -# строки прозы тут же даёт четыре ложных расхождения, и лекарство выходит хуже -# болезни. -# -# ПУТИ. Связная череда строк-пунктов (маркер, номер, ячейка таблицы или -# закавыченный литерал), в которой стоит ТРИ и более разных имени объекта -# дерева. Расхождение: имя, которого в дереве нет ни файлом, ни каталогом. -# -# ── Как звать ──────────────────────────────────────────────────────────────── -# sh scripts/guards/hand-written-lists.sh перепись: два числа и все адреса -# sh scripts/guards/hand-written-lists.sh --check то же и код 1, если расхождений -# больше, чем записано в ведомости -# sh scripts/guards/hand-written-lists.sh --targets только перечни целей печати -# -# Коды: 0 — сошлось; 1 — не сошлось; 2 — судить нечем (нет двоичного, нет -# ведомости). Второй — «не проверено», а НЕ отрицательный приговор. -# -# Ведомость известных расхождений — scripts/ledgers/hand-written-lists-ledger.tsv. Она -# сверяется В ОБЕ СТОРОНЫ: запись, переставшая быть расхождением, красит так же, -# как новое расхождение. Иначе ведомость сама стала бы перечнем, пережившим -# дерево. - -set -eu - -# ── ЛОКАЛЬ ЗАДАЁТСЯ ЗДЕСЬ, А НЕ СНАРУЖИ ───────────────────────────────────── -# `comm` сравнивает строки байтами всегда, а `sort` — по правилам локали. Под -# `LC_ALL=ru_RU.UTF-8` они расходятся молча: сверка с ведомостью печатала три -# жалобы `comm: file 2 is not in sorted order`, под `C.UTF-8` — ни одной. -# Порядок сравнения обязан быть свойством сверки, а не машины, на которой её -# гоняют (задача 1312). -export LC_ALL=C.UTF-8 -export LC_COLLATE=C - -ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd) -cd "$ROOT" - -LEDGER=scripts/ledgers/hand-written-lists-ledger.tsv - -mode=census -targets_only=0 -for a in "$@"; do - case $a in - --check) mode=check ;; - --targets) targets_only=1 ;; - --help|-h) sed -n '5,40p' "$0"; exit 0 ;; - *) printf '%s\n' "неизвестный довод: $a" >&2; exit 2 ;; - esac -done - -# ── ПРИБОР: без двоичного сверять целевые перечни нечем ───────────────────── -# -# Целей печати в дереве ДВЕ штуки (см. ниже), и вторую — цели у двоичного — -# спрашивает прогон `bootstrap/flang emit --help`. Без двоичного этот список -# выходит пустым, и всякий перечень, называющий восемь целей семени, перестаёт -# сходиться хоть с чем-нибудь. Замерено на стволе `fa45f9ff`: с двоичным -# перепись даёт «расходятся 60 (целей 15, путей 45)», без него — «109 (целей -# 56)», а `--check` объявляет 49 НЕСУЩЕСТВУЮЩИХ новых расхождений и уходит -# кодом 1. -# -# Код 1 читается как «в дереве беда, чините дерево», и на нём уже потеряли -# время. Отсутствие прибора — это «не проверено», код 2 (задача 1312; образец -# отказа — scripts/targets/identical-declarations.sh). -if [ ! -x bootstrap/flang ]; then - printf 'НЕ СУДИЛ: нет двоичного %s/bootstrap/flang.\n' "$ROOT" >&2 - printf 'Список целей печати у двоичного берётся прогоном `flang emit --help`;\n' >&2 - printf 'без него всякий перечень целей выглядит разошедшимся, и перепись\n' >&2 - printf 'называет расхождения, которых нет.\n' >&2 - printf 'Это не «перечни разошлись», это «сверять не с чем».\n' >&2 - printf 'Соберите его: make -C bootstrap -j8\n' >&2 - exit 2 -fi - -TMP=$(mktemp -d "${TMPDIR:-/tmp}/hand-written-lists.XXXXXX") -trap 'rm -rf "$TMP"' EXIT INT TERM - -# ── Источники. Всё прогоном, ни одного имени руками ───────────────────────── -git -c core.quotepath=false ls-files > "$TMP/оглавление" -# ── Целей печати в дереве ДВЕ штуки, и это не описка ───────────────────────── -# Слои печати лежат в исходнике: flang/self/emit-*.flang — их девять. -# Двоичный, которым дерево судят, собран из СЕМЕНИ, и своих целей у него ровно -# столько же: перепись сама печатает оба числа, сверять их на глаз не надо. -# -# ПОПРАВКА 5 сентября 2026. Прежде здесь стояло, что у семени целей восемь, а -# девятая (cpp) в него ещё не перепечатана, и потому перечень из восьми не лжёт. -# Это перестало быть правдой: семя с тех пор перепечатано, и оба источника дают -# девять — проверено прогоном (`bootstrap/flang emit --target cpp --out …` даёт -# 7 файлов и код 0, напечатанное — настоящий C++ с `namespace flang`). Значит -# перечень из восьми теперь расходится С ОБОИМИ источниками, и перепись его -# красит по делу. Само правило не менялось: лжёт тот, кто не сошёлся ни с одним. -# Урок общий и за сутки четвёртый: примечание про «исходник ≠ семя» протухает -# ровно тогда, когда семя догоняет, — и молча, потому что примечания никто не -# сверяет прогоном. -ls flang/self/emit-*.flang | sed 's|.*/emit-||; s|\.flang$||' | sort > "$TMP/цели" -: > "$TMP/цели-семени" -if [ -x bootstrap/flang ]; then - bootstrap/flang emit --help 2>/dev/null \ - | LC_ALL=C.UTF-8 /usr/bin/grep -a -o -m1 -- '--target [a-z|]*' \ - | sed 's|--target ||' | tr '|' '\n' | LC_ALL=C.UTF-8 /usr/bin/grep -a -v '^$' | sort > "$TMP/цели-семени" -fi -git -c core.quotepath=false ls-files \ - | LC_ALL=C.UTF-8 /usr/bin/grep -a -E '\.(flang|fscript|mjs|sh|js|py|awk|json|yml|yaml|md|tsv)$' > "$TMP/все-числящиеся" -# ── Числится в git ≠ лежит на диске ───────────────────────────────────────── -# Пути ниже уезжают в gawk ДОВОДАМИ (`$(cat "$TMP/файлы")`), а gawk на -# несуществующем файле не краснеет, а ПАДАЕТ: «gawk: fatal … cannot open file», -# код 2. Ловится это не выдуманным случаем, а обычным: посреди перебазирования -# или при снятой правке файл ещё числится в `ls-files`, а на диске его уже нет, -# и сторож в этот миг не говорит ни правды, ни лжи — он просто умирает. -# Поэтому: отсутствующие отсеиваются, но НЕ молча — их число печатается в -# итоге, потому что числа переписи сняты тогда с неполного набора, и знать об -# этом обязан тот, кто на них смотрит. Само по себе отсутствие красным не -# делаем: дерево посреди перебазирования — не изъян дерева. -: > "$TMP/пропали" -: > "$TMP/файлы" -while IFS= read -r put; do - if [ -f "$put" ]; then printf '%s\n' "$put" >> "$TMP/файлы" - else printf '%s\n' "$put" >> "$TMP/пропали"; fi -done < "$TMP/все-числящиеся" -# Семья ПУТЕЙ идёт только по коду. В прозе имя исчезнувшего файла часто и есть -# предмет речи («flang/src/lexer.mjs больше нет»), и красить это — врать; в коде -# путь, которого в дереве нет, — всегда изъян. -LC_ALL=C.UTF-8 /usr/bin/grep -a -E '\.(flang|fscript|mjs|sh|js|py|awk)$' "$TMP/файлы" > "$TMP/код" - -# ── Перечни целей печати ──────────────────────────────────────────────────── -gawk -v targets_file="$TMP/цели" -v seed_file="$TMP/цели-семени" ' - BEGIN { - while ((getline t < targets_file) > 0) if (t != "") { tgt[t] = 1; all_n++ } - while ((getline t < seed_file) > 0) if (t != "") { seed[t] = 1; seed_n++ } - need = int(all_n * 2 / 3) # шесть из девяти - if (need < 3) need = 3 - } - function reset( i) { delete seen; n = 0; start = 0 } - function flush( i, miss, misslist, smiss) { - if (n >= need) { - lists++ - miss = 0; misslist = "" - for (i in tgt) if (!(i in seen)) { miss++; misslist = misslist (miss > 1 ? "," : "") i } - smiss = 0 - if (seed_n > 0) { for (i in seed) if (!(i in seen)) smiss++ } - if (miss == 0) { printf "ЦЕЛИ-ЦЕЛ\t%s\t%d\t%d\t%d\tпо исходнику\n", file, start, n, all_n } - else if (seed_n > 0 && smiss == 0 && n == seed_n) { - seedlists++ - printf "ЦЕЛИ-СЕМЯ\t%s\t%d\t%d\t%d\tпо семени (%d целей); в исходнике нет: %s\n", file, start, n, all_n, seed_n, misslist - } - else { diverged++; printf "ЦЕЛИ\t%s\t%d\t%d\t%d\tнет ни там, ни там: %s\n", file, start, n, all_n, misslist } - } - reset() - } - FNR == 1 { flush(); file = FILENAME } - { - # имя цели считается названным, если стоит отдельным словом: в кавычках, - # в обратных кавычках, через пробел в строке оболочки или как «emit-имя». - s = $0; k = 0 - if (file ~ /\.md$/) { - # в прозе имя цели всегда стоит в кавычках или обратных кавычках; без - # этого правила связная проза «цель c печатает, а go отказывает» слилась - # бы в перечень, которым она не является. - while (match(s, /["\x27`][a-z]+["\x27`]/)) { - w = substr(s, RSTART + 1, RLENGTH - 2) - s = substr(s, RSTART + RLENGTH) - if (w in tgt) { if (!(w in seen)) { seen[w] = 1; n++ }; k++ } - } - } else { - # в коде перечень бывает и без кавычек: VSE="c go rust …", - # «for module in emit-go emit-rust …» - gsub(/[^A-Za-z0-9_-]/, " ", s) - gsub(/(^| )emit-/, " ", s) - nw = split(s, wds, /[ ]+/) - for (wi = 1; wi <= nw; wi++) { - w = wds[wi] - if (w in tgt) { if (!(w in seen)) { seen[w] = 1; n++ }; k++ } - } - } - if (k > 0) { if (start == 0) start = FNR } - else if (n > 0) flush() - } - END { flush(); printf "ИТОГ-ЦЕЛИ\t%d\t%d\t%d\n", lists, diverged, seedlists } -' $(cat "$TMP/файлы") > "$TMP/цели.tsv" - -# ── Перечни путей дерева ──────────────────────────────────────────────────── -gawk -v inventory="$TMP/оглавление" ' - BEGIN { - while ((getline t < inventory) > 0) if (t != "") { - tree[t] = 1 - p = t; while (match(p, "/[^/]*$")) { p = substr(p, 1, RSTART - 1); tree[p] = 1; tree[p "/"] = 1 } - q = t; while (match(q, "^[^/]*/")) { q = substr(q, RSTART + RLENGTH); tree[q] = 1 } - } - reset() - } - # порождённое имя (bootstrap/flang) в оглавлении не лежит, а на диске есть - function on_disk(nm, r) { - if (nm in disk) return disk[nm] - r = (system("test -e \"" nm "\"") == 0) - disk[nm] = r - return r - } - function reset( i) { delete names; n = 0; start = 0; gap = 0; delete lineof } - function flush( i, miss, misslist) { - if (n >= 3) { - lists++ - miss = 0; misslist = "" - for (i = 1; i <= n; i++) if (!(names[i] in tree) && !on_disk(names[i])) { - miss++; misslist = misslist (miss > 1 ? " " : "") names[i] ":" lineof[names[i]] - } - if (miss > 0) { diverged++; printf "ПУТИ\t%s\t%d\t%d\t%d\tнет: %s\n", file, start, miss, n, misslist } - else printf "ПУТИ-ЦЕЛ\t%s\t%d\t0\t%d\t-\n", file, start, n - } - reset() - } - FNR == 1 { flush(); file = FILENAME } - { - text = $0 - gsub(/\\[nrt]/, " ", text) # "\ndocs/a.md" — не имя дерева - shape = 0 - if (text ~ /^[ \t]*[-*+][ \t]/) shape = 1 - else if (text ~ /^[ \t]*[0-9]+[.)][ \t]/) shape = 1 - else if (text ~ /^[ \t]*\|/) shape = 1 - else if (text ~ /["\x27`]/) shape = 1 - k = 0; delete fresh - if (shape && index(text, "://") == 0) { - s = text - while (match(s, /[A-Za-z0-9_][A-Za-z0-9_.-]*(\/[A-Za-z0-9_.А-Яа-яЁё-]+)+/)) { - c = substr(s, RSTART, RLENGTH) - pre = substr(s, 1, RSTART - 1) - s = substr(s, RSTART + RLENGTH) - if (pre ~ /[$%{]$/) continue # подстановка оболочки - if (c ~ /^[A-Z][A-Z0-9_]*\//) continue # $ПЕРЕМЕННАЯ/путь - if (c ~ /\*/) continue # маска, а не имя - if (c !~ /\.(flang|fscript|mjs|md|sh|c|h|json|tsv|txt|py|fts|yml|yaml|js|awk|ex|java|cs|vim|html|hex|toml|lock)$/ && - c !~ /^(flang|docs|scripts|tasks|fspec|examples|benchmarks|bootstrap|packaging|editors|web)\//) continue - base = c; sub(/^.*\//, "", base) - if (base ~ /^[a-zA-Z0-9]\./) continue # a.md — выдуманный пример пробы - fresh[++k] = c - } - } - if (k > 0) { - if (n == 0) start = FNR - for (i = 1; i <= k; i++) { - was = 0 - for (j = 1; j <= n; j++) if (names[j] == fresh[i]) was = 1 - if (!was) { names[++n] = fresh[i]; lineof[fresh[i]] = FNR } - } - gap = 0 - } else if (n > 0) { gap++; if (gap > 1) flush() } - } - END { flush(); printf "ИТОГ-ПУТИ\t%d\t%d\n", lists, diverged } -' $(cat "$TMP/код") > "$TMP/пути.tsv" - -# ── Свод ──────────────────────────────────────────────────────────────────── -tgt_lists=$(LC_ALL=C.UTF-8 /usr/bin/grep -a '^ИТОГ-ЦЕЛИ' "$TMP/цели.tsv" | cut -f2) -tgt_bad=$(LC_ALL=C.UTF-8 /usr/bin/grep -a '^ИТОГ-ЦЕЛИ' "$TMP/цели.tsv" | cut -f3) -tgt_seed=$(LC_ALL=C.UTF-8 /usr/bin/grep -a '^ИТОГ-ЦЕЛИ' "$TMP/цели.tsv" | cut -f4) -nseed=$(wc -l < "$TMP/цели-семени" | tr -d ' ') -path_lists=$(LC_ALL=C.UTF-8 /usr/bin/grep -a '^ИТОГ-ПУТИ' "$TMP/пути.tsv" | cut -f2) -path_bad=$(LC_ALL=C.UTF-8 /usr/bin/grep -a '^ИТОГ-ПУТИ' "$TMP/пути.tsv" | cut -f3) - -if [ "$targets_only" = 1 ]; then - all_lists=$tgt_lists; all_bad=$tgt_bad - LC_ALL=C.UTF-8 /usr/bin/grep -a '^ЦЕЛИ ' "$TMP/цели.tsv" > "$TMP/расхождения" || true -else - all_lists=$((tgt_lists + path_lists)); all_bad=$((tgt_bad + path_bad)) - { LC_ALL=C.UTF-8 /usr/bin/grep -a '^ЦЕЛИ ' "$TMP/цели.tsv" || true - LC_ALL=C.UTF-8 /usr/bin/grep -a '^ПУТИ ' "$TMP/пути.tsv" || true; } > "$TMP/расхождения" -fi - -commit=$(git -c core.quotepath=false rev-parse --short HEAD) -ntargets=$(wc -l < "$TMP/цели" | tr -d ' ') - -printf 'перепись перечней, набранных руками — ствол %s\n' "$commit" -printf 'целей печати по исходнику flang/self/emit-*.flang: %s (%s)\n' "$ntargets" "$(tr '\n' ' ' < "$TMP/цели")" -printf 'целей печати у двоичного bootstrap/flang: %s (%s)\n' "$nseed" "$(tr '\n' ' ' < "$TMP/цели-семени")" -printf '\n' -printf 'перечней набрано руками: %s (целей %s, путей %s)\n' "$all_lists" "$tgt_lists" "$path_lists" -printf 'из них расходятся с деревом сегодня: %s (целей %s, путей %s)\n' "$all_bad" "$tgt_bad" "$path_bad" -printf 'перечней целей, сошедшихся с семенем, а не с исходником: %s\n' "$tgt_seed" -printf '\n' - -if [ "$tgt_seed" -gt 0 ]; then - printf 'перечни целей, сошедшиеся с ДВОИЧНЫМ, а не с исходником (отстают на девятую цель):\n' - LC_ALL=C.UTF-8 /usr/bin/grep -a '^ЦЕЛИ-СЕМЯ ' "$TMP/цели.tsv" \ - | while IFS=' ' read -r kind fname lno cnt tot rest; do - printf ' %s:%s\t%s\n' "$fname" "$lno" "$rest" - done - printf '\n' -fi - -if [ "$all_bad" -gt 0 ]; then - printf 'расхождения:\n' - while IFS=' ' read -r kind fname lno cnt tot rest; do - printf ' %s\t%s:%s\t%s из %s\t%s\n' "$kind" "$fname" "$lno" "$cnt" "$tot" "$rest" - done < "$TMP/расхождения" - printf '\n' -fi - -[ "$mode" = check ] || exit 0 - -# ── Сверка с ведомостью, в обе стороны ────────────────────────────────────── -# Нет ведомости — второй прибор отсутствует, и это тоже «не проверено», код 2: -# «сверять не с чем» и «сверка не сошлась» — разные ответы (задача 1312). -[ -f "$LEDGER" ] || { printf 'НЕ СУДИЛ: ведомости %s нет — сверять не с чем\n' "$LEDGER" >&2; exit 2; } - -LC_ALL=C.UTF-8 /usr/bin/grep -a -v '^#' "$LEDGER" | LC_ALL=C.UTF-8 /usr/bin/grep -a -v '^$' \ - | cut -f1,2,3 | sort > "$TMP/ведомость" -cut -f1,2,3 "$TMP/расхождения" | sort > "$TMP/сейчас" - -comm -13 "$TMP/ведомость" "$TMP/сейчас" > "$TMP/новые" -comm -23 "$TMP/ведомость" "$TMP/сейчас" > "$TMP/мёртвые" - -n_new=$(wc -l < "$TMP/новые" | tr -d ' ') -n_dead=$(wc -l < "$TMP/мёртвые" | tr -d ' ') - -n_gone=$(wc -l < "$TMP/пропали" | tr -d ' ') -if [ "$n_gone" -gt 0 ]; then - printf 'ЧИСЛЯТСЯ В GIT, НО НЕ ЛЕЖАТ НА ДИСКЕ: %s — перепись снята БЕЗ них\n' "$n_gone" >&2 - while IFS= read -r put; do printf ' нет на диске\t%s\n' "$put" >&2; done < "$TMP/пропали" - printf 'красным это не делаем: посреди перебазирования так и бывает; но числа\n' >&2 - printf 'ниже сняты с неполного набора, и на них нельзя ссылаться как на полные.\n\n' >&2 -fi - -bad=0 -if [ "$n_new" -gt 0 ]; then - bad=1 - printf 'НОВЫХ РАСХОЖДЕНИЙ: %s — их нет в ведомости %s\n' "$n_new" "$LEDGER" >&2 - while IFS=' ' read -r kind fname lno; do - printf ' %s\t%s:%s\n' "$kind" "$fname" "$lno" >&2 - done < "$TMP/новые" - printf '\n' >&2 -fi -if [ "$n_dead" -gt 0 ]; then - bad=1 - printf 'МЁРТВЫХ ЗАПИСЕЙ ВЕДОМОСТИ: %s — расхождения нет, а запись стоит\n' "$n_dead" >&2 - printf 'ведомость, пережившая дерево, — та же болезнь; уберите строки:\n' >&2 - while IFS=' ' read -r kind fname lno; do - printf ' %s\t%s:%s\n' "$kind" "$fname" "$lno" >&2 - done < "$TMP/мёртвые" - printf '\n' >&2 -fi - -if [ "$bad" = 1 ]; then - printf 'перепись: новых %s, мёртвых записей %s\n' "$n_new" "$n_dead" >&2 - exit 1 -fi - -printf 'перепись сошлась с ведомостью: %s расхождений, все названы с доводом\n' "$all_bad" -exit 0 -# короткая команда «hand-written-lists:census» sh — сколько перечней в дереве набрано руками и сколько из них разошлось с деревом — оба числа своим прогоном -# короткая команда «hand-written-lists:check» sh --check — новое расхождение перечня с деревом красит; запись описи, переставшая быть расхождением, красит тоже diff --git a/scripts/ledgers/guards-without-forgery-probe.json b/scripts/ledgers/guards-without-forgery-probe.json index f50a2b39e..54967c4cf 100644 --- a/scripts/ledgers/guards-without-forgery-probe.json +++ b/scripts/ledgers/guards-without-forgery-probe.json @@ -17,7 +17,7 @@ "bad-octet:check": "ПРОБА ПОСТРОЕНА И ИСПРАВНА, звать НЕЛЬЗЯ: сторож красен сам по себе. Замер 5 сентября: сторож код 1 («красных: 4»), проба код 1 — но её собственный вывод говорит «сторож покраснел (код 1) — порча видна», то есть порчу она видит. Ненулевой код у пробы приходит от красноты дерева, а не от слепоты сторожа. Врезать в CI — значит завести вечно красный шаг.", "published:check": "CI ЗОВЁТ ЕГО И ЕМУ ВЕРИТ, а покраснеть на порче не показано ни разу. Самый опасный род: выпотрошенный сторож останется зелёным, и сказать об этом будет некому. Пробу строить в первую очередь.", "memory:check": "ПРОБУ СТРОИТЬ НЕ НА ЧЕМ, но причина другая, чем записано: сторож упирается в ПРЕДЕЛ ШАГОВ, заданный ключом своей команды, — код 3 за 353 с, FLANG_RECURSION_LIMIT на 80 000 000 шагов, пик памяти 116,6 ГиБ (перемер 6 сентября 2026, свой прогон). С ключом 400 млн стена переезжает на память: 205,7 ГиБ за 528 с. Прежняя запись 5 сентября: код 124 на 200 с (задача 5612).", - "hand-written-lists:check": "сторож КРАСЕН по делу и в CI не стоит — пробу строить рано: сперва закрыть долг, на котором он краснеет. КРАСЕН по делу (15 с). Ставить в CI нельзя, пока долг не закрыт; глуши", + "hand-written-lists:check": "ПРОБА ПОСТРОЕНА командой hand-written-lists:forgery и ПРОГНАНА 4 октября 2026: она вписывает в ведомость запись «ПУТИ подделка/нет.md 1» о месте, которого в дереве нет, и требует, чтобы сторож назвал её мёртвой — код 1 и имя в выводе; прежний сторож на оболочке на том же подлоге отвечает тем же («мёртвых записей 65», та же строка). Судит проба НЕ ПО КОДУ, а по имени: сторож красен и сам по себе. CI её не зовёт, и это не забывчивость: сам сторож КРАСЕН по делу (новых 121, мёртвых 64) и в CI не стоит, а звать пробу мимо сторожа значило бы проверять прибор, которым не меряют. Сверх того она стоит обхода дерева вычислителем — 700 с. Обе команды поедут в CI разом, когда долг переписи закрыт.", "surfaces:check": "ПРОБА ПОСТРОЕНА, звать НЕЛЬЗЯ: сторож красен сам по себе. Замер 5 сентября: код 1 за 1 с — «разбивка слотов на странице даёт 76, а прогон — 74». Сперва закрыть этот долг, потом врезать пару.", "kernel-forgeries:check": "CI ЗОВЁТ ЕГО И ЕМУ ВЕРИТ, а покраснеть на порче не показано ни разу. Самый опасный род: выпотрошенный сторож останется зелёным, и сказать об этом будет некому. Пробу строить в первую очередь.", "counts:check": "СТОРОЖ ПРОГНАН ЦЕЛИКОМ, пробы всё ещё нет: код 1 за 6884 с — 1 ч 55 мин (перемер 6 сентября 2026, свой прогон). Дорог не предел, а обход 295 файлов корпуса через flang check --proof. Прежняя запись 5 сентября: код 124 на 200 с (задача 5612).", diff --git a/scripts/ledgers/hand-written-lists-ledger.tsv b/scripts/ledgers/hand-written-lists-ledger.tsv index 7fa8f307c..c9228adcf 100644 --- a/scripts/ledgers/hand-written-lists-ledger.tsv +++ b/scripts/ledgers/hand-written-lists-ledger.tsv @@ -97,3 +97,5 @@ ПУТИ scripts/release/emit-package.flang 17 задача 8649 переехала в docs/tasks/completed; имя стоит в комментарии как ссылка на разбор, а не как живой файл ПУТИ scripts/guards/homebrew-formula-guard.fscript 484 содержимое сабмодуля packaging/homebrew-tap: в git ls-files лежит одно имя сабмодуля, а не Formula/flang.rb ПУТИ scripts/release/release-in-c.fscript 158 «куда» ПРИМЕРА — каталог, который складывает прогон выпуска (output/release-c/…); в дереве его нет по устройству +ПУТИ scripts/guards/hand-written-lists.fscript 1140 выдуманные входы пробы, а не имена дерева: перечень подделок не протухает +ПУТИ scripts/guards/hand-written-lists.fscript 1622 выдуманные входы пробы, а не имена дерева: перечень подделок не протухает diff --git a/scripts/ledgers/link-guard-known-not-a-path.tsv b/scripts/ledgers/link-guard-known-not-a-path.tsv index beaf7bfc0..19ee99eb3 100644 --- a/scripts/ledgers/link-guard-known-not-a-path.tsv +++ b/scripts/ledgers/link-guard-known-not-a-path.tsv @@ -254,3 +254,5 @@ docs/tasks/7328-a-free-statement-over-a-finite-sum-has-no-way-to-exhaust-its-cas docs/tasks/7367-induction-in-a-free-statement-refuses-the-nonnegative-segment.md проба.flang имя пробы из прогона задачи, не файл дерева docs/tasks/5771-integrality-does-not-tighten-a-strict-order-by-one.md scripts/guards/proved-share-vs-tree.sh история: сторож перенесён на план scripts/guards/proved-share-vs-tree.fscript 4 октября 2026; в задаче он назван тем именем, какое носил тогда docs/tasks/7328-a-free-statement-over-a-finite-sum-has-no-way-to-exhaust-its-cases.md scripts/guards/proved-share-vs-tree.sh история: сторож перенесён на план scripts/guards/proved-share-vs-tree.fscript 4 октября 2026; в задаче он назван тем именем, какое носил тогда +docs/tasks/4717-lists-typed-by-hand-in-guards-are-counted-and-taken-from-the-tree.md scripts/guards/hand-written-lists.sh история: задача называет прибор того дня; он снят 4 октября 2026 (задача 5821), перепись ведёт план scripts/guards/hand-written-lists.fscript — прогон обоих на одном дереве дал одну строку знак в знак +docs/tasks/5821-shell-scripts-that-can-become-flang-are-counted-and-moved.md hand-written-lists.sh история: пункт задачи про снятый сторож; имя оставлено зачёркнутым, чтобы было видно, ЧТО снято и чем заменено diff --git a/scripts/ledgers/proved-share-ledger.txt b/scripts/ledgers/proved-share-ledger.txt index 5bd3e72d0..cbf04051f 100644 --- a/scripts/ledgers/proved-share-ledger.txt +++ b/scripts/ledgers/proved-share-ledger.txt @@ -1570,6 +1570,7 @@ bb9f8dadc0aa937a5fc4dbda79707edd|18|16|2|0|0|scripts/guards/file-extensions.fscr ce0f26e8f64ce11b7f2f8e559d0f090b|11|11|0|0|0|scripts/guards/guards-without-forgery-probe.fscript d29d464d969d58822bc10e6e696017ef|14|14|0|0|0|scripts/flangrc.fscript 001c0ecd7217d8ae84b4133d3dca9085|4|4|0|0|0|scripts/guards/flangrc-guard.fscript +6f7dedb574161de9cc3422f9b3033f5e|16|16|0|0|0|scripts/guards/hand-written-lists.fscript baa3170dc90958c56352eb9b3f49ab9b|62|49|10|3|0|scripts/guards/homebrew-formula-guard.fscript 03f3f6607069aae79dee667bbe870c10|19|18|0|1|0|scripts/guards/input-boundary.fscript b00f9a812077e3b8497c15864acff995|11|7|3|0|0|scripts/guards/io-dictionary-copies-guard.fscript diff --git a/scripts/ledgers/uncalled-guards.json b/scripts/ledgers/uncalled-guards.json index 1af62d628..c4d101d52 100644 --- a/scripts/ledgers/uncalled-guards.json +++ b/scripts/ledgers/uncalled-guards.json @@ -13,7 +13,7 @@ "dictionary-copies:check": "ЗЕЛЕН (13 с на dev 4a75918d, 6 сентября 2026): сверяет имена поручений и откликов в трёх выписанных руками копиях со словарём языка. В CI не поставлен — заведён сегодня и в дереве не обкатан; ставить его надо вместе с парной командой dictionary-copies:forgery, а не поодиночке.", "bad-octet:check": "КРАСЕН по делу (15 с). Ставить в CI нельзя, пока долг не закрыт; глушить — тем более.", "memory:check": "УПИРАЕТСЯ В ПРЕДЕЛ ШАГОВ, а не во время: код 3 за 353 с (перемер 6 сентября 2026, свой прогон) — FLANG_RECURSION_LIMIT, функция «Числа до без проверок» исчерпала 80 000 000 шагов на глубине вызовов 2881. Предел этот ЗАДАН ключом самой команды (--max-steps 80000000), а потолок двоичного не при чём: израсходовано 0,95 млрд из 1 400 000 000 000. Пик памяти на этом прогоне 116,6 ГиБ. Поднятие ключа до 400 млн переносит стену на память: 205,7 ГиБ за 528 с и рост, снял сам. Это закрывает пункт 4 задачи 3144 числом: «не снято: валит память» пора менять. Прежняя запись 5 сентября: дороже предела замера, код 124 на 200 с (задача 5612).", - "hand-written-lists:check": "КРАСЕН по делу (15 с). Ставить в CI нельзя, пока долг не закрыт; глушить — тем более.", + "hand-written-lists:check": "КРАСЕН по делу (700 с: сверка стала планом flang, обход дерева идёт в вычислителе). Ставить в CI нельзя, пока долг не закрыт; глушить — тем более.", "surfaces:check": "КРАСЕН по делу (4 с). Ставить в CI нельзя, пока долг не закрыт; глушить — тем более.", "counts:check": "КРАСЕН по делу и ОЧЕНЬ ДОРОГ: код 1 за 6884 с, то есть 1 ч 55 мин (перемер 6 сентября 2026, свой прогон). Сходится. Цена — полный обход корпуса: 295 файлов через flang check --proof, и файлы flang/self стоят по 10-20 минут каждый. Ставить в CI нельзя ни по долгу, ни по цене. Прежняя запись 5 сентября: дороже предела замера, код 124 на 200 с (задача 5612).", "binary-rules:check": "КРАСЕН по делу (5 с). Ставить в CI нельзя, пока долг не закрыт; глушить — тем более. ТРИ ОСЛЕПШИЕ ПРОВЕРКИ ПОЧИНЕНЫ 6 сентября, сторож не снят: (1) состав правил двоичного он снимал обходом ввозов вида «использует «X» из \"путь\"», которых во входе двоичного 0 из 32, и видел 4 правила из 57 — теперь снимает с напечатанного bootstrap/compiler_flang.c поимённым вопросом по 72 названным кодам; (2) фразу про процессы («объявления эти сверены НЕ ДО КОНЦА — processes») не ловил вовсе — теперь маркеров два, и каждый сверяется с эталоном: пропадёт фраза — сторож покраснеет, а не онемеет; (3) отказ печати кодом 1 считал молчанием. Находок было 10, стало 7: слепых ушло 6, новых по делу пришло 3 — FLANG_HANDLER_NOT_TOTAL, FLANG_PROCESS и FLANG_UNKNOWN_PROCESS переехали к двоичному, а РАЗНИЦА числит их долгом. Живой долг: печать выпускает кодом 0 две подделки, о которых check сказал кодом 2 (category-not-closed, morphism-compose); поверхность «требование к функции» не прогоняется ни одной уликой; ключ plans эталон называет, а РАЗНИЦА нет. ПОКРАСНЕЛ НА ПОДЛОГЕ (порча на копии дерева, команды-подлога нет): пропавшая фраза, исчезнувший код, снятый напечатанный компилятор, снятый корпус подделок, печать кодом 3 без названного пробела. С 7 сентября 2026 команда зовёт двойник на flang («flang io flang/scripts/binary-rules-guard.fscript», прежний binary-rules-guard.mjs снесён): те же 7 находок, код 1 за 38 с, пик 0,68 ГиБ.",