aontu 0.62.0 → 0.64.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 +7 -7
- 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 +3 -3
- package/dist/aontu.js +4 -84
- package/dist/aontu.js.map +1 -1
- package/dist/aontumodel.d.ts +4 -0
- package/dist/aontumodel.js +27 -0
- package/dist/aontumodel.js.map +1 -0
- package/dist/casing.d.ts +5 -0
- package/dist/casing.js +90 -0
- package/dist/casing.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +228 -935
- 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 +2 -2
- package/dist/helpdoc.js.map +1 -1
- package/dist/hints.d.ts +0 -6
- package/dist/hints.js +57 -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/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 -149
- package/dist/mcp.js.map +1 -1
- package/dist/mod-tool.js +16 -131
- 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/profile.d.ts +9 -0
- package/dist/profile.js +28 -0
- package/dist/profile.js.map +1 -0
- 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/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/trace.d.ts +21 -0
- package/dist/trace.js +107 -0
- package/dist/trace.js.map +1 -0
- 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 +13 -248
- 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.d.ts +2 -0
- package/dist/val/CmpFuncVal.js +49 -72
- 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 +18 -54
- 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 +3 -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/skill/tasks.md +9 -7
- package/src/agentsmd.ts +0 -35
- package/src/alias.ts +0 -39
- package/src/allow.ts +1 -96
- package/src/aontu.ts +4 -116
- package/src/aontumodel.ts +26 -0
- package/src/casing.ts +95 -0
- package/src/cli.ts +258 -1024
- 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 +2 -2
- package/src/hints.ts +69 -57
- package/src/jsonschema.ts +0 -123
- package/src/keyorder.ts +0 -42
- package/src/lang.ts +19 -931
- 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 -169
- package/src/mod-tool.ts +18 -159
- package/src/mod.ts +0 -178
- package/src/patch.ts +0 -232
- package/src/profile.ts +42 -0
- 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/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/trace.ts +157 -0
- package/src/trim.ts +0 -53
- package/src/type.ts +2 -45
- package/src/unify.ts +14 -257
- 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 +68 -184
- 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 +10 -99
- 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 +4 -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/lower.d.ts +0 -23
- package/dist/lower.js +0 -578
- package/dist/lower.js.map +0 -1
- package/dist/render.d.ts +0 -53
- package/dist/render.js +0 -547
- package/dist/render.js.map +0 -1
- 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/lower.ts +0 -636
- package/src/render.ts +0 -732
- package/src/std.ts +0 -683
package/src/val/ListVal.ts
CHANGED
|
@@ -69,8 +69,6 @@ class ListVal extends BagVal {
|
|
|
69
69
|
spread.v[0] :
|
|
70
70
|
spread.v
|
|
71
71
|
|
|
72
|
-
// let tmv = Array.isArray(spread.v) ? spread.v : [spread.v]
|
|
73
|
-
// this.spread.cj = new ConjunctVal({ peg: tmv }, ctx)
|
|
74
72
|
}
|
|
75
73
|
}
|
|
76
74
|
}
|
|
@@ -88,23 +86,10 @@ class ListVal extends BagVal {
|
|
|
88
86
|
const TOP = top()
|
|
89
87
|
peer = peer ?? TOP
|
|
90
88
|
|
|
91
|
-
// A sizing residual (`length`, `unique`) sorts AFTER containers in a
|
|
92
|
-
// conjunct so that it counts the MERGED list rather than the first
|
|
93
|
-
// fragment (SIZING_CJO in ConstraintVal.ts). That makes the list the
|
|
94
|
-
// accumulator and the constraint its peer, the reverse of the usual
|
|
95
|
-
// order — and the reading belongs to the constraint either way, so
|
|
96
|
-
// hand it straight back.
|
|
97
89
|
if (true === (peer as any).isConstraint) {
|
|
98
90
|
return peer.unify(this, ctx)
|
|
99
91
|
}
|
|
100
92
|
|
|
101
|
-
// A DISJUNCT ALTERNATIVE MATCHES ITS OWN LENGTH (BUGS.md §52
|
|
102
|
-
// regime 4, the X-C3 adjudication): in a trial, a literal list
|
|
103
|
-
// with no spread admits only a peer list of the same length -- a
|
|
104
|
-
// spread makes it variadic. Outside trials the ordinary
|
|
105
|
-
// elementwise merge stands (two statements of one list are one
|
|
106
|
-
// list), so `[] | [&: T]` stops admitting every list through the
|
|
107
|
-
// empty arm while `a: [] a: [1]` still merges.
|
|
108
93
|
if (true === ctx._trialMode && true === (peer as any).isList
|
|
109
94
|
&& null == this.spread.cj && null == (peer as any).spread.cj
|
|
110
95
|
&& this.peg.length !== (peer as any).peg.length) {
|
|
@@ -153,19 +138,6 @@ class ListVal extends BagVal {
|
|
|
153
138
|
|
|
154
139
|
propagateMarks(this, child)
|
|
155
140
|
|
|
156
|
-
// APPLIED ONCE PER ELEMENT, the guard MapVal has carried since
|
|
157
|
-
// the spread was written: an element that already holds this
|
|
158
|
-
// template's contribution is progressed by self-unification
|
|
159
|
-
// instead of having the template met into it a second time.
|
|
160
|
-
// Re-applying is the identity for a template that has already
|
|
161
|
-
// RESOLVED, which is why the missing guard went unnoticed here
|
|
162
|
-
// — but a template that residuates (`&: {k: key(1)}`, G8 phase
|
|
163
|
-
// 0) is not yet a value to be idempotent about, so each pass
|
|
164
|
-
// conjoined another copy and the element's canon DOUBLED per
|
|
165
|
-
// pass. The old `ctx.cc < 3` key delay hid it by ending the
|
|
166
|
-
// growth at three passes; the staging rule waits for the model
|
|
167
|
-
// to settle, and a model whose canon doubles every pass never
|
|
168
|
-
// does.
|
|
169
141
|
let oval: Val
|
|
170
142
|
if (!spread_cj.isTop
|
|
171
143
|
&& (child as any)._spr === spreadId(spread_cj)) {
|
|
@@ -187,11 +159,6 @@ class ListVal extends BagVal {
|
|
|
187
159
|
oval =
|
|
188
160
|
child.isNil ? child :
|
|
189
161
|
key_spread_cj.isNil ? key_spread_cj :
|
|
190
|
-
// The no-op meet is SKIPPED on the normal path (it is the
|
|
191
|
-
// identity) but TAKEN while recording: a value written once
|
|
192
|
-
// and never met is still a contribution the author wants
|
|
193
|
-
// pointed at, and the Go port's unite sees that meet (G7
|
|
194
|
-
// phase 4). Instrumented runs pay knowingly.
|
|
195
162
|
key_spread_cj.isTop && child.done && undefined === keyctx.prov
|
|
196
163
|
? child :
|
|
197
164
|
child.isTop && key_spread_cj.done ? key_spread_cj :
|
|
@@ -281,13 +248,6 @@ class ListVal extends BagVal {
|
|
|
281
248
|
}
|
|
282
249
|
|
|
283
250
|
|
|
284
|
-
// Spread clone: only deep-clone children that are path-dependent
|
|
285
|
-
// (isFunc, isRef). Share all other children directly.
|
|
286
|
-
// Spread clone: when all children are ScalarKindVal (simple type
|
|
287
|
-
// constraints like `string`, `number`), share them directly to avoid
|
|
288
|
-
// N x M allocations. ScalarKindVal is safe to share: it is immutable,
|
|
289
|
-
// always done, never path-dependent, and never has marks mutated.
|
|
290
|
-
// For anything more complex, fall back to full deep clone.
|
|
291
251
|
spreadClone(ctx: AontuContext): Val {
|
|
292
252
|
// B1: share directly when the spread tree has no path-dependent
|
|
293
253
|
// leaves. See MapVal.spreadClone for rationale.
|
|
@@ -337,11 +297,6 @@ class ListVal extends BagVal {
|
|
|
337
297
|
out.peg[entry[0]] =
|
|
338
298
|
(entry[1] as any)?.isVal ? (entry[1] as Val).clone(ctx, {
|
|
339
299
|
...childspec,
|
|
340
|
-
// AN ELEMENT IS A POSITION, exactly as a map's child is
|
|
341
|
-
// (MapVal.clone). Without this an explicitly pathed clone
|
|
342
|
-
// rebased the list and left every element at its source
|
|
343
|
-
// path -- the Go twin descends by index (go/clone.go, the
|
|
344
|
-
// *ListVal arm of clonePathKind).
|
|
345
300
|
path: [...out.path, entry[0]],
|
|
346
301
|
}) : entry[1]
|
|
347
302
|
}
|
|
@@ -352,36 +307,22 @@ class ListVal extends BagVal {
|
|
|
352
307
|
out.closed = this.closed
|
|
353
308
|
out.optionalKeys = [...this.optionalKeys]
|
|
354
309
|
|
|
355
|
-
// console.log('LISTVAL-CLONE', this.canon, '->', out.canon)
|
|
356
310
|
return out
|
|
357
311
|
}
|
|
358
312
|
|
|
359
313
|
|
|
360
314
|
get canon() {
|
|
361
|
-
// console.log('LISTVAL-CANON', this.optionalKeys)
|
|
362
315
|
let keys = Object.keys(this.peg)
|
|
363
316
|
return '' +
|
|
364
|
-
// this.errcanon() +
|
|
365
317
|
'[' +
|
|
366
318
|
(this.spread.cj ? '&:' + this.spread.cj.canon +
|
|
367
319
|
(0 < keys.length ? ',' : '') : '') +
|
|
368
|
-
// No optional-element rendering. A list HAS no optional elements to
|
|
369
|
-
// render: a key:value pair in list position contributes no element
|
|
370
|
-
// at all, in either spelling and whatever its key (issue #40), so
|
|
371
|
-
// nothing a source can write reaches this method with an optional
|
|
372
|
-
// key. The Go port's ListVal.Canon has no such arm either, and the
|
|
373
|
-
// two canons must agree -- a canon is round-trippable, and a marker
|
|
374
|
-
// on an element the grammar cannot produce would not reparse.
|
|
375
|
-
// canonRiders, not .canon: a deprecated element renders
|
|
376
|
-
// back as its `deprecate(x, m)` call, reparseably (G3).
|
|
377
320
|
keys.map(k => canonRiders(this.peg[k])).join(',') +
|
|
378
321
|
']'
|
|
379
322
|
}
|
|
380
323
|
} /* node:coverage ignore next 8 */
|
|
381
324
|
|
|
382
325
|
|
|
383
|
-
|
|
384
|
-
|
|
385
326
|
export {
|
|
386
327
|
ListVal,
|
|
387
328
|
}
|
package/src/val/LowerFuncVal.ts
CHANGED
|
@@ -19,7 +19,6 @@ import { Decimal } from '../val/Decimal'
|
|
|
19
19
|
import { caseRange, rangeArg } from './caserange'
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
import { FuncBaseVal } from './FuncBaseVal'
|
|
24
23
|
|
|
25
24
|
|
|
@@ -51,12 +50,6 @@ class LowerFuncVal extends FuncBaseVal {
|
|
|
51
50
|
const arg = args?.[0]
|
|
52
51
|
const oldpeg = arg?.peg
|
|
53
52
|
|
|
54
|
-
// THE RANGE (ts/src/val/caserange.ts): `start` names the first
|
|
55
|
-
// character of the run when it is zero or positive and the last
|
|
56
|
-
// when it is negative; `len` of -1, and the absent argument, are
|
|
57
|
-
// the source's length. Refused on a NUMBER, where a run of
|
|
58
|
-
// characters means nothing -- the numeric arm below is a ceiling,
|
|
59
|
-
// not a case mapping.
|
|
60
53
|
const start = rangeArg(args?.[1])
|
|
61
54
|
const len = rangeArg(args?.[2])
|
|
62
55
|
const ranged = undefined !== start || undefined !== len
|
|
@@ -68,11 +61,6 @@ class LowerFuncVal extends FuncBaseVal {
|
|
|
68
61
|
const peg = 'string' === typeof oldpeg ?
|
|
69
62
|
caseRange(oldpeg, start ?? 0, len ?? -1, false) :
|
|
70
63
|
'number' === typeof oldpeg ? Math.floor(oldpeg) :
|
|
71
|
-
// The exact leaves take an EXACT floor and keep their kind: a
|
|
72
|
-
// biginteger is already integral so it is its own floor, and a
|
|
73
|
-
// bigdecimal floors by coefficient arithmetic. Math.floor is not
|
|
74
|
-
// an option for either — it would round the value into binary64
|
|
75
|
-
// first, which is the loss the `0d` leaves exist to refuse.
|
|
76
64
|
'bigint' === typeof oldpeg ? oldpeg :
|
|
77
65
|
oldpeg instanceof Decimal ? oldpeg.floor() :
|
|
78
66
|
undefined
|
package/src/val/MapVal.ts
CHANGED
|
@@ -39,20 +39,10 @@ import { cmpCodePoint } from '../keyorder'
|
|
|
39
39
|
import { markSpread } from '../provenance'
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
// Structural snapshots of ref spreads (see MapVal.unify), keyed by the
|
|
43
|
-
// ref's canon + source site rather than object identity: spread
|
|
44
|
-
// application clones templates (and the refs inside them) freely, and a
|
|
45
|
-
// clone must find the snapshot its parse-origin ref captured on an early
|
|
46
|
-
// pass. The map lives on the unify root ctx (see Unify), so it persists
|
|
47
|
-
// across fixpoint passes and is GC'd with the run.
|
|
48
42
|
function spreadSnapKey(cj: any): string {
|
|
49
43
|
return cj.spelling + '~' + cj.site.row + ':' + cj.site.col
|
|
50
44
|
}
|
|
51
45
|
|
|
52
|
-
// Snapshot a path-dependent ref spread to its structural target once,
|
|
53
|
-
// while inner key()/path() funcs in the target are still unresolved (see
|
|
54
|
-
// the call site comments in MapVal.unify). Shared by the direct
|
|
55
|
-
// application path and the deferred-spread early-snapshot walk.
|
|
56
46
|
function snapshotRefSpread(cj: any, ctx: AontuContext): Val | undefined {
|
|
57
47
|
let snapmap: Map<string, Val> | undefined = (ctx as any).snapmap
|
|
58
48
|
if (undefined === snapmap) {
|
|
@@ -70,12 +60,6 @@ function snapshotRefSpread(cj: any, ctx: AontuContext): Val | undefined {
|
|
|
70
60
|
// A ref to a type() resolves to its inner template — snapshot that,
|
|
71
61
|
// so a type-wrapped ref behaves like a plain-map ref spread.
|
|
72
62
|
if (tgt && (tgt as any).isTypeFunc) tgt = (tgt as any).peg?.[0]
|
|
73
|
-
// A pending type()/hide() CALL is not yet a value to snapshot
|
|
74
|
-
// (ADR-005, the same rule find's non-snap path defers on): cached
|
|
75
|
-
// here it resolves at every destination and STAMPS marks the
|
|
76
|
-
// clearing walk ran too early to clear -- a mutual recursive
|
|
77
|
-
// schema's members vanished from generation this way. No cache;
|
|
78
|
-
// retry once the wrapper has resolved at its own field.
|
|
79
63
|
if (tgt && pendingMarkWrapper(tgt)) {
|
|
80
64
|
return undefined
|
|
81
65
|
}
|
|
@@ -119,12 +103,6 @@ class MapVal extends BagVal {
|
|
|
119
103
|
|
|
120
104
|
if (spread) {
|
|
121
105
|
if ('&' === spread.o) {
|
|
122
|
-
// Multiple same-level spreads arrive as an array and conjoin;
|
|
123
|
-
// an unequal spread arriving from ANOTHER statement meets this
|
|
124
|
-
// one in unify's spread combination below — sound since the
|
|
125
|
-
// combined template became stateless (pure ExpectVal, BUGS.md
|
|
126
|
-
// §6-§7): each child meets the combined constraint
|
|
127
|
-
// independently and children never meet each other's data.
|
|
128
106
|
this.spread.cj =
|
|
129
107
|
Array.isArray(spread.v) ?
|
|
130
108
|
1 < spread.v.length ?
|
|
@@ -134,25 +112,9 @@ class MapVal extends BagVal {
|
|
|
134
112
|
}
|
|
135
113
|
}
|
|
136
114
|
|
|
137
|
-
// console.log('MAPVAL-ctor', this.type, spec)
|
|
138
115
|
}
|
|
139
116
|
|
|
140
117
|
|
|
141
|
-
// NOTE: order of keys is not preserved!
|
|
142
|
-
// not possible in any case - consider {a,b} unify {b,a}
|
|
143
|
-
// ALIAS DECLARATIONS MUST SIT AT THE DOCUMENT ROOT. Stated on the
|
|
144
|
-
// VALUE rather than at the parse, because the parse cannot see it: an
|
|
145
|
-
// INCLUDED file's declarations are at the root of their own text, and
|
|
146
|
-
// only once the loaded map is placed does it become apparent that
|
|
147
|
-
// root is not the document's. `%name` is spelled as a reference from
|
|
148
|
-
// the document root, so an included file's own `%b` would otherwise
|
|
149
|
-
// reach the INCLUDER's `%b` -- cross-file capture, the hazard the
|
|
150
|
-
// sigil exists to prevent, one level up.
|
|
151
|
-
//
|
|
152
|
-
// P1 is single-file by construction; carrying a name ACROSS files is
|
|
153
|
-
// what `export` and the destructure are for (P2, not built), and this
|
|
154
|
-
// refusal is what keeps the two from being confused meanwhile. Pathed
|
|
155
|
-
// at the DECLARATION, which is what is wrong, not at the map.
|
|
156
118
|
aliasDeclarationsAreRooted(ctx: AontuContext): Val | undefined {
|
|
157
119
|
if (0 === this.aliasKeys.length || 0 === this.path.length) {
|
|
158
120
|
return undefined
|
|
@@ -168,17 +130,10 @@ class MapVal extends BagVal {
|
|
|
168
130
|
if (undefined !== arooted) {
|
|
169
131
|
return arooted
|
|
170
132
|
}
|
|
171
|
-
// console.log('MAPVAL-UNIFY', this.id, this.canon, peer.id, peer.canon)
|
|
172
133
|
|
|
173
134
|
const TOP = top()
|
|
174
135
|
peer = peer ?? TOP
|
|
175
136
|
|
|
176
|
-
// A sizing residual (`length`, `unique`) sorts AFTER containers in a
|
|
177
|
-
// conjunct so that it counts the MERGED map rather than the first
|
|
178
|
-
// fragment (SIZING_CJO in ConstraintVal.ts). That makes the map the
|
|
179
|
-
// accumulator and the constraint its peer, the reverse of the usual
|
|
180
|
-
// order — and the reading belongs to the constraint either way, so
|
|
181
|
-
// hand it straight back.
|
|
182
137
|
if (true === (peer as any).isConstraint) {
|
|
183
138
|
return peer.unify(this, ctx)
|
|
184
139
|
}
|
|
@@ -197,10 +152,6 @@ class MapVal extends BagVal {
|
|
|
197
152
|
out.spread.cj = this.spread.cj
|
|
198
153
|
out.site = this.site
|
|
199
154
|
|
|
200
|
-
// A rel() peer DRIVES whichever side the fold hands it on: the
|
|
201
|
-
// relation constraint rewrites this container leaf by leaf
|
|
202
|
-
// (RELATIONS.0.md §3.2), exactly as a sizing residual takes the
|
|
203
|
-
// driver's seat above.
|
|
204
155
|
if (true === (peer as any)?.isRel) {
|
|
205
156
|
return peer.unify(this, te ? ctx.clone({ explain: ec(te, 'REL') }) : ctx)
|
|
206
157
|
}
|
|
@@ -229,24 +180,6 @@ class MapVal extends BagVal {
|
|
|
229
180
|
}
|
|
230
181
|
|
|
231
182
|
if (!exit) {
|
|
232
|
-
// Combine two spread constraints. Identical templates (same canon)
|
|
233
|
-
// collapse to one: re-unifying them resolves key()/path() at the
|
|
234
|
-
// shared intermediate path, producing spurious values (f1bb1063).
|
|
235
|
-
// Distinct templates are unified in place — unite is idempotent,
|
|
236
|
-
// whereas deferring the distinct case into a fresh ConjunctVal (as
|
|
237
|
-
// f1bb1063 did) re-wraps every fixpoint pass, growing the conjunct
|
|
238
|
-
// without bound and non-terminating on real models (the apidef +
|
|
239
|
-
// sdkgen entity schemas each contribute a `&:` spread with name:key(),
|
|
240
|
-
// combined here). unite resolves key()/path() at each destination via
|
|
241
|
-
// spreadClone below, so nested + sibling key() cases stay correct
|
|
242
|
-
// (test/spec/spread-nested-key, spread-key-all).
|
|
243
|
-
//
|
|
244
|
-
// The combined template must stay STATELESS: this meet wraps a
|
|
245
|
-
// key present in only one side as an ExpectVal, the combined
|
|
246
|
-
// map is shared across destinations when path-independent
|
|
247
|
-
// (spreadClone tier 1), and a stateful expect accumulated the
|
|
248
|
-
// first sibling's data and met it into the next (BUGS.md
|
|
249
|
-
// §6-§7). ExpectVal.unify is pure for exactly this reason.
|
|
250
183
|
out.spread.cj = null == out.spread.cj ? peer.spread.cj : (
|
|
251
184
|
null == peer.spread.cj ? out.spread.cj :
|
|
252
185
|
out.spread.cj.canon === peer.spread.cj.canon ? out.spread.cj :
|
|
@@ -256,32 +189,20 @@ class MapVal extends BagVal {
|
|
|
256
189
|
}
|
|
257
190
|
}
|
|
258
191
|
else {
|
|
259
|
-
// console.log('MAPVAL-PEER-OTHER', this.id, this.canon, this.done, peer.id, peer.canon, peer.done)
|
|
260
192
|
}
|
|
261
193
|
|
|
262
194
|
|
|
263
195
|
if (!exit) {
|
|
264
196
|
out.dc = this.dc + 1
|
|
265
197
|
|
|
266
|
-
// let newtype = this.type || peer.type
|
|
267
198
|
|
|
268
199
|
let spread_cj = out.spread.cj ?? TOP
|
|
269
200
|
|
|
270
|
-
// Snapshot a path-dependent *ref* spread to its structural target
|
|
271
|
-
// once (while inner key()/path() funcs are still unresolved), so
|
|
272
|
-
// later fixpoint passes don't re-resolve the ref against the mutated
|
|
273
|
-
// tree and capture the target's own resolved key()/path() literals,
|
|
274
|
-
// which would leak the source key into the spread destination.
|
|
275
201
|
if (spread_cj.isRef && (spread_cj as any).find) {
|
|
276
202
|
const snap = snapshotRefSpread(spread_cj, ctx)
|
|
277
203
|
if (snap) spread_cj = snap
|
|
278
204
|
}
|
|
279
205
|
|
|
280
|
-
// A type() used as a spread applies as its inner template: emit the
|
|
281
|
-
// (constrained) values at each destination rather than marking the
|
|
282
|
-
// destination as a type. I.e. `&:type({k:key(),x:number})` behaves
|
|
283
|
-
// like the non-type spread `&:{k:key(),x:number}` — key() resolves
|
|
284
|
-
// to the destination key, kinds constrain, fields are emitted.
|
|
285
206
|
if ((spread_cj as any).isTypeFunc) {
|
|
286
207
|
spread_cj = (spread_cj as any).peg?.[0] ?? TOP
|
|
287
208
|
}
|
|
@@ -293,15 +214,6 @@ class MapVal extends BagVal {
|
|
|
293
214
|
|
|
294
215
|
propagateMarks(this, child)
|
|
295
216
|
|
|
296
|
-
// Apply the spread constraint ONCE per child (marked with the
|
|
297
|
-
// constraint's id below): the first application merges the
|
|
298
|
-
// template into the child (with key()/path() placeholders that
|
|
299
|
-
// resolve in place on later passes), so the constraint content
|
|
300
|
-
// is inside the child from then on and only self-unification is
|
|
301
|
-
// needed to progress it. Re-applying on every fixpoint pass and
|
|
302
|
-
// every conjunct-fold step is the identity (unite is idempotent)
|
|
303
|
-
// but costs O(keys) deep template clones per pass on large
|
|
304
|
-
// models — the dominant cost on generated-SDK model trees.
|
|
305
217
|
let oval: Val
|
|
306
218
|
// No `undefined !== child` here: propagateMarks above already
|
|
307
219
|
// dereferenced it, so a missing child would have thrown there.
|
|
@@ -327,11 +239,6 @@ class MapVal extends BagVal {
|
|
|
327
239
|
oval =
|
|
328
240
|
child.isNil ? child :
|
|
329
241
|
key_spread_cj.isNil ? key_spread_cj :
|
|
330
|
-
// The no-op meet is SKIPPED on the normal path (it is the
|
|
331
|
-
// identity) but TAKEN while recording: a value written once
|
|
332
|
-
// and never met is still a contribution the author wants
|
|
333
|
-
// pointed at, and the Go port's unite sees that meet (G7
|
|
334
|
-
// phase 4). Instrumented runs pay knowingly.
|
|
335
242
|
key_spread_cj.isTop && child.done && undefined === keyctx.prov
|
|
336
243
|
? child :
|
|
337
244
|
child.isTop && key_spread_cj.done ? key_spread_cj :
|
|
@@ -369,9 +276,6 @@ class MapVal extends BagVal {
|
|
|
369
276
|
out.optionalKeys.push(peerkey)
|
|
370
277
|
}
|
|
371
278
|
|
|
372
|
-
// ... and so is an alias declaration, for the same reason:
|
|
373
|
-
// two statements for one map are one map, and a name declared
|
|
374
|
-
// in either is declared in the result.
|
|
375
279
|
if (upeer.aliasKeys.includes(peerkey) && !out.aliasKeys.includes(peerkey)) {
|
|
376
280
|
out.aliasKeys.push(peerkey)
|
|
377
281
|
}
|
|
@@ -381,15 +285,6 @@ class MapVal extends BagVal {
|
|
|
381
285
|
const peerctx = ctx.descend(peerkey)
|
|
382
286
|
|
|
383
287
|
let oval = out.peg[peerkey] =
|
|
384
|
-
// A peer-only key is CARRIED, not met — except on an
|
|
385
|
-
// instrumented run, where the identity meet is taken so
|
|
386
|
-
// the recorder sees where the value came from. The Go port
|
|
387
|
-
// unites a genable peer-only child with TOP unconditionally
|
|
388
|
-
// (go/mapval.go), and the difference was invisible until
|
|
389
|
-
// G4's identity merge brought a peer whose children the
|
|
390
|
-
// recorder counts as WRITTEN: `why $.b.k` on two positions
|
|
391
|
-
// of one entity named the site in Go and answered "nothing
|
|
392
|
-
// met here" in TypeScript.
|
|
393
288
|
undefined === child
|
|
394
289
|
? (undefined !== peerctx.prov && peerchild.isGenable
|
|
395
290
|
? unite(peerctx, peerchild, TOP, 'map-peer-only')
|
|
@@ -407,14 +302,6 @@ class MapVal extends BagVal {
|
|
|
407
302
|
if ((oval as any)._spr !== spreadId(spread_cj)) {
|
|
408
303
|
let key_spread_cj = spread_cj.spreadClone(peerctx)
|
|
409
304
|
|
|
410
|
-
// A SPREAD IS A SPREAD FROM EITHER SIDE. The own-key loop
|
|
411
|
-
// above marks its template so `why` can say the
|
|
412
|
-
// contribution came from `&:` rather than from the key;
|
|
413
|
-
// this arm did not, so the SAME document reported the
|
|
414
|
-
// role or dropped it depending on whether the template
|
|
415
|
-
// and the keys were written in one statement or two --
|
|
416
|
-
// `services: &: {..}` plus `services: {web:{}}` took the
|
|
417
|
-
// peer path and lost `(spread)` (use-cases/BUGS.md §55).
|
|
418
305
|
if (undefined !== peerctx.prov) {
|
|
419
306
|
markSpread(key_spread_cj)
|
|
420
307
|
}
|
|
@@ -457,13 +344,6 @@ class MapVal extends BagVal {
|
|
|
457
344
|
}
|
|
458
345
|
}
|
|
459
346
|
|
|
460
|
-
// console.log(
|
|
461
|
-
// 'MAPVAL-OUT', out.canon,
|
|
462
|
-
// '\n SELF', this,
|
|
463
|
-
// '\n PEER', peer,
|
|
464
|
-
// '\n OUT', out,
|
|
465
|
-
// '\n FROM', (out as any).spread.cj
|
|
466
|
-
// )
|
|
467
347
|
|
|
468
348
|
ctx.explain && explainClose(te, out)
|
|
469
349
|
|
|
@@ -471,20 +351,6 @@ class MapVal extends BagVal {
|
|
|
471
351
|
}
|
|
472
352
|
|
|
473
353
|
|
|
474
|
-
// Spread clone: return a Val usable as the per-key spread constraint.
|
|
475
|
-
//
|
|
476
|
-
// Three tiers:
|
|
477
|
-
// 1. tree is path-independent (no RefVal/KeyFuncVal/PathFuncVal/
|
|
478
|
-
// MoveFuncVal/SuperFuncVal anywhere below): return `this` directly.
|
|
479
|
-
// Nothing in the unify path mutates the spread root, and no
|
|
480
|
-
// child depends on its own stored .path, so sharing is safe.
|
|
481
|
-
// 2. top-level children are all ScalarKindVal: shallow clone
|
|
482
|
-
// (share children, fresh MapVal wrapper).
|
|
483
|
-
// 3. otherwise: full deep clone via `this.clone(ctx)`.
|
|
484
|
-
//
|
|
485
|
-
// Tier 1 handles the foo-sdk common case of simple type-constraint
|
|
486
|
-
// spreads like `&:{active: *true | boolean, version: *'0.0.1' | string}`,
|
|
487
|
-
// which are cloned thousands of times per run.
|
|
488
354
|
spreadClone(ctx: AontuContext): Val {
|
|
489
355
|
if (!this.isPathDependent) return this
|
|
490
356
|
|
|
@@ -531,7 +397,6 @@ class MapVal extends BagVal {
|
|
|
531
397
|
for (let entry of Object.entries(this.peg)) {
|
|
532
398
|
out.peg[entry[0]] =
|
|
533
399
|
(entry[1] as any)?.isVal ?
|
|
534
|
-
// (entry[1] as Val).clone(ctx, spec?.mark ? { mark: spec.mark } : {}) :
|
|
535
400
|
(entry[1] as Val).clone(ctx, {
|
|
536
401
|
mark: spec?.mark ?? {},
|
|
537
402
|
path: [...out.path, entry[0]],
|
|
@@ -551,23 +416,12 @@ class MapVal extends BagVal {
|
|
|
551
416
|
out.optionalKeys = [...this.optionalKeys]
|
|
552
417
|
out.aliasKeys = [...this.aliasKeys]
|
|
553
418
|
|
|
554
|
-
// out.from = this.from
|
|
555
419
|
|
|
556
|
-
// console.log('MAPVAL-CLONE', this.canon, '->', out.canon)
|
|
557
420
|
return out
|
|
558
421
|
}
|
|
559
422
|
|
|
560
423
|
|
|
561
424
|
get canon() {
|
|
562
|
-
// Keys are emitted in CODE POINT order so the canonical form is
|
|
563
|
-
// independent of insertion/unification order and matches the Go
|
|
564
|
-
// port. A bare .sort() is UTF-16 code-unit order, which puts an
|
|
565
|
-
// astral key ahead of everything in U+E000-U+FFFF -- see cmpCodePoint.
|
|
566
|
-
// An alias declaration is not part of the document, so canon does
|
|
567
|
-
// not render it: a document with aliases and the document with
|
|
568
|
-
// every alias written out longhand must produce the same text and
|
|
569
|
-
// therefore the same `aon1-` hash. That is the sharpest statement
|
|
570
|
-
// of what an alias IS -- a name for a value, and nothing more.
|
|
571
425
|
let keys = Object.keys(this.peg)
|
|
572
426
|
.filter(k => !this.aliasKeys.includes(k))
|
|
573
427
|
.sort(cmpCodePoint)
|
|
@@ -583,11 +437,6 @@ class MapVal extends BagVal {
|
|
|
583
437
|
JSON.stringify(k) +
|
|
584
438
|
(this.optionalKeys.includes(k) ? '?' : '') +
|
|
585
439
|
':' +
|
|
586
|
-
// canonRiders, not .canon: a deprecated field renders
|
|
587
|
-
// back as its `deprecate(x, m)` call, reparseably (G3). The
|
|
588
|
-
// guard is the isVal FLAG, never the canon getter: computing
|
|
589
|
-
// canon in the guard and again in the render doubles the
|
|
590
|
-
// recursion per level, which is 2^depth on a nested document.
|
|
591
440
|
(true === this.peg[k]?.isVal
|
|
592
441
|
? canonRiders(this.peg[k]) : this.peg[k])
|
|
593
442
|
])
|
package/src/val/MatchFuncVal.ts
CHANGED
|
@@ -1,37 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// GENERATION: `match(v, p1, r1, p2, r2, …, d?)` (G8 phase 2,
|
|
4
|
-
// docs/capability-review/g8-generation.md). A BOUNDED conditional:
|
|
5
|
-
// alternating pattern/result arguments and an optional trailing
|
|
6
|
-
// default. The first pattern IN ARGUMENT ORDER that `v` unifies with
|
|
7
|
-
// SELECTS its result, and the result is the answer.
|
|
8
|
-
//
|
|
9
|
-
// The design said the answer was `v & p & r` -- the scrutinee narrowed
|
|
10
|
-
// by the arm rather than replaced by it. That cannot be what a match
|
|
11
|
-
// is for: it makes every arm whose result is not already a `v` a
|
|
12
|
-
// contradiction, and the design's own example
|
|
13
|
-
// (`match($.tier, small, {cpu:1}, …)`, a string scrutinee and map
|
|
14
|
-
// results) cannot be evaluated at all under it. A match MAPS a value
|
|
15
|
-
// to another value; a document that wants the scrutinee kept can say
|
|
16
|
-
// so, because the scrutinee is a value it can name.
|
|
17
|
-
//
|
|
18
|
-
// size: match($.tier, small, {cpu:1}, large, {cpu:8}, {cpu:2})
|
|
19
|
-
//
|
|
20
|
-
// WHAT KEEPS IT FROM BECOMING A CONDITIONAL LANGUAGE. The scrutinee is
|
|
21
|
-
// matched by UNIFIABILITY only: no boolean guards, no comparisons
|
|
22
|
-
// beyond what the constraint atoms already are, no fallthrough (first
|
|
23
|
-
// match wins, in a spec-pinned order), and no way to write a pattern
|
|
24
|
-
// that is not an ordinary Aontu value. The whole form is total.
|
|
25
|
-
//
|
|
26
|
-
// NO MATCH AND NO DEFAULT IS AN ERROR, not an empty answer, and the
|
|
27
|
-
// report names the patterns that were tried -- the admissible-
|
|
28
|
-
// alternatives shape (G2's error contract). A default is how a
|
|
29
|
-
// document says it meant to allow the rest.
|
|
30
|
-
//
|
|
31
|
-
// A RESULT IS NOT EVALUATED UNTIL IT IS SELECTED. Only the scrutinee
|
|
32
|
-
// and the patterns are driven; an unselected result never runs, so a
|
|
33
|
-
// broken arm nobody takes is not an error the document has to carry
|
|
34
|
-
// (which multi-error collection, G2 phase 6, would otherwise report).
|
|
35
3
|
|
|
36
4
|
import type {
|
|
37
5
|
Val,
|
|
@@ -48,22 +16,6 @@ import { prefInnerPeg } from './PrefVal'
|
|
|
48
16
|
import { FuncBaseVal, trialUnify } from './FuncBaseVal'
|
|
49
17
|
|
|
50
18
|
|
|
51
|
-
// THE DEFAULTED-SCRUTINEE RULE (ADR-004, use-cases/BUGS.md §5). The
|
|
52
|
-
// generation-effective view of a settled scrutinee: a preference — or
|
|
53
|
-
// a disjunction carrying one — means "this value unless something
|
|
54
|
-
// overrides it", and by resolve time the model has SETTLED (staging
|
|
55
|
-
// rule), so nothing will. The value generation is about to emit is
|
|
56
|
-
// therefore the value the patterns must be tested against. Testing
|
|
57
|
-
// against the still-open preference instead let a pattern SELECT an
|
|
58
|
-
// arm by overriding the default: `side_effect:*readonly|write|
|
|
59
|
-
// destructive` beside `match(.side_effect, destructive, true, false)`
|
|
60
|
-
// answered `true` while generating "readonly" next to it — a derived
|
|
61
|
-
// value contradicting the very value it derives from, exit 0.
|
|
62
|
-
// A pref-free scrutinee (open disjunction included) is untouched:
|
|
63
|
-
// matching by unifiability is its documented meaning.
|
|
64
|
-
// Exported for the multi-pref unit test (ADR-002, the subsumeNode
|
|
65
|
-
// precedent): rankPrefs leaves a settled disjunct at most one pref, so
|
|
66
|
-
// the min-rank scan below cannot be reached through a document.
|
|
67
19
|
export function effectiveScrutinee(v: Val): Val {
|
|
68
20
|
let out: any = v
|
|
69
21
|
if (true === out?.isDisjunct && Array.isArray(out.peg)) {
|
|
@@ -71,10 +23,6 @@ export function effectiveScrutinee(v: Val): Val {
|
|
|
71
23
|
if (0 === prefs.length) {
|
|
72
24
|
return v
|
|
73
25
|
}
|
|
74
|
-
// Generation picks the LOWEST rank (effectiveDefault in
|
|
75
|
-
// subsume.ts; `a:**1|*2` generates 2). rankPrefs leaves at most
|
|
76
|
-
// one pref standing in a settled disjunct, so the scan is
|
|
77
|
-
// defensive.
|
|
78
26
|
out = prefs.reduce((a: any, b: any) => b.rank < a.rank ? b : a)
|
|
79
27
|
}
|
|
80
28
|
return prefInnerPeg(out)
|
|
@@ -84,9 +32,6 @@ export function effectiveScrutinee(v: Val): Val {
|
|
|
84
32
|
class MatchFuncVal extends FuncBaseVal {
|
|
85
33
|
isMatchFunc = true
|
|
86
34
|
|
|
87
|
-
// THE STAGING RULE (G8 phase 0). A scrutinee that is still being
|
|
88
|
-
// narrowed can match an EARLIER pattern than the one it will end up
|
|
89
|
-
// matching, and the arm a match takes is not a thing to guess at.
|
|
90
35
|
staged = true
|
|
91
36
|
|
|
92
37
|
constructor(
|
|
@@ -107,10 +52,6 @@ class MatchFuncVal extends FuncBaseVal {
|
|
|
107
52
|
}
|
|
108
53
|
|
|
109
54
|
|
|
110
|
-
// The scrutinee is argument 0 and the patterns are the odd
|
|
111
|
-
// arguments; the results are the even ones after 0, and the last
|
|
112
|
-
// argument is a DEFAULT when the count is even. Written once, read
|
|
113
|
-
// by both the driver below and resolve.
|
|
114
55
|
hasDefault() {
|
|
115
56
|
return 0 === this.peg.length % 2
|
|
116
57
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* Copyright (c) 2026 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Val,
|
|
6
|
+
ValSpec,
|
|
7
|
+
} from '../type'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
AontuContext,
|
|
11
|
+
} from '../ctx'
|
|
12
|
+
|
|
13
|
+
import { unite } from '../unify'
|
|
14
|
+
import { AbsentVal } from './AbsentVal'
|
|
15
|
+
import { FuncBaseVal } from './FuncBaseVal'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
top
|
|
20
|
+
} from './top'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class MaybeFuncVal extends FuncBaseVal {
|
|
24
|
+
isMaybeFunc = true
|
|
25
|
+
|
|
26
|
+
forgives = true
|
|
27
|
+
|
|
28
|
+
// A reference that has not resolved YET is not a reference to
|
|
29
|
+
// nothing (ADR-034).
|
|
30
|
+
staged = true
|
|
31
|
+
|
|
32
|
+
constructor(
|
|
33
|
+
spec: ValSpec,
|
|
34
|
+
ctx?: AontuContext
|
|
35
|
+
) {
|
|
36
|
+
super(spec, ctx)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
funcname() {
|
|
41
|
+
return 'maybe'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
// Null so the base drives nothing: it would drive on the CALLER's
|
|
46
|
+
// context, where NilVal.make records the miss before resolve runs.
|
|
47
|
+
prepare(_ctx: AontuContext, _args: Val[]) {
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
unify(peer: Val, ctx: AontuContext): Val {
|
|
53
|
+
if (!ctx.settle) {
|
|
54
|
+
return this.residuate(peer, ctx)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return super.unify(peer, ctx)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
resolve(ctx: AontuContext, args: Val[]) {
|
|
62
|
+
// Cloned rather than swapped and restored, which is the
|
|
63
|
+
// own-property hazard trialUnify documents at length.
|
|
64
|
+
const sink: Val[] = []
|
|
65
|
+
const actx = ctx.clone({ err: sink, collect: true })
|
|
66
|
+
const out = unite(actx, args[0], top(), 'maybe')
|
|
67
|
+
|
|
68
|
+
// ONLY a missing referent. A conflict inside the argument stays
|
|
69
|
+
// the document's error.
|
|
70
|
+
if (out.isNil && 'reference' === (out as any).class) {
|
|
71
|
+
return this.place(new AbsentVal({}, ctx))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (const err of sink) {
|
|
75
|
+
ctx.adderr(err as any)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return out
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
} /* node:coverage ignore next 6 */
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
export {
|
|
85
|
+
MaybeFuncVal,
|
|
86
|
+
}
|