Answer prose round 1: the keep rule names what is kept and who decides, headSpans says what it counts, and compileStep and config.load stop restating

This commit is contained in:
2026-10-09 11:19:40 +02:00
committed by Lillem4n
parent 2bd04b528a
commit 8989cae9d9
5 changed files with 11 additions and 11 deletions
+1 -1
View File
@@ -990,7 +990,7 @@ name.go names: {x as n} bindings, the scopes they live in, the reads the
namefence.go the load fences over names namefence.go the load fences over names
pick.go a render's named picks: each level's pick key, the frame each name scope renders in, the memo a pick keeps, and the reads kept under it pick.go a render's named picks: each level's pick key, the frame each name scope renders in, the memo a pick keeps, and the reads kept under it
env.go renderEnv: what a render reads names and rows through, the stack of frames it renders in, and the frames a read opens and finds env.go renderEnv: what a render reads names and rows through, the stack of frames it renders in, and the frames a read opens and finds
path.go the dotted-path walks: the paths List advertises, the sub-paths every variant of a choice carries, proving a path reaches a node, and drawing it path.go the dotted-path walks: the paths List advertises, the sub-paths every variant of a choice carries, proving a path reaches a node, and drawing the path
render.go Fake, the recursive renderer (choices, format strings, expansions) and the reads its tokens make render.go Fake, the recursive renderer (choices, format strings, expansions) and the reads its tokens make
record.go records: Record, the JSON/CSV/SQL serializers, and their entry points record.go records: Record, the JSON/CSV/SQL serializers, and their entry points
struct.go structs: FakeStruct, fake tags as one record's columns, and a field's Go type as its column's datatype struct.go structs: FakeStruct, fake tags as one record's columns, and a field's Go type as its column's datatype
+1 -1
View File
@@ -27,9 +27,9 @@ package fejkdata
// - named pick — the draw a token such as {/person as p} binds to a name, drawn // - named pick — the draw a token such as {/person as p} binds to a name, drawn
// on its first read and kept while its scope renders: `nameBinding`, // on its first read and kept while its scope renders: `nameBinding`,
// `namedPick`, `pickFrame`. // `namedPick`, `pickFrame`.
// - level, pick key, addressed key — `pickKey`.
// - memo — what a named pick keeps its draws in, the variant drawn at each level // - memo — what a named pick keeps its draws in, the variant drawn at each level
// and the value each path read: `drawMemo`. // and the value each path read: `drawMemo`.
// - level, pick key, addressed key — `pickKey`.
// - pin — fixing which row of a table one path, or one named pick, uses: // - pin — fixing which row of a table one path, or one named pick, uses:
// `pinSet`, `namedPick.pins`, `table.followStep`. // `pinSet`, `namedPick.pins`, `table.followStep`.
// - link — a table's tie to its parent table, each row to its parent row: // - link — a table's tie to its parent table, each row to its parent row:
+1 -2
View File
@@ -89,8 +89,7 @@ func New(opts ...Option) (*Generator, error) {
return &Generator{drawState: drawstate.New(seed), root: root}, nil return &Generator{drawState: drawstate.New(seed), root: root}, nil
} }
// load builds the tree New starts from: with only the shipped set, every category unloaded; else // load builds the tree New starts from. docs/decisions.md#with-only-the-shipped-set-a-category-loads-on-the-first-call-reaching-it-beside-a---data-path-every-category-loads-in-new
// every source loaded and merged. docs/decisions.md#with-only-the-shipped-set-a-category-loads-on-the-first-call-reaching-it-beside-a---data-path-every-category-loads-in-new
func (c config) load() (folder, error) { func (c config) load() (folder, error) {
if c.shipped && len(c.sources) == 0 { if c.shipped && len(c.sources) == 0 {
return unloadedTree(), nil return unloadedTree(), nil
+3 -3
View File
@@ -69,8 +69,8 @@ const (
// compiledPath walks a path and proves it reaches a node whichever way the draws go: every // compiledPath walks a path and proves it reaches a node whichever way the draws go: every
// variant of a choice carries the rest of it, and is walked, a selector names a row inside the // variant of a choice carries the rest of it, and is walked, a selector names a row inside the
// rows selected before it, and no level read carries a repeat. Once run, it holds the steps a // rows selected before it, and no level read carries a repeat. Once run, it holds the steps a
// draw takes, and every leaf the path may render. Its errors spell a level as head, then the // draw takes, and every leaf the path may render. headSpans is how many of tail's first segments
// segments of tail after the first headSpans, which head already spells. // head stands for. An error names a level as head, then tail's segments after those, up to that level.
type compiledPath struct { type compiledPath struct {
pins pinSet pins pinSet
head string head string
@@ -115,7 +115,7 @@ func (p pathPos) more() bool { return len(p.tail) > 0 || p.fromRow }
// compileStep takes the first step of at.tail from at.n, which must not be a choice, moves at past // compileStep takes the first step of at.tail from at.n, which must not be a choice, moves at past
// it, and appends the step to steps: a field, or the route through a table. whole is the full // it, and appends the step to steps: a field, or the route through a table. whole is the full
// path; an error spells a level of it as head, then the segments after the first headSpans. // path; head and headSpans spell an error's level, as in compiledPath.
func compileStep(at *pathPos, whole []string, head string, headSpans int, steps []pathStep, pins *pinSet) ([]pathStep, error) { func compileStep(at *pathPos, whole []string, head string, headSpans int, steps []pathStep, pins *pinSet) ([]pathStep, error) {
i := len(whole) - len(at.tail) i := len(whole) - len(at.tail)
switch x := at.n.(type) { switch x := at.n.(type) {
+5 -4
View File
@@ -14,12 +14,13 @@ import (
// fresh read, the template it sits in. Load gives each read one key per level, in levelKeys. // fresh read, the template it sits in. Load gives each read one key per level, in levelKeys.
// //
// A name's addressed keys are the keys some read of it lands on or passes, from the level its // A name's addressed keys are the keys some read of it lands on or passes, from the level its
// binding lands on onward; load gathers them in addressedKeys. A fresh read rendering in a pick // binding lands on onward; load gathers them in addressedKeys. When a template a pick renders
// is kept in it only where its first level, moved under the key of what renders, is addressed: // reads a field, such as the {first} that {p} renders, the pick keeps that read's value only if
// keptInPick, then readUnder. // the read's first-level key, put under the rendering template's key, is one of the name's
// addressed keys. keptInPick decides this, and readUnder reads it.
// //
// In data/geo/SE/address.json, {.locality as l} binds l, and {l.street.name} passes the levels // In data/geo/SE/address.json, {.locality as l} binds l, and {l.street.name} passes the levels
// "", "street" and "street.name", the last its key. With {l.name} and {l.postal-code.code}, // "", "street" and "street.name", the last of which is its key. With {l.name} and {l.postal-code.code},
// l's addressed keys are those three, "name", "postal-code" and "postal-code.code". Where p // l's addressed keys are those three, "name", "postal-code" and "postal-code.code". Where p
// binds a category whose format reads {first}, and both {p} and {p.first} are read, the {first} // binds a category whose format reads {first}, and both {p} and {p.first} are read, the {first}
// that {p} renders has the key "first" under {p}'s key "". {p.first} addresses "first", so both // that {p} renders has the key "first" under {p}'s key "". {p.first} addresses "first", so both