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

Справочник стандартной библиотеки

Библиотека лежит рядом с компилятором и написана на самом flang. Каждая её функция проходит тот же путь, что ваша программа: разбор, типы, завершаемость, примеры. Ниже — раздел на модуль и таблица на все его функции.

использует — это импорт. Модуль подключается по имени, путь писать не нужно:

модуль «Моя программа»
  использует «Lists»

Модуль приходит ЦЕЛИКОМ, и напечатанный код несёт его весь. Нужна одна функция — назовите её:

  использует «Lists» только «Сумма»

только не досчитывает зависимости названной функции. Позовёте «Двоичный поиск» без «Поиск в диапазоне» — компилятор ответит так:

FLANG_UNKNOWN_NAME, строка 569, столбец 3: неизвестная функция «Поиск в диапазоне»
FLANG_NOT_TOTAL, строка 569, столбец 3: тотальная функция «Двоичный поиск» вызывает неизвестную функцию «Поиск в диапазоне»: завершение доказать нельзя

Допишите недостающее имя через запятую — или подключайте модуль целиком.

В таблицах ниже столбцы «принимает» и «возвращает» — подпись из исходника, слово в слово. Столбец «что делает» — постусловие функции, строка обеспечивает из её объявления, тоже слово в слово. Оттуда в нём авторские обороты: «довод» значит аргумент, «октеты» — байты.

С чего начать

Девять модулей закрывают почти всё, что пишется каждый день. У каждого — целая программа, которую можно скопировать и проверить.

Lists

Списки любых значений и списки чисел: длина, срез, промежуток, поиск, свёртки, сортировка.

Импорт: использует «Lists».

функцияпринимаетвозвращаетчто делает
«Длина» от «А»элементы: список «А»числосчёт звеньев сходится со встроенной длиной
«Приписать в начало» от «А»первый: «А», элементы: список «А»список «А»приписывание удлиняет список ровно на один
«Соединить списки» от «А»первый: список «А», второй: список «А»список «А»длина соединения есть сумма длин
«Обратить» от «А»элементы: список «А»список «А»обращение не теряет и не добавляет элементов
«Отбросить первые» от «А»элементы: список «А», сколько: числосписок «А»при неположительном сколько не отброшено ничего
«Взять первые» от «А»элементы: список «А», сколько: числосписок «А»целое N внутри длины даёт ровно N
«Срез» от «А»элементы: список «А», начало: число, конец: числосписок «А»срез от первого до последнего есть весь список
«Числа до»предел: числосписок числапредел стоит в промежутке
«Числа от и до»начало: число, конец: числосписок числапромежуток, начатый не выше единицы, доходит до конца
«Элемент»элементы: список числа, индекс: числочислона целом номере внутри списка обход сходится со встроенной формой
«Индекс»элементы: список числа, значение: числочислонайденное место держит искомое, а ноль значит: не найдено
«Содержит число»элементы: список числа, значение: числопризнаквстроенная форма и обход по индексу согласны
«Списки равны»первый: список числа, второй: список числапризнакпустому равен только пустой
«Поиск в диапазоне»элементы: список числа, цель: число, низ: число, верх: число, витков: неотрицательноечислоотрезок из одного места отдаёт это место, когда оно держит цель
«Двоичный поиск»элементы: список числа, цель: числочислоненулевое место держит цель
«Все не меньше»элементы: список числа, порог: числопризнакпустому списку годится любой порог
«Любой не меньше»элементы: список числа, порог: числопризнакпустому списку не годится ни один порог
«Минимум»элементы: список числачислонаименьшее взято из самого списка, а на пустом это ноль
«Максимум»элементы: список числачислонаибольшее взято из самого списка, а на пустом это ноль
«Сумма»элементы: список числачислосумма неотрицательных не меньше наибольшего из них
«Произведение»элементы: список числачислопроизведение чисел не меньше единицы не меньше наибольшего из них
«Вставить по порядку»значение: число, элементы: список числасписок числавставка удлиняет список ровно на один
«Вставками по порядку»элементы: список числасписок числавставками не теряется и не добавляется ни одного элемента
«Сортировать»элементы: список числасписок числасортировка не теряет и не добавляет элементов
«Уникальные»элементы: список числасписок числапервый элемент переживает отсев и остаётся первым, а пустой список остаётся пустым
«Считать вхождения»элементы: список числа, значение: числочислосчёт не ноль ровно тогда, когда значение в списке
«Без значения»элементы: список числа, значение: числосписок числаудалено ровно столько, сколько было вхождений
«Сжать в пары»первые: список числа, вторые: список числасписок «Пара чисел»пар ровно столько, сколько в коротком из списков
«Сжать суммами»первые: список числа, вторые: список числасписок числасумм ровно столько, сколько в коротком из списков

Пример целиком — проверяется командой flang check:

модуль «Проба списков»
  использует «Lists»

тотальная функция «Сумма чисел до предела»
  принимает предел: число
  возвращает число
  пример «До пяти»
    дано предел равно 5
    ожидается 15
  «Сумма» от («Числа до» от предел)

Strings

Строка как данные: разбиение, замена, регистр, префикс и суффикс, вопросы о знаке, дополнение до ширины.

Импорт: использует «Strings».

функцияпринимаетвозвращаетчто делает
«Приписать строку в начало»первая: строка, элементы: список строкисписок строкиприписывание удлиняет список ровно на один
«Соединить строки»части: список строки, разделитель: строкастрокасклейка начинается первой частью
«Разбить по символу»текст: строка, разделитель: строкасписок строкиразбиение даёт хотя бы одну часть
«Заменить»текст: строка, что: строка, чем: строкастрокакусков по новому разделителю не меньше, чем было по старому
«Считать символ»текст: строка, буква: строкачислоноль ровно тогда, когда вхождения нет
«Позиция подстроки»текст: строка, часть: строкачислоноль значит нет вхождения
«Начинается с»текст: строка, префикс: строкапризнакначинается с — это когда кусок ПЕРЕД первым вхождением пуст
«Заканчивается на»текст: строка, суффикс: строкапризнакотрезал суффикс, приклеил обратно — исходное
«Заглавная буква»буква: строкастрокастрочная латинская буква поднимается ровно на 32 кода
«Строчная буква»буква: строкастроказаглавная латинская буква опускается ровно на 32 кода
«В верхний регистр»текст: строкастрокаверхний регистр не меняет длины
«В нижний регистр»текст: строкастроканижний регистр не меняет длины
«Символы»текст: строкасписок строкисимволов ровно столько, какова длина строки
«Обратить строку»текст: строкастрокаобращение не удлиняет строку
«Палиндром»текст: строкапризнакразложить на знаки и склеить обратно — ответ тот же
«Повторить»текст: строка, раз: числострокаположительный повтор начинается исходным текстом
«Обрезать слева»текст: строкастрокаприставить обратно отнятые пробелы — получить исходное
«Обрезать справа»текст: строкастрокадописать обратно отнятые пробелы — получить исходное
«Обрезать пробелы»текст: строкастрокаубраны только пробелы
«Первый символ»текст: строкастрокапервый символ длиной не больше знака
«Последний символ»текст: строкастрокапоследний символ длиной не больше знака
«Это цифра»знак: строкапризнакдля цифры поиск вхождением и поиск позицией отвечают одно
«Это пробел»знак: строкапризнакдля пробела поиск вхождением и поиск позицией отвечают одно
«Это латинская буква»знак: строкапризнаклатинская буква — это ровно тот знак, у которого меняется регистр
«Только цифры»текст: строкапризнакубери из текста все десять цифр — у одних цифр не останется ничего
«Цифра числом»знак: строкачислонеотрицательный ответ показывает на тот самый знак
«Сколько дополнить»ширина: неотрицательное, набрано: неотрицательноечислодополнение — это ровно недостача, а при достатке ноль
«Дополнить слева»текст: строка, ширина: неотрицательное, знак: строкастрокаисходное целиком стоит в дополненном слева
«Дополнить справа»текст: строка, ширина: неотрицательное, знак: строкастрокадополненное справа начинается исходным
«Без знака»текст: строка, знак: строкастроканечего убирать — текст не тронут
«Урезать»текст: строка, предел: неотрицательноестрокаурезанное — начало исходного

Пример целиком — проверяется командой flang check:

модуль «Проба строк»
  использует «Strings»

тотальная функция «Слово задом наперёд»
  принимает текст: строка
  возвращает строка
  пример «Слово»
    дано текст равно " шалаш "
    ожидается "шалаш"
  «Обратить строку» от («Обрезать пробелы» от текст)

Numbers

Числа: знак, модуль, целочисленное деление, НОД и НОК, степень, факториал, цифры.

Импорт: использует «Numbers».

функцияпринимаетвозвращаетчто делает
«Абсолютное значение»число: числочисломодуль не меньше самого числа и не меньше противоположного ему
«Знак»число: числочислознак читает порядок: у положительного единица, у отрицательного минус единица, у нуля ноль
«Минимум двух»первое: число, второе: числочисломинимум — одно из двух чисел и не больше каждого сравнимого с ним
«Максимум двух»первое: число, второе: числочисломаксимум — одно из двух чисел и не меньше каждого сравнимого с ним
«Ограничить»число: число, снизу: число, сверху: числочислоограничение отдаёт либо само число, либо одну из границ
«Целочисленное деление»делимое: число, делитель: числочислочастное и остаток восстанавливают делимое
«Целая часть»значение: числочислоцелая часть — само число без остатка от единицы
«Чётное»число: числопризнакчётность есть делимость на два
«Делится на»число: число, делитель: числопризнакделимость — это ровно то, что деление нацело восстанавливает число
«НОД»первое: число, второе: числочислообщий делитель и правда делит оба числа
«НОК»первое: число, второе: числочислообщее кратное и правда делится на оба числа
«Степень»основание: число, показатель: неотрицательноечислоединица в любой степени — единица
«Факториал»число: неотрицательноечислофакториал не меньше единицы
«Цифры»число: числосписок числацифра хотя бы одна
«Сумма цифр»число: числочислоу однозначного целого сумма цифр — оно само

Пример целиком — проверяется командой flang check:

модуль «Проба чисел»
  использует «Numbers»

тотальная функция «Доля в процентах»
  принимает часть: число, целое: число
  возвращает число
  пример «Половина»
    дано часть равно 1
    дано целое равно 2
    ожидается 50
  «Ограничить» от («Целочисленное деление» от (часть умножить на 100) и целое) и 0 и 100

Optional

Значение, которого может не быть: «Есть» или «Нет» над любым типом.

Импорт: использует «Optional».

Типы модуля: «Возможно».

функцияпринимаетвозвращаетчто делает
«Обернуть» от «А»значение: «А»«Возможно» от «А»обёрнутое значение всегда есть
«Есть значение» от «А»опция: «Возможно» от «А»признакзначение есть ровно тогда, когда опция — не пустая
«Значение или запасное» от «А»опция: «Возможно» от «А», запасное: «А»«А»у пустой опции берётся запасное, у полной — ровно то, что внутри
«Первый элемент» от «А»элементы: список «А»«Возможно» от «А»первый элемент есть ровно у непустого списка
«Первый элемент или запасное» от «А»элементы: список «А», запасное: «А»«А»у пустого списка — запасное, у непустого — ровно первый элемент
«Последний элемент» от «А»элементы: список «А»«Возможно» от «А»последний элемент есть ровно у непустого списка
«Последний элемент или запасное» от «А»элементы: список «А», запасное: «А»«А»у пустого списка — запасное, у непустого — ровно последний элемент
«Найти не меньше»элементы: список числа, порог: число«Возможно» от числазначение есть ровно тогда, когда в списке нашлось не меньшее порога, и оно само не меньше порога
«Найти не меньше или запасное»элементы: список числа, порог: число, запасное: числочислонашли — не меньше порога, не нашли — запасное
«Умножить значение»опция: «Возможно» от числа, множитель: число«Возможно» от числаумножение не создаёт и не теряет значения
«Первый удвоенный или запасное»элементы: список числа, запасное: числочислопервый удваивается, а у пустого списка берётся запасное

Пример целиком — проверяется командой flang check:

модуль «Проба опции»
  использует «Optional»

тотальная функция «Первое или ноль»
  принимает элементы: список числа
  возвращает число
  пример «Пустой список»
    дано элементы равно пустой список
    ожидается 0
  «Первый элемент или запасное» от элементы и 0

Result

Итог вычисления: успех со значением или ошибка с причиной.

Импорт: использует «Result».

Типы модуля: «Результат».

функцияпринимаетвозвращаетчто делает
«Успешный результат» от «Значение» и «Беда»значение: «Значение»«Результат» от «Значение» и «Беда»успешный результат успешен
«Ошибочный результат» от «Значение» и «Беда»сообщение: «Беда»«Результат» от «Значение» и «Беда»ошибочный результат не успешен
«Успешно» от «Значение» и «Беда»итог: «Результат» от «Значение» и «Беда»признакуспех узнаётся по варианту, и только по нему
«Успех или запасное» от «Значение» и «Беда»итог: «Результат» от «Значение» и «Беда», запасное: «Значение»«Значение»у успеха берётся ровно его значение, у ошибки — запасное
«Сообщение или пусто» от «Значение»итог: «Результат» от «Значение» и строкистрокау успеха сообщение пусто, у ошибки — ровно её сообщение
«Безопасное деление»делимое: число, делитель: число«Результат» от числа и строкиделение успешно ровно при ненулевом делителе
«Деление или запасное»делимое: число, делитель: число, запасное: числочислонулевой делитель даёт запасное, прочий — частное
«Сообщение деления»делимое: число, делитель: числострокасообщение есть ровно на нулевом делителе
«Разобрать цифру»текст: строка«Результат» от числа и строкиразбор успешен ровно на одиночной цифре
«Цифра или запасное»текст: строка, запасное: числочислоцифра разбирается в своё число, прочее даёт запасное
«Ошибка разбора»текст: строкастрокасообщение называет причину: не одна — так не цифра

Пример целиком — проверяется командой flang check:

модуль «Проба результата»
  использует «Result»

тотальная функция «Деление на ноль не роняет»
  принимает делимое: число, делитель: число
  возвращает число
  пример «Ноль в делителе»
    дано делимое равно 10
    дано делитель равно 0
    ожидается -1
  «Деление или запасное» от делимое и делитель и -1

Higher order

Функции-значения: отобразить, отфильтровать, свернуть, сортировать по своему порядку.

Импорт: использует «Higher order».

функцияпринимаетвозвращаетчто делает
«Удвоить»х: числочислоудвоение есть сложение с самим собой
«Возвести в квадрат»х: числочислоквадрат есть умножение на самого себя
«Утроить»х: числочислоутроение есть умножение на три
«Противоположное»х: числочислопротивоположное складывается с исходным в ноль, пока это число
«Положительное»х: числопризнакположительно то, что больше нуля пересиливает
«Сложить»первое: число, второе: числочислослагаемые можно переставить
«Умножить»первое: число, второе: числочислосомножители можно переставить
«Меньшее»первое: число, второе: числочисломеньшее и большее вместе дают ту же сумму
«Большее»первое: число, второе: числочислона строгом неравенстве отдаётся то из двух, что больше
«По возрастанию»первое: число, второе: числопризнакпорядок вперёд есть порядок назад с переставленными доводами
«По убыванию»первое: число, второе: числопризнакна строгом неравенстве порядок назад решается однозначно
«Свернуть»ф: функция из числа и числа в число, основа: число, элементы: список числачислона пустом списке свёртка есть само основание
«Отобразить» от «А» и «Б»ф: функция из «А» в «Б», элементы: список «А»список «Б»отображение сохраняет длину списка
«Отфильтровать» от «А»условие: функция из «А» в признак, элементы: список «А»список «А»подходящий первый элемент отбор не теряет
«Считать где»условие: функция из числа в признак, элементы: список числачислосчёт подходящих есть длина отобранного
«Все»условие: функция из числа в признак, элементы: список числапризнаквсе подходят ровно тогда, когда подходящих столько же, сколько элементов
«Любой»условие: функция из числа в признак, элементы: список числапризнакхоть один подходит ровно тогда, когда подходящих не меньше одного
«Найти первое»условие: функция из числа в признак, элементы: список числа, запасное: числочисловсё, что не запасное, подходит
«Позиция где»условие: функция из числа в признак, элементы: список числачислона найденном месте стоит подходящее, а ноль значит: не найдено
«Вставить по»раньше: функция из числа и числа в признак, значение: число, элементы: список числасписок числавставка удлиняет список ровно на один
«Сортировать по»раньше: функция из числа и числа в признак, элементы: список числасписок числасортировка по порядку не теряет и не добавляет элементов
«Сортировать по направлению»убывание: признак, элементы: список числасписок числасортировка не теряет и не добавляет элементов
«Составить»внешняя: функция из числа в число, внутренняя: функция из числа в число, х: числочислосостав есть два отображения подряд
«Отобразить составом»внешняя: функция из числа в число, внутренняя: функция из числа в число, элементы: список числасписок числаотображение составом сохраняет длину списка
«Сжать»ф: функция из числа и числа в число, первые: список числа, вторые: список числасписок числасжато ровно столько, сколько в коротком из списков
«Сумма сложением»элементы: список числачислосумма положительных не меньше наибольшего из них
«Произведение умножением»элементы: список числачислопроизведение одного элемента есть он сам
«Минимум меньшим из двух»элементы: список числачислонаименьшее взято из самого списка, а на пустом это ноль
«Максимум большим из двух»элементы: список числачислонаибольшее взято из самого списка, а на пустом это ноль
«Обратить знаки»элементы: список числасписок числаобращение знаков сохраняет длину списка
«Заглавная точка»текст: строкастрокаточка удлиняет строку ровно на один знак
«Непустая»текст: строкапризнакнепустая — та, чья длина положительна

Пример целиком — проверяется командой flang check:

модуль «Проба высшего порядка»
  использует «Higher order»

тотальная функция «Сумма квадратов»
  принимает элементы: список числа
  возвращает число
  пример «Три числа»
    дано элементы равно [1, 2, 3]
    ожидается 14
  «Свернуть» от функция «Сложить» и 0 и («Отобразить» от функция «Возвести в квадрат» и элементы)

Dictionary

Словарь строка → строка списком связей. Поиск линейный: на тысяче ключей ведёт себя как список на тысячу элементов.

Импорт: использует «Dictionary».

Типы модуля: «Связь».

функцияпринимаетвозвращаетчто делает
«Ключ связи»связь: «Связь»строкаключ связи — это ключ, записанный в связи
«Значение связи»связь: «Связь»строказначение связи — это значение, записанное в связи
«Есть ключ»словарь: список «Связь», искомый: строкапризнакключ найден ровно тогда, когда он есть среди ключей
«Взять или запасное»словарь: список «Связь», искомый: строка, запасное: строкастрокачего нет среди ключей, того и не взято: отдаётся запасное
«Убрать»словарь: список «Связь», искомый: строкасписок «Связь»удаление не удлиняет словарь
«Положить»словарь: список «Связь», ключ: строка, значение: строкасписок «Связь»после записи словарь непуст
«Ключи»словарь: список «Связь»список строкиключей ровно столько, сколько связей
«Значения»словарь: список «Связь»список строкизначений ровно столько, сколько связей
«Размер»словарь: список «Связь»числоразмер словаря неотрицателен

Пример целиком — проверяется командой flang check:

модуль «Проба словаря»
  использует «Dictionary»

тотальная функция «Значение по ключу связью»
  принимает ключ: строка
  возвращает строка
  пример «Ключа нет»
    дано ключ равно "рост"
    ожидается "нет"
  пусть словарь равно («Положить» от пустой список и "цвет" и "синий")
  «Взять или запасное» от словарь и ключ и "нет"

Hash map

Словарь строка → строка за постоянное время: дерево по цифрам хеша.

Импорт: использует «Hash map».

Типы модуля: «Звено», «Узел хеша».

функцияпринимаетвозвращаетчто делает
«Ключ звена»звено: «Звено»строкаключ звена — это ключ, записанный в звене
«Значение звена»звено: «Звено»строказначение звена — это значение, записанное в звене
«В кольцо»значение: числочислокольцо неотрицательно
«Хеш числа»значение: числочислохеш числа неотрицателен
«Хеш ключа»ключ: строкачислохеш ключа неотрицателен
«Путь хеша»хеш: числосписок числапуть хеша — ровно четырнадцать ступеней
«Гнездо»звенья: список «Звено», спуск: число«Узел хеша»гнездо держит ровно те звенья, что дали, и не глубже одного уровня
«Слить звенья»первые: список «Звено», вторые: список «Звено»список «Звено»длина слияния есть сумма длин
«Вписать»звенья: список «Звено», новое: «Звено»список «Звено»после вписывания список звеньев непуст
«Развести»путь: список числа, первые: список «Звено», спуск: число, вторые: список «Звено», прежний: число«Узел хеша»разведение не теряет и не двоит: звеньев ровно столько, сколько дали
«Вложить»узел: «Узел хеша», спуск: число, новое: «Звено»«Узел хеша»вложенное по спуску по тому же спуску и находится
«Искать»узел: «Узел хеша», спуск: число, искомый: строка, запасное: строкастрокагде признака нет, поиск отдаёт запасное
«Искать признак»узел: «Узел хеша», спуск: число, искомый: строкапризнакв пустом месте ключей нет, одиночка отвечает по своему ключу, а пустая гроздь всегда молчит
«Положить в словарь»словарь: «Узел хеша», ключ: строка, значение: строка«Узел хеша»положенное по ключу тем же ключом и находится
«Найти в словаре»словарь: «Узел хеша», искомый: строка, запасное: строкастрокачего в словаре нет, за то отдаётся запасное
«Есть ключ в словаре»словарь: «Узел хеша», искомый: строкапризнакключ есть ровно тогда, когда поиск не отдаёт запасное — и всё равно какое
«Звенья словаря»словарь: «Узел хеша»список «Звено»у пустого места звеньев нет, у одиночки ровно одно и своё, у грозди — весь её набор
«Размер словаря»словарь: «Узел хеша»числоразмер — это сколько у словаря ключей
«Ключи словаря»словарь: «Узел хеша»список строкиключей ровно столько, сколько звеньев
«Значения словаря»словарь: «Узел хеша»список строкизначений ровно столько, сколько звеньев
«Больше из двух»слева: число, справа: числочислобольше из двух — одно из двух
«Глубина словаря»словарь: «Узел хеша»числогде есть звенья, там есть и глубина
«Словарь из ключей»ключи: список строки«Узел хеша»ни один поданный ключ не потерялся

Пример целиком — проверяется командой flang check:

модуль «Проба словаря хешем»
  использует «Hash map»

тотальная функция «Значение по ключу»
  принимает ключ: строка
  возвращает строка
  пример «Ключ найден»
    дано ключ равно "цвет"
    ожидается "синий"
  пусть словарь равно («Положить в словарь» от («Словарь из ключей» от пустой список) и "цвет" и "синий")
  «Найти в словаре» от словарь и ключ и "нет"

JSON

JSON как значение: разметка, разбор, печать. Ни одного обращения к миру.

Импорт: использует «JSON».

Типы модуля: «Значение json», «Поле json», «Итог json», «Знак json», «Разметка json», «Счёт json», «Исход числа json», «Рамка json», «Ход json».

функцияпринимаетвозвращаетчто делает
«Имя поля json»пара: «Поле json»строкаимя поля — это записанное в поле имя
«Содержимое поля json»пара: «Поле json»«Значение json»содержимое поля — это записанное в поле значение
«Беда разметки json»разметка: «Разметка json»строкабеда разметки — это записанная в состоянии беда
«Знаки разметки json»разметка: «Разметка json»список «Знак json»знаки разметки — это записанный в состоянии список знаков
«Сломать разметку json»разметка: «Разметка json», причина: строка«Разметка json»сломанная разметка не бывает без причины
«Пробельный json»симв: строкапризнакпробельны ровно четыре знака, и ровно по одному
«Цифра json»симв: строкапризнакцифра — ровно тот знак, у которого значение цифры лежит в 0..9
«Значение цифры json»симв: строкачислозначение цифры — код первого знака без сорока восьми, и пустая строка ведёт себя как ноль
«Шестнадцатеричная json»симв: строкапризнакшестнадцатеричны ровно двадцать два знака набора
«Буква слова json»симв: строкапризнакбуквы слов — ровно те, из которых сложены true, false и null
«Одиночный знак json»симв: строкапризнакодиночны ровно шесть знаков разметки
«Начало счёта json»ничего: строка«Счёт json»свежий счёт ещё ничего не прочёл: этап начальный, знаки положительны, целое и дробь нули
«Шаг счёта json»счёт: «Счёт json», симв: строка«Счёт json»сбой липкий: из сорванного этапа счёт не выходит и цифр больше не набирает
«Десять в степени json»показатель: числочислостепень десяти положительна
«Число из текста json»текст: строка«Исход числа json»пустой текст числом не разбирается
«Начало разметки json»ничего: строка«Разметка json»свежая разметка пуста во всех пяти полях
«Добавить знак json»разметка: «Разметка json», знак: «Знак json»«Разметка json»беда липкая: к сломанной разметке знак не добавляется
«Копить json»разметка: «Разметка json», лад: строка, добавка: строка, хвост: строка«Разметка json»беда липкая: сломанная разметка не копит
«Закрыть лексему json»разметка: «Разметка json»«Разметка json»беда липкая: сломанную разметку закрытие не трогает
«Знак вне json»разметка: «Разметка json», симв: строка«Разметка json»беда липкая: сломанная разметка знаков не читает
«Шаг разметки json»разметка: «Разметка json», симв: строка«Разметка json»беда липкая: сломанная разметка дальше не идёт
«Знаки json»текст: строка«Разметка json»у целой разметки лексема всегда закрыта: лад и копилка пусты
«Начало хода json»ничего: строка«Ход json»свежий ход ждёт значения: стопка и готовое пусты, изъяна нет
«Сломать ход json»ход: «Ход json», причина: строка«Ход json»изъян липкий: первую причину вторая не затирает
«Вписать поле json»набор: список «Поле json», новое: «Поле json»список «Поле json»в пустой набор поле встаёт одно и со своим именем
«Вложить значение json»ход: «Ход json», значение: «Значение json»«Ход json»изъян липкий: сломанный ход значений не берёт
«Закрыть рамку json»ход: «Ход json», квадратной: признак«Ход json»изъян липкий: сломанный ход рамок не закрывает
«Верх это массив json»стопка: список «Рамка json»признакпустая рамка массива наверху — это массив
«Записать ключ json»ход: «Ход json», имя: строка«Ход json»ключ вне объекта — названный изъян
«Шаг разбора json»ход: «Ход json», знак: «Знак json»«Ход json»изъян липкий: сломанный разбор дальше не идёт
«Разобрать json»текст: строка«Итог json»пустой вход отвергается с названной причиной
«Шестнадцатеричная цифра json»значение: числострокацифра — ровно один знак
«Заслонить знак json»симв: строкастроказаслонение не укорачивает и пусто ровно на пустом
«Напечатать строку json»текст: строкастрокапечать строки — кавычки плюс не меньше знаков, чем было
«Напечатать json»значение: «Значение json»строканапечатанное значение непусто

Пример целиком — проверяется командой flang check:

модуль «Проба json»
  использует «JSON»

тотальная функция «Разобрать и напечатать»
  принимает текст: строка
  возвращает строка
  пример «Массив печатается обратно»
    дано текст равно "[1,2]"
    ожидается "[1,2]"
  разбор («Разобрать json» от текст)
    случай вариант «Разобран json» с значение как значение
      то «Напечатать json» от значение
    случай вариант «Не разобран json» с причина как причина
      то причина

Что написано последним

Пять модулей моложе остальных. У каждого сказано, что он умеет и чего не умеет.

МодульУмеетНе умеет
«AES»Шифрует и расшифровывает AES-128: один блок, поток в режиме CTR, режим GCM с выработкой и проверкой тега.Ключей длиннее 128 бит нет, и ключ здесь не вырабатывается — берите его из «Вывод ключа» или «X25519».
«X25519»Считает общий ключ двух сторон: умножает точку Curve25519 на скаляр — и на образующую, и на чужой открытый ключ.Подписи Ed25519 здесь нет, и случайного скаляра модуль не берёт: секрет приходит аргументом.
«DER»Читает DER: метку, длину, содержимое, вложенные последовательности, целые, строки и идентификаторы объектов.Печати DER нет — только чтение.
«X.509»Достаёт сертификат из PEM и читает версию, серийный номер, издателя и владельца, срок действия и имя алгоритма подписи; отвечает, действует ли он на заданный день.Открытого ключа и расширений не разбирает, подпись не проверяет, цепочку не строит, отзыв не читает.
«База SQLite»Читает файл базы: заголовок, размер страницы, страницы и ячейки, записи, значения колонок, имена таблиц из схемы и строки таблицы по имени.Записи в файл нет — только чтение. Запрос SQL не разбирается: таблица берётся по имени, условие пишете сами.

AES

Шифр AES-128: один блок, режим счётчика CTR и режим GCM с проверкой тега.

Импорт: использует «AES».

Типы модуля: «Ход шифра», «Ход счёта», «Ход гаммы», «Ход поля», «Ход сдвига», «Ход GHASH», «Ход гаммы GCM», «Печать GCM», «Исход GCM».

функцияпринимаетвозвращаетчто делает
«Веса байта»список числаразрядов ровно восемь
«Исключающее или байтов»первый: число, второй: числочислоитог — байт снизу
«Байт по номеру»байты: список числа, номер: числочислобайт по номеру — байт сверху
«Таблица подстановки»список числав таблице ровно двести пятьдесят шесть байтов
«Подстановка»байт: числочислоподстановка — байт
«Удвоить в поле»байт: числочислоудвоенное — байт
«Утроить в поле»байт: числочислоутроенное — байт
«Четыре байта»байты: список числа, смещение: числосписок числаслово — ровно четыре байта
«Шестнадцать байтов»байты: список числа, смещение: числосписок числаблок — ровно шестнадцать байтов
«Сложить слова»первое: список числа, второе: список числасписок числасумма слов — четыре байта
«Постоянные раундов»список числапостоянных ровно десять
«Слово поворота»слово: список числа, постоянная: числосписок числаитог — четыре байта
«Шаг расширения»расширение: список числа, постоянная: числосписок числашаг дописывает ровно шестнадцать байтов
«Расширение ключа»ключ: список числасписок числарасширение — сто семьдесят шесть байтов, одиннадцать ключей раунда
«Подстановка блока»квадрат: список числасписок числаподстановка длины не меняет
«Сдвиг строк»квадрат: список числасписок числасдвиг даёт ровно шестнадцать байтов
«Смешать столбец»б0: число, б1: число, б2: число, б3: числосписок числасмешанный столбец — четыре байта
«Смешать столбцы»квадрат: список числасписок числасмешение даёт ровно шестнадцать байтов
«Сложить с ключом»квадрат: список числа, ключ: список числасписок числасложение даёт ровно шестнадцать байтов
«Ключ раунда»расширение: список числа, раунд: числосписок числаключ раунда — шестнадцать байтов
«Шаг раунда шифра»ход: «Ход шифра», раунд: число«Ход шифра»раунд шифра ключа не трогает
«Состояние хода»ход: «Ход шифра»список числаквадрат хода — то самое квадрат
«Зашифровать блок»ключ: список числа, блок: список числасписок числашифроблок ровно той же длины, что и блок, — шестнадцать байтов
«Шаг счёта»ход: «Ход счёта», байт: число«Ход счёта»счёт удлиняет ответ ровно на байт
«Байты счёта»ход: «Ход счёта»список числабайты счёта — те самые байты
«Прибавить единицу»счётчик: список числасписок числасчётчик CTR остаётся блоком в шестнадцать байтов
«Шаг гаммы»ход: «Ход гаммы», байт: число«Ход гаммы»выход гаммы удлиняется ровно на байт
«Выход гаммы»ход: «Ход гаммы»список числавыход хода гаммы — тот самый выход
«Шифр CTR»ключ: список числа, счётчик: список числа, текст: список числасписок числашифротекст CTR ровно той же длины, что и открытый текст
«Сложить блоки»первый: список числа, второй: список числасписок числасумма блоков — ровно шестнадцать байтов
«Многочлен поля»список числамногочлен — блок в шестнадцать байтов
«Шаг сдвига блока»ход: «Ход сдвига», байт: число«Ход сдвига»сдвиг удлиняет ответ ровно на байт
«Байты сдвига»ход: «Ход сдвига»список числабайты сдвига — те самые байты
«Сдвиг блока вправо»блок: список числасписок числасдвиг не меняет длины
«Привести сдвиг»блок: список числасписок числаприведение не меняет длины
«Шаг разряда поля»ход: «Ход поля», бит: число«Ход поля»произведение разряда остаётся блоком
«Шаг байта поля»ход: «Ход поля», байт: число«Ход поля»произведение байта остаётся блоком
«Произведение поля»ход: «Ход поля»список числапроизведение хода — то самое накопленное
«Умножить в поле»первый: список числа, второй: список числасписок числапроизведение — блок в шестнадцать байтов
«Шаг GHASH»ход: «Ход GHASH», байт: число«Ход GHASH»
«Свод GHASH»ход: «Ход GHASH»список числа
«GHASH»ключ: список числа, данные: список числасписок числа
«Ключ хеша»ключ: список числасписок числаключ поля — блок в шестнадцать байтов
«Прибавить единицу по младшим четырём»счётчик: список числасписок числасчётчик GCM остаётся блоком в шестнадцать байтов
«Шаг гаммы GCM»ход: «Ход гаммы GCM», байт: число«Ход гаммы GCM»выход гаммы GCM удлиняется ровно на байт
«Выход гаммы GCM»ход: «Ход гаммы GCM»список числавыход хода гаммы GCM — тот самый выход
«Шифр GCTR»ключ: список числа, счётчик: список числа, текст: список числасписок числашифротекст GCTR ровно той же длины, что и открытый текст
«Набивка до блока»байты: список числасписок числанабитое нулями делится на блоки нацело
«Данные GHASH»доп: список числа, шифротекст: список числасписок числаданные делятся на блоки нацело
«Начальный счётчик»ключ: список числа, вектор: список числасписок числаначальный счётчик — блок в шестнадцать байтов
«Тег GCM»ключ: список числа, вектор: список числа, доп: список числа, шифротекст: список числасписок числатег GCM — ровно шестнадцать байтов
«Зашифровать GCM»ключ: список числа, вектор: список числа, доп: список числа, текст: список числа«Печать GCM»тег шифрования GCM — ровно шестнадцать байтов
«Расшифровано ли»исход: «Исход GCM»признакуспех признаётся успехом
«Текст исхода»исход: «Исход GCM»список числау отказа текста нет
«Расшифровать GCM»ключ: список числа, вектор: список числа, доп: список числа, шифротекст: список числа, тег: список числа«Исход GCM»при отказе открытого текста не выдаётся
«Байт двумя знаками»байт: числострокабайт печатается ровно двумя знаками
«Байты шестнадцатеричной строкой»байты: список числастрокана каждый байт — по два знака

X25519

Обмен ключами X25519 на кривой Curve25519 — RFC 7748.

Импорт: использует «X25519».

Типы модуля: «Ход переноса», «Ход займа», «Ход лестницы».

функцияпринимаетвозвращаетчто делает
«Нули»сколько: числосписок числатри нуля
«Разряд»разряды: список числа, номер: числочисловторой разряд
«Взять первые»разряды: список числа, сколько: числосписок числапервые два
«Отбросить первые»разряды: список числа, сколько: числосписок числабез первых двух
«Сложить по разрядам»первые: список числа, вторые: список числасписок числадлина суммы — длина длинного из слагаемых
«Добавить к первому»разряды: список числа, добавка: числосписок числадобавка ложится на младший разряд
«Шаг переноса»ход: «Ход переноса», разряд: число«Ход переноса»
«Разложить»разряды: список числа«Ход переноса»
«Ужать»разряды: список числасписок числа
«Свести»разряды: список числасписок числасведение не меняет числа разрядов, пока их шестнадцать
«Ноль поля»список числаноль поля — шестнадцать разрядов
«Единица поля»список числаединица поля — шестнадцать разрядов
«Простое поля»список числапростое поля — шестнадцать разрядов
«Четыре простых»список числачетыре простых — шестнадцать разрядов
«Из байтов»байты: список числасписок числаиз тридцати двух байтов выходит шестнадцать разрядов
«Точка из байтов»байты: список числасписок числашестнадцать разрядов из тридцати двух байтов
«В байты»разряды: список числасписок числана каждый разряд по два байта
«Снять старший»разряды: список числасписок числа
«Вычесть с займом»первые: список числа, вторые: список числа, заём: число«Ход займа»
«Канон»разряды: список числасписок числашестнадцать разрядов, пока их было шестнадцать
«Это ноль»разряды: список числапризнакноль
«Это единица»разряды: список числапризнакединица
«Сложение»а: список числа, б: список числасписок числасумма — те же шестнадцать разрядов
«Вычитание»а: список числа, б: список числасписок числаразность — те же шестнадцать разрядов
«Свёртка разрядов»а: список числа, б: список числасписок числадвойка на тройку
«Свернуть разряды»разряды: список числасписок числа
«Умножение»а: список числа, б: список числасписок числапроизведение полей — те же шестнадцать разрядов
«Квадрат»а: список числасписок числаквадрат — те же шестнадцать разрядов
«Умножить на число»а: список числа, множитель: числосписок числапроизведение на число — те же шестнадцать разрядов
«Квадраты»а: список числа, сколько: числосписок числани одного квадрата — само число
«Обращение»а: список числасписок числаобращённое — те же шестнадцать разрядов
«Веса байта»список числавосемь весов
«Бит скаляра»скаляр: список числа, номер: числочисломладший бит девятки
«Зажать скаляр»байты: список числасписок числабайтов столько же, сколько было
«Шаг лестницы»ход: «Ход лестницы», точка: список числа, бит: число«Ход лестницы»
«Лестница»скаляр: список числа, точка: список числа, ход: «Ход лестницы», осталось: число«Ход лестницы»
«Умножить точку»скаляр: список числа, точка: список числасписок числарезультат — ровно тридцать два байта
«Основание»список числатридцать два байта
«Открытый ключ»тайна: список числасписок числаоткрытый ключ — ровно тридцать два байта

DER

Разбор DER — двоичной записи ASN.1 из X.690, той самой, которой записан сертификат.

Импорт: использует «DER».

функцияпринимаетвозвращаетчто делает
«Октет»октеты: список числа, место: числочислоза концом списка октет нулевой
«Шаг куска»ход: «Ход куска», октет: число, начало: число, конец: число«Ход куска»номер подвинулся ровно на один
«Ход по куску»октеты: список числа, начало: число, конец: число«Ход куска»пройден весь список, номер стал длиной плюс один
«Кусок»октеты: список числа, начало: число, конец: числосписок числакусок не длиннее целого
«Делить нацело»делимое: число, делитель: числочислоделение на ноль даёт ноль, а не бесконечность
«Разобрать меру»октеты: список числа, место: число«Мера DER»у меры без беды хотя бы один октет длины
«Число из октетов»октеты: список числачислопустая цепочка октетов даёт ноль
«Разобрать голову»октеты: список числа, место: число«Голова DER»конец не раньше начала
«Собрать голову»октеты: список числа, место: число, мера: «Мера DER»«Голова DER»беда меры переходит в беду головы
«Содержимое»октеты: список числа, место: числосписок числасодержимое не длиннее всего разбираемого
«Шаг обхода»ход: «Обход DER», октеты: список числа, конец: число«Обход DER»обход не пятится
«Шаг вперёд»ход: «Обход DER», голова: «Голова DER», конец: число«Обход DER»беда головы останавливает обход на конце
«Ход по вложенным»октеты: список числа, место: число«Обход DER»вложенных не больше, чем всех октетов, и обход не пятится назад
«Вложенные»октеты: список числа, место: числосписок числавложенных не больше, чем октетов во всём разбираемом
«Вложенное по счёту»октеты: список числа, место: число, номер: числочисломесто вложенного либо ноль, либо лежит внутри октетов
«Целое DER»октеты: список числачислопустое целое равно нулю
«Цифра 16»н: числострокацифра — ровно один знак
«Октет шестнадцатеричным»октет: числострокаоктет печатается ровно двумя знаками
«Октеты шестнадцатеричным»октеты: список числастрокана каждый октет ровно два знака
«Октеты двоеточиями»октеты: список числастрокапустое даёт пустое
«Знак октета»октет: числостроказнак всегда ровно один
«Строка DER»октеты: список числастрокана каждый октет ровно один знак
«Закрыть узел OID»ход: «Ход OID», значение: число«Ход OID»после закрытия узла копилка пуста
«Шаг OID»ход: «Ход OID», октет: число«Ход OID»узел закрывается ровно на октете без старшего бита
«Идентификатор объекта»октеты: список числастрокапустой идентификатор печатается пустым
«Цифра октета»октет: числочислоне цифра даёт ноль
«Двузначное»октеты: список числа, место: числочислодвузначное меньше ста
«Разобрать время»метка: число, октеты: список числа«Время DER»у времени без беды год не меньше тысяча девятьсот пятидесятого
«Название месяца»месяц: числостроканазвание месяца — ровно три знака
«Два знака»н: числострокаровно два знака
«Время как у openssl»время: «Время DER»строкапечать времени непуста
«Время числом»время: «Время DER»числовремя числом неотрицательно

X.509

Разбор сертификата X.509 — RFC 5280: поля, имена, сроки, ключ.

Импорт: использует «X.509».

функцияпринимаетвозвращаетчто делает
«Строка не окаймление»строчка: строкапризнакокаймление начинается с дефиса
«Тело PEM»текст: строкастрокатело не длиннее исходного текста
«Октеты сертификата из PEM»текст: строкасписок числаоктетов сертификата не больше, чем знаков в его тексте
«Место тела сертификата»октеты: список числачислотело сертификата начинается не раньше третьего октета
«Сдвиг версии»октеты: список числачислосдвиг версии сертификата — ноль или один, третьего не бывает
«Место поля тела»октеты: список числа, номер: числочисломесто поля тела сертификата лежит внутри октетов или равно нулю
«Короткое имя атрибута»опр: строкастрокаимя атрибута непусто, если непуст сам идентификатор
«Печать пары имени»октеты: список числа, место: числострокапара печатается со знаком равенства
«Печать набора имени»октеты: список числа, место: числострокапечать набора не длиннее трёх знаков на октет
«Печать имени»октеты: список числа, место: числострокапечать имени не длиннее трёх знаков на октет
«Версия сертификата»октеты: список числачисловерсия сертификата — от первой до третьей
«Октеты серийного номера»октеты: список числасписок числасерийный номер не длиннее всего сертификата
«Серийный номер»октеты: список числастрокасерийный номер печатается не длиннее трёх знаков на октет сертификата
«Имя алгоритма»опр: строкастрокаимя алгоритма непусто, если непуст идентификатор
«Алгоритм подписи»октеты: список числастрокаимя алгоритма подписи непусто у непустого сертификата
«Издатель»октеты: список числастрокаиздатель печатается не длиннее, чем весь сертификат знаками
«Субъект»октеты: список числастрокасубъект печатается не длиннее, чем весь сертификат знаками
«Место срока»октеты: список числачисломесто срока не отрицательно
«Не ранее»октеты: список числа«Время DER»у времени начала срока месяц не больше двенадцати
«Не позднее»октеты: список числа«Время DER»у времени конца срока месяц не больше двенадцати
«Сертификат просрочен»октеты: список числа, сейчас: числопризнакдо конца срока сертификат не просрочен
«Сертификат ещё не начался»октеты: список числа, сейчас: числопризнакпосле начала срока сертификат уже начался
«Сертификат действует»октеты: список числа, сейчас: числопризнакдействующий сертификат не позднее своего конца срока

SQLite

Чтение файла базы SQLite 3: заголовок, страницы, ячейки, значения.

Импорт: использует «SQLite».

Типы модуля: «Варинт», «Сбор варинтов», «Сбор указателей», «Значение», «Ряд», «Таблица».

функцияпринимаетвозвращаетчто делает
«Отбросить октеты»октеты: список числа, сколько: числосписок числаотброшено не больше, чем было
«Взять октеты»октеты: список числа, сколько: числосписок числавзято не больше, чем было
«Кусок октетов»октеты: список числа, смещение: число, сколько: числосписок числакусок не длиннее заказанного и не длиннее источника
«Целое из октетов»октеты: список числачислопустые октеты дают ноль
«Целое у смещения»октеты: список числа, смещение: число, ширина: числочислоцелое неотрицательно, пока октеты неотрицательны
«Текст октетов»октеты: список числастрокапустые октеты дают пустой текст
«Магия базы»строкамагия названа целиком
«Это база SQLite»октеты: список числапризнаккороче магии — не база
«Размер страницы»октеты: список числачислоразмер страницы у настоящей базы не меньше пятисот двенадцати
«Страниц в базе»октеты: список числачислостраниц ровно столько, сколько их влезает в файл, пока заголовок не врёт
«Страница»октеты: список числа, номер: числосписок числастраница начинается не позже конца файла и не длиннее остатка файла
«Смещение заголовка страницы»номер: числочислосто на первой странице, ноль на всякой другой
«Вид страницы»страница: список числа, номер: числочисловид неотрицателен
«Это лист таблицы»страница: список числа, номер: числопризнаклист таблицы — это ровно вид 13
«Ячеек на странице»страница: список числа, номер: числочислоячеек не больше, чем указателей влезает в страницу
«Длина заголовка страницы»вид: числочисловосемь у листьев, двенадцать у внутренних
«Шаг указателя»ход: «Сбор указателей», октет: число«Сбор указателей»первый октет пары только копится, второй даёт указатель
«Указатели из октетов»октеты: список числасписок числауказателей ровно половина от числа октетов, когда их чётно
«Указатели ячеек»страница: список числа, номер: числосписок числауказателей ровно столько, сколько ячеек названо заголовком страницы
«Варинт из октетов»октеты: список числа, набрано: число, взято: число«Варинт»варинт съедает хотя бы один октет и не больше девяти
«Взять варинт»октеты: список числа«Варинт»на пустом входе не взято ничего
«Шаг варинта»ход: «Сбор варинтов», октет: число«Сбор варинтов»замыкающий октет добавляет ровно одно число, продолжающий — ни одного
«Варинты подряд»октеты: список числасписок числаваринтов не больше, чем октетов
«Ширина по типу»серийный: числочислоширина неотрицательна
«Значение по типу»серийный: число, октеты: список числа«Значение»ничто выходит ровно у серийного типа 0
«Значения записи»типы: список числа, тело: список числасписок «Значение»значений ровно столько, сколько серийных типов
«Разобрать запись»нагрузка: список числасписок «Значение»значений ровно столько, сколько серийных типов в заголовке записи
«Строка ячейки»страница: список числа, указатель: число«Ряд»номер строки неотрицателен
«Строки листа»страница: список числа, номер: числосписок «Ряд»строк выдано ровно столько, сколько ячеек на листе
«Строки страницы»октеты: список числа, номер: числосписок «Ряд»пустая база строк не даёт
«Строки схемы»октеты: список числасписок «Ряд»строк схемы ровно столько, сколько ячеек на первой странице
«Текст значения»значение: «Значение»строкау нетекстового значения текста нет
«Число значения»значение: «Значение»числоу нецелого значения числа нет
«Колонка строки»ряд: «Ряд», номер: число«Значение»за пределами строки — ничто
«Таблица из строки схемы»ряд: «Ряд»«Таблица»корень неотрицателен
«Таблицы схемы»октеты: список числасписок «Таблица»таблиц не больше, чем ячеек на странице-схеме
«Имена таблиц»октеты: список числасписок строкиимён ровно столько, сколько таблиц
«Корень таблицы»октеты: список числа, имя: строкачислокорень неотрицателен, а ноль значит: такой таблицы нет
«Строки таблицы»октеты: список числа, имя: строкасписок «Ряд»у ненайденной таблицы строк нет
«Значение строкой»значение: «Значение»строкацелое печатается числом
«Строка текстом»ряд: «Ряд»строкапечать непуста, пока в строке есть хоть одно значение

Модуль читает октеты — список байтов файла. Открывать файл он не умеет и не должен: байты приносит план. План — это программа, которая шаг за шагом поручает работу с миром хозяину (flang io) и получает от него отклик; ниже поручение одно — «Прочитать октеты из файла».

Готовьте файл-образец сторонней sqlite3 — тогда есть с чем сверять. Размер страницы задан явно, чтобы числа ниже совпали с вашими:

python3 -c "import sqlite3; c=sqlite3.connect('база.db'); \
  c.execute('pragma page_size=1024'); c.execute('vacuum'); \
  c.execute('create table люди(имя text, лет integer)'); \
  c.executemany('insert into люди values (?,?)', [('Аня',31),('Боря',44),('Вера',7)]); \
  c.commit()"
модуль «Заголовок базы»
  использует «SQLite»

тип «Ход»
  вариант «Начало»
  вариант «Ждём октеты»

тотальная функция «Начало хода»
  возвращает «Ход»
  вариант «Начало»

тотальная функция «Отчёт»
  принимает октеты: список числа
  возвращает строка
  соединить [
      "это база SQLite: ", (если («Это база SQLite» от октеты) то "да" иначе "нет"),
      "\nразмер страницы: ", (к строке («Размер страницы» от октеты)),
      "\nстраниц: ", (к строке («Страниц в базе» от октеты)),
      "\nтаблицы: ", (соединить («Имена таблиц» от октеты) по ", ")
    ] по ""

тотальная функция «Дальше»
  принимает ход: «Ход», отклик: «Отклик»
  возвращает «Продолжение»
  разбор ход
    случай вариант «Начало»
      то вариант «Сделать» с поручение равным (вариант «Прочитать октеты из файла» с путь равным "база.db") и потом равным (вариант «Ждём октеты»)
    случай вариант «Ждём октеты»
      то разбор отклик
        случай вариант «Октеты» с октеты как октеты
          то вариант «Конец работы» с значение равным («Отчёт» от октеты)
        случай любое
          то вариант «Провал» с код равным "FLANG_IO_ORDER" и сообщение равным "ждали октетов"

план «Заголовок»
  состояние «Ход»
  начинает с «Начало хода»
  обрабатывает «Дальше»
flang io заголовок.flang
{"plan":"Заголовок","result":"это база SQLite: да\nразмер страницы: 1024\nстраниц: 2\nтаблицы: люди","orders":1}

Чего этот модуль сегодня не даст. Заголовок, схема и имена таблиц читаются; на значениях строк вычисление упирается в предел шагов. План examples/db/sqlite-read.flang, который печатает ещё и строки таблицы, на базе в 2 КиБ отвечает так:

FLANG_RECURSION_LIMIT: функция «Кодовые точки из байтов» исчерпала лимит шагов (10000000) на глубине вызовов 19

Раскодирование UTF-8 идёт байт за байтом рекурсией, и на каждой ячейке заново. Пока это так, читать через модуль стоит заголовок и схему, а не содержимое.

Остальные модули

Key derivation

Вывод ключа из пароля: PBKDF2-HMAC-SHA256, RFC 8018.

Импорт: использует «Key derivation».

Типы модуля: «Ход вывода».

функцияпринимаетвозвращаетчто делает
«Дописать номер»меньшие: список числа, байтов: числосписок числаграница куска — номер дописывается
«Номера кусков»байтов: неотрицательноесписок числакусков хватает на заказанную длину
«Шаг витка»пароль: список числа, ход: «Ход вывода»«Ход вывода»
«Витки вывода»пароль: список числа, ход: «Ход вывода», осталось: число«Ход вывода»
«Итог витков»ход: «Ход вывода»список числа
«Кусок вывода»пароль: список числа, соль: список числа, повторов: число, номер: числосписок числакусок — ровно тридцать два байта
«Вывод ключа»пароль: список числа, соль: список числа, повторов: число, байтов: неотрицательноесписок числаключ ровно заказанной длины

Date and time

Дата и время как значения: разбор ISO-8601, сложение, разность, високосные годы, дни недели. «Который час» не спрашивает — время приезжает аргументом.

Импорт: использует «Date and time».

Типы модуля: «Календарный день», «Часы», «Отметка», «Итог даты».

функцияпринимаетвозвращаетчто делает
«Пол дроби»значение: числочислона конечном числе пол цел, не больше входа и отстоит не дальше единицы
«Деление вниз»делимое: число, делитель: числочислоделение вниз — это пол частного
«Високосный год»год: числопризнаквисокосный год — тот, в котором 366 дней
«Дней в месяце»год: число, месяц: числочислов месяце не больше 31 дня
«Дата верна»дата: «Календарный день»признакдата верна ровно тогда, когда круг через счёт дней её не меняет
«Часы верны»часы: «Часы»признаквремя верно ровно тогда, когда напечатанные ЧЧ:ММ:СС читаются обратно в границах суток
«Дней от эпохи»дата: «Календарный день»числоотсчёт привязан к эпохе: 1970-01-01 — ноль, следующий день — единица, предыдущий — минус единица
«Дата из дней»дни: число«Календарный день»дата, собранная из дня, тем же днём и отсчитывается
«День недели»дата: «Календарный день»числодень недели не больше шести
«Имя дня недели»номер: неотрицательноестрокау всякого дня недели имя есть, и оно от пяти до одиннадцати букв
«День года»дата: «Календарный день»числоу верной даты день года лежит между первым и триста шестьдесят шестым
«Прибавить дни»дата: «Календарный день», сколько: число«Календарный день»между исходной датой и сдвинутой ровно столько дней, сколько прибавили
«Разность дат»первая: «Календарный день», вторая: «Календарный день»числодаты, отстоящие на целое число недель, приходятся на один день недели
«Секунд от эпохи»отметка: «Отметка»числоэпоха на нуле, полдень на 43200, а тот же полдень в поясе плюс три — на 32400
«Раньше»первая: «Отметка», вторая: «Отметка»признакчто раньше по мгновению, то раньше и по ответу, и с одновременностью это не совмещается
«Одно мгновение»первая: «Отметка», вторая: «Отметка»признаксовпали секунды — совпало и мгновение, как бы ни были записаны пояса
«Число из цифр»текст: строкачислопустая строка даёт минус единицу, а число из пятнадцати цифр не длиннее своей записи
«Смещение из хвоста»хвост: строкачислошестизначная запись пояса разбирается и печатается той же записью, а плюс с ненулевым часом даёт положительное смещение
«Разобрать отметку»текст: строка«Итог даты»отметка короче десяти знаков отвергается с названной причиной
«Двумя знаками»значение: числострокадвумя знаками — это ровно два знака, пока число целое
«Четырьмя знаками»значение: числострокачетырёхзначное целое печатается четырьмя знаками и читается обратно собой
«Напечатать дату»дата: «Календарный день»строкапечать даты не короче десяти знаков, а ровно десять — это ГГГГ-ММ-ДД
«Напечатать пояс»смещение: числостроканоль печатается буквой Z, а целое смещение до 23:59 — знаком, часами и минутами, читаемыми обратно
«Напечатать отметку»отметка: «Отметка»строкапечать отметки не короче двадцати знаков, а ровно двадцать — это запись со всемирным поясом

Requests and responses

Чистая половина HTTP: разбор и печать запроса и ответа, заголовки, коды, адрес, процентное кодирование.

Импорт: использует «Requests and responses».

Типы модуля: «Заголовок», «Запрос», «Ответ», «Разбор запроса», «Разбор заголовков», «Разбор тела», «Длина тела», «Целое из строки», «Ход раскодирования».

функцияпринимаетвозвращаетчто делает
«Склеить куски»части: список строки, разделитель: строкастрокасклейка содержит первый кусок
«Первый кусок»части: список строкистрокау пустого списка первого куска нет, а у непустого он — его голова
«Прочие куски»части: список строкисписок строкипрочих ровно на один меньше
«Обрезать пробельные знаки слева»текст: строкастрокаслева снят край, и снят он только тогда, когда там пробел
«Обрезать пробельные знаки справа»текст: строкастрокасправа снят край, и снят он только тогда, когда там пробел
«Перевернуть»текст: строкастрокапустое переворачивается в пустое, один знак — в себя, а два знака меняются местами
«Обрезать края»текст: строкастрокаобрезка краёв есть обрезка справа после обрезки слева
«Строчный код»код: числочислозаглавная латинская буква переезжает в нижний регистр ровно на тридцать два, всё прочее не двигается, пока это число
«Имена совпадают»первое: строка, второе: строкапризнакимена разной длины не совпадают, а две пустые совпадают
«Цифра десятичная»код: числочислоразбор цифры обратен таблице шестнадцати
«Цифра шестнадцатеричная»код: числочислоразбор шестнадцатеричной обратен таблице шестнадцати
«Целое из десятичной»текст: строка«Целое из строки»пустая строка числом не является, одна цифра даёт своё значение, а один нецифровой знак — отказ
«Целое из шестнадцатеричной»текст: строка«Целое из строки»пустая строка размером не является, а одна шестнадцатеричная цифра даёт своё значение
«Знак по коду»код: числостроказнак по коду есть ровно тогда, когда код в таблице, и его код — тот самый
«Цифра в шестнадцатеричную»н: числострокашестнадцатеричная цифра — ровно один знак
«Байт процентами»байт: числострокабайт процентами — ровно три знака
«Незарезервированный»код: числопризнакбуква и тильда незарезервированы, а пробел и разделители адреса — зарезервированы
«Знак процентами»знак: строкастрокапустой знак даёт пустое, незарезервированный не трогается, а прочий однобайтовый становится тройкой с процентом впереди
«Точка процентами»точка: числострокана каждый октет UTF-8 по три знака, и октетов от одного до четырёх
«Закодировать проценты»текст: строкастрокакодирование процентами не укорачивает
«Свести байт»собрано: строка, байт: число, сырое: строка«Ход раскодирования»сведение байта закрывает ожидание, а собранное растёт: печатный байт даёт один знак, непечатный возвращает сырую запись целиком
«Шаг раскодирования»ход: «Ход раскодирования», знак: строка«Ход раскодирования»процент вне ожидания начинает ожидание двух цифр и запоминается сырым
«Раскодировать проценты»текст: строкастрокатекст без процента раскодированием не меняется
«Плюсы в пробелы»текст: строкастроказамена плюсов сохраняет длину
«Путь цели»цель: строкастрокапуть и строка запроса покрывают цель без остатка
«Строка запроса цели»цель: строкастрокастрока запроса — весь хвост после первого вопроса
«Разобрать пару»кусок: строка«Заголовок»кусок без равенства даёт имя из всего куска и пустое значение
«Разобрать параметры»строказапроса: строкасписок «Заголовок»строка запроса без амперсанда и с непустым именем даёт ровно один параметр, и это та же пара
«Имя заголовка»заголовок: «Заголовок»строкаимя заголовка — это записанное в нём имя
«Значение заголовка»заголовок: «Заголовок»строказначение заголовка — это записанное в нём значение
«Сколько заголовков»заголовки: список «Заголовок», имя: строкачислостолько заголовков, сколько их отбирается по имени
«Взять заголовок»заголовки: список «Заголовок», имя: строкастрокау пустого списка заголовка нет, а на одном заголовке берётся его значение ровно при совпадении имён
«Есть заголовок»заголовки: список «Заголовок», имя: строкапризнакзаголовок есть ровно тогда, когда отбор по имени непуст
«Шаг заголовков»прежнее: «Разбор заголовков», строка: строка«Разбор заголовков»негодный блок заголовков негодным и остаётся: первую беду вторая не затирает
«Разобрать заголовки»строки: список строки«Разбор заголовков»пустой список строк даёт пустой блок заголовков, а одна строка без двоеточия — названную негодность
«Длина тела»заголовки: список «Заголовок»«Длина тела»без заголовка длина не названа, а при двух заголовках она негодна с названной причиной
«Тело чанками»заголовки: список «Заголовок»признакодин заголовок передачи со значением chunked объявляет чанки
«Чанки с запасом»остаток: строка, запас: число, собрано: строка«Разбор тела»исчерпанный запас — названная порча
«Собрать чанки»текст: строка«Разбор тела»пустой текст запаса не даёт и потому объявляется испорченным, а один нулевой чанк закрывает пустое тело
«Голый перевод строки»голова: строкапризнакв пустом блоке голых переводов нет, одиночные перевод и возврат — голые, а пара из них — нет
«Есть длинная строка»строки: список строки, предел: числопризнаку пустого списка длинных строк нет, а одна строка длинна ровно тогда, когда длиннее предела
«Свести тело»метод: строка, цель: строка, версия: строка, заголовки: список «Заголовок», сырое: строка«Разбор запроса»длина тела и чанки, объявленные разом, — названная порча
«Собрать запрос»голова: строка, сырое: строка«Разбор запроса»голый перевод строки в голове отвергает запрос названной причиной
«Разобрать запрос»текст: строка«Разбор запроса»вход без пустой строки между головой и телом — неполон, и отвечать на него нечем
«Пояснение кода»код: числострокаизвестные коды получают свои слова, неизвестный — пустое
«Код успешен»код: числопризнакуспешны ровно те коды, у которых пояснение из двухсотых
«Напечатать заголовки»заголовки: список «Заголовок»строкана каждый заголовок не меньше четырёх знаков: двоеточие, пробел и конец строки
«Напечатать ответ»ответ: «Ответ»строкапечать начинается версией, кодом и пояснением, а длина тела в ней названа по самому телу
«Ответ с телом»код: число, тело: строка«Ответ»ответ несёт свой код, пояснение по коду, ровно один заголовок вида и то самое тело
«Ответ на разбор»разобранное: «Разбор запроса»строканеполному и разобранному запросу не отвечают вовсе, а испорченному отвечают его же кодом и его же причиной
«Напечатать запрос»запрос: «Запрос»строкапечать начинается методом, целью и версией, а длина тела в ней названа по самому телу
«Куски пути»путь: строкасписок строкикусков ровно столько, сколько непустых частей пути
«Глубина пути»путь: строкачислоглубина — число непустых частей пути
«Кусок пути»путь: строка, номер: числостроканомер меньше единицы куска не даёт, а первый кусок пути — это голова его разбиения
«Значение параметра»параметры: список «Заголовок», имя: строкастрокау пустого списка значения нет, а первый параметр с в точности тем же именем отдаёт своё значение, даже пустое
«Есть параметр»параметры: список «Заголовок», имя: строкапризнакпараметр есть ровно тогда, когда имя встретилось хоть раз
«Схема адреса»адрес: строкастрокасхема — ровно то, что стоит перед ://
«Адрес годен»адрес: строкапризнакгоден ровно тот адрес, у которого схема http или https

Logic

Операции над признаками: и, или, не, исключающее или, импликация, а также «все верны» и «есть верное» по списку.

Импорт: использует «Logic».

функцияпринимаетвозвращаетчто делает
«Оба верны»первый: признак, второй: признакпризнакконъюнкция читается и со второго довода: при истинном втором ответ есть первый, при ложном — ложь
«Хотя бы одно»первый: признак, второй: признакпризнакдизъюнкция читается и со второго довода: при истинном втором ответ истина, при ложном — первый
«Не так»значение: признакпризнакотрицание есть импликация в ложь
«Ровно одно»первый: признак, второй: признакпризнакисключающее или есть неравенство признаков
«Следует»посылка: признак, следствие: признакпризнакимпликация есть отрицание посылки или следствие
«Все верны»значения: список признакапризнаквсе верны ровно тогда, когда ложного среди значений нет
«Есть верное»значения: список признакапризнакесть верное ровно тогда, когда истинное среди значений есть

String sets

Множество строк: добавить, убрать, объединение, пересечение, разность, подмножество.

Импорт: использует «String sets».

функцияпринимаетвозвращаетчто делает
«Есть в множестве»множество: список строки, искомое: строкапризнакесть в множестве — это встроенная проверка вхождения
«Добавить в множество»множество: список строки, новое: строкасписок строкидобавление не укорачивает множество
«Убрать из множества»множество: список строки, лишнее: строкасписок строкиудаление не удлиняет множество
«Из списка»элементы: список строкисписок строкимножество из списка не длиннее списка
«Объединение»первое: список строки, второе: список строкисписок строкиобъединение не короче первого множества
«Пересечение»первое: список строки, второе: список строкисписок строкипересечение не длиннее первого множества
«Разность»первое: список строки, второе: список строкисписок строкиразность не длиннее уменьшаемого
«Подмножество»меньшее: список строки, большее: список строкипризнакподмножество — это когда лишних элементов нет
«Размер множества»множество: список строкичислоразмер множества неотрицателен

Base64

Основание 64 по RFC 4648: обычная азбука и азбука для адреса.

Импорт: использует «Base64».

Типы модуля: «Ход кодирования 64», «Ход раскодирования 64».

функцияпринимаетвозвращаетчто делает
«Азбука 64»строкав азбуке ровно 64 знака
«Азбука 64 для адреса»строкав азбуке для адреса тоже ровно 64 знака
«Знак 64»шестёрка: числостроказнак азбуки — ровно один знак
«Знак 64 для адреса»шестёрка: числостроказнак адресной азбуки — ровно один знак
«Значение знака 64»код: числочислозначение знака либо шестёрка, либо честный отказ минус один
«Это знак 64»знак: строкапризнакзнак азбуки — ровно один из шестидесяти шести знаков обеих азбук
«Первая шестёрка»байт: числочислопервая шестёрка неотрицательна, пока байт конечен
«Вторая шестёрка»первый: число, второй: числочисловторая шестёрка неотрицательна, пока байты конечны
«Третья шестёрка»второй: число, третий: числочислотретья шестёрка неотрицательна, пока байты конечны
«Четвёртая шестёрка»байт: числочислочетвёртая шестёрка неотрицательна, пока байт конечен
«Тройка байтов»первый: число, второй: число, третий: числострокатройка байтов даёт ровно четыре знака
«Шаг кодирования»ход: «Ход кодирования 64», байт: число«Ход кодирования 64»пока байтов меньше трёх, кодировка не растёт, а счёт растёт на один
«Закрыть кодирование»ход: «Ход кодирования 64»строканедобранная тройка добивается ровно до четырёх знаков, добранная не трогается
«Закодировать байты»байты: список числастрокадлина кодировки кратна четырём
«Сложить шестёрку»готовые: список числа, сколько: число, набралось: число«Ход раскодирования 64»четвёртая шестёрка выкладывает ровно три байта и обнуляет копилку
«Свести шестёрку»ход: «Ход раскодирования 64», значение: число«Ход раскодирования 64»знак не из азбуки хода не меняет
«Шаг раскодирования 64»ход: «Ход раскодирования 64», знак: строка«Ход раскодирования 64»знак не из азбуки пропускается без следа
«Закрыть раскодирование»ход: «Ход раскодирования 64»список числахвост из двух знаков даёт байт, из трёх — два, из нуля — ни одного
«Раскодировать в байты»код: строкасписок числабайтов не больше, чем знаков

Wire

Общая половина двоичного протокола: октет, целое в сетевом порядке, строка с нулём на конце, резка потока на куски.

Импорт: использует «Wire».

Типы модуля: «Печать», «Набор байтов», «Разбор целого», «Разбор строки», «Разбор числа».

функцияпринимаетвозвращаетчто делает
«Знак байта»байт: числострокапечатаемый байт даёт ровно один знак, всякий другой — ни одного
«Байт печатается»байт: числопризнакпечатается только тот байт, у которого в таблице знак
«Код знака байта»байт: числочислочто положили байтом, то и достали кодом
«Байтов в знаке»знак: строкачислоноль байтов весит пустой знак и только он, всякий другой — от одного до четырёх
«Знак испорчен»знак: строкапризнакпорчей считается ровно то, что начинается знаком замены
«Знаки текста»текст: строкасписок строкизнаков ровно столько, какова длина текста
«Текст знаков»знаки: список строкистрокав склейке ровно столько знаков, сколько их было во всех кусках
«Байтов в тексте»текст: строкачислобайтов не меньше, чем знаков, и не больше, чем вчетверо
«Есть порча»знаки: список строкипризнаку пустого списка порчи нет, а на одном знаке порча — это порча самого знака
«Коды нулевые»знаки: список строкипризнакнулевые коды значат текст из одних нулевых знаков, по знаку на звено
«Набрать байты»знаки: список строки, сколько: число«Набор байтов»набранное весит ровно столько октетов, сколько просили, вместе с остатком даёт исходный поток, а отказ бывает только при непустом запросе
«Дописать знак спереди»знак: строка, набор: «Набор байтов»«Набор байтов»дописка исхода не меняет, удлиняет набранное ровно на один знак и остатка не трогает
«Взять целое»знаки: список строки, ширина: неотрицательное, набрано: число«Разбор целого»нулевая ширина берёт накопленное и входа не трогает, а испортиться целое может только при непустой ширине
«Взять строку»знаки: список строки«Разбор строки»взятая строка — начало входа, нуль съеден, а нуля не нашлось только там, где вход не начинается нулём
«Дописать знак к строке»знак: строка, исход: «Разбор строки»«Разбор строки»дописка исхода не меняет, удлиняет текст ровно на длину знака и остатка не трогает
«Текст до нуля»знаки: список строкистрокатекст до нуля — начало потока, и до первого нуля он доходит целиком
«Хвост после нуля»знаки: список строки, запас: неотрицательноесписок строкихвост после нуля короче входа, а начальный нуль снимает ровно один знак
«Последние»знаки: список строки, сколько: числосписок строкипоследних берётся ровно столько, сколько просили, а если столько не набралось — весь список
«Без первых»знаки: список строки, сколько: числосписок строкиснимается ровно столько первых, сколько просили, а больше, чем есть, не снимается
«Четыре знака»значение: число«Печать»напечатано ровно четыре знака, и печатается ровно то число, у которого печатаемы все четыре октета
«Четыре октета печатаются»значение: числопризнакотрицательное не печатается
«Четыре октета»значение: числострокапечатаемое число читается из своих четырёх октетов обратно тем же числом
«Два октета»значение: числострокачисло, умещающееся в два печатаемых октета, читается из них обратно тем же числом
«Строка с нулём»текст: строкастрокастрока с нулём — тот же текст и ровно один лишний знак в один байт
«Число из целого»целое: «Разбор целого»числовзятое целое отдаётся своим значением, испорченное — нулём
«Текст печати»печать: «Печать»строканапечатанное отдаётся своим текстом, а непечатаемое — пустой строкой
«Цифра провода»знак: строкачислознак-цифра даёт своё значение
«Цифры числом»знаки: список строки, набрано: числочислопустой список отдаёт накопленное, цифра приписывается справа, а не цифра портит всё число
«Целое из текста»текст: строка«Разбор числа»пустой текст числом не считается
«Число без знака»знаки: список строки«Разбор числа»пусто и длиннее пятнадцати цифр числом не считается
«Отрицать число»исход: «Разбор числа»«Разбор числа»разобранное число меняет знак, а не число остаётся не числом

Postgres

Протокол PostgreSQL 3.0, чистая половина: сборка сообщений клиента и разбор сообщений сервера. Сокета здесь нет.

Импорт: использует «Postgres».

Типы модуля: «Поле», «Беда базы», «Весть», «Разбор вести», «Разбор потока», «Значение».

функцияпринимаетвозвращаетчто делает
«Кадр»метка: строка, тело: строка«Печать»кадр — метка, четыре октета длины и тело, а названное непечатаемым число есть та самая длина
«Пуск»пользователь: строка, база: строка«Печать»пусковое сообщение — четыре октета длины и тело, и записанная длина есть весь его размер в байтах
«Тело пуска»пользователь: строка, база: строкастрокатело пуска — версия протокола, две пары с нулями и завершающий нуль: двадцать один знак сверх обоих имён
«Простой запрос»запрос: строка«Печать»простой запрос едет буквой Q, а вместе с длиной и завершающим нулём весит на шесть байтов больше самого запроса
«Начало SASL»способ: строка, ответ: строка«Печать»первое сообщение SASL едет буквой p, а вместе с двумя длинами, именем способа и его нулём весит на десять байтов больше способа и ответа вместе
«Ответ SASL»ответ: строка«Печать»ответ SASL едет буквой p, а вместе с длиной весит на пять байтов больше самого ответа
«Пароль открытым текстом»пароль: строка«Печать»пароль едет малой буквой p, а вместе с длиной и завершающим нулём весит на шесть байтов больше самого пароля
«Прощание»«Печать»прощание — буква X и записанная длина четыре, а всего пять байтов
«Согласование»«Печать»согласование — буква S и записанная длина четыре, а всего пять байтов
«Подготовка»запрос: строка«Печать»подготовка едет буквой P с безымянным запросом и без объявленных типов: на девять байтов больше самого запроса
«Привязка»значения: список строки«Печать»привязка едет буквой B и весит на пять байтов больше своего тела, а непечатаемой бывает лишь от негодных значений или от негодной длины
«Значения привязываются»значения: список строкипризнакпустой список привязывается, а список от ста двадцати восьми значений — уже нет
«Тело привязки»значения: список строкистрокатело привязки — два безымянных имени, ноль форматов, число значений и ноль форматов ответа: восемь знаков сверх самих значений
«Значения параметров»значения: список строкистроказначения едут подряд, и каждое несёт впереди четыре октета своей длины
«Значение с длиной впереди»значение: строкастрокаперед значением стоят четыре октета его длины в байтах, и они читаются обратно тем же числом
«Исполнение»«Печать»исполнение — буква E, безымянный портал, нулевой предел строк, и записанная длина сходится с размером
«Дополнить запрос»запрос: строка, надбавка: число, запас: неотрицательноестрокадополнение только приписывает пробелы: запрос остаётся началом, а длина растёт не больше чем на запас
«Разобрать весть»знаки: список строки«Разбор вести»разобранная весть съедает из потока не меньше пяти знаков, а ждать велят лишь там, где знаков меньше, чем обещала длина
«Разобрать весть по длине»метка: строка, целое: «Разбор целого»«Разбор вести»испорченная длина и длина меньше четырёх дают порчу кадра с названной причиной, и никак иначе
«Разобрать весть по телу»метка: строка, набор: «Набор байтов»«Разбор вести»весть выходит только из целого тела без знака замены, нехватка байтов значит ждать, а знак поперёк границы — порчу
«Разобрать тело»метка: строка, тело: список строки«Весть»незнакомой буква названа своим именем и только тогда, когда она и вправду не из четырнадцати понятых
«Разобрать тело дальше»метка: строка, тело: список строки«Весть»здесь понимают восемь букв, и всякая другая выходит наружу своим именем
«Разобрать вход»целое: «Разбор целого»«Весть»нулём вход разрешён, тройкой просят пароль, десяткой предлагают SASL, одиннадцатой продолжают, двенадцатой кончают — и груз каждой из трёх приезжает целиком; всякий иной способ назван своим числом, а испорченное целое — минус единицей
«Разобрать настройку»исход: «Разбор строки»«Весть»имя настройки — это взятая строка, значение — текст до следующего нуля, а без нуля настройка безымянна и пуста
«Разобрать поля»целое: «Разбор целого», запас: неотрицательноесписок «Поле»полей выходит не больше, чем обещало их число, и не больше запаса, а испорченное число полей не даёт ни одного
«Собрать поля»знаки: список строки, сколько: число, запас: неотрицательноесписок «Поле»полей не больше, чем просили, и не больше запаса
«Разобрать беду»тело: список строки«Беда базы»метка S в начале тела становится важностью беды
«Поле беды»тело: список строки, метка: строка, запас: неотрицательноестрокаполе беды — текст до нуля сразу за искомой меткой
«Разобрать поток»знаки: список строки, запас: неотрицательное«Разбор потока»вестей выходит не больше запаса, остаток не длиннее входа, а оборван поток бывает только с названной причиной
«Приписать весть»весть: «Весть», поток: «Разбор потока»«Разбор потока»приписка удлиняет список вестей ровно на одну, исхода потока не меняет и ни остатка, ни причины не трогает
«Ответ дочитан»знаки: список строкипризнакпроверка на шесть знаков здесь лишняя: её делает сама проверка на готовность
«Это готовность»знаки: список строкипризнакготовность — шесть знаков, из которых первые пять есть Z и длина пять; шестой не проверяется вовсе
«Пароль спрошен»знаки: список строкипризнакпроверка на девять знаков здесь лишняя: её делает сама проверка на просьбу
«Это просьба о пароле»знаки: список строкипризнакпросьба о пароле — ровно девять знаков R 00 00 00 08 00 00 00 03, и ни один не оставлен на волю
«Есть отказ»вести: список «Весть»признаку пустого списка отказа нет
«Это отказ»весть: «Весть»признакотказ узнаётся по варианту вести, и только по нему
«Вход прошёл»вести: список «Весть»признаку пустого списка разрешения нет
«Это разрешение»весть: «Весть»признакразрешение узнаётся по варианту вести, и только по нему
«Строки ответа»вести: список «Весть»список строкистрок выходит ровно столько, сколько среди вестей строк данных
«Досыпать строку»весть: «Весть», собрано: список строкисписок строкистрока данных досыпается в конец ровно одна, прочее проносит собранное нетронутым, и собранное всегда остаётся началом
«Строка полей»ячейки: список «Поле»строкаполя склеены табуляциями: длина есть сумма длин полей плюс разделители
«Текст поля»ячейка: «Поле»строкатекст поля — это записанный в поле текст
«Итог дела»вести: список «Весть»строкау пустого списка итога нет, а на одной вести итог — это её же досыпка к пустому
«Досыпать метку»весть: «Весть», собрано: строкастрокаметку берёт только весть о сделанном деле, прочее проносит собранное нетронутым
«Текст отказа»вести: список «Весть»строкатекст отказа пуст ровно тогда, когда отказа среди вестей нет
«Досыпать отказ»весть: «Весть», собрано: строкастрокатекст берёт только весть об отказе, прочее проносит собранное нетронутым
«Текст беды»беда: «Беда базы»строкатекст беды — важность, код и сообщение через два пробела, и начинается он с важности
«Значение поля»оид: число, текст: строка«Значение»логическая колонка истинна ровно на букве t
«Текстовый тип»оид: числопризнактекст — текстовый тип
«Целое значение»текст: строка, оид: число«Значение»пустой текст целым не становится и приезжает нетронутым
«Вести потока»поток: «Разбор потока»список «Весть»вестей выходит ровно столько, сколько поток успел разобрать — и у целого потока, и у оборванного
«Причина обрыва»поток: «Разбор потока»строкау целого потока причины нет, у оборванного она — та самая, что записана
«Настройки потока»вести: список «Весть»список строкипар выходит ровно столько, сколько среди вестей настроек
«Досыпать настройку»весть: «Весть», собрано: список строкисписок строкинастройка досыпается в конец одной парой из имени, знака равенства и значения, прочее проносит собранное нетронутым

Redis

Протокол Redis (RESP 2), чистая половина: сборка команд и разбор ответов.

Импорт: использует «Redis».

Типы модуля: «Ответ Redis», «Разбор Redis», «Край Redis», «Поток Redis».

функцияпринимаетвозвращаетчто делает
«Край строки»строкакрай — два знака: тринадцатый и десятый коды
«Груз строкой»текст: строкастрокагруз начинается с доллара, несёт сам текст, и длиннее его ровно на доллар, запись длины и два края
«Грузы»части: список строкистрокапустой список даёт пустую запись, а всякая часть весит не меньше пяти знаков
«Команда»части: список строкистрокакоманда начинается со звёздочки и числа частей, а длиной равна шапке вместе с грузами
«Отклик»строкаотклик — команда из одной части, и часть эта PING
«Вход»пароль: строкастрокавход — команда из двух частей, в ней стоит слово AUTH и сам пароль
«Вход с именем»имя: строка, пароль: строкастрокавход с именем — команда из трёх частей, и в ней стоят оба довода
«Положить в Redis»ключ: строка, значение: строкастроказапись — команда из трёх частей, и в ней стоят ключ и значение
«Взять значение»ключ: строкастрокачтение — команда из двух частей, и в ней стоит ключ
«Убрать ключ»ключ: строкастрокаудаление — команда из двух частей, и в ней стоит ключ
«Сколько ключей»строкасчёт ключей — команда из одной части
«Выбрать базу»номер: неотрицательноестрокавыбор базы — команда из двух частей, и номер в ней записан десятичной записью
«Проститься»строкапрощание — команда из одной части
«Дописать знак к краю»знак: строка, исход: «Край Redis»«Край Redis»дописка к краю исхода не меняет, удлиняет текст ровно на длину знака и остатка не трогает
«Взять край»знаки: список строки«Край Redis»взятый текст — начало входа, а остаток короче входа ровно на этот текст и два знака края
«Край за возвратом»хвост: список строки«Край Redis»край берётся только при переводе строки следом, и снимает он ровно один знак
«Ответ числом»исход: «Разбор числа», дальше: список строки«Разбор Redis»разобранное целое становится счётом с тем же значением, а неразобранное — названной порчей
«Груз с краем»текст: строка, край: «Край Redis»«Разбор Redis»край сразу за телом даёт груз с тем же текстом, край с лишними знаками — названную порчу, а отсутствие края — нехватку
«Груз по набору»набор: «Набор байтов»«Разбор Redis»недобранные байты значат нехватку, а не порчу
«Ответ грузом»исход: «Разбор числа», дальше: список строки«Разбор Redis»отрицательная длина даёт отсутствие значения, неразобранная — названную порчу
«Разобрать по метке»метка: строка, край: «Край Redis»«Разбор Redis»плюс даёт слово, минус — беду, а без края разбирать нечего
«Разобрать простой ответ»знаки: список строки«Разбор Redis»пустой поток значит нехватку, а набор внутри набора назван порчей
«Собрать части»знаки: список строки, осталось: число, собрано: список «Ответ Redis», запас: неотрицательное«Разбор Redis»готовый набор несёт не меньше частей, чем уже было собрано
«Набор по числу»исход: «Разбор числа», дальше: список строки, запас: неотрицательное«Разбор Redis»неразобранное число частей — названная порча, отрицательное — отсутствие набора
«Разобрать набор»край: «Край Redis», запас: неотрицательное«Разбор Redis»без края набора нет — байты ещё едут
«Разобрать ответ»знаки: список строки, запас: неотрицательное«Разбор Redis»пустой поток значит нехватку
«Разобрать поток Redis»знаки: список строки, ответы: список «Ответ Redis», запас: неотрицательное«Поток Redis»разобранных ответов не меньше, чем было накоплено, а обрыв всегда назван причиной
«Текст простого ответа»ответ: «Ответ Redis»строкаслово и груз отдают свой текст, отказ помечен словом, отсутствие значения названо, а не подменено пустотой
«Тексты частей»части: список «Ответ Redis»строкапустой набор даёт пустую запись
«Текст ответа»ответ: «Ответ Redis»строканабор берётся в скобки и ровно на них длиннее своего содержимого, а всё прочее печатается как простой ответ
«Тексты ответов»ответы: список «Ответ Redis»строкапустой список даёт пустую запись
«Это отказ Redis»ответ: «Ответ Redis»признакотказом считается только беда
«Есть отказ Redis»ответы: список «Ответ Redis»признакв пустом списке отказа нет

Tree map

Словарь строка → строка деревом поиска: доступ за O(log n).

Импорт: использует «Tree map».

Типы модуля: «Дерево».

функцияпринимаетвозвращаетчто делает
«Строка раньше»первая: строка, вторая: строкапризнакпустая раньше всякой непустой, а непустая не раньше пустой
«Хеш строки»текст: строкачислохеш неотрицателен
«Это дерево поиска»дерево: «Дерево»признакпустое дерево — дерево поиска
«Приоритет»дерево: «Дерево»числоу листа приоритета нет, а у узла он — записанный в узле
«Уравновесить слева»узел: «Дерево»«Дерево»уравновешивание слева не заводит и не хоронит узлов
«Уравновесить справа»узел: «Дерево»«Дерево»уравновешивание справа не заводит и не хоронит узлов
«Положить в дерево»дерево: «Дерево», ключ: строка, значение: строка«Дерево»положенный ключ в дереве есть
«Найти в дереве»дерево: «Дерево», искомый: строка, запасное: строкастрокачего нет среди ключей, того поиск не выдумывает: отдаётся запасное
«Есть ключ в дереве»дерево: «Дерево», искомый: строкапризнакв дереве поиска ключ есть ровно тогда, когда он среди ключей
«Размер дерева»дерево: «Дерево»числоразмер неотрицателен
«Глубина дерева»дерево: «Дерево»числоглубина ноль ровно у дерева без ключей
«Глубже»слева: число, справа: числочислоглубже не мельче каждой из половин
«Ключи дерева»дерево: «Дерево»список строкиключей ровно столько, сколько узлов
«Дерево из ключей»ключи: список строки«Дерево»из пустого списка — пустое дерево, из непустого — непустое

String lists

Список строк: первая, последняя, хвост, склейка, доступ по номеру, общее начало.

Импорт: использует «String lists».

функцияпринимаетвозвращаетчто делает
«Первая строка»части: список строкистрокапервая строка есть строка номер один
«Последняя строка»части: список строкистрокапоследняя — это строка с номером, равным длине списка
«Хвост строк»части: список строкисписок строкихвост короче ровно на одну, и первая с хвостом склеиваются в исходное
«Строка по номеру»части: список строки, номер: неотрицательное, запасная: строкастроканомер в списке даёт элемент этого номера
«Номер строки»части: список строки, искомая: строкачислоноль ровно тогда, когда строки нет, а ненулевой номер показывает на неё
«Дописать строку»части: список строки, новая: строкасписок строкидописывание удлиняет список ровно на один
«Склеить»части: список строкистрокасклейка начинается первой частью, а одна часть склеивается сама в себя
«Хвост через»части: список строки, разделитель: строкастрокаэто ровно склейка того хвоста, который отдаёт функция хвоста
«Непустые»части: список строкисписок строкисклейка непустых та же, что склейка всех
«Общее начало двух»первая: строка, вторая: строкастрокаобщее начало начинает обе строки и дальше них не тянется
«Общее начало»части: список строкистроканачинает первую и последнюю часть, не длиннее их общего начала, а на одной и на двух частях совпадает с ним точно
«Слова»текст: строкасписок строкисклейка слов та же, что склейка кусков

Number tree

Упорядоченное дерево чисел: вставка, поиск вглубь, сортировка обходом.

Импорт: использует «Number tree».

Типы модуля: «Дерево чисел».

функцияпринимаетвозвращаетчто делает
«Добавить число»дерево: «Дерево чисел», число: число«Дерево чисел»добавленное число в дереве находится
«Дерево из чисел»элементы: список числа«Дерево чисел»в дереве ровно столько чисел, сколько в списке
«Есть число»дерево: «Дерево чисел», число: числопризнакпоиск не выдумывает чисел, а в дереве из одной развилки и не промахивается
«Обход по порядку»дерево: «Дерево чисел»список числаобход не короче высоты дерева
«Сортировать деревом»элементы: список числасписок числасортировка деревом не теряет и не добавляет чисел
«Высота»дерево: «Дерево чисел»числовысота дерева неотрицательна

HMAC

Подпись HMAC-SHA256 — RFC 2104 и RFC 4231.

Импорт: использует «HMAC».

Типы модуля: «Ход начала», «Ход слияния».

функцияпринимаетвозвращаетчто делает
«Байты слова»слово: числосписок числаслово занимает ровно четыре байта
«Байты шестнадцатеричным»байты: список числастрокана каждый байт ровно два знака
«Байты свода»свод: «Свод sha256»список числа
«Шаг начала»ход: «Ход начала», байт: число«Ход начала»пока просят — берём
«Начало списка»байты: список числа, сколько: числосписок числавзято меньшее из заказанного и наличного
«Байт или ноль»байты: список числа, номер: числочислопервый
«Шаг слияния»ход: «Ход слияния», байт: число«Ход слияния»первый разряд сливается со вторым списком
«Исключающее или списков»первый: список числа, второй: список числасписок числаслияние длиной в первый список
«Ключ блока»ключ: список числасписок числаключ приведён ровно к блоку хеша
«Набивка ключа»блок: список числа, набивка: числосписок числанабивка не меняет длину
«Подпись байтами»ключ: список числа, сообщение: список числасписок числаподпись — ровно тридцать два байта
«Подпись шестнадцатеричным»ключ: список числа, сообщение: список числастрокаподпись печатается ровно шестьюдесятью четырьмя знаками

SCRAM

Вход SCRAM-SHA-256 со стороны клиента — RFC 5802 и RFC 7677.

Импорт: использует «SCRAM».

функцияпринимаетвозвращаетчто делает
«Октеты ASCII»текст: строкасписок числаоктетов ровно столько, сколько знаков
«Строка только из ASCII»текст: строкапризнакстрока, начинающаяся знаком за пределом ASCII, признаётся негодной
«Поле сообщения»сообщение: строка, имя: строкастрокасоль
«Цифра знака»знак: строкачислоноль
«Число из текста»текст: строкачислопустая запись даёт ноль
«Соль вызова»вызов: строкасписок числасоль раскодируется из основания 64
«Витков вызова»вызов: строкачисловитки берутся числом, а не строкой
«Одноразовое вызова»вызов: строкастрокаодноразовое сервера начинается одноразовым клиента
«Первое клиента без заголовка»пользователь: строка, одноразовое: строкастрокапервое сообщение начинается именем и несёт одноразовое целиком
«Первое клиента»пользователь: строка, одноразовое: строкастроказаголовок GS2 стоит впереди, и это ровно три знака
«Последнее без подписи»вызов: строкастрокапоследнее сообщение возвращает серверу его же одноразовое и заголовок GS2
«Сообщение подписи»пользователь: строка, одноразовое: строка, вызов: строкастрокав сообщение подписи входит вызов сервера целиком
«Солёный пароль»пароль: список числа, вызов: строкасписок числасолёный пароль — ровно тридцать два байта
«Ключ клиента»солёный: список числасписок числаключ клиента — ровно тридцать два байта
«Серверный ключ»солёный: список числасписок числасерверный ключ — ровно тридцать два байта
«Хранимый ключ»клиентский: список числасписок числа
«Доказательство клиента»пароль: список числа, пользователь: строка, одноразовое: строка, вызов: строкасписок числадоказательство — ровно тридцать два байта
«Последнее клиента»пароль: список числа, пользователь: строка, одноразовое: строка, вызов: строкастрокапоследнее сообщение начинается тем же, что и без подписи
«Подпись сервера»пароль: список числа, пользователь: строка, одноразовое: строка, вызов: строкастрокаподпись сервера — поле v и ровно сорок четыре знака основания 64
«Проверка сервера сошлась»пароль: список числа, пользователь: строка, одноразовое: строка, вызов: строка, проверка: строкапризнакпустая проверка не сходится никогда

SHA-1

SHA-1, HMAC-SHA1 и PBKDF2-HMAC-SHA1. Хеш устаревший: берите его только там, где чужой протокол требует именно его.

Импорт: использует «SHA-1».

Типы модуля: «Свод SHA-1», «Ход блока SHA-1», «Ход хеша SHA-1», «Ход вывода SHA-1».

функцияпринимаетвозвращаетчто делает
«Начальный свод SHA-1»«Свод SHA-1»67452301 efcdab89 98badcfe 10325476 c3d2e1f0
«Номера раундов SHA-1»список числараундов ровно восемьдесят
«Постоянная раунда SHA-1»номер: числочислопостоянная — слово
«Смесь раунда SHA-1»номер: число, второе: число, третье: число, четвёртое: числочислосмесь — слово
«Следующее слово SHA-1»расписание: «Расписание»числоследующее слово — слово сверху
«Шаг раунда SHA-1»ход: «Ход блока SHA-1», номер: число«Ход блока SHA-1»
«Сложить своды SHA-1»первый: «Свод SHA-1», второй: «Свод SHA-1»«Свод SHA-1»
«Сжать блок SHA-1»свод: «Свод SHA-1», блок: список числа«Свод SHA-1»
«Шаг байта SHA-1»ход: «Ход хеша SHA-1», байт: число«Ход хеша SHA-1»
«Свод байтов SHA-1»байты: список числа«Свод SHA-1»
«Байты свода SHA-1»свод: «Свод SHA-1»список числа
«Хеш байтов SHA-1»байты: список числастрокахеш SHA-1 — ровно сорок знаков
«Ключ блока SHA-1»ключ: список числасписок числаключ SHA-1 приведён ровно к блоку хеша
«Подпись байтами SHA-1»ключ: список числа, сообщение: список числасписок числаподпись SHA-1 — ровно двадцать байтов
«Подпись SHA-1 шестнадцатеричным»ключ: список числа, сообщение: список числастрокаподпись печатается ровно сорока знаками
«Дописать номер SHA-1»меньшие: список числа, байтов: числосписок числаграница куска — номер дописывается
«Номера кусков SHA-1»байтов: неотрицательноесписок числакусков SHA-1 хватает на заказанную длину
«Шаг витка SHA-1»пароль: список числа, ход: «Ход вывода SHA-1»«Ход вывода SHA-1»
«Витки вывода SHA-1»пароль: список числа, ход: «Ход вывода SHA-1», осталось: число«Ход вывода SHA-1»
«Итог витков SHA-1»ход: «Ход вывода SHA-1»список числа
«Кусок вывода SHA-1»пароль: список числа, соль: список числа, повторов: число, номер: числосписок числакусок — ровно двадцать байтов
«Вывод ключа SHA-1»пароль: список числа, соль: список числа, повторов: число, байтов: неотрицательноесписок числаключ SHA-1 ровно заказанной длины

SHA-256

Хеш SHA-256 — FIPS 180-4.

Импорт: использует «SHA-256».

Типы модуля: «Свод sha256», «Расписание», «Ход блока», «Сбор слов», «Ход хеша».

функцияпринимаетвозвращаетчто делает
«Веса слова»список числаразрядов ровно тридцать два
«Бит»слово: число, вес: числочисломладший бит целого слова — остаток от двойки
«Четвёрка»слово: число, вес: числочисломладшая четвёрка целого слова — остаток от шестнадцати
«Свести к слову»х: числочислослово неотрицательно, пока это число
«Свести к байту»байт: числочислобайт неотрицателен, пока это число
«Это байты»байты: список числапризнаку пустого списка байтовость истинна
«Исключающее или трёх»первое: число, второе: число, третье: числочислорезультат — слово снизу, пока это число
«Выбор»условие: число, единичное: число, нулевое: числочисловыбор — слово снизу, пока это число
«Большинство»первое: число, второе: число, третье: числочислобольшинство — слово снизу, пока это число
«Поворот вправо»слово: число, степень: числочислоповорот — слово снизу, пока это число
«Сдвиг вправо»слово: число, степень: числочислосдвиг — слово снизу, пока это число
«Большая сигма ноль»слово: числочислобольшая сигма ноль — слово сверху, пока это число
«Большая сигма один»слово: числочислобольшая сигма один — слово сверху, пока это число
«Малая сигма ноль»слово: числочисломалая сигма ноль — слово сверху, пока это число
«Малая сигма один»слово: числочисломалая сигма один — слово сверху, пока это число
«Начальный свод»«Свод sha256»6a09e667 bb67ae85 3c6ef372 a54ff53a 510e527f 9b05688c 1f83d9ab 5be0cd19
«Постоянные раунда»список числапостоянных ровно шестьдесят четыре
«Пустое расписание»«Расписание»у пустого расписания все шестнадцать слов — нули
«Сдвинуть расписание»расписание: «Расписание», слово: число«Расписание»сдвиг съезжает на одно поле, а новое слово встаёт последним
«Следующее слово»расписание: «Расписание»числоследующее слово — слово сверху, пока это число
«Шаг сбора слов»сбор: «Сбор слов», байт: число«Сбор слов»четвёртый байт замыкает слово: копилка обнуляется, а слово встаёт последним в расписании
«Расписание блока»блок: список числа«Расписание»четыре байта складываются в одно слово старшим байтом вперёд и встают последним полем
«Шаг раунда»ход: «Ход блока», постоянная: число«Ход блока»первый раунд блока abc из fips
«Сложить своды»первый: «Свод sha256», второй: «Свод sha256»«Свод sha256»
«Сжать блок»свод: «Свод sha256», блок: список числа«Свод sha256»единственный блок сообщения abc — это и есть весь хеш abc
«Нули»сколько: неотрицательноесписок числанулей не бывает меньше нуля
«Байт разряда»число: число, степень: числочисломладший байт целого числа — остаток от двухсот пятидесяти шести
«Байты длины»битов: числосписок числадлина занимает ровно восемь байтов
«Дополнить сообщение»байты: список числасписок числадополненное сообщение делится на блоки нацело
«Шаг байта»ход: «Ход хеша», байт: число«Ход хеша»шестьдесят четвёртый байт закрывает блок: буфер пустеет, счёт обнуляется
«Свод байтов»байты: список числа«Свод sha256»пустое сообщение
«Азбука 16»строкав азбуке шестнадцать знаков
«Цифра 16»н: числострокацифра — ровно один знак
«Слово шестнадцатеричным»слово: числострокаслово печатается ровно восемью знаками
«Свод шестнадцатеричным»свод: «Свод sha256»строкахеш печатается ровно шестьюдесятью четырьмя знаками
«Хеш байтов»байты: список числастрокахеш — ровно шестьдесят четыре знака

UTF-8

Текст в байты и байты обратно в кодовые точки — UTF-8, RFC 3629.

Импорт: использует «UTF-8».

Типы модуля: «Ход разбора utf8».

функцияпринимаетвозвращаетчто делает
«Одинокий суррогат»код: числопризнакблок суррогатов — ровно 2048 точек подряд, считая от D800
«Байты кодовой точки»код: числосписок числабайтов у точки хотя бы один
«Байтов в точке»код: числочислобайтов в точке хотя бы один
«Досыпать байты»готовые: список числа, добавка: список числасписок числадосыпка складывает длины
«Кодовые точки текста»текст: строкасписок числаточек ровно столько, сколько символов
«Байты текста»текст: строкасписок числабайтов не меньше, чем символов
«Длина в байтах»текст: строкачислодлина в байтах не меньше длины в символах
«Текст без одиноких суррогатов»текст: строкапризнакна тексте из одного знака ответ — это ответ про одинокий суррогат, взятый наоборот
«Начало разбора utf8»«Ход разбора utf8»начальный ход пуст: ни точек, ни недобранных байтов, ни замещений
«Начать байт»точки: список числа, замещений: число, байт: число«Ход разбора utf8»точек не убыло при начале байта
«Шаг разбора utf8»ход: «Ход разбора utf8», байт: число«Ход разбора utf8»шаг не теряет точек
«Закрыть разбор utf8»ход: «Ход разбора utf8»список числаточек стало столько же ровно тогда, когда хвост цел
«Кодовые точки из байтов»байты: список числасписок числаточек не больше, чем байтов
«Байты годны как UTF-8»байты: список числапризнакпустое годно
«Круговой ход держится»текст: строкапризнаккруговой ход держится ровно там, где одиноких суррогатов нет
«Списки точек равны»первый: список числа, второй: список числапризнакравные списки одной длины и с одной головой

Дальше