[2026-09-17] eagle: personal/projects/zont-config-compiler.md

This commit is contained in:
Alexey Martemyanov
2026-09-17 21:29:16 +06:00
parent 3c85f91872
commit e18b58343d
+128 -5
View File
@@ -629,6 +629,10 @@ iconv -f cp1251 -t utf-8 out.txt | tr -d '\r' | grep '^#Z<id>=<тип>'
| 28g | 🔴 **Мусорный ярлык в `type:` ломает читаемость сильнее, чем отсутствие ярлыка** | `type: condition` у объекта с `param: target_temp` — «condition» врёт: запись 49 несёт **значение**, а не условие. Alex: «тут почему condition?». Ярлык должен называть **содержимое** (`param`), а не «формат записи» |
| 28h | 🔴 **Переиспользование занятого имени ключа ломает сборку** | Алекс: «value», но `value` уже занят сырым числом в том же узле → коллизия. Решение: освободить `value` под `type`-слово, сырое число → `raw_value`. Перед вводом ключа — `grep` по **всем** использованиям имени |
| 28i | 🔴 **`grep -oE` c `[^\r]*` обрезает строку на мультибайте (cp1251)** | `grep -oE "#Z9964=[^\r]*"` вернул `59,'set va` — я чуть не доложил «строка битая». Читать файл целиком через `iconv -f cp1251 -t utf-8` + `grep -nE '^#Z…='`, либо `python3` с явной кодировкой. Кириллица в cp1251 ≠ байты UTF-8, регексп рвёт её посередине |
| 28j | 🔴 **Дублирующий разбор вытесняет уже принятую форму** | Ветка `t == 'var'` в `_inline_script_body` собирала тот же `set var`, что и `set_var`, и стояла **выше** в трёх кортежах (`_script_body`, `emit_action`, `emit_step`) → в YAML появилось `type: var` + голый `object`, `set_var` исчез. Alex: «где блядь `set_var`». Новый разбор, дублирующий принятую форму, обязан её **заменить**, а не сосуществовать. Проверять порядок веток в **обеих** точках входа (§10.7, круг 29) |
| 28k | 🔴 **`elif` по типу цели недостижим — различать по наличию объекта** | `int`-цель (`#Z9964=…,42,0,1`) проходит **обе** ветки: форма-«объект» и форма-«число». `elif` бывает недостижим, а `tgt_body = None` молча роняет шаг в `descr`+`args`. Признак — `target in Z_dict`, не `isinstance(int)` (§10.7, круг 30) |
| 28l | 🔴 **`args` тела-цели не должны попадать в хвост шага** | Для составного тела (`expr`) его `args` (`[9965, 9966]`) уходили в **хвост шага**`#Z9968=59,'set varname',9967,9965,9966` вместо `…,9967,0,0`. У формы с составным телом хвост шага всегда `[0, 0]` (§10.7, круг 32) |
| 28m | 🔴 **Правка `value` у цели-скрипта в РОДИТЕЛЕ не доезжает** | `value` формы 3 живёт в **отдельной строке цели** (`#Z9962`); родитель — лишь ссылка полем 2. Проверять подменой именно **строку источника**, иначе «правка не работает» (§10.7) |
### 7.3. Проверка гипотез
@@ -1141,6 +1145,9 @@ Alex видел `field: 1` **после** переименования в `mode`
- `set var1` в конфиге **10**, не 12 (в плане было 12 — ошибка счёта). Формы: 9 с ненулевым
`args[0]` → получили `set_var`; `#Z8472=59,'set var1',0,0,0` (arg1 = 0) → **без** `set_var`
(запись ничего не пишет, разворачивать нечего).
> ⚠️ **УСТАРЕЛО (круг 31, §10.7):** `#Z8472` теперь **тоже** получает `set_var` —
> `{name: var1, value: 0}` (форма «цель — число»). Признак — не `args[0] != 0`, а **наличие
> объекта** `args[0]` в `Z_dict`. Семантика `0` («пусто» vs «ноль») UI не подтверждена.
- `set var1` — 0 не влезает в предикат намеренно: `0` = «нет цели», не id.
- `storeev`**4** записи (не 5): `I` ×2, `A` ×2. Все развёрнуты в `storeenv`.
- `puts`**5** записей → `log` (§10.3).
@@ -1562,11 +1569,127 @@ curl -s --max-time 30 http://192.168.0.50/config.txt -o "config_local_${TS}.txt"
> **72 сценария** (+`Values test`) · `21-13-18` = **774 строки** / 72 сценария
> (`Values test` + расширенный «Простой тестовый сценарий»).
> ⚠️ **`set varname` (шаги `9963/9964/9968/9971/9973`) НЕ разворачивается** — цель это
> `#Z9962=59,'2 ;#p'` / `9966` / `9969` / `9972` (`5 ;#p`, `exp…`), т.е. **другой скрипт**,
> а не запись 49/50. Остаётся `descr` + `args`. Это не дефект: разворачивать нечего.
> Отдельный случай — `#Z9964=59,'set varname',42,0,1`: цель `42` не объект, а **число**,
> аргумент 3 = `1` (а не `0`). Форма та же `descr` + `args`.
> **`set varname` (шаги `9963/9964/9968/9971/9973/9974`) РАЗВЁРНУТЫ** — все четыре формы цели
> разобраны, см. **§10.7**. Прежняя запись «разворачивать нечего» **УСТАРЕЛА**.
### 10.7. ✅ `set var` — ЧЕТЫРЕ формы цели (круги 29–32) — ЗАКРЫТО
**Запрос Alex:** «Теперь разверни set var, print log и alarm нотификации» → после разбора 49/50
(§10.6) остались шаги «Простой тестовый сценарий», где цель — **не** запись 49/50.
Alex показал блок и спросил: «это че блядь» / «где блядь `set_var`».
#### 🔴 Круг 29: `type: var` — МОЯ выдуманная ветка, вытеснившая `set_var`
Симптом: в YAML вместо `set_var` появилось
```yaml
- id: 9963
type: var
name: varname
object: 9962 # голый id — читать бессмысленно
- id: 9964
type: var
name: varname
object: 42
args: [0, 1]
```
Причина — **дублирующая ветка**: `_inline_script_body(..., t == 'var')` собирала `[59, 'set %s',
name, tgt, …]`, и в `emit_action`/`emit_step` условие `'var' in ('objstate','expr','const','var')`
стояло **выше** ветки `set_var`. Итог: для одного и того же смысла существовало **две формы**,
и новая перебила принятую. Alex: **«где блядь `set_var`»**.
**Фикс:** ветка `t == 'var'` **удалена полностью**; `'var'` убран из трёх кортежей
(`_script_body`, `emit_action`, `emit_step`); из `_inline_script_value` убран разбор `set`
все `set var` идут **только** через `set_var`. `type: var` в файле — **0 вхождений**.
> 📌 Урок: **новый разбор, дублирующий уже принятую форму, обязан её заменить, а не сосуществовать.**
> Проверять порядок веток в **обеих** точках входа (`emit_action` + инлайн `emit_step`).
#### 🔴 Круг 30: `elif` по типу цели — недостижимая ветка
Первый фикс разделял формы по типу: `int` → объект, `elif isinstance(int/float)` → число.
Но `#Z9964=59,'set varname',42,0,1``42` это `int`, значит заходил в **первую** ветку, а
объекта `42` нет → `tgt_body = None` → падал в `descr`+`args`. **`elif` недостижим.**
**Фикс:** различать **не по типу, а по наличию объекта**`target in Z_dict`.
Порядок: цель 49/50 → объект 59 → объекта нет (число) → объект иного типа.
#### ✅ Четыре формы цели (поле 2) — ФИНАЛ
| # | Цель | Признак | YAML | Строка конфига |
|---|---|---|---|---|
| 1 | запись **49/50** | `_set_var_value_body(t)` ≠ None | `set_var: {id, name, type: param\|time_condition\|days_mask, …тело}` | `#Z9961=59,'set var1',9960,0,0` |
| 2 | **число** | target **отсутствует** в `Z_dict` | `set_var: {name, value: 42, args: [0,1]}` | `#Z9964=59,'set varname',42,0,1` |
| 3 | другой скрипт **59** | target есть, `entry[0] == 59` | `set_var: {name, target: <id>, type: const\|expr\|objstate, …}` | `#Z9963=59,'set varname',9962,0,0` |
| 4 | объект иного типа | target есть, не 49/50/59 | `descr` + `args` (**без** `set_var`) | `#Z9886=59,'set var1',9885,0,0` |
Живые примеры снимка `21-13-18`:
```yaml
- id: 9961 # #Z9961=59,'set var1',9960,0,0 (форма 1)
set_var: {id: 9960, name: var1, type: param, object: 8560, param: target_temp, args: [0, 0]}
- id: 9963 # #Z9963=59,'set varname',9962,0,0 (форма 3)
set_var: {name: varname, target: 9962, type: const, value: 2}
- id: 9964 # #Z9964=59,'set varname',42,0,1 (форма 2)
set_var: {name: varname, value: 42, args: [0, 1]}
- id: 9968 # #Z9968=59,'set varname',9967,0,0 (форма 3, expr)
set_var: {name: varname, target: 9967, type: expr, expr: '%0 + %1', args: [9965, 9966]}
- id: 9974 # #Z9974=59,'set varname',8472,0,0 (форма 3, цель сама set)
set_var: {name: varname, target: 8472, value: 0, var: var1}
```
**Форма 3 подробно.** Цель — **свой объект** (`9962` = `#Z9962=59,'2 ;#p',0,0,0`), поэтому тело
разворачивается на месте родителя, но при сборке регистрируется **своей строкой** под `target`
(`_register(data['scenario_scripts'], tgt_ref, body)`). Если цель сама является `set`
(`#Z8472=59,'set var1',0,0,0`) — добавляются `value` (поле 2 цели) и `var` (имя переменной цели).
#### 🔴 Круг 31: `elif` не покрывал `0` — «нет цели» ≠ «значение ноль»
`#Z8472=59,'set var1',0,0,0` — цель `0`. Ранее (§10.1) он оставался **без** `set_var`
(«0 = нет цели, разворачивать нечего»). Теперь форма 2 ловит его как **число**
`set_var: {name: var1, value: 0}`. Подмена `value: 0 → 5` даёт `#Z8472=59,'set var1',5,0,0` ✅.
Форма работает, но семантика `0` («пустая переменная» vs «значение 0») **не подтверждена UI**.
#### 🔴 Круг 32: хвост `args` шага забирал аргументы тела-цели
Для формы 3 `args` (напр. `[9965, 9966]` у `expr`) принадлежат **телу цели**, а не шагу.
Сборка подставляла их в хвост шага: `#Z9968=59,'set varname',9967,9965,9966` вместо `…,9967,0,0`.
**Фикс:** у формы 3 с составным телом хвост шага всегда `[0, 0]` — args ушли в тело.
#### Питфолл: подмена `value` цели-скрипта в родителе НЕ доезжает
`value` формы 3 живёт **в отдельной строке цели** (`#Z9962`). Правка `value` в родителе
(`9963`) не доезжает — родитель лишь **ссылка** полем 2.
```bash
# ❌ правит не то — 9963 останется 'set varname',9962,0,0
- id: 9963
set_var: {name: varname, target: 9962, type: const, value: 7} # правка в родителе
# ✅ правит источник — #Z9962=59,'7 ;#p',0,0,0
- id: 9962
type: const
value: 7
```
Проверено подменой: правка `9962``value: 2 → 7` доехала в `#Z9962=59,'7 ;#p',0,0,0`,
`9963` не изменился.
#### Проверка
| Проверка | Результат |
|---|---|
| круг `21-13-18` | ✅ `774 → 774`, ключей 774/774, различий **0** |
| `type: var` в YAML | **0 вхождений** |
| подмена формы 2 (`9964` `value: 42 → 99`) | ✅ `#Z9964=59,'set varname',99,0,1` |
| подмена формы 3 (`9962` `value: 2 → 7`) | ✅ `#Z9962=59,'7 ;#p',0,0,0`, родитель не тронут |
| подмена формы 3-цель-`set` (`8472` `0 → 5`) | ✅ `#Z8472=59,'set var1',5,0,0` |
> ⚠️ **Двойной разбор шага** (питфолл): тело сначала разбирает `_inline_script_value`, затем —
> блок `set_var`. Оба обязаны **согласованно пропускать** друг друга; иначе `descr`+`args`
> затирают разобранную форму.
---