Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -111,5 +111,5 @@ In [docs/decisions.md](docs/decisions.md):
|
||||
- `List` advertises direct descents only
|
||||
- A path draws through its compiled steps
|
||||
- A name lives in the category binding it, or in the repeat binding it, and is drawn on its first read
|
||||
- comprehension floor: every dimension and the overall at 7.0 or above; the change making every `{…}` draw afresh, the moves of the draw state and the grammar, and items 99 to 106 ship with no scoring run, and item 5 scores them
|
||||
- comprehension floor: every dimension and the overall at 7.0 or above; item 5 scores the restructure, which ships unscored: every `{…}` drawing afresh, the moves of the draw state and the grammar, and items 99 to 106
|
||||
- The template engine stays the root package until item 107; the draw state and the grammar sit in `internal/`, and items 99 to 103 move what else stands alone there
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"github.com/larvit/fejkdata/internal/grammar"
|
||||
)
|
||||
|
||||
// evalCalc evaluates an expression over the operand values expand read, so the
|
||||
// evaluator touches neither the rng nor the node tree.
|
||||
// evalCalc evaluates an expression over the operand values expand already read, so it
|
||||
// draws nothing and reads no template node.
|
||||
func evalCalc(n grammar.CalcNode, operands []string) float64 {
|
||||
switch n := n.(type) {
|
||||
case grammar.CalcNum:
|
||||
@@ -209,8 +209,7 @@ func calcPrep(args []string) callFn {
|
||||
}
|
||||
}
|
||||
|
||||
// parsedCalc parses an expression checkCalc accepted. A nil AST would dereference later, with
|
||||
// no message.
|
||||
// parsedCalc parses an expression checkCalc accepted.
|
||||
func parsedCalc(expr string) grammar.Calc {
|
||||
c, err := grammar.ParseCalc(expr)
|
||||
if err != nil {
|
||||
|
||||
+2
-2
@@ -105,11 +105,11 @@ func TestCalcReproducible(t *testing.T) {
|
||||
func TestParsedCallReadsOnlyAnOperandBuiltin(t *testing.T) {
|
||||
for _, format := range []string{"{luhn()}", "{calc()}", "{calc(1 +)}", "{calc(()}"} {
|
||||
if toks, err := grammar.ParseFormat(format); err != nil || len(toks) != 1 || tokenReads(toks[0]) != nil {
|
||||
t.Errorf("tokenReads(%q) = %+v, %v, want one call reading no operand", format, toks, err)
|
||||
t.Errorf("ParseFormat(%q) = %+v, %v, want one call reading no operand", format, toks, err)
|
||||
}
|
||||
}
|
||||
if toks, err := grammar.ParseFormat("{calc(net * qty)}"); err != nil || len(toks) != 1 || len(tokenReads(toks[0])) != 2 {
|
||||
t.Errorf("tokenReads({calc(net * qty)}) = %+v, %v, want both operands", toks, err)
|
||||
t.Errorf("ParseFormat({calc(net * qty)}) = %+v, %v, want both operands", toks, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -825,9 +825,9 @@ category's frames, since the field sits inside it.
|
||||
|
||||
Valid while names are read only inside the category binding them.
|
||||
|
||||
## comprehension floor: every dimension and the overall at 7.0 or above; the change making every `{…}` draw afresh, the moves of the draw state and the grammar, and items 99 to 106 ship with no scoring run, and item 5 scores them
|
||||
## comprehension floor: every dimension and the overall at 7.0 or above; item 5 scores the restructure, which ships unscored: every `{…}` drawing afresh, the moves of the draw state and the grammar, and items 99 to 106
|
||||
|
||||
2026-10-04, Lilleman auf Larv. Serves goal 3. The nine-seat panels in `todo.md`'s git history, 2026-09-22 to 2026-09-30, held the score between 5.2 and 6.1, with Locality lowest at every seat. The hardest units were the draw fences, which the change making every `{…}` draw afresh deleted. The change making every `{…}` draw afresh, the moves of the draw state into `internal/drawstate` and the grammar into `internal/grammar`, and `todo.md` items 99 to 106 delete or move what the earlier chunks of the below-floor round touched, so a scoring run before item 106 merges would score code about to go; the calc change accepting a name as an operand shipped unscored on 2026-10-05 for that reason. The change making every `{…}` draw afresh, the moves of the draw state and the grammar, and items 99 to 106 are the restructure the maintainer approved, which `AGENTS.md`'s comprehension rule lets merge below the floor. No scoring run or panel runs until item 5, which runs the nine-seat panel and larv-review's scoring run. The scoring run writes this entry's first scores. Valid until `todo.md` item 5 runs.
|
||||
2026-10-04, Lilleman auf Larv. Serves goal 3. The nine-seat panels in `todo.md`'s git history, 2026-09-22 to 2026-09-30, held the score between 5.2 and 6.1, with Locality lowest at every seat. The hardest units were the draw fences, which the change making every `{…}` draw afresh deleted. The change making every `{…}` draw afresh, the moves of the draw state into `internal/drawstate` and the grammar into `internal/grammar`, and `todo.md` items 99 to 106 delete or move what the earlier chunks of the below-floor round touched, so a scoring run before item 106 merges would score code about to go; the calc change accepting a name as an operand shipped unscored on 2026-10-05 for that reason. These are the restructure the maintainer approved, which `AGENTS.md`'s comprehension rule lets merge below the floor. No scoring run or panel runs until item 5, which runs the nine-seat panel and larv-review's scoring run. The scoring run writes this entry's first scores. Valid until `todo.md` item 5 runs.
|
||||
|
||||
## The template engine stays the root package until item 107; the draw state and the grammar sit in `internal/`, and items 99 to 103 move what else stands alone there
|
||||
|
||||
@@ -836,9 +836,9 @@ engine's types, `template`, `table`, `arm`, `op` and `nameBinding`, bound in one
|
||||
because several passes each write part of the same structs; the template language's
|
||||
recursion reads few of those types. Moving the engine before items 101 and 104 to 106 give
|
||||
each value one writer would spread that knot across packages, behind forwarding calls from
|
||||
every public method. The draw state reads no engine type, so it sits in `internal/drawstate`,
|
||||
behind an import list a test checks, and so does the grammar, in `internal/grammar`.
|
||||
every public method. The draw state and the grammar read no engine type, so they sit in
|
||||
`internal/drawstate` and `internal/grammar`, behind an import list a test checks.
|
||||
`DataType` reads none either. `proven`, what a proof knows of a value, is keyed by
|
||||
`DataType`, so the two move together. The reading of data files, `proven`, the builtins and
|
||||
a table's rows stop reading any engine type once items 99 to 103 remove those reads, and
|
||||
each of those items moves its part and adds it to that list. Valid until `todo.md` item 107 moves the engine.
|
||||
a table's rows stop reading any engine type once items 99 to 103 remove those reads; items
|
||||
99, 100, 102 and 103 each move their part and add it to that list. Valid until `todo.md` item 107 moves the engine.
|
||||
|
||||
@@ -304,8 +304,6 @@ func pathArm(name, head, writtenHead string, segs []string) arm {
|
||||
return arm{spelling: name, head: head, writtenHead: writtenHead, tail: segs, levels: levels, path: head + "." + strings.Join(segs, ".")}
|
||||
}
|
||||
|
||||
// checkSegments refuses an empty segment in a path, which a field really named "" would
|
||||
// otherwise resolve, so a typo would read as a path that worked.
|
||||
func checkSegments(a arm) error {
|
||||
if len(a.tail) == 0 {
|
||||
return nil
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SplitPath splits a dotted path into segments, a selector — [key or name] after a
|
||||
// table's name — becoming a segment of its own, brackets kept, and so does each "..". A
|
||||
// dot inside a selector is part of the key or name.
|
||||
// SplitPath splits a dotted path into segments. A selector, [key or name] after a table's
|
||||
// name, is a segment of its own with its brackets kept, and so is each "..". A dot inside a
|
||||
// selector belongs to the key or name.
|
||||
func SplitPath(path string) ([]string, error) {
|
||||
segs := make([]string, 0, strings.Count(path, ".")+2*strings.Count(path, "[")+1)
|
||||
start, open := 0, -1
|
||||
@@ -162,8 +162,7 @@ func JoinSegments(segs []string) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// CheckSegments refuses an unfinished path: "a." and "a...b" each have a segment naming
|
||||
// nothing.
|
||||
// CheckSegments refuses a path with an empty segment, such as "a." or "a...b".
|
||||
func CheckSegments(segs []string) error {
|
||||
if slices.Contains(segs, "") {
|
||||
return fmt.Errorf("path has an empty segment")
|
||||
|
||||
@@ -87,8 +87,9 @@ func (t *table) route(tail []string, descended bool) (tableRoute, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// stepUp proves a ".." after a row of t can step up: t has a parent, rest names it, and no
|
||||
// selector follows, since a row selected below the parent row could lie outside it.
|
||||
// stepUp proves a ".." after a row of t can step up: t has a parent, rest has no empty
|
||||
// segment and names it, and no selector follows, since a row selected below the parent row
|
||||
// could lie outside it.
|
||||
func (t *table) stepUp(rest []string) error {
|
||||
if t.parentT == nil {
|
||||
return fmt.Errorf(`%s has no parent table for ".." to step up to`, t.segment)
|
||||
|
||||
@@ -246,7 +246,7 @@ Asked of the maintainer by the product-owner pass of the chunk that made every `
|
||||
|
||||
### 5. Run the nine-seat comprehension panel and larv-review's scoring run once items 99 to 106 have restructured the code, and file what the panel names.
|
||||
|
||||
Until a panel scores 7.0 or above, only items 99 to 106 and the exceptions in `AGENTS.md`'s comprehension rule merge. The decision "comprehension floor: every dimension and the overall at 7.0 or above; the change making every `{…}` draw afresh, the moves of the draw state and the grammar, and items 99 to 106 ship with no scoring run, and item 5 scores them" suspends every scoring run and panel until this item runs.
|
||||
Until a panel scores 7.0 or above, only items 99 to 106 and the exceptions in `AGENTS.md`'s comprehension rule merge. The decision "comprehension floor: every dimension and the overall at 7.0 or above; item 5 scores the restructure, which ships unscored: every `{…}` drawing afresh, the moves of the draw state and the grammar, and items 99 to 106" suspends every scoring run and panel until this item runs.
|
||||
|
||||
### 91. Accept a path through a name as a `calc` operand, so `{/misc.coordinate as c}{c}: {calc(c.lat * 60)}` computes from the coordinate `{c}` prints.
|
||||
|
||||
@@ -395,7 +395,7 @@ Require the path step to reach a sibling category.
|
||||
|
||||
### 110. Refuse an empty segment in a path `Fake`, `FakeRecord` and the CLI take, as a reference does: `sv_SE.person.` reports `path has an empty segment`.
|
||||
|
||||
Today `fejkdata 'sv_SE.person.'` reports `no field ""`, while `{/sv_SE.person.}` reports `path has an empty segment`. `grammar.CheckSegments` is the check a reference, a sibling path and a step up `..` run.
|
||||
Today `fejkdata 'sv_SE.person.'` reports `no field ""`, while `{/sv_SE.person.}` reports `path has an empty segment`. `grammar.CheckSegments` is the check a reference, a sibling path and a step up `..` run. The new refusal owes a `CHANGELOG.md` entry.
|
||||
|
||||
### 107. Move the template engine into `internal/`, leaving the root the public API and its options.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user