From ecb90f828f13721593d656a5314491265b5f5996 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Mon, 28 Sep 2026 03:09:30 +0200 Subject: [PATCH] Correct the comments and decision around link-time compilation --- docs/decisions.md | 8 ++++---- node.go | 6 +++--- reference.go | 15 +++++---------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/docs/decisions.md b/docs/decisions.md index bbb1731..c1d176e 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -123,10 +123,10 @@ wording improves in a minor. ## Every format is fenced at link, and its errors name its path -2026-09-28, larv-review; approval pending. Goal 2: every format compiles in one phase, -at link, since one holding a reference can compile only once bound, so no check reads -compiled ops a format lacks yet. Its fences name the category path as every link error -does, a cell's with its line. Valid while compilation needs the bound references. +2026-09-28, larv-review; approval pending. Goal 2. Every format compiles once, at +link: one holding a reference compiles only once bound, and compiling all there +leaves no check reading ops a format lacks yet. A link error names the category +path, a table cell's with its line. Valid while compilation needs the bound references. ## Raising the lowest supported Go is a major diff --git a/node.go b/node.go index a0cc34c..bb0975c 100644 --- a/node.go +++ b/node.go @@ -55,11 +55,11 @@ type template struct { isRecord bool // compiled at the top without a repeat, so its fields are record columns table *table // the table whose format this is, whose columns are the fields - // Filled by `checkCells`, after the cell's own format has compiled: + // Filled by `checkCells`: cellOf *table // the table whose cell this is cellRow int // the row the cell sits in - // Filled by `template.compileFormat`, from `template.format` and `template.refs`: + // Filled by `template.compileFormat` at link, from `template.tokens` and `template.refs`: ops []op // what expand walks grow int // minimum output size, to size the render buffer // bound maps each field the format addresses by dotted path to one path token @@ -209,7 +209,7 @@ func compileString(s string) (node, error) { return &template{format: s, tokens: toks, repeat: 1, fromString: true}, nil } -// fixedText is the whole output of a format holding no token, which every render is. +// fixedText is one render's output when the format holds no token; repeat is the caller's. func (t *template) fixedText() (string, bool) { switch { case len(t.tokens) == 0: diff --git a/reference.go b/reference.go index d5cf94e..fceff0f 100644 --- a/reference.go +++ b/reference.go @@ -67,14 +67,10 @@ func refSegments(name string, folder []string) ([]string, error) { return append(append([]string{}, base...), segs...), nil } -// linkRefs resolves every reference in the assembled tree and compiles every format. -// The head of the path — up to the category it names — is bound into the referring -// template's refHeads under its root path, and the rest reads into it the way a -// sibling path does, so a reference is held like a sibling and two spellings of one -// target are one draw. It runs once, after all data is merged, so a reference sees -// the final (override-resolved) tree. A path that is unknown, names a folder, or -// reads a field not every variant carries fails here, keeping a bad reference a -// New-time error, never a random render-time one. +// linkRefs binds every reference and compiles every format, once all data is merged, +// so a reference sees the override-resolved tree. A reference's head binds into +// refHeads under its root path and its tail reads like a sibling path, so two +// spellings of one target are one draw. func linkRefs(root map[string]node) error { return eachTemplate(root, func(folder []string, path string, t *template) error { category := strings.Join(strings.Split(path, ".")[:len(folder)+1], ".") @@ -83,7 +79,6 @@ func linkRefs(root map[string]node) error { }) } -// linkTemplateRefs binds one template's references against root, then compiles its format. func linkTemplateRefs(folder []string, path, category string, t *template, root map[string]node) error { if t.cellOf != nil { path = fmt.Sprintf("%s, line %d", path, t.cellRow+2) @@ -100,7 +95,7 @@ func linkTemplateRefs(folder []string, path, category string, t *template, root return nil } -// bindRefs refuses a reference naming the category t sits in. +// bindRefs fills refs and refHeads, refusing a reference to t's own category: // docs/decisions.md#a-category-never-references-itself-and-a-records-fences-run-at-load func (t *template) bindRefs(folder []string, path, category string, names []string, root map[string]node) error { t.refs = make(map[string]refBinding, len(names))