Answer architecture round 2: guard Noun's range, name calc once as builtinfunc.Calc, and place readTableOptions in item 46
This commit is contained in:
@@ -26,7 +26,7 @@ func checkCalcFields(args []string, fields map[string]node) error {
|
|||||||
// checkCalcNames holds each calc of t reading a name to the checks checkCalcFields makes of a field.
|
// checkCalcNames holds each calc of t reading a name to the checks checkCalcFields makes of a field.
|
||||||
func checkCalcNames(path string, t *template) error {
|
func checkCalcNames(path string, t *template) error {
|
||||||
for _, o := range t.compiled.ops {
|
for _, o := range t.compiled.ops {
|
||||||
if o.Fn != "calc" || !slices.ContainsFunc(o.operands, func(a arm) bool { return a.kind == namedRead }) {
|
if o.Fn != builtinfunc.Calc || !slices.ContainsFunc(o.operands, func(a arm) bool { return a.kind == namedRead }) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := checkOperands(o.Args[0], builtinfunc.ParsedCalc(o.Args[0]), operandNodes(o)); err != nil {
|
if err := checkOperands(o.Args[0], builtinfunc.ParsedCalc(o.Args[0]), operandNodes(o)); err != nil {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
// operands fields holds.
|
// operands fields holds.
|
||||||
func checkFunc(tok grammar.Token, fields map[string]node) error {
|
func checkFunc(tok grammar.Token, fields map[string]node) error {
|
||||||
err := builtinfunc.Check(tok.Fn, tok.Args)
|
err := builtinfunc.Check(tok.Fn, tok.Args)
|
||||||
if err == nil && tok.Fn == "calc" {
|
if err == nil && tok.Fn == builtinfunc.Calc {
|
||||||
err = checkCalcFields(tok.Args, fields)
|
err = checkCalcFields(tok.Args, fields)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ type builtin struct {
|
|||||||
prints datatype.DataType
|
prints datatype.DataType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calc is the name of the builtin whose operands the caller checks and proves, as nodes only
|
||||||
|
// it holds.
|
||||||
|
const Calc = "calc"
|
||||||
|
|
||||||
// rng is the randomness a builtin sample draws from, which *drawstate.State satisfies.
|
// rng is the randomness a builtin sample draws from, which *drawstate.State satisfies.
|
||||||
type rng interface {
|
type rng interface {
|
||||||
IntN(n int) int
|
IntN(n int) int
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ var builtins = withTransforms(map[string]builtin{
|
|||||||
}},
|
}},
|
||||||
"date": {arity: -1, checkArgs: dateArgs, prep: datePrep},
|
"date": {arity: -1, checkArgs: dateArgs, prep: datePrep},
|
||||||
"time": {arity: -1, checkArgs: timeArg, prep: timePrep},
|
"time": {arity: -1, checkArgs: timeArg, prep: timePrep},
|
||||||
"calc": {arity: -1, checkArgs: checkCalc, prep: calcPrep, operands: calcOperands, noRefOperands: true},
|
Calc: {arity: -1, checkArgs: checkCalc, prep: calcPrep, operands: calcOperands, noRefOperands: true},
|
||||||
// seq is the one stateful builtin: a per-generator counter from 1, advancing on
|
// seq is the one stateful builtin: a per-generator counter from 1, advancing on
|
||||||
// each call. An optional name selects an independent counter; no name uses the
|
// each call. An optional name selects an independent counter; no name uses the
|
||||||
// default one. Deterministic by construction, so seeded output stays stable.
|
// default one. Deterministic by construction, so seeded output stays stable.
|
||||||
|
|||||||
@@ -31,4 +31,9 @@ func (d DataType) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Noun is the datatype as an error names what a value is.
|
// Noun is the datatype as an error names what a value is.
|
||||||
func Noun(d DataType) string { return nouns[d] }
|
func Noun(d DataType) string {
|
||||||
|
if d < 0 || d >= Count {
|
||||||
|
return d.String()
|
||||||
|
}
|
||||||
|
return nouns[d]
|
||||||
|
}
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ Require the path step to reach a sibling category.
|
|||||||
|
|
||||||
### 46. Report the same error every load for a table with two bad options, and for a folder with two unnamed rows files.
|
### 46. Report the same error every load for a table with two bad options, and for a folder with two unnamed rows files.
|
||||||
|
|
||||||
`readTableOptions` and `walkDir` in `internal/datafiles` return on the first in Go's map order.
|
`readTableOptions` in `table.go` and `walkDir` in `internal/datafiles` return on the first in Go's map order.
|
||||||
|
|
||||||
### 107. Move the template engine into `internal/`, leaving the root the public API and its options.
|
### 107. Move the template engine into `internal/`, leaving the root the public API and its options.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -173,7 +173,7 @@ func (p *valueProof) proveTemplate(t *template) proven.Value {
|
|||||||
leaves = append(leaves, a.leaves...)
|
leaves = append(leaves, a.leaves...)
|
||||||
}
|
}
|
||||||
return p.proveUnion(leaves)
|
return p.proveUnion(leaves)
|
||||||
case name == "calc":
|
case name == builtinfunc.Calc:
|
||||||
return p.proveCalc(o)
|
return p.proveCalc(o)
|
||||||
case builtinfunc.IsTransform(name):
|
case builtinfunc.IsTransform(name):
|
||||||
return proven.Unproven(fmt.Sprintf("{%s} rewrites text rather than printing a value; write the values it would print", body))
|
return proven.Unproven(fmt.Sprintf("{%s} rewrites text rather than printing a value; write the values it would print", body))
|
||||||
|
|||||||
Reference in New Issue
Block a user