aontu 0.62.0 → 0.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agentsmd.js +0 -27
- package/dist/agentsmd.js.map +1 -1
- package/dist/alias.js.map +1 -1
- package/dist/allow.js +0 -92
- package/dist/allow.js.map +1 -1
- package/dist/aontu.d.ts +1 -1
- package/dist/aontu.js +1 -79
- package/dist/aontu.js.map +1 -1
- package/dist/aontumodel.d.ts +4 -0
- package/dist/aontumodel.js +33 -0
- package/dist/aontumodel.js.map +1 -0
- package/dist/cli.js +101 -620
- package/dist/cli.js.map +1 -1
- package/dist/ctx.js +0 -48
- package/dist/ctx.js.map +1 -1
- package/dist/diff.js +0 -32
- package/dist/diff.js.map +1 -1
- package/dist/err.js +0 -40
- package/dist/err.js.map +1 -1
- package/dist/escape.js +0 -45
- package/dist/escape.js.map +1 -1
- package/dist/exactjson.d.ts +0 -35
- package/dist/exactjson.js +0 -131
- package/dist/exactjson.js.map +1 -1
- package/dist/format.js +13 -203
- package/dist/format.js.map +1 -1
- package/dist/grammar.d.ts +9 -0
- package/dist/grammar.js +54 -0
- package/dist/grammar.js.map +1 -0
- package/dist/graph.js +0 -26
- package/dist/graph.js.map +1 -1
- package/dist/hcanon.js +0 -82
- package/dist/hcanon.js.map +1 -1
- package/dist/helpdoc.js +1 -1
- package/dist/helpdoc.js.map +1 -1
- package/dist/hints.d.ts +0 -6
- package/dist/hints.js +54 -55
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.js +0 -114
- package/dist/jsonschema.js.map +1 -1
- package/dist/keyorder.d.ts +0 -7
- package/dist/keyorder.js +0 -41
- package/dist/keyorder.js.map +1 -1
- package/dist/lang.js +17 -915
- package/dist/lang.js.map +1 -1
- package/dist/lower.js +11 -61
- package/dist/lower.js.map +1 -1
- package/dist/lsp-server.js +0 -16
- package/dist/lsp-server.js.map +1 -1
- package/dist/lsp.d.ts +1 -1
- package/dist/lsp.js +12 -159
- package/dist/lsp.js.map +1 -1
- package/dist/mcp-server.js +0 -26
- package/dist/mcp-server.js.map +1 -1
- package/dist/mcp.js +0 -113
- package/dist/mcp.js.map +1 -1
- package/dist/mod-tool.js +0 -130
- package/dist/mod-tool.js.map +1 -1
- package/dist/mod.js +0 -162
- package/dist/mod.js.map +1 -1
- package/dist/patch.js +0 -217
- package/dist/patch.js.map +1 -1
- package/dist/provenance.js +0 -140
- package/dist/provenance.js.map +1 -1
- package/dist/query.js +0 -75
- package/dist/query.js.map +1 -1
- package/dist/reach.js +0 -43
- package/dist/reach.js.map +1 -1
- package/dist/relation.js +0 -61
- package/dist/relation.js.map +1 -1
- package/dist/render.js +20 -135
- package/dist/render.js.map +1 -1
- package/dist/report-sarif.d.ts +0 -11
- package/dist/report-sarif.js +0 -28
- package/dist/report-sarif.js.map +1 -1
- package/dist/sig.js +0 -35
- package/dist/sig.js.map +1 -1
- package/dist/sigdecl.js +1 -1
- package/dist/sigdecl.js.map +1 -1
- package/dist/siggate.js +0 -4
- package/dist/siggate.js.map +1 -1
- package/dist/site.js +3 -29
- package/dist/site.js.map +1 -1
- package/dist/subsume.d.ts +0 -10
- package/dist/subsume.js +0 -137
- package/dist/subsume.js.map +1 -1
- package/dist/template.d.ts +2 -1
- package/dist/template.js +58 -138
- package/dist/template.js.map +1 -1
- package/dist/trim.js +0 -41
- package/dist/trim.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type.js.map +1 -1
- package/dist/unify.js +12 -242
- package/dist/unify.js.map +1 -1
- package/dist/utility.js +0 -22
- package/dist/utility.js.map +1 -1
- package/dist/val/AbnfFuncVal.d.ts +18 -0
- package/dist/val/AbnfFuncVal.js +132 -0
- package/dist/val/AbnfFuncVal.js.map +1 -0
- package/dist/val/AbsentVal.d.ts +11 -0
- package/dist/val/AbsentVal.js +30 -0
- package/dist/val/AbsentVal.js.map +1 -0
- package/dist/val/AggFuncVal.d.ts +10 -1
- package/dist/val/AggFuncVal.js +104 -116
- package/dist/val/AggFuncVal.js.map +1 -1
- package/dist/val/ArithFuncVal.js +0 -12
- package/dist/val/ArithFuncVal.js.map +1 -1
- package/dist/val/BagVal.js +1 -78
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/BigDecimalVal.js +0 -16
- package/dist/val/BigDecimalVal.js.map +1 -1
- package/dist/val/BigIntegerVal.js +0 -16
- package/dist/val/BigIntegerVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +0 -9
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/CmpFuncVal.js +2 -59
- package/dist/val/CmpFuncVal.js.map +1 -1
- package/dist/val/ConjunctVal.js +0 -29
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.js +0 -500
- package/dist/val/ConstraintVal.js.map +1 -1
- package/dist/val/ContainerKindVal.js +0 -2
- package/dist/val/ContainerKindVal.js.map +1 -1
- package/dist/val/CopyFuncVal.js +0 -3
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.js +0 -179
- package/dist/val/Decimal.js.map +1 -1
- package/dist/val/DeprecateFuncVal.js.map +1 -1
- package/dist/val/DisjunctVal.js +0 -152
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/EachFuncVal.js +0 -3
- package/dist/val/EachFuncVal.js.map +1 -1
- package/dist/val/EmitFuncVal.d.ts +1 -1
- package/dist/val/EmitFuncVal.js +6 -119
- package/dist/val/EmitFuncVal.js.map +1 -1
- package/dist/val/ExpectVal.js +0 -62
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FilterFuncVal.js +0 -25
- package/dist/val/FilterFuncVal.js.map +1 -1
- package/dist/val/FuncBaseVal.d.ts +1 -0
- package/dist/val/FuncBaseVal.js +7 -127
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/GraphAtomVal.js +0 -15
- package/dist/val/GraphAtomVal.js.map +1 -1
- package/dist/val/HideFuncVal.js +0 -13
- package/dist/val/HideFuncVal.js.map +1 -1
- package/dist/val/IntegerVal.js +0 -61
- package/dist/val/IntegerVal.js.map +1 -1
- package/dist/val/JunctionVal.js +0 -20
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.js +0 -46
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +0 -57
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js +0 -11
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.js +0 -151
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MatchFuncVal.js +0 -27
- package/dist/val/MatchFuncVal.js.map +1 -1
- package/dist/val/{FormFuncVal.d.ts → MaybeFuncVal.d.ts} +5 -5
- package/dist/val/MaybeFuncVal.js +50 -0
- package/dist/val/MaybeFuncVal.js.map +1 -0
- package/dist/val/MoveFuncVal.js +0 -18
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.js +0 -60
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/NomFuncVal.js +8 -42
- package/dist/val/NomFuncVal.js.map +1 -1
- package/dist/val/NumberVal.js +0 -15
- package/dist/val/NumberVal.js.map +1 -1
- package/dist/val/OpBaseVal.d.ts +1 -0
- package/dist/val/OpBaseVal.js +3 -15
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/PackFuncVal.js +0 -34
- package/dist/val/PackFuncVal.js.map +1 -1
- package/dist/val/PathFuncVal.js +0 -6
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PathVal.js +0 -41
- package/dist/val/PathVal.js.map +1 -1
- package/dist/val/PlaceVal.js +0 -25
- package/dist/val/PlaceVal.js.map +1 -1
- package/dist/val/PlusOpVal.d.ts +1 -7
- package/dist/val/PlusOpVal.js +13 -74
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js +0 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.js +0 -167
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RecurseVal.js +0 -55
- package/dist/val/RecurseVal.js.map +1 -1
- package/dist/val/RefVal.js +0 -282
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.js +0 -232
- package/dist/val/ReferFuncVal.js.map +1 -1
- package/dist/val/ScalarKindVal.js +0 -49
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/ScalarVal.js +0 -11
- package/dist/val/ScalarVal.js.map +1 -1
- package/dist/val/StrFuncVal.js +0 -18
- package/dist/val/StrFuncVal.js.map +1 -1
- package/dist/val/SuperFuncVal.js +0 -32
- package/dist/val/SuperFuncVal.js.map +1 -1
- package/dist/val/TopVal.js +0 -1
- package/dist/val/TopVal.js.map +1 -1
- package/dist/val/TranslateFuncVal.js +1 -3
- package/dist/val/TranslateFuncVal.js.map +1 -1
- package/dist/val/UpperFuncVal.js +0 -11
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +1 -0
- package/dist/val/Val.js +2 -133
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js +0 -12
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/arith.js +0 -37
- package/dist/val/arith.js.map +1 -1
- package/dist/val/caserange.js +0 -61
- package/dist/val/caserange.js.map +1 -1
- package/dist/val/members.js +0 -6
- package/dist/val/members.js.map +1 -1
- package/dist/val/numcmp.js +0 -11
- package/dist/val/numcmp.js.map +1 -1
- package/dist/val/numkind.js +0 -145
- package/dist/val/numkind.js.map +1 -1
- package/dist/val/valutil.js +0 -16
- package/dist/val/valutil.js.map +1 -1
- package/dist/vet.js +0 -461
- package/dist/vet.js.map +1 -1
- package/dist/view.js +0 -414
- package/dist/view.js.map +1 -1
- package/dist/walk.js +0 -41
- package/dist/walk.js.map +1 -1
- package/grammar/aontu.abnf +8 -6
- package/grammar/aontu.gbnf +4 -4
- package/grammar/aontu.lark +4 -4
- package/grammar/aontu.tmLanguage.json +1 -1
- package/package.json +4 -2
- package/src/agentsmd.ts +0 -35
- package/src/alias.ts +0 -39
- package/src/allow.ts +1 -96
- package/src/aontu.ts +3 -110
- package/src/aontumodel.ts +32 -0
- package/src/cli.ts +113 -682
- package/src/ctx.ts +0 -103
- package/src/diff.ts +0 -40
- package/src/err.ts +0 -40
- package/src/escape.ts +0 -46
- package/src/exactjson.ts +0 -131
- package/src/format.ts +14 -257
- package/src/grammar.ts +72 -0
- package/src/graph.ts +0 -61
- package/src/hcanon.ts +0 -82
- package/src/helpdoc.ts +1 -1
- package/src/hints.ts +66 -57
- package/src/jsonschema.ts +0 -123
- package/src/keyorder.ts +0 -42
- package/src/lang.ts +19 -931
- package/src/lower.ts +12 -62
- package/src/lsp-server.ts +0 -16
- package/src/lsp.ts +12 -180
- package/src/mcp-server.ts +0 -31
- package/src/mcp.ts +0 -130
- package/src/mod-tool.ts +0 -158
- package/src/mod.ts +0 -178
- package/src/patch.ts +0 -232
- package/src/provenance.ts +0 -183
- package/src/query.ts +0 -84
- package/src/reach.ts +0 -53
- package/src/relation.ts +0 -84
- package/src/render.ts +20 -172
- package/src/report-sarif.ts +0 -48
- package/src/sig.ts +0 -35
- package/src/sigdecl.ts +1 -1
- package/src/siggate.ts +0 -30
- package/src/site.ts +3 -29
- package/src/subsume.ts +1 -161
- package/src/template.ts +69 -140
- package/src/trim.ts +0 -53
- package/src/type.ts +2 -45
- package/src/unify.ts +13 -251
- package/src/utility.ts +0 -31
- package/src/val/AbnfFuncVal.ts +181 -0
- package/src/val/AbsentVal.ts +54 -0
- package/src/val/AggFuncVal.ts +152 -188
- package/src/val/ArithFuncVal.ts +0 -20
- package/src/val/BagVal.ts +1 -78
- package/src/val/BigDecimalVal.ts +0 -16
- package/src/val/BigIntegerVal.ts +0 -16
- package/src/val/CloseFuncVal.ts +0 -9
- package/src/val/CmpFuncVal.ts +4 -166
- package/src/val/ConjunctVal.ts +0 -33
- package/src/val/ConstraintVal.ts +2 -537
- package/src/val/ContainerKindVal.ts +0 -18
- package/src/val/CopyFuncVal.ts +0 -5
- package/src/val/Decimal.ts +1 -185
- package/src/val/DeprecateFuncVal.ts +0 -10
- package/src/val/DisjunctVal.ts +0 -157
- package/src/val/EachFuncVal.ts +0 -40
- package/src/val/EmitFuncVal.ts +8 -208
- package/src/val/ExpectVal.ts +0 -62
- package/src/val/FilterFuncVal.ts +0 -55
- package/src/val/FuncBaseVal.ts +9 -130
- package/src/val/GraphAtomVal.ts +0 -42
- package/src/val/HideFuncVal.ts +0 -15
- package/src/val/IntegerVal.ts +0 -61
- package/src/val/JunctionVal.ts +0 -20
- package/src/val/KeyFuncVal.ts +0 -48
- package/src/val/ListVal.ts +0 -59
- package/src/val/LowerFuncVal.ts +0 -12
- package/src/val/MapVal.ts +0 -151
- package/src/val/MatchFuncVal.ts +0 -59
- package/src/val/MaybeFuncVal.ts +86 -0
- package/src/val/MoveFuncVal.ts +0 -20
- package/src/val/NilVal.ts +0 -60
- package/src/val/NomFuncVal.ts +8 -95
- package/src/val/NumberVal.ts +0 -16
- package/src/val/OpBaseVal.ts +4 -17
- package/src/val/PackFuncVal.ts +0 -63
- package/src/val/PathFuncVal.ts +0 -32
- package/src/val/PathVal.ts +0 -66
- package/src/val/PlaceVal.ts +0 -45
- package/src/val/PlusOpVal.ts +18 -75
- package/src/val/PrefFuncVal.ts +0 -1
- package/src/val/PrefVal.ts +0 -179
- package/src/val/RecurseVal.ts +0 -81
- package/src/val/RefVal.ts +1 -285
- package/src/val/ReferFuncVal.ts +0 -255
- package/src/val/ScalarKindVal.ts +0 -50
- package/src/val/ScalarVal.ts +0 -12
- package/src/val/StrFuncVal.ts +0 -44
- package/src/val/SuperFuncVal.ts +0 -42
- package/src/val/TopVal.ts +0 -1
- package/src/val/TranslateFuncVal.ts +1 -51
- package/src/val/UpperFuncVal.ts +0 -12
- package/src/val/Val.ts +3 -192
- package/src/val/VarVal.ts +0 -15
- package/src/val/arith.ts +0 -92
- package/src/val/caserange.ts +0 -62
- package/src/val/members.ts +0 -23
- package/src/val/numcmp.ts +1 -27
- package/src/val/numkind.ts +0 -149
- package/src/val/valutil.ts +0 -16
- package/src/vet.ts +1 -582
- package/src/view.ts +0 -507
- package/src/walk.ts +0 -41
- package/dist/std.d.ts +0 -3
- package/dist/std.js +0 -672
- package/dist/std.js.map +0 -1
- package/dist/val/FormFuncVal.js +0 -55
- package/dist/val/FormFuncVal.js.map +0 -1
- package/dist/val/NamerFuncVal.d.ts +0 -12
- package/dist/val/NamerFuncVal.js +0 -176
- package/dist/val/NamerFuncVal.js.map +0 -1
- package/src/std.ts +0 -683
|
@@ -18,98 +18,16 @@ const err_1 = require("../err");
|
|
|
18
18
|
const FeatureVal_1 = require("./FeatureVal");
|
|
19
19
|
const ScalarKindVal_1 = require("./ScalarKindVal");
|
|
20
20
|
const numcmp_1 = require("./numcmp");
|
|
21
|
-
// THE PATTERN SUBSET, AND HOW IT IS ENFORCED (G1 phase 2; ADR-003).
|
|
22
|
-
//
|
|
23
|
-
// `re(p)` must mean the same thing in both engines and cost about the
|
|
24
|
-
// same, and the two host engines guarantee neither: TypeScript compiles
|
|
25
|
-
// with JavaScript's backtracking RegExp, Go with RE2 — a different
|
|
26
|
-
// language in a different complexity class, over a different alphabet.
|
|
27
|
-
//
|
|
28
|
-
// The enforcement is NORMALISATION, not refusal (ADR-003). Every
|
|
29
|
-
// construct whose expansion is engine-defined is rewritten here, by
|
|
30
|
-
// this function, into an explicit form that cannot be read two ways;
|
|
31
|
-
// only the rewritten pattern reaches a host engine. The alternative —
|
|
32
|
-
// refusing everything that might differ — was tried first and leaked
|
|
33
|
-
// three times, because its correctness depended on this comment knowing
|
|
34
|
-
// every difference between two large engines.
|
|
35
|
-
//
|
|
36
|
-
// Aontu therefore DEFINES the abbreviations rather than inheriting
|
|
37
|
-
// either host's. The definitions are deliberately the small ASCII ones,
|
|
38
|
-
// because a config value containing U+00A0 is a mistake to catch, not a
|
|
39
|
-
// space to accept silently:
|
|
40
|
-
//
|
|
41
|
-
// \d [0-9] \D [^0-9]
|
|
42
|
-
// \w [0-9A-Za-z_] \W [^0-9A-Za-z_]
|
|
43
|
-
// \s [ \t\n\r\f\v] \S [^ \t\n\r\f\v]
|
|
44
|
-
// . [^\n]
|
|
45
|
-
// \A ^ \z $
|
|
46
|
-
//
|
|
47
|
-
// Neither host agreed with all of these before rewriting: JavaScript's
|
|
48
|
-
// \s also matches U+00A0 and other Unicode spaces, RE2's omits \v, and
|
|
49
|
-
// the two `.` sets differ by \r and the Unicode line separators. After
|
|
50
|
-
// rewriting, both engines see one explicit class and cannot disagree.
|
|
51
|
-
//
|
|
52
|
-
// What is still REFUSED, and why refusal is right for these:
|
|
53
|
-
//
|
|
54
|
-
// 1. Constructs one engine simply lacks — backreferences and
|
|
55
|
-
// lookaround (not in RE2, and not expressible as regular
|
|
56
|
-
// expressions at all), POSIX classes, `\p{...}`, `\x{...}`, `\u`.
|
|
57
|
-
// There is nothing to normalise them TO.
|
|
58
|
-
// 2. `(?` other than `(?:` — named groups are spelled differently
|
|
59
|
-
// (`(?P<n>` in RE2, `(?<n>` in JavaScript) and inline flags change
|
|
60
|
-
// the meaning of everything after them.
|
|
61
|
-
// 3. A quantifier applied to a group containing a quantifier or an
|
|
62
|
-
// alternation. This one is about TIME, not meaning: `(a+)+$`
|
|
63
|
-
// against twenty-nine characters takes 45 SECONDS in JavaScript
|
|
64
|
-
// and 0.065s under RE2, and a regex match is counted by no
|
|
65
|
-
// evaluator budget, so an untrusted schema could otherwise stall
|
|
66
|
-
// the TypeScript evaluator indefinitely (docs/trust.md clause 2).
|
|
67
|
-
// Normalisation cannot fix a complexity difference; only owning the
|
|
68
|
-
// matcher could, which ADR-003 records as the future option.
|
|
69
|
-
//
|
|
70
|
-
// The alphabet is fixed separately, by compiling with the `u` flag:
|
|
71
|
-
// JavaScript otherwise matches UTF-16 code units where RE2 matches code
|
|
72
|
-
// points, so `^.$` accepted U+1D11E in Go and refused it in TypeScript.
|
|
73
|
-
//
|
|
74
|
-
// This function is mirrored statement for statement in go/constraint.go,
|
|
75
|
-
// and `test/spec/files/regex-corpus.txt` pins that the two produce
|
|
76
|
-
// byte-identical output for every pattern in a generated corpus.
|
|
77
|
-
// The largest repeat count Aontu's pattern language admits. RE2 caps a
|
|
78
|
-
// repeat at 1000 and refuses to compile past it, where JavaScript's
|
|
79
|
-
// backtracking engine accepts any count -- so `re("^a{1001}$")` was
|
|
80
|
-
// VALID in TypeScript and an `error` verdict in Go, a cross-port
|
|
81
|
-
// verdict flip on a schema an agent could be handed
|
|
82
|
-
// (status-2026-08-21.md section 4). Under ADR-003 the host's own
|
|
83
|
-
// compile failure must never be what a user sees, so the bound is
|
|
84
|
-
// Aontu's: at most RE_REPEAT_MAX, refused identically in both ports
|
|
85
|
-
// before either engine compiles. Nested products beyond the cap were
|
|
86
|
-
// already refused, by the quantified-group rule below.
|
|
87
21
|
const RE_REPEAT_MAX = 1000;
|
|
88
22
|
// The normative expansions. These are Aontu's definitions, not either
|
|
89
23
|
// host's; both hosts are rewritten to them.
|
|
90
24
|
const RE_CLASS_DIGIT = '0-9';
|
|
91
25
|
const RE_CLASS_WORD = '0-9A-Za-z_';
|
|
92
26
|
const RE_CLASS_SPACE = ' \\t\\n\\r\\f\\v';
|
|
93
|
-
// Metacharacters that may be escaped to mean themselves, in both
|
|
94
|
-
// engines. `-` is handled separately: it is legal escaped only INSIDE a
|
|
95
|
-
// character class, because RE2 accepts `a\-b` and JavaScript's unicode
|
|
96
|
-
// mode makes it a syntax error.
|
|
97
27
|
const RE_ESCAPE_PUNCT = '\\.+*?()[]{}|^$/';
|
|
98
28
|
// Escapes passed through unchanged: the control characters, the ASCII
|
|
99
29
|
// word boundary, and `\xHH`. Each was probed in both engines.
|
|
100
30
|
const RE_ESCAPE_PASS = 'tnrfv';
|
|
101
|
-
// A counted quantifier `{n}`, `{n,}` or `{n,m}` starting at `src[at]`.
|
|
102
|
-
// Two rules, both about what the hosts do NOT share:
|
|
103
|
-
//
|
|
104
|
-
// - A bound above RE_REPEAT_MAX: RE2 refuses to compile it, JavaScript
|
|
105
|
-
// accepts it.
|
|
106
|
-
// - A brace that does not open a well-formed counted quantifier at
|
|
107
|
-
// all (`x{y}`, `a{`, `{,5}`): JavaScript compiled with the `u` flag
|
|
108
|
-
// makes it a SYNTAX ERROR, while RE2 reads it as a literal brace, so
|
|
109
|
-
// `re("^x{y}$")` was `constraint_pattern` in TypeScript and a plain
|
|
110
|
-
// unresolved value in Go -- the same class of verdict flip as the
|
|
111
|
-
// repeat cap, found by sweeping around it. A literal brace is
|
|
112
|
-
// written escaped (`a\\{1001\\}`), which both engines share.
|
|
113
31
|
function repeatWhy(src, at) {
|
|
114
32
|
const bad = (what) => [
|
|
115
33
|
'a ' + what + ', which the two engines do not read the same way', -1
|
|
@@ -241,10 +159,6 @@ function normaliseEscape(n, src, i, inClass) {
|
|
|
241
159
|
function normaliseRe(src) {
|
|
242
160
|
let inClass = false;
|
|
243
161
|
const out = [];
|
|
244
|
-
// One frame per open group, recording whether it contains a quantifier
|
|
245
|
-
// or an alternation. A group carrying either may not itself be
|
|
246
|
-
// quantified; containment is transitive, so a frame hands its flags up
|
|
247
|
-
// to its parent when it closes.
|
|
248
162
|
const groups = [];
|
|
249
163
|
const mark = (k) => {
|
|
250
164
|
if (0 < groups.length) {
|
|
@@ -266,23 +180,12 @@ function normaliseRe(src) {
|
|
|
266
180
|
return ['', why];
|
|
267
181
|
}
|
|
268
182
|
out.push(emit);
|
|
269
|
-
// `\b` AND `\B` ARE ASSERTIONS TOO, and quantifying one is the
|
|
270
|
-
// same disagreement `^{1}` is: JavaScript under `u` calls it a
|
|
271
|
-
// syntax error, RE2 quantifies the assertion happily. The rule
|
|
272
|
-
// said "`\b` and `\B` quantify identically in both and are left
|
|
273
|
-
// alone" and that was measured wrong -- `re("\\b{1}x")` is
|
|
274
|
-
// `constraint_pattern` in TypeScript and an accepted schema in
|
|
275
|
-
// Go. Only OUTSIDE a class: inside one, `\b` is a backspace in
|
|
276
|
-
// both engines and repeats like any other character.
|
|
277
183
|
if (!inClass && ('b' === src[i + 1] || 'B' === src[i + 1])) {
|
|
278
184
|
anchorPrev = true;
|
|
279
185
|
}
|
|
280
186
|
i += 1 + extra;
|
|
281
187
|
continue;
|
|
282
188
|
}
|
|
283
|
-
// A POSIX class opener, anywhere: the form lives inside an ordinary
|
|
284
|
-
// class (`[[:alpha:]]`), and refusing it everywhere is one rule
|
|
285
|
-
// rather than two.
|
|
286
189
|
if ('[' === c && ':' === src[i + 1]) {
|
|
287
190
|
return ['', 'a POSIX class ([:...:]), which JavaScript does not have'];
|
|
288
191
|
}
|
|
@@ -347,12 +250,6 @@ function normaliseRe(src) {
|
|
|
347
250
|
continue;
|
|
348
251
|
}
|
|
349
252
|
if ('*' === c || '+' === c || '?' === c || '{' === c) {
|
|
350
|
-
// Nothing to repeat. JavaScript under the `u` flag makes this a
|
|
351
|
-
// SYNTAX ERROR, where RE2 quantifies the assertion happily and
|
|
352
|
-
// matches, so `re("^{1}")` was `constraint_pattern` in
|
|
353
|
-
// TypeScript and an accepted schema in Go. The four assertions
|
|
354
|
-
// behave alike here -- `^`, `$`, `\b` and `\B` -- so the rule
|
|
355
|
-
// names all four.
|
|
356
253
|
if (afterAnchor) {
|
|
357
254
|
return ['', 'a quantifier applied to `^`, `$`, `\\b` or ' +
|
|
358
255
|
'`\\B`, which has nothing to repeat'];
|
|
@@ -368,10 +265,6 @@ function normaliseRe(src) {
|
|
|
368
265
|
out.push(c);
|
|
369
266
|
continue;
|
|
370
267
|
}
|
|
371
|
-
// A `}` that closes no counted quantifier: JavaScript under `u`
|
|
372
|
-
// refuses it as a lone quantifier bracket, RE2 reads it as a
|
|
373
|
-
// literal. Written escaped inside a class (`[}]`) it is a literal
|
|
374
|
-
// in both, which is the spelling that survives.
|
|
375
268
|
if ('}' === c) {
|
|
376
269
|
if (i !== repeatEnd) {
|
|
377
270
|
return ['', 'a `}` that closes no counted quantifier, which ' +
|
|
@@ -401,18 +294,9 @@ function numericLeaf(v) {
|
|
|
401
294
|
function stringLeaf(v) {
|
|
402
295
|
return true === v?.isScalar && 'string' === typeof v.peg && v.isString;
|
|
403
296
|
}
|
|
404
|
-
// The VALUE-admission widening of stringLeaf: a path value is a string
|
|
405
|
-
// with more structure (path <: string, ADR-016), so the string-domain
|
|
406
|
-
// constraints admit one -- `refer() & re("auth$")` must still check a
|
|
407
|
-
// link whose value is now a path. The ARGUMENT sites keep the strict
|
|
408
|
-
// test: a pattern, a bound or an exclusion is spelled with a plain
|
|
409
|
-
// string, never a path.
|
|
410
297
|
function stringishLeaf(v) {
|
|
411
298
|
return stringLeaf(v) || (true === v?.isScalar && true === v.isPath);
|
|
412
299
|
}
|
|
413
|
-
// Scalar identity: leaf AND value, the lattice's own rule (1 and 1.0
|
|
414
|
-
// are different scalars). Exact numeric comparison decides the value
|
|
415
|
-
// half for numeric leaves.
|
|
416
300
|
function sameScalar(a, b) {
|
|
417
301
|
if (numericLeaf(a) && numericLeaf(b)) {
|
|
418
302
|
return (0, numcmp_1.towerRank)(a) === (0, numcmp_1.towerRank)(b) && 0 === (0, numcmp_1.cmpNumeric)(a, b);
|
|
@@ -438,20 +322,6 @@ function leafMarker(v) {
|
|
|
438
322
|
return v.isBigDecimal ? ScalarKindVal_1.BigDecimal : v.isBigInteger ? ScalarKindVal_1.BigInteger :
|
|
439
323
|
v.isInteger ? ScalarKindVal_1.Integer : ScalarKindVal_1.Float;
|
|
440
324
|
}
|
|
441
|
-
// Conjunct sort order for an atom that must see the WHOLE value.
|
|
442
|
-
// Every other value sorts below the container default (99999), so such
|
|
443
|
-
// an atom is the LAST term to fold: `a:length(2) a:{x:1} a:{y:2}` must
|
|
444
|
-
// count the MERGED map, and a constraint that folded at 50000 would
|
|
445
|
-
// count `{x:1}` alone and refuse the layering that is the whole point
|
|
446
|
-
// of the language.
|
|
447
|
-
//
|
|
448
|
-
// The order atoms keep the low slot: `min(2) & 1 & 2` may decide as
|
|
449
|
-
// soon as it sees a scalar, because meeting more scalars can only
|
|
450
|
-
// narrow. Meeting more containers GROWS the member set, which is why
|
|
451
|
-
// the two orders differ.
|
|
452
|
-
//
|
|
453
|
-
// Three atoms are late: `length` and `unique` (they count members), and
|
|
454
|
-
// `must` (an evaluate-only check against the finished value).
|
|
455
325
|
const LATE_CJO = 150000;
|
|
456
326
|
function lateAtom(atom) {
|
|
457
327
|
return 'length' === atom || 'unique' === atom || 'must' === atom;
|
|
@@ -483,16 +353,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
483
353
|
}
|
|
484
354
|
else if (spec.atom) {
|
|
485
355
|
const args = atomArgs(spec.atom, spec.peg ?? []);
|
|
486
|
-
// An argument that is not yet concrete — a reference, an
|
|
487
|
-
// arithmetic expression, a conjunct of atoms — makes the whole
|
|
488
|
-
// atom PENDING rather than invalid (G1 phase 4). It is resolved
|
|
489
|
-
// in unify, where there is a ctx to resolve through, and the
|
|
490
|
-
// residual is built from the settled arguments. Only a settled
|
|
491
|
-
// argument of the wrong shape is an `invalid-arg`.
|
|
492
|
-
// The effectful-argument refusal happens HERE, on the written
|
|
493
|
-
// form, and not in fromAtom: settling is what runs the effect, so
|
|
494
|
-
// by the time fromAtom sees a settled `move($.b)` the move has
|
|
495
|
-
// already happened and the argument is just its result.
|
|
496
356
|
if ('must' === spec.atom && args.some((a) => holdsMove(a))) {
|
|
497
357
|
this.invalid = 'invalid-arg';
|
|
498
358
|
}
|
|
@@ -518,26 +378,10 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
518
378
|
this.notdone();
|
|
519
379
|
}
|
|
520
380
|
}
|
|
521
|
-
// Normalise one atom call into state. Every argument here is already
|
|
522
|
-
// SETTLED — the constructor routes an unsettled one to `pending` —
|
|
523
|
-
// so a shape this cannot use is a genuine `invalid-arg`, not a
|
|
524
|
-
// not-yet.
|
|
525
381
|
fromAtom(atom, args) {
|
|
526
|
-
// Mark the residual invalid. It answers NOTHING: every caller
|
|
527
|
-
// spells its exit `return bad(...)` and none reads a value, so a
|
|
528
|
-
// return type would be a value nobody consumes -- and a routine
|
|
529
|
-
// that answers on some paths and not others is the shape a reader
|
|
530
|
-
// (and a static analyser) has to stop and check.
|
|
531
382
|
const bad = (why) => {
|
|
532
383
|
this.invalid = why;
|
|
533
384
|
};
|
|
534
|
-
// `unique()` is a property of the container -- not a comparison
|
|
535
|
-
// against a value -- so with no argument it says the members are
|
|
536
|
-
// pairwise DISTINCT. THE ONE ARGUMENT IS A PROJECTOR (the review's
|
|
537
|
-
// finding I: "unique()-by-field is reserved but absent", and the
|
|
538
|
-
// arity was reserved for exactly this): `unique(port)` says no two
|
|
539
|
-
// members share a `port`, which is how "no two services share a
|
|
540
|
-
// port" and "event ids are unique" are said.
|
|
541
385
|
if ('unique' === atom) {
|
|
542
386
|
if (0 === args.length) {
|
|
543
387
|
this.uniq = true;
|
|
@@ -549,12 +393,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
549
393
|
this.uniqBy = [args[0].peg];
|
|
550
394
|
return;
|
|
551
395
|
}
|
|
552
|
-
// `must(c, msg)` is Band B: an evaluate-only check against the
|
|
553
|
-
// finished value, carrying the author's own message. It is KEPT,
|
|
554
|
-
// never simplified and never consulted for emptiness or
|
|
555
|
-
// subsumption — Band B is opaque by construction, which is exactly
|
|
556
|
-
// what makes it the honest channel for a rule the algebra cannot
|
|
557
|
-
// reason about (docs/reference-language.md, "Band B: `must`").
|
|
558
396
|
if ('must' === atom) {
|
|
559
397
|
if (2 !== args.length) {
|
|
560
398
|
return bad('arg');
|
|
@@ -562,11 +400,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
562
400
|
if (!stringLeaf(args[1])) {
|
|
563
401
|
return bad('invalid-arg');
|
|
564
402
|
}
|
|
565
|
-
// A check carrying a nil can never be satisfied, so it is refused
|
|
566
|
-
// as an ARGUMENT rather than left to fail against every value with
|
|
567
|
-
// the author's message attached -- which would blame the data for
|
|
568
|
-
// a mistake in the check. `must([1-x],m)` is the reachable case: a
|
|
569
|
-
// degenerate expression leaves a nil inside the written list.
|
|
570
403
|
if (holdsNil(args[0])) {
|
|
571
404
|
return bad('invalid-arg');
|
|
572
405
|
}
|
|
@@ -604,8 +437,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
604
437
|
return bad('invalid-arg');
|
|
605
438
|
}
|
|
606
439
|
const src = a.peg;
|
|
607
|
-
// Normalise BEFORE compiling: the host engines only ever see a
|
|
608
|
-
// pattern that cannot be read two ways (ADR-003).
|
|
609
440
|
const [norm, why] = normaliseRe(src);
|
|
610
441
|
if ('' !== why) {
|
|
611
442
|
this.invalidWhy = why;
|
|
@@ -613,23 +444,9 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
613
444
|
}
|
|
614
445
|
let re;
|
|
615
446
|
try {
|
|
616
|
-
// The `u` flag is REQUIRED for parity, not an optimisation.
|
|
617
|
-
// Without it JavaScript matches UTF-16 code units while RE2
|
|
618
|
-
// matches code points, so `re("^.$")` accepted U+1D11E in Go
|
|
619
|
-
// and refused it in TypeScript (and `^..$` did the reverse).
|
|
620
|
-
// With it, `.` and every quantifier count code points in both.
|
|
621
|
-
// It also makes JavaScript refuse the identity escapes this
|
|
622
|
-
// scanner rejects by hand, which is defence in depth rather
|
|
623
|
-
// than a substitute: RE2 accepts some of them, so the scanner
|
|
624
|
-
// is what keeps the two ports agreeing.
|
|
625
447
|
re = new RegExp(norm, 'u');
|
|
626
448
|
}
|
|
627
449
|
catch (e) {
|
|
628
|
-
// The host engine refuses what the subset scanner passed — a
|
|
629
|
-
// malformed quantifier, an unbalanced group. Same refusal under
|
|
630
|
-
// the same code: the author gets one rule, not two. The message
|
|
631
|
-
// is the host's, so it is NOT pinned by a shared row; the code
|
|
632
|
-
// and the located frame are.
|
|
633
450
|
this.invalidWhy = 'not a valid pattern';
|
|
634
451
|
return bad('constraint_pattern');
|
|
635
452
|
}
|
|
@@ -637,16 +454,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
637
454
|
this.res = [{ v: a, src, norm, re }];
|
|
638
455
|
return;
|
|
639
456
|
}
|
|
640
|
-
// `length` is the other non-ORDER atom: its argument constrains the
|
|
641
|
-
// COUNT, not the value, so it is itself a residual over the integer
|
|
642
|
-
// domain (docs/reference-language.md, "`length` semantics"). It is
|
|
643
|
-
// resolved HERE, at construction, by walking the written argument
|
|
644
|
-
// rather than by unifying it: the func-paren handler builds atoms
|
|
645
|
-
// without an AontuContext, so there is nothing to fold a nested
|
|
646
|
-
// conjunct through. Walking is enough because a length argument is by
|
|
647
|
-
// definition a meet of concrete Band A atoms; anything else (a
|
|
648
|
-
// reference, an expression) is refused rather than deferred, the
|
|
649
|
-
// same discipline min/max apply to their own arguments.
|
|
650
457
|
if ('length' === atom) {
|
|
651
458
|
const arg = countArgState(a);
|
|
652
459
|
if (null == arg) {
|
|
@@ -680,15 +487,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
680
487
|
// Every branch of the ladder assigns, so no initialiser: a
|
|
681
488
|
// residual is stable and the ladder is total.
|
|
682
489
|
let out;
|
|
683
|
-
// A rel residual or a graph atom HOLDS constraints for the value
|
|
684
|
-
// they stand for (RELATIONS P1/P2): hand the drive over before
|
|
685
|
-
// any settling, exactly as a container does, so `rel(t) & re(x)`
|
|
686
|
-
// reads the same in either order. Reached through the INCLUDE
|
|
687
|
-
// flow (a loaded schema's conjunct re-drives with the constraint
|
|
688
|
-
// on the left) -- inline documents route rel/atom peers through
|
|
689
|
-
// unite's b-drives first, which is why use-cases/12-relations
|
|
690
|
-
// refused without this arm while every inline row stayed green;
|
|
691
|
-
// pinned by constraint-hands-drive-to-rel-and-atom.
|
|
692
490
|
if (true === peer?.isRel
|
|
693
491
|
|| true === peer?.isGraphAtom) {
|
|
694
492
|
out = peer.unify(this, ctx);
|
|
@@ -719,31 +517,11 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
719
517
|
}
|
|
720
518
|
/* node:coverage ignore next 12 */
|
|
721
519
|
else {
|
|
722
|
-
// Every other shape: no order, no membership, nothing to count —
|
|
723
|
-
// a conflict of the constraint family. The ladder above is total
|
|
724
|
-
// in practice: every remaining Val kind either sorts BELOW a
|
|
725
|
-
// constraint in a conjunct (conjunct, disjunct, pref, ref) and so
|
|
726
|
-
// drives the meet from its own side, or resolves to a
|
|
727
|
-
// scalar/container before a constraint sees it (func, op, var,
|
|
728
|
-
// expect). The arm is kept because "in practice" depends on the
|
|
729
|
-
// cjo table, and a future value class would land here rather than
|
|
730
|
-
// falling out of unify with no result.
|
|
731
520
|
out = this.fail(ctx, peer);
|
|
732
521
|
}
|
|
733
522
|
ctx.explain && (0, utility_1.explainClose)(te, out);
|
|
734
523
|
return out;
|
|
735
524
|
}
|
|
736
|
-
// Resolve a pending atom's arguments and, once they have all settled,
|
|
737
|
-
// become the residual they describe (G1 phase 4).
|
|
738
|
-
//
|
|
739
|
-
// This is the residuation discipline FuncBaseVal already follows for
|
|
740
|
-
// its own operands: push each unsettled argument one step by unifying
|
|
741
|
-
// it with `top`, and if any is still moving, mark not-done and defer
|
|
742
|
-
// — either as this same pending atom (against a `top` peer) or
|
|
743
|
-
// wrapped with the peer in a conjunct the next pass will re-enter.
|
|
744
|
-
// Nothing is decided from a half-resolved argument, which is what
|
|
745
|
-
// keeps `min($.lo)` from reporting a conflict against a bound that
|
|
746
|
-
// has not arrived yet.
|
|
747
525
|
settle(peer, ctx) {
|
|
748
526
|
const TOP = (0, top_1.top)();
|
|
749
527
|
const pend = this.pending;
|
|
@@ -752,9 +530,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
752
530
|
for (const arg of pend.args) {
|
|
753
531
|
let next = arg;
|
|
754
532
|
if (true !== arg?.done) {
|
|
755
|
-
// Charged to the depth budget: this recurses without going
|
|
756
|
-
// through `unite`, so the counter would otherwise stay flat
|
|
757
|
-
// while the stack grows (the rule FuncBaseVal follows).
|
|
758
533
|
next = (0, unify_1.withDepth)(ctx, arg, TOP, () => arg.unify(TOP, ctx));
|
|
759
534
|
}
|
|
760
535
|
settled = settled && true === next?.done;
|
|
@@ -801,9 +576,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
801
576
|
return this.fail(ctx, peer);
|
|
802
577
|
}
|
|
803
578
|
if (null != this.count) {
|
|
804
|
-
// Only a string among the scalars has a length, and it is counted
|
|
805
|
-
// in CODE POINTS -- not UTF-16 units (this host's native count)
|
|
806
|
-
// and not bytes (Go's). Iterating a string yields code points.
|
|
807
579
|
if (!stringishLeaf(peer)) {
|
|
808
580
|
return this.fail(ctx, peer);
|
|
809
581
|
}
|
|
@@ -820,30 +592,10 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
820
592
|
}
|
|
821
593
|
return peer;
|
|
822
594
|
}
|
|
823
|
-
// Band B, applied to a finished value. Each check is a plain
|
|
824
|
-
// unification against a CLONE of the peer: `must` reports, it never
|
|
825
|
-
// contributes: whatever the check would have added to the value is
|
|
826
|
-
// discarded, and `peer` is returned untouched by the callers.
|
|
827
|
-
//
|
|
828
|
-
// The trial runs in an isolated collect context so a failing check
|
|
829
|
-
// leaves nothing on the caller's error list — only the located nil
|
|
830
|
-
// this returns, carrying the author's own message.
|
|
831
|
-
// `final` is the generation-time reading (see settleContainer): a
|
|
832
|
-
// must whose own check is a SIZING atom inherits that atom's
|
|
833
|
-
// provisionality, because `must(length(2), …)` against a map that may
|
|
834
|
-
// still gain members has not failed yet -- it has not been answered.
|
|
835
|
-
// Without this the must would decide against whatever the container
|
|
836
|
-
// held when it first settled, which is the very defect the sizing
|
|
837
|
-
// atoms were fixed for (use-cases/BUGS.md §16, §17).
|
|
838
595
|
checkMusts(peer, ctx, final) {
|
|
839
596
|
for (const m of this.musts) {
|
|
840
597
|
const trial = ctx.clone({ err: [], collect: true });
|
|
841
598
|
let got = (0, unify_1.unite)(trial, m.v.clone(trial), peer.clone(trial), 'must');
|
|
842
|
-
// A must whose check is a SIZING atom answers a residue rather
|
|
843
|
-
// than a verdict, because the atom is waiting for members that
|
|
844
|
-
// may still arrive. Before generation that residue IS the answer
|
|
845
|
-
// -- the must has not failed, it has not been asked yet -- and at
|
|
846
|
-
// generation it is settled, because nothing more can arrive.
|
|
847
599
|
const residue = (0, BagVal_1.sizingResidue)(got);
|
|
848
600
|
if (undefined !== residue) {
|
|
849
601
|
if (true !== final) {
|
|
@@ -861,25 +613,9 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
861
613
|
}
|
|
862
614
|
return undefined;
|
|
863
615
|
}
|
|
864
|
-
// THE FINAL READING of a sizing atom over a container: the same
|
|
865
|
-
// checks admitContainer makes, with the provisional ones taken as
|
|
866
|
-
// decided. Called from ConjunctVal.gen, which is where no more
|
|
867
|
-
// members can arrive. Returns the container (to generate) or the
|
|
868
|
-
// constraint's own nil (to report).
|
|
869
616
|
settleContainer(peer, ctx) {
|
|
870
617
|
return this.admitContainer(peer, ctx, true);
|
|
871
618
|
}
|
|
872
|
-
// Membership for a container peer. Only the SIZING atoms have anything
|
|
873
|
-
// to say about a map or a list; every other atom is scalar-domain and
|
|
874
|
-
// refuses one.
|
|
875
|
-
//
|
|
876
|
-
// The members that count are the members that GENERATE
|
|
877
|
-
// (docs/reference-language.md, "`length` semantics"), and rather than
|
|
878
|
-
// mirror generation's filter — type/hide marks, optional keys that
|
|
879
|
-
// drop, empty optional values — this asks generation itself, in an
|
|
880
|
-
// isolated collect context so nothing leaks into the caller's errors.
|
|
881
|
-
// A mirror would be a second copy of a filter that has already grown
|
|
882
|
-
// subtle, free to drift from it; asking is correct by construction.
|
|
883
619
|
admitContainer(peer, ctx, final) {
|
|
884
620
|
// A scalar-domain residual has no reading over a container.
|
|
885
621
|
if (null != this.domain) {
|
|
@@ -896,13 +632,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
896
632
|
if (null != bad) {
|
|
897
633
|
return bad;
|
|
898
634
|
}
|
|
899
|
-
// A MUST OVER A CONTAINER RESIDUATES with the atoms, for the same
|
|
900
|
-
// reason (use-cases/BUGS.md §17): `must({t: max(60)}, …)` beside a
|
|
901
|
-
// `{t: integer}` schema was answered against the schema layer
|
|
902
|
-
// ALONE, and discharged before the data it was written to judge
|
|
903
|
-
// ever arrived. It is decided at generation, where the value is
|
|
904
|
-
// whole -- unless there is nothing else on the constraint AND the
|
|
905
|
-
// reading is already final.
|
|
906
635
|
if (!this.uniq && 0 === this.uniqBy.length && null == this.count) {
|
|
907
636
|
if (true === final || 0 === this.musts.length) {
|
|
908
637
|
return peer;
|
|
@@ -911,42 +640,11 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
911
640
|
}
|
|
912
641
|
const members = emittedMembers(peer, ctx);
|
|
913
642
|
if (null == members) {
|
|
914
|
-
// NOT COUNTABLE YET IS NOT A PASS. A container that cannot
|
|
915
|
-
// generate cannot be counted, and a SCHEMA is exactly that: the
|
|
916
|
-
// members of `{a: integer}` are types, so nothing is emitted and
|
|
917
|
-
// nothing can be counted. Discharging the atom here was the §16
|
|
918
|
-
// defect wearing its other face -- `length(min(2)) & {a: integer}`
|
|
919
|
-
// dropped its bound while still alone, so the data half of a
|
|
920
|
-
// `vet` meet was never measured at all and short data vetted
|
|
921
|
-
// clean against a bound the evaluator enforces.
|
|
922
|
-
//
|
|
923
|
-
// At generation the reading IS final: a container that still
|
|
924
|
-
// cannot generate has its own error, and that error is the one
|
|
925
|
-
// worth reporting, so it passes through untouched.
|
|
926
643
|
if (true === final) {
|
|
927
644
|
return peer;
|
|
928
645
|
}
|
|
929
646
|
return this.hold(peer, ctx);
|
|
930
647
|
}
|
|
931
|
-
// MONOTONE READINGS ONLY (the review's finding C, use-cases/BUGS.md
|
|
932
|
-
// §16). Members ACCUMULATE under unification -- a meet adds keys and
|
|
933
|
-
// never removes them -- so a settled container is settled ON ITS
|
|
934
|
-
// OWN and not against every value that may still contribute. The
|
|
935
|
-
// schema half of a `vet` meet, a document that is about to receive
|
|
936
|
-
// an `@` include, a bag a later `pack` will fill: each settles, and
|
|
937
|
-
// an atom that decided there decided too early.
|
|
938
|
-
//
|
|
939
|
-
// So a verdict is taken only when MORE MEMBERS CANNOT CHANGE IT:
|
|
940
|
-
// - an upper bound VIOLATED is permanent -> refuse now;
|
|
941
|
-
// satisfied is provisional -> keep the atom, re-check later.
|
|
942
|
-
// - a lower bound SATISFIED is permanent -> that part may go;
|
|
943
|
-
// violated is provisional -> keep the atom (which is why
|
|
944
|
-
// `length(min(1))` beside a template no longer kills the schema
|
|
945
|
-
// it was written for).
|
|
946
|
-
// - a DUPLICATE is permanent -> refuse now; distinctness is
|
|
947
|
-
// provisional -> keep the atom.
|
|
948
|
-
// Anything provisional residuates, exactly as an unsettled
|
|
949
|
-
// container does above, and the two spellings then agree.
|
|
950
648
|
const count = null == this.count ? undefined : this.count;
|
|
951
649
|
const n = members.length;
|
|
952
650
|
if (null != count) {
|
|
@@ -964,11 +662,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
964
662
|
}
|
|
965
663
|
}
|
|
966
664
|
if (this.uniq) {
|
|
967
|
-
// Members compare by CANONICAL FORM, which reduces to scalar
|
|
968
|
-
// identity for scalars (so [1, 1.0] is distinct) and gives
|
|
969
|
-
// structural equality for container members without a second
|
|
970
|
-
// rule. A generated value could not express the first: `1` and
|
|
971
|
-
// `1.0` generate the same JSON number.
|
|
972
665
|
const seen = new Set();
|
|
973
666
|
for (const m of members) {
|
|
974
667
|
const key = m.canon;
|
|
@@ -978,10 +671,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
978
671
|
seen.add(key);
|
|
979
672
|
}
|
|
980
673
|
}
|
|
981
|
-
// ... and the same test per PROJECTED key. A member that has no such
|
|
982
|
-
// key FAILS the constraint rather than being skipped: distinctness
|
|
983
|
-
// it cannot be shown to have is distinctness it does not have, and
|
|
984
|
-
// skipping would let one keyless record hide a duplicate.
|
|
985
674
|
for (const field of this.uniqBy) {
|
|
986
675
|
const seen = new Set();
|
|
987
676
|
for (const m of members) {
|
|
@@ -1008,46 +697,14 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
1008
697
|
if (spent) {
|
|
1009
698
|
return peer;
|
|
1010
699
|
}
|
|
1011
|
-
// DONE, unlike the unsettled case above. The container HAS settled;
|
|
1012
|
-
// the atom is kept only because a LATER value could still add
|
|
1013
|
-
// members, and a residue that reported itself unresolved would
|
|
1014
|
-
// leave every enclosing value unresolved with it -- a `type()`
|
|
1015
|
-
// waiting on its argument for ever, and use case 09's whole
|
|
1016
|
-
// registry with it.
|
|
1017
|
-
// The ATOM is done too, not just the conjunct. An earlier pass may
|
|
1018
|
-
// have set `dc = 0` on the unsettled branch above, and a conjunct
|
|
1019
|
-
// recomputes its own doneness from its terms on every later meet --
|
|
1020
|
-
// so a stale 0 here would drag the residue, and every value holding
|
|
1021
|
-
// it, back to unresolved for ever.
|
|
1022
700
|
return this.hold(peer, ctx);
|
|
1023
701
|
}
|
|
1024
|
-
// The atom kept on a value whose reading is still provisional.
|
|
1025
|
-
// DONE, unlike the unsettled container above: the value HAS settled;
|
|
1026
|
-
// the atom is kept only because a LATER value could still add
|
|
1027
|
-
// members, and a residue that reported itself unresolved would leave
|
|
1028
|
-
// every enclosing value unresolved with it -- a `type()` waiting on
|
|
1029
|
-
// its argument for ever, and use case 09's whole registry with it.
|
|
1030
|
-
// The ATOM is done too, not just the conjunct. An earlier pass may
|
|
1031
|
-
// have set `dc = 0` on the unsettled branch, and a conjunct
|
|
1032
|
-
// recomputes its own doneness from its terms on every later meet --
|
|
1033
|
-
// so a stale 0 here would drag the residue, and every value holding
|
|
1034
|
-
// it, back to unresolved for ever.
|
|
1035
702
|
hold(peer, ctx) {
|
|
1036
703
|
this.dc = type_1.DONE;
|
|
1037
704
|
const held = new ConjunctVal_1.ConjunctVal({ peg: [this, peer] }, ctx);
|
|
1038
705
|
held.dc = type_1.DONE;
|
|
1039
706
|
return held;
|
|
1040
707
|
}
|
|
1041
|
-
// Meet with a kind: `number` (or `string` on the string domain) is
|
|
1042
|
-
// already implied by an ORDER atom's argument; a numeric LEAF narrows
|
|
1043
|
-
// the residual; anything else has an empty intersection with the
|
|
1044
|
-
// constraint's domain.
|
|
1045
|
-
//
|
|
1046
|
-
// A sizing residual (`length`, `unique`) has no domain of its own -- a
|
|
1047
|
-
// count says nothing about what is counted -- so a kind here SETS one
|
|
1048
|
-
// rather than merely agreeing with it: `string & length(3)` is a
|
|
1049
|
-
// three-character string, and `number & length(3)` is empty because a
|
|
1050
|
-
// number has no length (stateEmpty decides that, not this).
|
|
1051
708
|
meetKind(peer, ctx) {
|
|
1052
709
|
const marker = peer.peg;
|
|
1053
710
|
const merged = this.cloneState();
|
|
@@ -1101,14 +758,7 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
1101
758
|
null == peer.count ? this.count : meetCount(this.count, peer.count);
|
|
1102
759
|
// `unique()` is idempotent: two of them are one.
|
|
1103
760
|
merged.uniq = this.uniq || peer.uniq;
|
|
1104
|
-
// `unique(a) & unique(b)` is BOTH, not the later one: each names a
|
|
1105
|
-
// key on which the members must differ, and dropping either would
|
|
1106
|
-
// silently weaken the constraint. Sorted and deduplicated, so the
|
|
1107
|
-
// meet is commutative and `unique(a) & unique(a)` is one atom.
|
|
1108
761
|
merged.uniqBy = [...new Set([...this.uniqBy, ...peer.uniqBy])].sort();
|
|
1109
|
-
// Band B checks accumulate in written order and are never merged,
|
|
1110
|
-
// deduplicated or reordered: each carries its own author message,
|
|
1111
|
-
// and two checks with the same shape may still say different things.
|
|
1112
762
|
merged.musts = [...this.musts, ...peer.musts];
|
|
1113
763
|
return this.finish(merged, ctx, peer);
|
|
1114
764
|
}
|
|
@@ -1122,10 +772,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
1122
772
|
out.site.row = this.site.row;
|
|
1123
773
|
out.site.col = this.site.col;
|
|
1124
774
|
out.site.url = this.site.url;
|
|
1125
|
-
// Marks ratchet across a meet (the propagateMarks rule): a fresh
|
|
1126
|
-
// residual must carry both operands' type/hide marks, or a
|
|
1127
|
-
// `type(min(0)) & max(10)` merge would silently unmark the field
|
|
1128
|
-
// (the Go fold re-ratchets from its terms; this is the TS twin).
|
|
1129
775
|
(0, utility_1.propagateMarks)(this, out);
|
|
1130
776
|
(0, utility_1.propagateMarks)(peer, out);
|
|
1131
777
|
return out;
|
|
@@ -1189,9 +835,6 @@ class ConstraintVal extends FeatureVal_1.FeatureVal {
|
|
|
1189
835
|
}
|
|
1190
836
|
}
|
|
1191
837
|
exports.ConstraintVal = ConstraintVal;
|
|
1192
|
-
// The tighter of two like-direction bounds: the higher lower bound (or
|
|
1193
|
-
// lower upper bound); on the same point the OPEN bound wins, and on a
|
|
1194
|
-
// full tie the tower-lowest endpoint spelling survives.
|
|
1195
838
|
function tighter(domain, a, b, lower) {
|
|
1196
839
|
if (null == a)
|
|
1197
840
|
return b;
|
|
@@ -1226,13 +869,6 @@ function dedupSorted(domain, neqs) {
|
|
|
1226
869
|
}
|
|
1227
870
|
return out;
|
|
1228
871
|
}
|
|
1229
|
-
// Is this value, or anything inside it, a nil? A written argument that
|
|
1230
|
-
// holds one can never be satisfied, so the atom refuses it as an
|
|
1231
|
-
// argument rather than reporting a mystery failure against every peer.
|
|
1232
|
-
// Every caller passes a Val: `args[0]` comes from atomArgs, and the
|
|
1233
|
-
// walk below descends only into container pegs, which hold Vals. The
|
|
1234
|
-
// null/non-Val guard this function used to open with was therefore
|
|
1235
|
-
// unreachable, and the coverage gate said so.
|
|
1236
872
|
function holdsNil(v) {
|
|
1237
873
|
if (true === v.isNil) {
|
|
1238
874
|
return true;
|
|
@@ -1250,12 +886,6 @@ function holdsNil(v) {
|
|
|
1250
886
|
}
|
|
1251
887
|
return false;
|
|
1252
888
|
}
|
|
1253
|
-
// Whether a value, or anything inside it, is an effectful call — one
|
|
1254
|
-
// whose evaluation changes a node OTHER than the one being computed.
|
|
1255
|
-
// `move()` is the only builtin that does: it hides its resolution
|
|
1256
|
-
// target in place. Band B refuses one as an argument, because settling
|
|
1257
|
-
// it runs the effect against the live root before `must`'s trial clone
|
|
1258
|
-
// is taken, and a check that mutates cannot be report-only.
|
|
1259
889
|
function holdsMove(v) {
|
|
1260
890
|
if (true === v.isFunc && 'move' === v.funcname?.()) {
|
|
1261
891
|
return true;
|
|
@@ -1273,15 +903,6 @@ function holdsMove(v) {
|
|
|
1273
903
|
}
|
|
1274
904
|
return false;
|
|
1275
905
|
}
|
|
1276
|
-
// The written arguments of an atom, flattened.
|
|
1277
|
-
//
|
|
1278
|
-
// A multi-argument call arrives from the func-paren grammar as ONE
|
|
1279
|
-
// entry holding the comma group, and `neq([3,1,2])` means the same as
|
|
1280
|
-
// `neq(3,1,2)`. The group is always a ListVal by the time it reaches
|
|
1281
|
-
// here -- the func-paren handler rawToVals every argument (issue #49) --
|
|
1282
|
-
// so there is no raw-array case to unwrap. Flattening happens before
|
|
1283
|
-
// the settled check, because an unsettled member hiding inside the
|
|
1284
|
-
// group would otherwise make the atom look ready.
|
|
1285
906
|
function atomArgs(atom, args) {
|
|
1286
907
|
if (('neq' === atom || 'must' === atom) && 1 === args.length &&
|
|
1287
908
|
true === args[0]?.isList) {
|
|
@@ -1289,19 +910,11 @@ function atomArgs(atom, args) {
|
|
|
1289
910
|
}
|
|
1290
911
|
return args;
|
|
1291
912
|
}
|
|
1292
|
-
// The canonical rendering of a residual, in the fixed atom order:
|
|
1293
|
-
// kind, lower bound, upper bound, neq, re, length, unique. Taken over the
|
|
1294
|
-
// STATE rather than the Val because `length`'s argument is a residual too,
|
|
1295
|
-
// and renders by exactly the same rules.
|
|
1296
913
|
function canonState(s) {
|
|
1297
914
|
const parts = [];
|
|
1298
915
|
if (null != s.kind) {
|
|
1299
916
|
parts.push(s.kind.name.toLowerCase());
|
|
1300
917
|
}
|
|
1301
|
-
// An ORDER atom's argument implies the domain, so it is not spelled
|
|
1302
|
-
// out. A SIZING residual carries no order, and there `string` is the
|
|
1303
|
-
// only thing saying what is being sized -- drop it and the reparse
|
|
1304
|
-
// would admit lists and maps too.
|
|
1305
918
|
else if ('string' === s.domain &&
|
|
1306
919
|
null == s.lo && null == s.hi && 0 === s.neqs.length && 0 === s.res.length) {
|
|
1307
920
|
parts.push('string');
|
|
@@ -1319,19 +932,11 @@ function canonState(s) {
|
|
|
1319
932
|
parts.push('re(' + r.v.canon + ')');
|
|
1320
933
|
}
|
|
1321
934
|
if (null != s.count) {
|
|
1322
|
-
// Rendered UNABRIDGED, implied parts and all: `length(3)` canonicalises
|
|
1323
|
-
// to `length(integer&min(3)&max(3))` because that IS the residual the
|
|
1324
|
-
// count must satisfy, and canon is a normal form (G6 hashes it),
|
|
1325
|
-
// not a pretty-printer. Abbreviating would mean a second set of
|
|
1326
|
-
// rules for when the implied `integer & min(0)` may be dropped.
|
|
1327
935
|
parts.push('length(' + canonState(s.count) + ')');
|
|
1328
936
|
}
|
|
1329
937
|
if (s.uniq) {
|
|
1330
938
|
parts.push('unique()');
|
|
1331
939
|
}
|
|
1332
|
-
// After the bare atom, and sorted: canon is a normal form, so two
|
|
1333
|
-
// documents writing the same keys in different orders must render
|
|
1334
|
-
// the same string.
|
|
1335
940
|
for (const key of s.uniqBy) {
|
|
1336
941
|
parts.push('unique(' + JSON.stringify(key) + ')');
|
|
1337
942
|
}
|
|
@@ -1344,15 +949,6 @@ function canonState(s) {
|
|
|
1344
949
|
}
|
|
1345
950
|
return parts.join('&');
|
|
1346
951
|
}
|
|
1347
|
-
// SUBSUMPTION over two residuals (G3, the query built on the table in
|
|
1348
|
-
// docs/reference-language.md "Subsumption"): does every value `s`
|
|
1349
|
-
// admits pass `g` too? Implemented here because the compare machinery
|
|
1350
|
-
// (cmpVal, sameScalar, the recursive count state) is this module's.
|
|
1351
|
-
//
|
|
1352
|
-
// Three-valued: true / false / 'undecided'. `must` on the GENERAL side
|
|
1353
|
-
// is undecided by construction (a Band B predicate is opaque — G3 maps
|
|
1354
|
-
// the table's "never" to the query's honest sub_evaluate_only); every
|
|
1355
|
-
// other approximation folds toward false, the safe direction.
|
|
1356
952
|
function constraintStateSubsumes(g, s) {
|
|
1357
953
|
// A Band B predicate on the general side makes its admitted set
|
|
1358
954
|
// unknowable; an extra `must` on the SPECIFIC side only narrows it
|
|
@@ -1407,11 +1003,6 @@ function constraintStateSubsumes(g, s) {
|
|
|
1407
1003
|
return false;
|
|
1408
1004
|
}
|
|
1409
1005
|
}
|
|
1410
|
-
// `unique()` subsumes only itself on that axis: a general uniqueness
|
|
1411
|
-
// demand admits no container the unconstrained specific also admits.
|
|
1412
|
-
// ... and a general `unique(k)` needs the same key on the specific
|
|
1413
|
-
// side: distinctness on `port` says nothing about distinctness on
|
|
1414
|
-
// `name`.
|
|
1415
1006
|
if (g.uniqBy.some((k) => !s.uniqBy.includes(k))) {
|
|
1416
1007
|
return false;
|
|
1417
1008
|
}
|
|
@@ -1440,18 +1031,11 @@ function constraintAdmitsScalar(g, scalar) {
|
|
|
1440
1031
|
if (g.uniq || 0 < g.uniqBy.length) {
|
|
1441
1032
|
return false;
|
|
1442
1033
|
}
|
|
1443
|
-
// A count residual admits by LENGTH, which is the meet's business;
|
|
1444
|
-
// the query answers false (the safe direction) rather than
|
|
1445
|
-
// reimplementing the sizing walk here.
|
|
1446
1034
|
if (null != g.count) {
|
|
1447
1035
|
return false;
|
|
1448
1036
|
}
|
|
1449
1037
|
return stateAdmits(g, scalar);
|
|
1450
1038
|
}
|
|
1451
|
-
// Does this residual's ORDER and MEMBERSHIP part admit the scalar? The
|
|
1452
|
-
// sizing atoms are deliberately not consulted: `admit` applies them to
|
|
1453
|
-
// the peer's length, and the count check applies this same function to
|
|
1454
|
-
// the count.
|
|
1455
1039
|
function stateAdmits(s, peer) {
|
|
1456
1040
|
const domainOf = numericLeaf(peer) ? 'number' :
|
|
1457
1041
|
stringishLeaf(peer) ? 'string' : undefined;
|
|
@@ -1488,10 +1072,6 @@ function stateAdmits(s, peer) {
|
|
|
1488
1072
|
return false;
|
|
1489
1073
|
}
|
|
1490
1074
|
}
|
|
1491
|
-
// Every accumulated pattern must match: the meet of two `re` atoms
|
|
1492
|
-
// is conjunction, and matching is UNANCHORED in both engines
|
|
1493
|
-
// (JS RegExp.test, Go regexp.MatchString), so `re("el")` admits
|
|
1494
|
-
// "hello". Anchor with ^ and $ to mean the whole string.
|
|
1495
1075
|
for (const r of s.res) {
|
|
1496
1076
|
if (!r.re.test(peer.peg)) {
|
|
1497
1077
|
return false;
|
|
@@ -1499,13 +1079,7 @@ function stateAdmits(s, peer) {
|
|
|
1499
1079
|
}
|
|
1500
1080
|
return true;
|
|
1501
1081
|
}
|
|
1502
|
-
// The eager emptiness rules. Each is EXACT -- it reports empty only
|
|
1503
|
-
// where no value could satisfy the residual -- so the algebra stays
|
|
1504
|
-
// sound; the incompleteness it accepts is documented in
|
|
1505
|
-
// docs/reference-language.md, "Emptiness".
|
|
1506
1082
|
function stateEmpty(s) {
|
|
1507
|
-
// Two disagreeing kind narrowings inside a length argument, recorded by
|
|
1508
|
-
// meetCount because that meet has no ctx to fail through.
|
|
1509
1083
|
if (s.clash) {
|
|
1510
1084
|
return true;
|
|
1511
1085
|
}
|
|
@@ -1539,10 +1113,6 @@ function stateEmpty(s) {
|
|
|
1539
1113
|
}
|
|
1540
1114
|
}
|
|
1541
1115
|
}
|
|
1542
|
-
// Point deletion under a narrowed leaf: a closed point interval
|
|
1543
|
-
// whose single value of the narrowed leaf is excluded is empty
|
|
1544
|
-
// (integer & min(3) & max(3) & neq(3)). Without a narrowing the
|
|
1545
|
-
// point survives in the other leaves.
|
|
1546
1116
|
if (null != s.kind && null != s.lo && null != s.hi &&
|
|
1547
1117
|
!s.lo.open && !s.hi.open &&
|
|
1548
1118
|
0 === cmpVal(d, s.lo.v, s.hi.v)) {
|
|
@@ -1552,10 +1122,6 @@ function stateEmpty(s) {
|
|
|
1552
1122
|
}
|
|
1553
1123
|
}
|
|
1554
1124
|
}
|
|
1555
|
-
// Sizing over the number domain: a number has neither a length nor
|
|
1556
|
-
// members, so `integer & length(3)` and `min(2) & unique()` admit
|
|
1557
|
-
// nothing. Uniqueness over the string domain is empty for the same
|
|
1558
|
-
// reason -- a string's members are not values the algebra compares.
|
|
1559
1125
|
if ('number' === d && (null != s.count || s.uniq ||
|
|
1560
1126
|
0 < s.uniqBy.length)) {
|
|
1561
1127
|
return true;
|
|
@@ -1570,10 +1136,6 @@ function stateEmpty(s) {
|
|
|
1570
1136
|
}
|
|
1571
1137
|
return false;
|
|
1572
1138
|
}
|
|
1573
|
-
// The base every `length` argument meets: a count is a non-negative
|
|
1574
|
-
// integer, whatever else the argument says (docs/reference-language.md,
|
|
1575
|
-
// "`length` semantics" -- `length(c)` is empty iff `c & integer & min(0)`
|
|
1576
|
-
// is).
|
|
1577
1139
|
function countBase() {
|
|
1578
1140
|
return {
|
|
1579
1141
|
domain: 'number',
|
|
@@ -1592,12 +1154,6 @@ function countBase() {
|
|
|
1592
1154
|
function countVal(n) {
|
|
1593
1155
|
return new IntegerVal_1.IntegerVal({ peg: n });
|
|
1594
1156
|
}
|
|
1595
|
-
// The pure meet of two count residuals. Both are number-domain and
|
|
1596
|
-
// carry no pattern or sizing atom of their own, so the merge is the
|
|
1597
|
-
// interval/exclusion part alone. A kind disagreement becomes a `clash`
|
|
1598
|
-
// rather than an error: this meet runs at construction, where there is
|
|
1599
|
-
// no AontuContext to raise through, and an empty residual carries the
|
|
1600
|
-
// same news to `unify`.
|
|
1601
1157
|
function meetCount(a, b) {
|
|
1602
1158
|
return {
|
|
1603
1159
|
domain: 'number',
|
|
@@ -1615,18 +1171,6 @@ function meetCount(a, b) {
|
|
|
1615
1171
|
(null != a.kind && null != b.kind && a.kind !== b.kind),
|
|
1616
1172
|
};
|
|
1617
1173
|
}
|
|
1618
|
-
// Read a WRITTEN `length` argument as a count residual, or undefined when
|
|
1619
|
-
// it is not one. Accepted: an integer literal (an exact count), a
|
|
1620
|
-
// numeric kind, a Band A residual over the number domain, and any
|
|
1621
|
-
// conjunct of those. A conjunct never reaches here any more: an
|
|
1622
|
-
// unsettled argument is held as `pending` and folded before the count
|
|
1623
|
-
// reads it (G1 phase 4), so `length(min(2)&max(5))` arrives as the
|
|
1624
|
-
// single residual it folds to.
|
|
1625
|
-
//
|
|
1626
|
-
// Anything else is refused rather than deferred. A reference or an
|
|
1627
|
-
// expression would have to residuate, and the sizing atoms do not
|
|
1628
|
-
// residuate on their ARGUMENT -- only on the peer whose members are
|
|
1629
|
-
// still settling.
|
|
1630
1174
|
function countArgState(arg) {
|
|
1631
1175
|
if (numericLeaf(arg)) {
|
|
1632
1176
|
return {
|
|
@@ -1673,18 +1217,7 @@ function countArgState(arg) {
|
|
|
1673
1217
|
}
|
|
1674
1218
|
return undefined;
|
|
1675
1219
|
}
|
|
1676
|
-
// A container is SETTLED when it and every child have converged. Until
|
|
1677
|
-
// then the member set can still change — an optional key whose value is
|
|
1678
|
-
// a still-resolving reference may yet generate — so a sizing atom must
|
|
1679
|
-
// defer rather than decide (docs/reference-language.md, "`length`
|
|
1680
|
-
// semantics"). Note that an optional holding a settled-but-ungenerable
|
|
1681
|
-
// value, `{x:1,y?:number}`, IS settled: the map converges on the first
|
|
1682
|
-
// pass and `y` is simply never emitted.
|
|
1683
1220
|
function containerSettled(bag) {
|
|
1684
|
-
// The bag's OWN done-counter is enough: BagVal.unify sets it from the
|
|
1685
|
-
// AND over its children, so an unsettled child already leaves the bag
|
|
1686
|
-
// unsettled. Walking the children again would be a second, drifting
|
|
1687
|
-
// copy of that rule.
|
|
1688
1221
|
return true === bag.done;
|
|
1689
1222
|
}
|
|
1690
1223
|
// The child kinds `BagVal.gen` will attempt to generate. Anything else
|
|
@@ -1695,32 +1228,12 @@ function genable(child) {
|
|
|
1695
1228
|
true === child.isList || true === child.isPref ||
|
|
1696
1229
|
true === child.isRef || true === child.isDisjunct ||
|
|
1697
1230
|
true === child.isNil ||
|
|
1698
|
-
// A settled sizing residue generates through ConjunctVal.gen, so it
|
|
1699
|
-
// is a member like any other -- and a `length` that did not count
|
|
1700
|
-
// its sibling's `unique` would be the early-fold defect again, one
|
|
1701
|
-
// level up.
|
|
1702
1231
|
undefined !== (0, BagVal_1.sizingResidue)(child);
|
|
1703
1232
|
}
|
|
1704
|
-
// The children a bag would EMIT, mirroring the selection in
|
|
1705
|
-
// `BagVal.gen` — type/hide marks skipped, non-generable residue and
|
|
1706
|
-
// values that generate nothing dropped, optional keys dropped when
|
|
1707
|
-
// they generate empty.
|
|
1708
|
-
//
|
|
1709
|
-
// It returns the member VALS rather than their generated values,
|
|
1710
|
-
// because uniqueness compares canon and a generated value cannot
|
|
1711
|
-
// express that distinction: `1` and `1.0` generate the same JSON number
|
|
1712
|
-
// and canon differently. Counting uses the same list, so both sizing
|
|
1713
|
-
// atoms see exactly one definition of "member".
|
|
1714
|
-
//
|
|
1715
|
-
// Returns undefined when a REQUIRED child is residue: the container's
|
|
1716
|
-
// own `gen` raises there, and that error is the one worth reporting.
|
|
1717
1233
|
function emittedMembers(bag, ctx) {
|
|
1718
1234
|
const out = [];
|
|
1719
1235
|
let entries = (0, utility_1.items)(bag.peg);
|
|
1720
1236
|
if (bag.isMap) {
|
|
1721
|
-
// Code-point order, because the two ports disagree on raw key order
|
|
1722
|
-
// — JavaScript hoists integer-like keys, Go keeps insertion order —
|
|
1723
|
-
// and a duplicate report must name the same pair in both.
|
|
1724
1237
|
entries = entries
|
|
1725
1238
|
.slice()
|
|
1726
1239
|
.sort((a, b) => (0, keyorder_1.cmpCodePoint)(String(a[0]), String(b[0])));
|
|
@@ -1738,10 +1251,6 @@ function emittedMembers(bag, ctx) {
|
|
|
1738
1251
|
}
|
|
1739
1252
|
return undefined;
|
|
1740
1253
|
}
|
|
1741
|
-
// Generation decides in an isolated collect context, so an
|
|
1742
|
-
// unresolved inner value neither raises here nor pollutes the
|
|
1743
|
-
// caller's errors — the same isolation BagVal.gen uses for an
|
|
1744
|
-
// optional child.
|
|
1745
1254
|
const cval = child.gen(ctx.clone({ err: [], collect: true }));
|
|
1746
1255
|
if (undefined === cval || (optional && (0, Val_1.empty)(cval))) {
|
|
1747
1256
|
continue;
|
|
@@ -1750,12 +1259,6 @@ function emittedMembers(bag, ctx) {
|
|
|
1750
1259
|
}
|
|
1751
1260
|
return out;
|
|
1752
1261
|
}
|
|
1753
|
-
// Sort accumulated patterns by source in code-point order and drop
|
|
1754
|
-
// exact duplicates. Patterns are NEVER simplified or compared for
|
|
1755
|
-
// containment: deciding `re("a")` subsumes `re("a|b")` is regex
|
|
1756
|
-
// containment, which the algebra deliberately does not do (emptiness
|
|
1757
|
-
// stays approximate — sound, incomplete). Two spellings of one language
|
|
1758
|
-
// therefore both survive, and both are tested.
|
|
1759
1262
|
function dedupSortedRes(res) {
|
|
1760
1263
|
const sorted = [...res].sort((a, b) => (0, numcmp_1.cmpCodePoints)(a.src, b.src));
|
|
1761
1264
|
const out = [];
|
|
@@ -1766,9 +1269,6 @@ function dedupSortedRes(res) {
|
|
|
1766
1269
|
}
|
|
1767
1270
|
return out;
|
|
1768
1271
|
}
|
|
1769
|
-
// The atom classes registered in the parser's funcMap: each is a
|
|
1770
|
-
// ConstraintVal that knows its atom name. Constructed by the
|
|
1771
|
-
// func-paren handler as `new funcval({peg: args})`.
|
|
1772
1272
|
class MinConstraintVal extends ConstraintVal {
|
|
1773
1273
|
constructor(spec, ctx) {
|
|
1774
1274
|
super({ ...spec, atom: 'min' }, ctx);
|