From c55c75a29e3bec0960a3ef3b2b39578f543c29d0 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Fri, 25 Sep 2026 19:16:57 +0200 Subject: [PATCH] Give dir, path, structs and r one meaning each, and name the table option indexes keyIndex through parentIndex --- data.go | 20 ++++++------- doc_test.go | 2 +- fejkdata.go | 4 +-- format.go | 12 ++++---- holdfence.go | 4 +-- shape_test.go | 2 +- struct.go | 14 ++++----- table.go | 80 +++++++++++++++++++++++++-------------------------- 8 files changed, 69 insertions(+), 69 deletions(-) diff --git a/data.go b/data.go index 3989539..3906661 100644 --- a/data.go +++ b/data.go @@ -13,11 +13,11 @@ import ( // label prefixes file names in errors; onDisk marks path as a directory that must // exist. type dataSource struct { - fsys fs.FS - label string - onDisk bool - path string - dir string + fsys fs.FS + label string + onDisk bool + diskPath string + baseDir string } func (s dataSource) labelled(p string) string { @@ -38,18 +38,18 @@ func loadData(sources []dataSource) (map[string]node, error) { root := map[string]node{} for _, src := range sources { if src.onDisk { - if src.path == "" { + if src.diskPath == "" { return nil, fmt.Errorf("a data path is empty") } - info, err := os.Stat(src.path) + info, err := os.Stat(src.diskPath) if err != nil { - return nil, fmt.Errorf("data path %s: %w", src.path, err) + return nil, fmt.Errorf("data path %s: %w", src.diskPath, err) } if !info.IsDir() { - return nil, fmt.Errorf("%s is not a directory", src.path) + return nil, fmt.Errorf("%s is not a directory", src.diskPath) } } - dir := src.dir + dir := src.baseDir if dir == "" { dir = "." } diff --git a/doc_test.go b/doc_test.go index c805159..b5d228d 100644 --- a/doc_test.go +++ b/doc_test.go @@ -95,7 +95,7 @@ func vocabulary(t *testing.T, files []*ast.File) string { } // declaredSymbols is every name the package declares at the top level, a method and -// a struct field keyed under its type: pinSet.pin, tableRead.whole. +// a struct field keyed under its type: pinSet.pin, tableRead.landsWhole. func declaredSymbols(files []*ast.File) map[string]bool { names := declaredFuncs(files) for _, f := range files { diff --git a/fejkdata.go b/fejkdata.go index ea89e72..d8bb4cc 100644 --- a/fejkdata.go +++ b/fejkdata.go @@ -72,7 +72,7 @@ func WithSeed(seed uint64) Option { // layer several; the last wins a name clash. func WithDataPath(dir string) Option { return func(c *config) { - c.sources = append(c.sources, dataSource{fsys: os.DirFS(dir), label: dir, onDisk: true, path: dir}) + c.sources = append(c.sources, dataSource{fsys: os.DirFS(dir), label: dir, onDisk: true, diskPath: dir}) } } @@ -99,7 +99,7 @@ func New(opts ...Option) (*Generator, error) { } var sources []dataSource if c.shipped { - sources = append(sources, dataSource{fsys: shippedFS, dir: "data"}) + sources = append(sources, dataSource{fsys: shippedFS, baseDir: "data"}) } sources = append(sources, c.sources...) if len(sources) == 0 { diff --git a/format.go b/format.go index fd3635a..1fac5ad 100644 --- a/format.go +++ b/format.go @@ -9,7 +9,7 @@ import ( // {…} token. type ftoken struct { kind byte // 'l' literal rune, 't' token body - r rune + char rune body string } @@ -24,7 +24,7 @@ func eachToken(format string, fn func(ftoken) error) error { switch c := rs[i]; c { case '{': if i+1 < len(rs) && rs[i+1] == '{' { - t.kind, t.r = 'l', '{' + t.kind, t.char = 'l', '{' i++ break } @@ -42,13 +42,13 @@ func eachToken(format string, fn func(ftoken) error) error { i = end case '}': if i+1 < len(rs) && rs[i+1] == '}' { - t.kind, t.r = 'l', '}' + t.kind, t.char = 'l', '}' i++ break } return fmt.Errorf("lone '}' in %q; a literal brace is written }}", format) default: - t.kind, t.r = 'l', c + t.kind, t.char = 'l', c } if err := fn(t); err != nil { return err @@ -81,7 +81,7 @@ func parseFormat(format string) ([]formatToken, error) { } err := eachToken(format, func(t ftoken) error { if t.kind == 'l' { - lit.WriteRune(t.r) + lit.WriteRune(t.char) return nil } flush() @@ -301,7 +301,7 @@ type arm struct { key string tail []string levels []string // the key at each level the tail passes through, the head's first - path string // key and tail, the one spelling every way of writing this read shares + path string // key and tail, the one path every way of writing this read shares } // splitArm splits one name into key and tail. refs maps a reference to what diff --git a/holdfence.go b/holdfence.go index c547cde..b6dea2f 100644 --- a/holdfence.go +++ b/holdfence.go @@ -188,8 +188,8 @@ func checkNoOverlap(ops []op, bound map[string]string) error { return nil } -// reader is one way a format reaches a bound field: as written, by its one -// spelling, and how to name it. +// reader is one way a format reaches a bound field: as written, by its path, +// and how to name it. type reader struct{ spelling, path, label string } // boundReaders lists every way a format reaches a bound sibling field, in the order the diff --git a/shape_test.go b/shape_test.go index aae7dbd..9747da2 100644 --- a/shape_test.go +++ b/shape_test.go @@ -77,7 +77,7 @@ func tableFacts(t *table) string { for _, o := range []struct { name string col int - }{{"key", t.keyCol}, {"name", t.nameCol}, {"weight", t.weightCol}, {"parent", t.parentCol}} { + }{{"key", t.keyIndex}, {"name", t.nameIndex}, {"weight", t.weightIndex}, {"parent", t.parentIndex}} { if o.col >= 0 { b.WriteString("\t" + o.name + " " + t.header[o.col]) } diff --git a/struct.go b/struct.go index 959fc07..66bfd61 100644 --- a/struct.go +++ b/struct.go @@ -49,7 +49,7 @@ func (f *Generator) structShapeOf(t reflect.Type) (*structShape, error) { if label == "" { label = "struct" } - sc := &structCompile{categories: f.categories, visiting: map[reflect.Type]bool{}, structs: maxStructs} + sc := &structCompile{categories: f.categories, visiting: map[reflect.Type]bool{}, structsLeft: maxStructs} shape, err := sc.compileShape(t, label) if err == nil && shape.empty() { err = fmt.Errorf("%s has no fake tags, so nothing to fill", t) @@ -82,9 +82,9 @@ func (s *structShape) empty() bool { return s.record == nil && len(s.nested) == // loaded tree, the types compiling or embedded above, so a pointer back to one is left alone // rather than filled without end, and how many more structs it may walk. type structCompile struct { - categories map[string]node - visiting map[reflect.Type]bool - structs int + categories map[string]node + visiting map[reflect.Type]bool + structsLeft int } // structFields gathers what one struct type fills: its tagged fields, those its embedded @@ -117,7 +117,7 @@ func (sc *structCompile) compileShape(t reflect.Type, label string) (*structShap } func (sc *structCompile) spend(label string) error { - if sc.structs--; sc.structs >= 0 { + if sc.structsLeft--; sc.structsLeft >= 0 { return nil } return fmt.Errorf(`%s: the struct fields reach more than %d structs; leave a struct field unfilled with fake:"-"`, label, maxStructs) @@ -252,13 +252,13 @@ func checkTaggedType(sf reflect.StructField) error { // compileRecord compiles the tagged fields of t as one record, and proves each column holds // only what its field's Go type can. -func (s *structShape) compileRecord(root map[string]node, t reflect.Type, label string, tags map[string]any) error { +func (s *structShape) compileRecord(categories map[string]node, t reflect.Type, label string, tags map[string]any) error { tags["format"] = "" n, err := compile(tags) if err != nil { return fmt.Errorf("%s: %w", label, err) } - if err := bindInline(n, label, root, checkRenders); err != nil { + if err := bindInline(n, label, categories, checkRenders); err != nil { return err } record, columns, err := recordOf(n) diff --git a/table.go b/table.go index 981de6f..5502e8d 100644 --- a/table.go +++ b/table.go @@ -23,10 +23,10 @@ type table struct { wholeRow *tableRow // the pinned row rendered by the format cells []string // rows × columns, flat cellTemplates map[int]*template - keyCol int // keyCol through parentCol are -1 where the option is absent - nameCol int - weightCol int - parentCol int + keyIndex int // keyIndex through parentIndex are column indexes, -1 where the option is absent + nameIndex int + weightIndex int + parentIndex int cum []float64 // cumulative weights, nil when uniform byKey map[string]int parentT *table @@ -93,7 +93,7 @@ func compileTable(m map[string]any, category string, files *categoryFiles) (*tab if err != nil { return nil, err } - t := &table{category: category, file: o.rows, keyCol: -1, nameCol: -1, weightCol: -1, parentCol: -1} + t := &table{category: category, file: o.rows, keyIndex: -1, nameIndex: -1, weightIndex: -1, parentIndex: -1} if err := t.parseRows(data); err != nil { return nil, fmt.Errorf("%s: %w", o.rows, err) } @@ -213,7 +213,7 @@ func (t *table) bindOptions(o tableOptionValues) error { for _, opt := range []struct { name, value string into *int - }{{"key", o.keyColumn, &t.keyCol}, {"name", o.nameColumn, &t.nameCol}, {"parent", o.parentColumn, &t.parentCol}, {"weight", o.weightColumn, &t.weightCol}} { + }{{"key", o.keyColumn, &t.keyIndex}, {"name", o.nameColumn, &t.nameIndex}, {"parent", o.parentColumn, &t.parentIndex}, {"weight", o.weightColumn, &t.weightIndex}} { if opt.value == "" { continue } @@ -223,7 +223,7 @@ func (t *table) bindOptions(o tableOptionValues) error { } *opt.into = i } - if t.nameCol >= 0 && t.keyCol < 0 && t.parentCol < 0 { + if t.nameIndex >= 0 && t.keyIndex < 0 && t.parentIndex < 0 { return fmt.Errorf("name selects a row as a key does, and lists the rows it matches by their keys, so it needs a key column, or a parent inside which each name is one row; add key") } if err := t.indexKeys(); err != nil { @@ -237,14 +237,14 @@ func (t *table) bindOptions(o tableOptionValues) error { // proveNamesInsideParent proves a name without a key names one row inside its parent. func (t *table) proveNamesInsideParent() error { - if t.keyCol >= 0 || t.nameCol < 0 { + if t.keyIndex >= 0 || t.nameIndex < 0 { return nil } inside := make(map[string]int, t.rowCount()) for r := 0; r < t.rowCount(); r++ { - k := t.cell(r, t.parentCol) + "\t" + t.cell(r, t.nameCol) + k := t.cell(r, t.parentIndex) + "\t" + t.cell(r, t.nameIndex) if first, dup := inside[k]; dup { - return fmt.Errorf("%s line %d: name %q repeats line %d inside %s %q; a name selects one row inside its parent; drop one, or add a key column", t.file, r+2, t.cell(r, t.nameCol), first+2, t.header[t.parentCol], t.cell(r, t.parentCol)) + return fmt.Errorf("%s line %d: name %q repeats line %d inside %s %q; a name selects one row inside its parent; drop one, or add a key column", t.file, r+2, t.cell(r, t.nameIndex), first+2, t.header[t.parentIndex], t.cell(r, t.parentIndex)) } inside[k] = r } @@ -253,12 +253,12 @@ func (t *table) proveNamesInsideParent() error { // indexKeys proves every key names one row, and keeps the index a link is proved by. func (t *table) indexKeys() error { - if t.keyCol < 0 { + if t.keyIndex < 0 { return nil } t.byKey = make(map[string]int, t.rowCount()) for r := 0; r < t.rowCount(); r++ { - k := t.cell(r, t.keyCol) + k := t.cell(r, t.keyIndex) if k == "" { return fmt.Errorf("%s line %d: the key is empty", t.file, r+2) } @@ -267,8 +267,8 @@ func (t *table) indexKeys() error { } t.byKey[k] = r } - for r := 0; r < t.rowCount() && t.nameCol >= 0; r++ { - if n := t.cell(r, t.nameCol); t.byKey[n] != r { + for r := 0; r < t.rowCount() && t.nameIndex >= 0; r++ { + if n := t.cell(r, t.nameIndex); t.byKey[n] != r { if other, isKey := t.byKey[n]; isKey { return fmt.Errorf("%s line %d: name %q is the key of line %d, which a selector reads first, so the name could never select this row", t.file, r+2, n, other+2) } @@ -279,15 +279,15 @@ func (t *table) indexKeys() error { // sumWeights proves every weight is a positive number and builds the cumulative table. func (t *table) sumWeights() error { - if t.weightCol < 0 { + if t.weightIndex < 0 { return nil } t.cum = make([]float64, t.rowCount()) total := 0.0 for r := range t.cum { - w, err := strconv.ParseFloat(t.cell(r, t.weightCol), 64) + w, err := strconv.ParseFloat(t.cell(r, t.weightIndex), 64) if err != nil || math.IsInf(w, 0) || math.IsNaN(w) || w <= 0 { - return fmt.Errorf("%s line %d: weight %q is not a positive number", t.file, r+2, t.cell(r, t.weightCol)) + return fmt.Errorf("%s line %d: weight %q is not a positive number", t.file, r+2, t.cell(r, t.weightIndex)) } total += w t.cum[r] = total @@ -302,7 +302,7 @@ func (t *table) sumWeights() error { func (t *table) checkCells() error { for i, cell := range t.cells { row, col := i/len(t.header), i%len(t.header) - if (col == t.keyCol || col == t.nameCol) && strings.ContainsAny(cell, inSelector) { + if (col == t.keyIndex || col == t.nameIndex) && strings.ContainsAny(cell, inSelector) { return fmt.Errorf("line %d: %s %q contains %q, which a selector cannot spell", row+2, t.header[col], cell, cell[strings.IndexAny(cell, inSelector):][:1]) } if strings.IndexByte(cell, '{') < 0 && strings.IndexByte(cell, '}') < 0 { @@ -379,7 +379,7 @@ func linkTables(root map[string]node) error { return err } case *table: - if n.parentCol < 0 { + if n.parentIndex < 0 { continue } if err := n.linkParent(path, children); err != nil { @@ -393,24 +393,24 @@ func linkTables(root map[string]node) error { } func (t *table) linkParent(path string, siblings map[string]node) error { - name := t.header[t.parentCol] + name := t.header[t.parentIndex] p, ok := siblings[name].(*table) switch { case siblings[name] == nil: return fmt.Errorf("parent %q names no table beside it", name) case !ok: return fmt.Errorf("parent %q is not a table; a link column reads a table's key", name) - case p.keyCol < 0: + case p.keyIndex < 0: return fmt.Errorf("parent %q has no key column to link to", name) } var ancestors []*table - for q, seen := p, map[*table]bool{t: true}; q != nil; q, _ = siblings[q.header[q.parentCol]].(*table) { + for q, seen := p, map[*table]bool{t: true}; q != nil; q, _ = siblings[q.header[q.parentIndex]].(*table) { if seen[q] { return fmt.Errorf("parent cycle: %s reaches itself through its parents", q.category) } seen[q] = true ancestors = append(ancestors, q) - if q.parentCol < 0 { + if q.parentIndex < 0 { break } } @@ -421,14 +421,14 @@ func (t *table) linkParent(path string, siblings map[string]node) error { } linked := make(map[string]bool, p.rowCount()) for r := 0; r < t.rowCount(); r++ { - k := t.cell(r, t.parentCol) + k := t.cell(r, t.parentIndex) if _, ok := p.byKey[k]; !ok { return fmt.Errorf("%s line %d: %s %q is no key of %s", t.file, r+2, name, k, p.file) } linked[k] = true } for r := 0; r < p.rowCount(); r++ { - if k := p.cell(r, p.keyCol); !linked[k] { + if k := p.cell(r, p.keyIndex); !linked[k] { return fmt.Errorf("%s links no row to %s %q; every %s row needs one, or drop line %d of %s", t.file, name, k, name, r+2, p.file) } } @@ -442,17 +442,17 @@ func (t *table) linkParent(path string, siblings map[string]node) error { func (t *table) indexed() *tableIndex { t.once.Do(func() { - if t.nameCol >= 0 { + if t.nameIndex >= 0 { t.index.byName = make(map[string][]int, t.rowCount()) for r := 0; r < t.rowCount(); r++ { - n := t.cell(r, t.nameCol) + n := t.cell(r, t.nameIndex) t.index.byName[n] = append(t.index.byName[n], r) } } - if t.parentCol >= 0 { + if t.parentIndex >= 0 { t.index.rowsByParent = map[string][]int{} for r := 0; r < t.rowCount(); r++ { - k := t.cell(r, t.parentCol) + k := t.cell(r, t.parentIndex) t.index.rowsByParent[k] = append(t.index.rowsByParent[k], r) } if t.cum != nil { @@ -460,7 +460,7 @@ func (t *table) indexed() *tableIndex { for k, rows := range t.index.rowsByParent { cum, total := make([]float64, len(rows)), 0.0 for i, r := range rows { - w, _ := strconv.ParseFloat(t.cell(r, t.weightCol), 64) // sumWeights proved it + w, _ := strconv.ParseFloat(t.cell(r, t.weightIndex), 64) // sumWeights proved it total += w cum[i] = total } @@ -489,7 +489,7 @@ func pickCum(s *session, cum []float64) int { // drawUnder picks a row among those linked to parent row pr. func (t *table) drawUnder(s *session, pr int) int { ix := t.indexed() - k := t.parentT.cell(pr, t.parentT.keyCol) + k := t.parentT.cell(pr, t.parentT.keyIndex) rows := ix.rowsByParent[k] if ix.childCum == nil { return rows[s.IntN(len(rows))] @@ -536,7 +536,7 @@ func (t *table) descendant(name string) *table { } // parentRow is the row of t's parent that row r links to. -func (t *table) parentRow(r int) int { return t.parentT.byKey[t.cell(r, t.parentCol)] } +func (t *table) parentRow(r int) int { return t.parentT.byKey[t.cell(r, t.parentIndex)] } // descends reports whether a is an ancestor of t. func (t *table) descends(a *table) bool { @@ -561,7 +561,7 @@ func (t *table) under(r int, a *table, pr int) bool { // find is the row a selector names: by key first, then by name, where a name // naming several rows resolves inside the ancestors pinned. func (t *table) find(sel string, pins *pinSet) (int, error) { - if t.keyCol < 0 && t.nameCol < 0 { + if t.keyIndex < 0 && t.nameIndex < 0 { return 0, fmt.Errorf("%s has no key or name column to select a row by", t.path) } if r, ok := t.byKey[sel]; ok { @@ -585,14 +585,14 @@ func (t *table) find(sel string, pins *pinSet) (int, error) { func (t *table) ambiguous(sel string, rows []int) error { spellings := make([]string, len(rows)) for i, r := range rows { - if t.keyCol < 0 { + if t.keyIndex < 0 { spellings[i] = t.selectorSpelling(r) } else { - spellings[i] = t.cell(r, t.keyCol) + spellings[i] = t.cell(r, t.keyIndex) } } listed := strings.Join(spellings, ", ") - if t.keyCol < 0 { + if t.keyIndex < 0 { return fmt.Errorf("%q names %d rows of %s; select it inside its %s, one of %s", sel, len(rows), t.path, t.parentT.path, listed) } inside := "" @@ -606,10 +606,10 @@ func (t *table) ambiguous(sel string, rows []int) error { // by name inside its parent's row. func (t *table) selectorSpelling(r int) string { switch { - case t.keyCol >= 0: - return t.path + "[" + t.cell(r, t.keyCol) + "]" - case t.nameCol >= 0: - return t.parentT.selectorSpelling(t.parentRow(r)) + "." + t.category + "[" + t.cell(r, t.nameCol) + "]" + case t.keyIndex >= 0: + return t.path + "[" + t.cell(r, t.keyIndex) + "]" + case t.nameIndex >= 0: + return t.parentT.selectorSpelling(t.parentRow(r)) + "." + t.category + "[" + t.cell(r, t.nameIndex) + "]" } return fmt.Sprintf("%s line %d", t.file, r+2) }