Answer architecture round 1: one invariant phrase in internal/invariant, held across every package, Source built by Dir and FS, coverage counted across packages, and file items 112 and 113

This commit is contained in:
2026-10-05 15:44:38 +02:00
committed by Lillem4n
parent 835cdb57d4
commit dd2fe61b13
26 changed files with 144 additions and 95 deletions
+8 -8
View File
@@ -31,7 +31,7 @@ type builtin struct {
// operands names the fields the call reads, which a render reads for it; nil
// for a builtin that reads none.
operands func(args []string) []string
// noRefOperands says no operand can be a reference, so a name read once there is not refused.
// noRefOperands says no operand can be a reference.
noRefOperands bool
// proveNumber bounds the number a call's text reads as, token its body, and says which
// datatypes that text is not; set it where every render reads as a finite number, which
@@ -97,9 +97,13 @@ func ProveNumber(name, token string, args []string) (proven.Value, bool) {
return b.proveNumber(token, b.prints, args), true
}
// NumberCalls lists the calls printing a number, or with text also those whose text is
// one, as an error names them.
func NumberCalls(text bool) string {
// TypedCalls lists the calls whose text a typed column may hold, as an error names them.
func TypedCalls() string { return numberCalls(false) }
// OperandCalls lists the calls whose text a calc reads as a number, as an error names them.
func OperandCalls() string { return numberCalls(true) }
func numberCalls(text bool) string {
var calls []string
for name, b := range builtins {
if b.proveNumber != nil && (text || b.prints != datatype.String) {
@@ -116,7 +120,3 @@ func plural(n int) string {
}
return "s"
}
func internalError(format string, a ...any) string {
return "fejkdata: internal error: " + fmt.Sprintf(format, a...)
}
+4 -3
View File
@@ -10,6 +10,7 @@ import (
"github.com/larvit/fejkdata/internal/datatype"
"github.com/larvit/fejkdata/internal/drawstate"
"github.com/larvit/fejkdata/internal/invariant"
"github.com/larvit/fejkdata/internal/proven"
)
@@ -104,7 +105,7 @@ func chars(alphabet string) func([]string) Call {
const hexDigits = "0123456789abcdef"
// formatFloat prints v to dp decimals, or shortestDecimals, and a zero unsigned.
// formatFloat prints v to dp decimals, or proven.ShortestDecimals, and a zero unsigned.
func formatFloat(v float64, dp int) string {
s := strconv.FormatFloat(v, 'f', dp, 64)
if strings.HasPrefix(s, "-") && strings.Trim(s, "-0.") == "" {
@@ -119,7 +120,7 @@ func formatFloat(v float64, dp int) string {
func atoi(s string) int {
n, err := strconv.Atoi(s)
if err != nil {
panic(internalError("builtin arg %q reached prep unvalidated: %v", s, err))
panic(invariant.Broken("builtin arg %q reached prep unvalidated: %v", s, err))
}
return n
}
@@ -128,7 +129,7 @@ func atoi(s string) int {
func atof(s string) float64 {
f, err := strconv.ParseFloat(s, 64)
if err != nil {
panic(internalError("builtin arg %q reached prep unvalidated: %v", s, err))
panic(invariant.Broken("builtin arg %q reached prep unvalidated: %v", s, err))
}
return f
}
+3 -2
View File
@@ -8,6 +8,7 @@ import (
"github.com/larvit/fejkdata/internal/drawstate"
"github.com/larvit/fejkdata/internal/grammar"
"github.com/larvit/fejkdata/internal/invariant"
"github.com/larvit/fejkdata/internal/proven"
)
@@ -28,7 +29,7 @@ func evalCalc(n grammar.CalcNode, operands []string) float64 {
case grammar.CalcBin:
return Arith(n.Operator, evalCalc(n.L, operands), evalCalc(n.R, operands))
}
panic(internalError("calc node %#v has no evaluation", n))
panic(invariant.Broken("calc node %#v has no evaluation", n))
}
// Arith applies a calc operator.
@@ -80,7 +81,7 @@ func calcPrep(args []string) Call {
func ParsedCalc(expr string) grammar.Calc {
c, err := grammar.ParseCalc(expr)
if err != nil {
panic(internalError("calc(%q) passed its check unparsed: %v", expr, err))
panic(invariant.Broken("calc(%q) passed its check unparsed: %v", expr, err))
}
return c
}
+4 -3
View File
@@ -6,6 +6,7 @@ import (
"time"
"github.com/larvit/fejkdata/internal/drawstate"
"github.com/larvit/fejkdata/internal/invariant"
)
const dayLayout = "2006-01-02"
@@ -56,7 +57,7 @@ func layoutArg(a string) (string, error) {
func layoutOf(a string) string {
layout, err := layoutArg(a)
if err != nil {
panic(internalError("builtin arg %q reached prep unvalidated: %v", a, err))
panic(invariant.Broken("builtin arg %q reached prep unvalidated: %v", a, err))
}
return layout
}
@@ -130,11 +131,11 @@ func timeArg(a []string) error {
func datePrep(a []string) Call {
from, err := time.Parse(dayLayout, a[0])
if err != nil {
panic(internalError("builtin arg %q reached prep unvalidated: %v", a[0], err))
panic(invariant.Broken("builtin arg %q reached prep unvalidated: %v", a[0], err))
}
to, err := time.Parse(dayLayout, a[1])
if err != nil {
panic(internalError("builtin arg %q reached prep unvalidated: %v", a[1], err))
panic(invariant.Broken("builtin arg %q reached prep unvalidated: %v", a[1], err))
}
layout, start, span := layoutOf(a[2]), from.Unix(), int(to.Unix()-from.Unix())+86400
return func(s *drawstate.State, _ string, _ []string) string {
+4 -3
View File
@@ -7,6 +7,7 @@ import (
"github.com/larvit/fejkdata/internal/drawstate"
"github.com/larvit/fejkdata/internal/grammar"
"github.com/larvit/fejkdata/internal/invariant"
)
// transforms are the builtins that rewrite one operand's value; they nest, so
@@ -20,7 +21,7 @@ var transforms = map[string]func(string) string{
func withTransforms(calls map[string]builtin) map[string]builtin {
for name, fn := range transforms {
if _, clash := calls[name]; clash {
panic(internalError("%s is registered as a builtin and a transform", name))
panic(invariant.Broken("%s is registered as a builtin and a transform", name))
}
calls[name] = builtin{arity: 1, checkArgs: transformArg, prep: transformPrep(fn), operands: transformOperand}
}
@@ -47,7 +48,7 @@ func unwrapTransform(arg string) (leaf string, chain []func(string) string, err
}
}
// transformArg proves a transform's chain; checkReads proves the operand it reads.
// transformArg proves a transform's chain.
func transformArg(a []string) error {
_, _, err := unwrapTransform(a[0])
return err
@@ -66,7 +67,7 @@ func transformPrep(outer func(string) string) func([]string) Call {
return func(a []string) Call {
_, chain, err := unwrapTransform(a[0])
if err != nil {
panic(internalError("transform arg %q reached prep unvalidated: %v", a[0], err))
panic(invariant.Broken("transform arg %q reached prep unvalidated: %v", a[0], err))
}
return func(_ *drawstate.State, _ string, operands []string) string {
v := operands[0]