From 2e553d29f7b3f0024430d4dac3de3b813c06e493 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Tue, 29 Sep 2026 09:20:20 +0200 Subject: [PATCH] Record each selector's table and spelling in pathProbe.readRow --- path.go | 30 ++++++++++++++++++++---------- readsurvey.go | 17 +++-------------- render.go | 2 +- todo.md | 3 --- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/path.go b/path.go index 9d2d791..cf62df0 100644 --- a/path.go +++ b/path.go @@ -289,10 +289,13 @@ func (w *pathCover) walk(n node, tail []string) (node, error) { // pathProbe proves a path resolves without drawing. Where pathCheck walks every // variant of a choice, it walks the first, which carriedByAll lets stand for all; at a -// table it selects as pathCheck does and marks in drawn the tables a draw would pin. +// table it selects as pathCheck does. Probing an arm, it records what the read takes: +// in drawn the tables a draw would pin, and in sels each selector's table and spelling. type pathProbe struct { pins pinSet + a *arm drawn map[*table]bool + sels []tableSel } func (w *pathProbe) walk(n node, tail []string) (node, error) { @@ -310,7 +313,7 @@ func (w *pathProbe) walk(n node, tail []string) (node, error) { if r, err = x.route(tail, descended); err != nil { return nil, err } - if err := w.readRow(x, r); err != nil { + if err := w.readRow(x, tail, r); err != nil { return nil, err } n, tail, descended = r.next, r.rest, r.descends @@ -324,15 +327,22 @@ func (w *pathProbe) walk(n node, tail []string) (node, error) { return n, nil } -func (w *pathProbe) readRow(t *table, r tableRoute) error { - if r.sel != "" { +func (w *pathProbe) readRow(t *table, tail []string, r tableRoute) error { + switch { + case r.sel != "": + if w.a != nil { + walked := len(w.a.tail) - len(tail) + 1 + written := w.a.spelling[:len(w.a.spelling)-len(joinSegments(w.a.tail))] + w.sels = append(w.sels, tableSel{t, written + joinSegments(w.a.tail[:walked])}) + } return w.pins.selectRow(t, r.sel) - } - if !r.draw { - return nil - } - for stop := w.pins.nearestPinned(t); t != stop; t = t.parentT { - w.drawn[t] = true + case r.draw && w.a != nil: + if w.drawn == nil { + w.drawn = map[*table]bool{} + } + for stop := w.pins.nearestPinned(t); t != stop; t = t.parentT { + w.drawn[t] = true + } } return nil } diff --git a/readsurvey.go b/readsurvey.go index 9490a3f..e2e94e6 100644 --- a/readsurvey.go +++ b/readsurvey.go @@ -191,21 +191,10 @@ func tableReadOf(head node, a arm, leaf node) *tableRead { if !isTable { return nil } - probe := &pathProbe{drawn: map[*table]bool{}} + probe := &pathProbe{a: &a} _, _ = probe.walk(t, a.tail) - tr := &tableRead{headTable: t, pins: probe.pins, drawn: probe.drawn} - written := a.spelling[:len(a.spelling)-len(joinSegments(a.tail))] - cur := t - for i, seg := range a.tail { - switch d := cur.descendant(seg); { - case isSelector(seg): - tr.sels = append(tr.sels, tableSel{cur, written + joinSegments(a.tail[:i+1])}) - case d != nil: - cur = d - } - } - _, tr.landsRow = leaf.(*tableRow) - return tr + _, landsRow := leaf.(*tableRow) + return &tableRead{headTable: t, pins: probe.pins, drawn: probe.drawn, sels: probe.sels, landsRow: landsRow} } // selected is the selector in r on t, or on the nearest ancestor of t it selects. diff --git a/render.go b/render.go index efc37dc..a83b9ef 100644 --- a/render.go +++ b/render.go @@ -39,7 +39,7 @@ func (f *Generator) Fake(path string) (string, error) { // selects or draws. func descend(s *session, root node, segments []string, sc renderScope) (node, error) { // docs/decisions.md#a-path-is-walked-once-without-drawing-before-it-is-walked-for-real - if _, err := (&pathProbe{drawn: map[*table]bool{}}).walk(root, segments); err != nil { + if _, err := (&pathProbe{}).walk(root, segments); err != nil { return nil, err } return drawPath(root, segments, "", &pathDraw{s: s, pins: &sc.groupHold().pins}), nil diff --git a/todo.md b/todo.md index 8009fd1..98f9537 100644 --- a/todo.md +++ b/todo.md @@ -28,9 +28,6 @@ ranking `readSurvey.walk` hardest and all seven the unit they would least modify This round, in order: -- Record each selector's table and spelling in `pathProbe.readRow`, and delete - `tableReadOf`'s second walk over the tail: it steps by `descendant` apart from - `route`, so a route that steps up to a parent row credits a selector to the wrong table. - Move the render's read path — `readField`, `readReference`, `readHeld`, `traceRead`, `renderLeaf`, `resolveChoice`, `renderOnce` and `expandAnew` — into `render.go`, and merge what `hold.go` and `holdset.go` keep into one file: both architects followed one read