Hold only an expansion's names in formatOps.held, deleting keepsHold
This commit is contained in:
@@ -25,7 +25,8 @@ package fejkdata
|
|||||||
// iteration of a `template.repeat`.
|
// iteration of a `template.repeat`.
|
||||||
// - hold — keeping one draw of a name, so every route to it reads that value:
|
// - 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
|
// 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
|
// - 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`.
|
// each level and the value each path read: `drawMemo`, `readMemo`.
|
||||||
// - draw group — reference draws kept apart inside one render:
|
// - draw group — reference draws kept apart inside one render:
|
||||||
|
|||||||
@@ -381,12 +381,12 @@ type op struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// formatOps is a compiled format: its ops, the size of its literal text, and the
|
// 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 {
|
type formatOps struct {
|
||||||
ops []op
|
ops []op
|
||||||
grow int
|
grow int
|
||||||
held map[string]firstReach
|
held map[string]firstReach
|
||||||
keepsHold bool // some held name is not a reference path, so expand makes a hold
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// firstReach is how a format first reaches a held name: the reader holding it, for
|
// 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) {
|
func (c *formatOps) holdName(a arm, label string) {
|
||||||
|
if isRef(a.head) && len(a.tail) > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
if c.held == nil {
|
if c.held == nil {
|
||||||
c.held = map[string]firstReach{}
|
c.held = map[string]firstReach{}
|
||||||
}
|
}
|
||||||
if !isRef(a.head) || len(a.tail) == 0 {
|
|
||||||
c.keepsHold = true
|
|
||||||
}
|
|
||||||
h, seen := c.held[a.head]
|
h, seen := c.held[a.head]
|
||||||
if !seen {
|
if !seen {
|
||||||
h.holder = label
|
h.holder = label
|
||||||
|
|||||||
+2
-5
@@ -17,9 +17,6 @@ func heldCheck(path string, n node) error {
|
|||||||
}
|
}
|
||||||
readers := pathHeadReaders(t.compiled)
|
readers := pathHeadReaders(t.compiled)
|
||||||
for _, name := range heldNames(t) {
|
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 {
|
if err := checkNameHeld(t, name, readers); err != nil {
|
||||||
return fmt.Errorf("%s: %w", path, err)
|
return fmt.Errorf("%s: %w", path, err)
|
||||||
}
|
}
|
||||||
@@ -201,12 +198,12 @@ func pathHeadReaders(c formatOps) []reader {
|
|||||||
var names []reader
|
var names []reader
|
||||||
for _, o := range c.ops {
|
for _, o := range c.ops {
|
||||||
for _, a := range o.operands {
|
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)})
|
names = append(names, reader{a, fmt.Sprintf("%s operand %q", o.fn, a.spelling)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, a := range o.arms {
|
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 + "}"})
|
names = append(names, reader{a, "token {" + a.spelling + "}"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
// repeat iteration get their own, since each is its own expansion. A reference
|
||||||
// path reads its draw group's memo in sc instead.
|
// path reads its draw group's memo in sc instead.
|
||||||
var hold *drawMemo
|
var hold *drawMemo
|
||||||
if t.compiled.keepsHold {
|
if len(t.compiled.held) > 0 {
|
||||||
hold = &drawMemo{
|
hold = &drawMemo{
|
||||||
variant: make(map[string]node, len(t.compiled.held)),
|
variant: make(map[string]node, len(t.compiled.held)),
|
||||||
value: make(map[string]readValue, len(t.compiled.held)),
|
value: make(map[string]readValue, len(t.compiled.held)),
|
||||||
|
|||||||
@@ -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:
|
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
|
- 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
|
`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
|
`check` why a level landing on a row may sit beside a path into it: five seats held
|
||||||
|
|||||||
Reference in New Issue
Block a user