Spell a reference path as arm.isRefPath, and say where each tail's head is held

This commit is contained in:
2026-09-29 16:24:10 +02:00
committed by Lillem4n
parent dee1e186e3
commit acbc6943b8
3 changed files with 9 additions and 7 deletions
+7 -3
View File
@@ -303,8 +303,8 @@ func checkNoRepeatedArm(body string, names []string) error {
// arm is one alternative of a {a|b} token or one operand, split into the head // arm is one alternative of a {a|b} token or one operand, split into the head
// `template.head` resolves and the tail of a dotted path into it. A non-empty tail // `template.head` resolves and the tail of a dotted path into it. A non-empty tail
// is what makes the arm a held draw: its head is drawn once per expansion (see // makes the arm a held draw: a reference path's for the render, any other for the
// compileOps). // expansion.
type arm struct { type arm struct {
spelling string // as written, for messages spelling string // as written, for messages
head string head string
@@ -314,6 +314,10 @@ type arm struct {
path string // head and tail, the one path every way of writing this read shares path string // head and tail, the one path every way of writing this read shares
} }
func (a arm) isRefPath() bool {
return isRef(a.head) && len(a.tail) > 0
}
// splitArm splits one name into head and tail. refs maps a reference to what // splitArm splits one name into head and tail. refs maps a reference to what
// linkRefs resolved it to; before linking, a reference is whole. // linkRefs resolved it to; before linking, a reference is whole.
func splitArm(name string, refs map[string]refBinding) arm { func splitArm(name string, refs map[string]refBinding) arm {
@@ -397,7 +401,7 @@ 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 { if a.isRefPath() {
return return
} }
if c.held == nil { if c.held == nil {
+1 -1
View File
@@ -156,7 +156,7 @@ func expand(s *generatorState, t *template, sc renderScope) string {
// read one row, either read twice gives one value, and a shown operand is the operand // read one row, either read twice gives one value, and a shown operand is the operand
// computed. Every other name is drawn afresh, so {word} {word} still draws twice. // computed. Every other name is drawn afresh, so {word} {word} still draws twice.
func readField(s *generatorState, t *template, hold *drawMemo, sc renderScope, a arm) readValue { func readField(s *generatorState, t *template, hold *drawMemo, sc renderScope, a arm) readValue {
if isRef(a.head) && len(a.tail) > 0 { if a.isRefPath() {
return readReference(s, t, sc, a) return readReference(s, t, sc, a)
} }
if sc.draws.trace != nil { if sc.draws.trace != nil {
+1 -3
View File
@@ -56,9 +56,7 @@ This round, in order:
which differs from the `pathCheck` type it wraps by word order alone: both architects which differs from the `pathCheck` type it wraps by word order alone: both architects
placed them wrong. placed them wrong.
- Correct the claims readers followed wrong: `IsTemplate`'s doc says an argument holding - Correct the claims readers followed wrong: `IsTemplate`'s doc says an argument holding
a bracket that is not valid JSON errors, where `misc.territory[SE]` is a path; `arm`'s a bracket that is not valid JSON errors, where `misc.territory[SE]` is a path; the README says rows are indexed on the first draw, where `New` builds the key
says a tail's head is drawn once per expansion, where a reference path is held per
render; the README says rows are indexed on the first draw, where `New` builds the key
map; and `loadDir`'s says it builds the tree deterministically, where it reports an map; and `loadDir`'s says it builds the tree deterministically, where it reports an
unnamed rows file in map order. unnamed rows file in map order.
- Delete the comments the panel found restating their code or arranging the file: - Delete the comments the panel found restating their code or arranging the file: