One spelling for an unvalidated builtin arg, and say what the hold buys
float's prep still swallowed ParseFloat's error three lines from the atoi that had just been changed to report one — two spellings of "parse an arg the check already validated". atof reports it the same way. The README paragraph said a reference reaching through an operand is caught, which the narrowed fence no longer does and should not: it says what the hold pins instead. Restored the why the trimmed comment in expand had carried. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -365,9 +365,10 @@ the reference sits, including in a field the format renders.
|
|||||||
|
|
||||||
A `{calc()}` operand is held on its own terms too, so the same fence guards it:
|
A `{calc()}` operand is held on its own terms too, so the same fence guards it:
|
||||||
`{..cat.net} x 2 = {calc(net * 2, 2)}` names one field two ways and is a load
|
`{..cat.net} x 2 = {calc(net * 2, 2)}` names one field two ways and is a load
|
||||||
error, with no path token anywhere. What an operand's draw fixes is the value it
|
error, with no path token anywhere. A calc renders its operand whole, so what the
|
||||||
renders, so a reference reaching *through* it is caught as well, while a sibling
|
hold pins is that one field — another route conflicts only by naming it. Two
|
||||||
its format never renders is free — that sibling is no part of the value.
|
names that merely draw from one source are two draws, as `{word} {word}` is, so
|
||||||
|
two dice over one `{..die}` are fine.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
token {p} renders a level that {p.first} reads a path into; name the fields you want instead
|
token {p} renders a level that {p.first} reads a path into; name the fields you want instead
|
||||||
|
|||||||
+10
-3
@@ -48,9 +48,7 @@ var builtins = map[string]builtin{
|
|||||||
return func(s *session, _ string, _ []string) string { return strconv.Itoa(lo + s.IntN(span)) }
|
return func(s *session, _ string, _ []string) string { return strconv.Itoa(lo + s.IntN(span)) }
|
||||||
}},
|
}},
|
||||||
"float": {arity: 3, check: floatArgs, prep: func(a []string) callFn {
|
"float": {arity: 3, check: floatArgs, prep: func(a []string) callFn {
|
||||||
lo, _ := strconv.ParseFloat(a[0], 64)
|
lo, hi, dp := atof(a[0]), atof(a[1]), atoi(a[2])
|
||||||
hi, _ := strconv.ParseFloat(a[1], 64)
|
|
||||||
dp := atoi(a[2])
|
|
||||||
return func(s *session, _ string, _ []string) string {
|
return func(s *session, _ string, _ []string) string {
|
||||||
return strconv.FormatFloat(lo+s.Float64()*(hi-lo), 'f', dp, 64)
|
return strconv.FormatFloat(lo+s.Float64()*(hi-lo), 'f', dp, 64)
|
||||||
}
|
}
|
||||||
@@ -104,6 +102,15 @@ func atoi(s string) int {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// atof is atoi for a float arg, and reports an unvalidated one the same way.
|
||||||
|
func atof(s string) float64 {
|
||||||
|
f, err := strconv.ParseFloat(s, 64)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("fakes: builtin arg %q reached prep unvalidated: %v", s, err))
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
func randBytes(r rng, n int) []byte {
|
func randBytes(r rng, n int) []byte {
|
||||||
b := make([]byte, n)
|
b := make([]byte, n)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
|
|||||||
@@ -156,7 +156,8 @@ func expand(s *session, t *template) string {
|
|||||||
case 'f':
|
case 'f':
|
||||||
b.WriteString(readField(s, t, held, o.arms[s.IntN(len(o.arms))]))
|
b.WriteString(readField(s, t, held, o.arms[s.IntN(len(o.arms))]))
|
||||||
case 'b':
|
case 'b':
|
||||||
// Read in the order calcVars fixed, which is what op.operands holds.
|
// Read before the call, so the value a calc computes is the value the
|
||||||
|
// format showed. calcVars fixed the order op.operands holds.
|
||||||
var operands []string
|
var operands []string
|
||||||
if len(o.operands) > 0 {
|
if len(o.operands) > 0 {
|
||||||
operands = make([]string, len(o.operands))
|
operands = make([]string, len(o.operands))
|
||||||
|
|||||||
Reference in New Issue
Block a user