52 lines
2.2 KiB
JavaScript
52 lines
2.2 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* step-pointer — указатель шага плана как ДЕРЕВО (волны D6/OQ1). Заменяет линейный
|
|
* счётчик Машины 2, когда шаг раскрывается в под-план. СТЕНДОВЫЙ модуль: построен и
|
|
* оттестирован, но в живой enforce-supreme-gate.main() НЕ врезается в этой сессии
|
|
* (см. журнал вопросов — отдельный шаг). Линейный режим обратно совместим.
|
|
*/
|
|
|
|
/** Указатель = стек уровней [{index, length}]; верхний — текущий под-план. */
|
|
export function createPointer({ length }) {
|
|
return { stack: [{ index: 0, length }], indexAtRoot: 0 };
|
|
}
|
|
|
|
/** Текущий путь — индексы по уровням стека. */
|
|
export function currentPath(p) { return p.stack.map((l) => l.index); }
|
|
|
|
/** Индекс на корневом уровне (обратная совместимость с линейным счётчиком). */
|
|
function rootIndex(p) { return p.stack[0].index; }
|
|
|
|
/** Продвинуть указатель на текущем (верхнем) уровне. */
|
|
export function advance(p) {
|
|
const stack = p.stack.map((l) => ({ ...l }));
|
|
stack[stack.length - 1].index += 1;
|
|
const np = { stack };
|
|
np.indexAtRoot = rootIndex(np);
|
|
return np;
|
|
}
|
|
|
|
/** Текущий шаг раскрылся в под-план длины length → углубляемся. */
|
|
export function enterSubPlan(p, { length }) {
|
|
const stack = p.stack.map((l) => ({ ...l }));
|
|
stack.push({ index: 0, length });
|
|
const np = { stack };
|
|
np.indexAtRoot = rootIndex(np);
|
|
return np;
|
|
}
|
|
|
|
/** Под-план исчерпан → возвращаемся к родителю (на его текущем шаге). */
|
|
export function exitSubPlan(p) {
|
|
if (p.stack.length <= 1) return p;
|
|
const stack = p.stack.slice(0, -1).map((l) => ({ ...l }));
|
|
const np = { stack };
|
|
np.indexAtRoot = rootIndex(np);
|
|
return np;
|
|
}
|
|
|
|
/** Готово, когда корневой уровень исчерпан. */
|
|
export function isDone(p) {
|
|
const root = p.stack[0];
|
|
return p.stack.length === 1 && root.index >= root.length;
|
|
}
|