diff --git a/doc.go b/doc.go index 949e257..8d1b118 100644 --- a/doc.go +++ b/doc.go @@ -25,7 +25,8 @@ package fejkdata // iteration of a `template.repeat`. // - hold — keeping one draw of a name, so every route to it reads that value: // an expansion holds a sibling path's head and an operand's field, its draw -// group a reference path's: `formatOps.held`, `formatOps.keepsHold`, `heldCheck`. +// group a reference path's: `formatOps.held` and `heldCheck` an expansion's, +// `readReference` a draw group's. // - memo — what a hold or a draw group keeps its draws in, the variant drawn at // each level and the value each path read: `drawMemo`, `readMemo`. // - draw group — reference draws kept apart inside one render: diff --git a/format.go b/format.go index 3a93418..7f64949 100644 --- a/format.go +++ b/format.go @@ -381,12 +381,12 @@ type op struct { } // formatOps is a compiled format: its ops, the size of its literal text, and the -// names it holds: every head a path starts from, plus the fields an operand reads. +// names its expansion holds: every head a path that is not a reference starts from, +// plus the fields an operand reads. type formatOps struct { - ops []op - grow int - held map[string]firstReach - keepsHold bool // some held name is not a reference path, so expand makes a hold + ops []op + grow int + held map[string]firstReach } // firstReach is how a format first reaches a held name: the reader holding it, for @@ -397,12 +397,12 @@ type firstReach struct { } func (c *formatOps) holdName(a arm, label string) { + if isRef(a.head) && len(a.tail) > 0 { + return + } if c.held == nil { c.held = map[string]firstReach{} } - if !isRef(a.head) || len(a.tail) == 0 { - c.keepsHold = true - } h, seen := c.held[a.head] if !seen { h.holder = label diff --git a/holdfence.go b/holdfence.go index 6f5bfd0..9b03056 100644 --- a/holdfence.go +++ b/holdfence.go @@ -17,9 +17,6 @@ func heldCheck(path string, n node) error { } readers := pathHeadReaders(t.compiled) for _, name := range heldNames(t) { - if t.compiled.held[name].path != "" && isRef(name) { - continue // held for the render: drawFence compares every read of it, by path, across the render and its groups - } if err := checkNameHeld(t, name, readers); err != nil { return fmt.Errorf("%s: %w", path, err) } @@ -201,12 +198,12 @@ func pathHeadReaders(c formatOps) []reader { var names []reader for _, o := range c.ops { for _, a := range o.operands { - if c.held[a.head].path != "" && !isRef(a.head) { + if c.held[a.head].path != "" { names = append(names, reader{a, fmt.Sprintf("%s operand %q", o.fn, a.spelling)}) } } for _, a := range o.arms { - if c.held[a.head].path != "" && !isRef(a.head) { + if c.held[a.head].path != "" { names = append(names, reader{a, "token {" + a.spelling + "}"}) } } diff --git a/render.go b/render.go index e6f83f7..08da588 100644 --- a/render.go +++ b/render.go @@ -121,7 +121,7 @@ func expand(s *generatorState, t *template, sc renderScope) string { // repeat iteration get their own, since each is its own expansion. A reference // path reads its draw group's memo in sc instead. var hold *drawMemo - if t.compiled.keepsHold { + if len(t.compiled.held) > 0 { hold = &drawMemo{ variant: make(map[string]node, len(t.compiled.held)), value: make(map[string]readValue, len(t.compiled.held)), diff --git a/todo.md b/todo.md index 1236cb0..457c85e 100644 --- a/todo.md +++ b/todo.md @@ -37,10 +37,6 @@ on 2026-09-29 a fifth time (Navigation 6.9, Locality 5.2, Shape 6.1, Self-suffic This round, in order: -- Split `formatOps.held` into the names an expansion holds and the reference paths a - render's draws hold, deleting `keepsHold` and `heldCheck`'s skip of a reference path: - one map carries both, told apart by `isRef` and `firstReach.path == ""`, and six seats - hunted for which fence owns which. - Give `surveyAt`'s whole read one field, its table and pins together, rename `alternatives` for what it answers, two reads that never render together, and say at `check` why a level landing on a row may sit beside a path into it: five seats held