Skip to content

Commit f87e776

Browse files
Ядро FTS на flang: вычислитель утилит
Третий слой из четырёх: по утилите и входной записи считает результат, проверяет свойства и прогоняет примеры. 20 функций, все тотальные; рекурсии в файле нет вовсе — правила, условия, свойства и примеры обходятся свёртками. Семантика воспроизведена дословно, а не пересказана: проценты считаются как (доля / 100) * значение, равенство скаляров по Object.is, свойство проверяется после всех правил и при пустом списке правил тоже. Исключений в языке нет, поэтому всё, что может отказать, возвращает сумму «Итог» с кодом и текстом ядра; короткое замыкание условий выражено состоянием свёртки. Совпадение с ядром на TypeScript доказано, а не заявлено: 20 документов, 24 утилиты, 11 180 входов, ноль расхождений — сверяются и значения, и коды диагностик. Сетка входов выведена из моделей: значения примеров, константы условий и границы c−1/c/c+1. Отдельным тестом проверено, что перевод FtsScalar → «Скаляр» обратим, иначе сверка шла бы на подменённых данных. Слой пришёл к тем же объявлениям типов, что и печать JSON, — контракт был исправлен по ходу работы, и оба слоя теперь описывают «Скаляр» дословно одинаково. Это условие стыковки: слои соединяются только через типы контракта. Записаны 7 долгов, главный — executeUtility и сводка testUtilities: проверки входа уровня документа требуют типа структуры, которого в контракте пока нет. evaluateUtility, то есть то, что задаёт раздел 3, реализована полностью.
1 parent eee1f66 commit f87e776

3 files changed

Lines changed: 1427 additions & 0 deletions

File tree

flang/core/SPEC.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,74 @@
248248
поэтому печать совпадает), но допускает то, чего объект JS допустить не
249249
может, — два одинаковых ключа. Проверки на это нет: значения приходят из
250250
объекта JS, где повтор невозможен по построению.
251+
252+
### Вычислитель (`flang/core/evaluate.flang`)
253+
254+
Тотальность: долгов нет. Все 20 функций файла помечены `тотальная` и доказаны
255+
`totality.mjs`. Рекурсии в файле нет вовсе: правила, свойства, условия и примеры
256+
— это списки, и обход каждого выражен свёрткой. Короткое замыкание `Array.every`
257+
(условия правила) и «первая диагностика прекращает счёт» (правила и свойства)
258+
выражены состоянием свёртки, а не выходом из цикла: сработавший отказ
259+
протаскивается дальше нетронутым, и тела остальных шагов не вычисляются.
260+
261+
Дифференциальная сверка (раздел 5) на всех `.fts` репозитория: 20 документов,
262+
24 утилиты, 11 180 входов, ноль расхождений — совпадают и значения (по
263+
`Object.is`, до последнего бита), и коды диагностик. Проверка —
264+
`flang/test/core-evaluate.test.mjs`.
265+
266+
Расхождения и отступления, оставленные сознательно:
267+
268+
1. **Скаляр — сумма типов, а не строка.** То же отступление и по той же
269+
причине, что долг 3 печати JSON: текстовый вид не различает `5`, `"5"` и
270+
`да`, а `Object.is` их различает, и на этом различии стоит вся семантика
271+
равенства. Поэтому `«Значение операнда»` несёт `«Скаляр»`, а объявления
272+
типов раздела 2 в `evaluate.flang` и `json.flang` совпадают дословно —
273+
вычислитель и печать обязаны читать одно значение. Первая версия файла шла
274+
за буквой раздела 2 и разбирала текст сама (`parseScalar` ядра, включая
275+
регулярное выражение числа, выраженное вычёркиванием цифр свёрткой по
276+
десяти литералам); от этого пришлось отказаться, чтобы не заводить второй
277+
разбор числа рядом с `Похоже на число` лексера. Раздел 2 стоит поправить.
278+
279+
2. **`executeUtility` не реализована — только `evaluateUtility`.** Раздел 3
280+
описывает семантику вычисления, и она воспроизведена полностью. Проверки
281+
входа уровня документа (`FTS_UNKNOWN_UTILITY`, отсутствие объявленного поля
282+
структуры, `FTS_UTILITY_INPUT_TYPE`, `FTS_UTILITY_INPUT_FIELD`) требуют
283+
типа структуры и списка утилит, а «Утилита» раздела 2 знает только имя
284+
своего входа (`принимает: строка`). Эти коды остаются за слоем, который
285+
увидит «Документ» целиком; `FTS_UTILITY_INPUT` для поля, которого нет в
286+
переданных привязках, здесь есть — его даёт `resolveField`.
287+
288+
3. **Сводка `testUtilities` не реализована.** `FTS_NO_UTILITIES` и
289+
`FTS_NO_UTILITY_EXAMPLES` — диагностики документа, а не утилиты, и по той же
290+
причине им здесь не на что смотреть. Прогон примеров одной утилиты есть:
291+
«Проверить примеры» возвращает список «Итог примера» — тот же набор полей,
292+
что у `UtilityExampleResult` ядра.
293+
294+
4. **Текст `FTS_EXAMPLE_MISMATCH` выбран здесь.** Кода `FTS_EXAMPLE_MISMATCH` в
295+
ядре на TS нет вовсе: `testUtilities` возвращает `passed: false` без
296+
диагностики, а код введён разделом 3 этого контракта. Сообщение —
297+
`пример «X» утилиты «Y»: ожидалось A, получено B`, значения печатаются как
298+
«к строке» (признак — `да`/`нет`, ничто — `ничто`). Дословного образца, с
299+
которым это можно было бы сверить, не существует; если он появится,
300+
поменять придётся одну строку.
301+
302+
5. **Диагностика без `span`.** Формат ядра — `{ code, message, severity, span }`;
303+
«Итог» несёт только код и сообщение. Позиции у вычислителя нет и взяться ей
304+
неоткуда: он работает над «Документом», из которого разметка исходника уже
305+
ушла. Слой, который печатает диагностику, обязан добавить `span` правила или
306+
свойства сам.
307+
308+
6. **Стандартная библиотека не переиспользована — нечего переиспользовать.**
309+
После отказа от разбора текста (долг 1) в файле не осталось ни одного
310+
действия над строками, кроме склейки сообщений встроенной «соединить»:
311+
ни `Разбить по символу`, ни `Заменить` из `flang/stdlib/strings.flang` не
312+
нужны. Импорта нет и по второй причине: `использует … из "…"`
313+
(`flang/src/link.mjs`) появился одновременно с этим файлом, и завязывать
314+
слой ядра на связывание, которое ещё меняется, рано.
315+
316+
7. **Свойства не выражены постусловиями функции.** SPEC языка даёт
317+
`postconditions` с полями `code` и `message`, и `compat.mjs` переводит
318+
свойства FTS именно в них. Здесь так нельзя: утилита — это данные, а не
319+
функция, её свойства известны во время вычисления, а не во время разбора
320+
`evaluate.flang`. Постусловие пригодится генератору кода (утилита → функция),
321+
а не вычислителю.

0 commit comments

Comments
 (0)