Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -246,7 +246,7 @@ func pathArm(name, head, writtenHead string, segs []string) arm {
|
|||||||
return arm{spelling: name, head: head, writtenHead: writtenHead, tail: segs, levels: levelKeys(append([]string{head}, segs...), 1)}
|
return arm{spelling: name, head: head, writtenHead: writtenHead, tail: segs, levels: levelKeys(append([]string{head}, segs...), 1)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// levelKeys is the key of each level path passes, the first after its first from segments.
|
// levelKeys keys each prefix of path, from its first from segments to the whole of it.
|
||||||
func levelKeys(path []string, from int) []pickKey {
|
func levelKeys(path []string, from int) []pickKey {
|
||||||
levels := make([]pickKey, len(path)-from+1)
|
levels := make([]pickKey, len(path)-from+1)
|
||||||
for i := range levels {
|
for i := range levels {
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ func nameTargets(ts []linkSite) map[*nameBinding]nameTarget {
|
|||||||
return targets
|
return targets
|
||||||
}
|
}
|
||||||
|
|
||||||
// addressedKeys is every key the reads of each name in ts land on or pass, from the name, with the
|
// addressedKeys is every key the reads of each name in ts land on or pass, from the name's own
|
||||||
// spelling of the first read reaching it.
|
// level, with the spelling of the first read reaching it.
|
||||||
func addressedKeys(ts []linkSite, targets map[*nameBinding]nameTarget) map[*nameBinding]map[pickKey]string {
|
func addressedKeys(ts []linkSite, targets map[*nameBinding]nameTarget) map[*nameBinding]map[pickKey]string {
|
||||||
keys := map[*nameBinding]map[pickKey]string{}
|
keys := map[*nameBinding]map[pickKey]string{}
|
||||||
for _, s := range ts {
|
for _, s := range ts {
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ func TestNoReferenceAllocRegression(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"a repeat of a reference path", `{"format":"{r}","r":{"format":"{/word.w}","repeat":20,"separator":", "}}`, 25},
|
{"a repeat of a reference path", `{"format":"{r}","r":{"format":"{/word.w}","repeat":20,"separator":", "}}`, 25},
|
||||||
{"a repeat of a name", `{"format":"{r}","r":{"format":"{/word as n}{n.w}{n.w}","repeat":20,"separator":", "}}`, 162},
|
{"a repeat of a name", `{"format":"{r}","r":{"format":"{/word as n}{n.w}{n.w}","repeat":20,"separator":", "}}`, 162},
|
||||||
|
{"a read under a nested pick", `{"format":"{place.geo as g}{g} {g.town.zip}","place":{"format":"{geo}","geo":{"format":"{town.zip}","town":{"format":"{zip}","zip":"1"}}}}`, 10},
|
||||||
} {
|
} {
|
||||||
f, err := New(WithoutShippedData(), WithDataFS(fstest.MapFS{
|
f, err := New(WithoutShippedData(), WithDataFS(fstest.MapFS{
|
||||||
"word.json": {Data: []byte(word)},
|
"word.json": {Data: []byte(word)},
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import (
|
|||||||
// the pick.
|
// the pick.
|
||||||
type pickKey string
|
type pickKey string
|
||||||
|
|
||||||
// under is the key of rel, a fresh read's key, in what renders at k. It never returns k itself: k
|
// under is the key of rel, a fresh read's key, in what renders at k. It never returns k itself: on
|
||||||
// is sc.pickAt, and a memo keeping it would move every render's scope to the heap.
|
// a render k is sc.pickAt, and a memo keeping it would move every render's scope to the heap.
|
||||||
func (k pickKey) under(rel pickKey) pickKey {
|
func (k pickKey) under(rel pickKey) pickKey {
|
||||||
if k == "" {
|
if k == "" {
|
||||||
return rel
|
return rel
|
||||||
@@ -20,8 +20,7 @@ func (k pickKey) under(rel pickKey) pickKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// namedPick is one draw of a name: the variant drawn at each level a read of it addresses, the
|
// namedPick is one draw of a name: the variant drawn at each level a read of it addresses, the
|
||||||
// value each read there produced, keyed by the path from the name, and the table rows they
|
// value each read there produced, by its pickKey, and the table rows they pinned.
|
||||||
// pinned.
|
|
||||||
type namedPick struct {
|
type namedPick struct {
|
||||||
named *nameBinding
|
named *nameBinding
|
||||||
memo drawMemo
|
memo drawMemo
|
||||||
@@ -29,7 +28,7 @@ type namedPick struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// drawMemo is what a named pick has drawn: the variant each level was drawn as, so every path
|
// drawMemo is what a named pick has drawn: the variant each level was drawn as, so every path
|
||||||
// under it reads one variant; the value each read produced, by its path, so the same read written
|
// under it reads one variant; the value each read produced, by its pickKey, so the same read written
|
||||||
// twice reads one value; the frames a read opens for the name scopes around where it lands
|
// twice reads one value; the frames a read opens for the name scopes around where it lands
|
||||||
// (enter); and the rows drawn by each step down after a "..", by level.
|
// (enter); and the rows drawn by each step down after a "..", by level.
|
||||||
type drawMemo struct {
|
type drawMemo struct {
|
||||||
@@ -202,9 +201,10 @@ func readUnder(s *drawstate.State, t *template, sc renderScope, a arm) readValue
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
levels := make([]pickKey, len(a.levels))
|
levels := make([]pickKey, len(a.levels))
|
||||||
for i, l := range a.levels {
|
for i, l := range a.levels[:len(levels)-1] {
|
||||||
levels[i] = sc.pickAt.under(l)
|
levels[i] = sc.pickAt.under(l)
|
||||||
}
|
}
|
||||||
|
levels[len(levels)-1] = key
|
||||||
leaf, pins := p.draw(s, t.head(a.head), a.steps, levels)
|
leaf, pins := p.draw(s, t.head(a.head), a.steps, levels)
|
||||||
return p.renderAt(s, leaf, pins, key, sc)
|
return p.renderAt(s, leaf, pins, key, sc)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,8 +146,7 @@ func expand(s *drawstate.State, t *template, sc renderScope) string {
|
|||||||
// a level that a read of the name being rendered addresses; every other read draws afresh, so
|
// a level that a read of the name being rendered addresses; every other read draws afresh, so
|
||||||
// {word} {word} draws twice and {p.a} {p.b} reads two draws of p.
|
// {word} {word} draws twice and {p.a} {p.b} reads two draws of p.
|
||||||
// A fresh read clears sc.pick. Kept, a read nested in the fresh one would key the pick's memo by
|
// A fresh read clears sc.pick. Kept, a read nested in the fresh one would key the pick's memo by
|
||||||
// sc.pickAt, where in the pick it renders, and share a value with a different
|
// sc.pickAt, where in the pick it renders, and share a value with a different node at that key.
|
||||||
// node at that path.
|
|
||||||
func readField(s *drawstate.State, t *template, sc renderScope, a arm) readValue {
|
func readField(s *drawstate.State, t *template, sc renderScope, a arm) readValue {
|
||||||
switch {
|
switch {
|
||||||
case a.kind == namedRead:
|
case a.kind == namedRead:
|
||||||
|
|||||||
Reference in New Issue
Block a user