Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33

Open
lilleman wants to merge 966 commits from worktree-todo-relative-dates-exact-counts into main
2 changed files with 24 additions and 24 deletions
Showing only changes of commit 186443f883 - Show all commits
+2 -2
View File
@@ -40,8 +40,8 @@ type Generator struct {
structs map[reflect.Type]structResult structs map[reflect.Type]structResult
} }
// generatorState is one generator's state across its renders: the seeded rng plus the {seq()} // generatorState is one generator's draw state, kept across its renders: the seeded rng plus
// counters. // the {seq()} counters.
type generatorState struct { type generatorState struct {
*rand.Rand *rand.Rand
counters map[string]uint64 counters map[string]uint64
+22 -22
View File
@@ -13,17 +13,17 @@ type scanUnit struct {
body string body string
} }
// eachToken scans a format string once and calls fn for each unit, the single // eachScanUnit scans a format string once and calls fn for each unit, the single
// source of truth for how braces are read: "{{" and "}}" are literal braces, a "{" // source of truth for how braces are read: "{{" and "}}" are literal braces, a "{"
// opens a token that must reach its "}", and a lone "}" is an error. // opens a token that must reach its "}", and a lone "}" is an error.
func eachToken(format string, fn func(scanUnit) error) error { func eachScanUnit(format string, fn func(scanUnit) error) error {
rs := []rune(format) rs := []rune(format)
for i := 0; i < len(rs); i++ { for i := 0; i < len(rs); i++ {
var t scanUnit var u scanUnit
switch c := rs[i]; c { switch c := rs[i]; c {
case '{': case '{':
if i+1 < len(rs) && rs[i+1] == '{' { if i+1 < len(rs) && rs[i+1] == '{' {
t.char = '{' u.char = '{'
i++ i++
break break
} }
@@ -37,19 +37,19 @@ func eachToken(format string, fn func(scanUnit) error) error {
if end >= len(rs) { if end >= len(rs) {
return fmt.Errorf("unterminated '{' in %q", format) return fmt.Errorf("unterminated '{' in %q", format)
} }
t.isToken, t.body = true, string(rs[i+1:end]) u.isToken, u.body = true, string(rs[i+1:end])
i = end i = end
case '}': case '}':
if i+1 < len(rs) && rs[i+1] == '}' { if i+1 < len(rs) && rs[i+1] == '}' {
t.char = '}' u.char = '}'
i++ i++
break break
} }
return fmt.Errorf("lone '}' in %q; a literal brace is written }}", format) return fmt.Errorf("lone '}' in %q; a literal brace is written }}", format)
default: default:
t.char = c u.char = c
} }
if err := fn(t); err != nil { if err := fn(u); err != nil {
return err return err
} }
} }
@@ -85,21 +85,21 @@ func parseFormat(format string) ([]formatToken, error) {
lit.Reset() lit.Reset()
} }
} }
err := eachToken(format, func(t scanUnit) error { err := eachScanUnit(format, func(u scanUnit) error {
if !t.isToken { if !u.isToken {
lit.WriteRune(t.char) lit.WriteRune(u.char)
return nil return nil
} }
flush() flush()
if indexOutside(t.body, '(') < 0 { if indexOutside(u.body, '(') < 0 {
toks = append(toks, formatToken{kind: nameRead, body: t.body, names: splitOutside(t.body, '|')}) toks = append(toks, formatToken{kind: nameRead, body: u.body, names: splitOutside(u.body, '|')})
return nil return nil
} }
name, args, ok := funcCall(t.body) name, args, ok := funcCall(u.body)
if !ok { if !ok {
return fmt.Errorf("malformed function token {%s}", t.body) return fmt.Errorf("malformed function token {%s}", u.body)
} }
toks = append(toks, formatToken{kind: builtinCall, body: t.body, fn: name, args: args, names: builtinOperands(name, args)}) toks = append(toks, formatToken{kind: builtinCall, body: u.body, fn: name, args: args, names: builtinOperands(name, args)})
return nil return nil
}) })
if err != nil { if err != nil {
@@ -110,12 +110,12 @@ func parseFormat(format string) ([]formatToken, error) {
} }
// builtin is a format-string function invoked as {name(args)}. It receives the // builtin is a format-string function invoked as {name(args)}. It receives the
// generatorState (its rng, and the {seq()} counters), the output emitted so far in the // generatorState, the output emitted so far in the current expansion (for derivations
// current expansion (for derivations such as a checksum over preceding digits), and // such as a checksum over preceding digits), and the values of the operands it named
// the values of the operands it named (calc and the transforms name them). All must // (calc and the transforms name them). All must stay pure over (rng, emitted, args) so
// stay pure over (rng, emitted, args) so seeded output is reproducible; seq advances // seeded output is reproducible; seq advances per-generator counter state, which is
// per-generator counter state, which is itself deterministic. arity is the exact arg // itself deterministic. arity is the exact arg count, or -1 for variadic (then
// count, or -1 for variadic (then checkArgs does all the validation). // checkArgs does all the validation).
type builtin struct { type builtin struct {
arity int arity int
// prep parses validated args once, at compile time, into the closure expand calls. // prep parses validated args once, at compile time, into the closure expand calls.