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
package/src/val/PathVal.ts
CHANGED
|
@@ -1,28 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// FIRST-CLASS PATHS (docs/design/PATHS.0.md). A PathVal is the value
|
|
4
|
-
// `path(p)` captures: a tree address as DATA -- the spelling, never
|
|
5
|
-
// the resolution. It is a scalar whose peg is the address string in
|
|
6
|
-
// exactly the grammar `refer` reads (`$.a.b` from the root, `.b` from
|
|
7
|
-
// the sibling scope, one more leading dot per parent step), which is
|
|
8
|
-
// what lets a captured path meet the checking machinery unchanged.
|
|
9
|
-
//
|
|
10
|
-
// Meets are SYNTACTIC, by the PREFIX rule (amended, ADR-016): two
|
|
11
|
-
// path values meet when one spells a prefix of the other -- same
|
|
12
|
-
// anchor, the shorter's segments opening the longer's -- and the
|
|
13
|
-
// result is the LONGER: a path can always be told more precisely.
|
|
14
|
-
// Incomparable spellings refuse as any two unequal scalars do.
|
|
15
|
-
// Resolving during a meet would make the meet depend on the value's
|
|
16
|
-
// position, which is the property the staging machinery exists to
|
|
17
|
-
// quarantine -- resolution stays the business of `refer`, `rel` and
|
|
18
|
-
// the graph.
|
|
19
|
-
//
|
|
20
|
-
// The kind sits UNDER string (ScalarKindVal.KIND_PARENT), so `string`
|
|
21
|
-
// admits a path value and the string constraints keep working; a
|
|
22
|
-
// plain string LITERAL and a path value refuse each other, exactly as
|
|
23
|
-
// the number tower's leaves do. A bare string is NEVER a path
|
|
24
|
-
// (ADR-016): `path("...")` -- the call's own string argument -- is
|
|
25
|
-
// the one conversion the language has.
|
|
26
3
|
|
|
27
4
|
import type {
|
|
28
5
|
Val,
|
|
@@ -41,10 +18,6 @@ import { ScalarVal } from './ScalarVal'
|
|
|
41
18
|
import { ScalarKindVal, Path } from './ScalarKindVal'
|
|
42
19
|
|
|
43
20
|
|
|
44
|
-
|
|
45
|
-
// A segment of a tree path: a map key or a list index. The same
|
|
46
|
-
// grammar the rest of the engine spells keys with, and a leading digit
|
|
47
|
-
// is legitimate because a list index is one.
|
|
48
21
|
const ADDR_SEGMENT = /^[A-Za-z0-9_-]+$/
|
|
49
22
|
|
|
50
23
|
export type Address = {
|
|
@@ -58,12 +31,6 @@ export type Address = {
|
|
|
58
31
|
}
|
|
59
32
|
|
|
60
33
|
|
|
61
|
-
// The address a string spells, or undefined when it does not spell
|
|
62
|
-
// one. An address is a TREE PATH, in exactly the two spellings a
|
|
63
|
-
// reference uses: `$.services.auth` from the root, `.auth` from the
|
|
64
|
-
// link's own sibling scope. The tree is the only namespace -- which is
|
|
65
|
-
// what makes a model instantiable more than once, each instance
|
|
66
|
-
// resolving its relative links inside itself (ADR-014).
|
|
67
34
|
export function parseAddress(s: string): Address | undefined {
|
|
68
35
|
if ('$' === s) {
|
|
69
36
|
// The whole document is not a relation's target: an address must
|
|
@@ -104,29 +71,11 @@ export function parseAddress(s: string): Address | undefined {
|
|
|
104
71
|
}
|
|
105
72
|
|
|
106
73
|
|
|
107
|
-
// The spelling string TEXT converts by, inside a `path(...)` call:
|
|
108
|
-
// text that carries no anchor is RELATIVE (`"a.b"` is the address
|
|
109
|
-
// `.a.b`), matching the raw form (`path(a.b)` captures `.a.b`). Only
|
|
110
|
-
// the anchor is supplied -- the result still has to parse, so
|
|
111
|
-
// malformed text (`""`, `"a..b"`, a bad `$` spelling) refuses as
|
|
112
|
-
// before. The prefix is not applied to text that claims an anchor:
|
|
113
|
-
// `"$x"` is a broken absolute address, not a relative one.
|
|
114
74
|
export function textAddress(s: string): string {
|
|
115
75
|
return ('$' === s[0] || '.' === s[0]) ? s : '.' + s
|
|
116
76
|
}
|
|
117
77
|
|
|
118
78
|
|
|
119
|
-
// The LONGER of two addresses when one spells a prefix of the other
|
|
120
|
-
// (docs/design/PATHS.0.md, amended): same anchor -- absolute or the
|
|
121
|
-
// same number of parent steps -- and the shorter's segments open the
|
|
122
|
-
// longer's. The meet of two path values, and of a refer's address
|
|
123
|
-
// with a later path peer: a path can always be told more precisely,
|
|
124
|
-
// and the more precise spelling is the result. Undefined when the two
|
|
125
|
-
// are not comparable, which refuses as any two unequal scalars do.
|
|
126
|
-
// Both arguments must already be valid addresses: every caller hands
|
|
127
|
-
// over a PathVal peg or a refer addrsrc, and both are validated at
|
|
128
|
-
// capture or conversion -- the same trust `unify`'s own address arm
|
|
129
|
-
// extends (`parseAddress(p.peg) as Address`).
|
|
130
79
|
export function prefixMeet(a: string, b: string): string | undefined {
|
|
131
80
|
const pa = parseAddress(a) as Address
|
|
132
81
|
const pb = parseAddress(b) as Address
|
|
@@ -144,7 +93,6 @@ export function prefixMeet(a: string, b: string): string | undefined {
|
|
|
144
93
|
}
|
|
145
94
|
|
|
146
95
|
|
|
147
|
-
|
|
148
96
|
class PathVal extends ScalarVal {
|
|
149
97
|
isPath = true
|
|
150
98
|
|
|
@@ -155,11 +103,6 @@ class PathVal extends ScalarVal {
|
|
|
155
103
|
super({ peg: spec.peg, kind: Path }, ctx)
|
|
156
104
|
}
|
|
157
105
|
|
|
158
|
-
// Two path values meet by the PREFIX rule (ADR-016): the longer
|
|
159
|
-
// when one opens the other, refusal otherwise. Exactly equal pegs
|
|
160
|
-
// are absorbed by unite's fast path before this runs, so the arm
|
|
161
|
-
// sees the unequal pairs; the winner carries both sides' marks, as
|
|
162
|
-
// the equal-scalar arm has always ratcheted them.
|
|
163
106
|
unify(peer: Val, ctx: AontuContext): Val {
|
|
164
107
|
const p: any = peer
|
|
165
108
|
if (true === p.isPath) {
|
|
@@ -182,10 +125,6 @@ class PathVal extends ScalarVal {
|
|
|
182
125
|
return 'path(' + this.peg + ')'
|
|
183
126
|
}
|
|
184
127
|
|
|
185
|
-
// The super() ladder lifts a path value to its own kind, and the
|
|
186
|
-
// kind must render as `path()` -- the bare word `path` is an
|
|
187
|
-
// ordinary string. ScalarVal.superior would mint the plain
|
|
188
|
-
// ScalarKindVal, whose canon is the bare word.
|
|
189
128
|
superior() {
|
|
190
129
|
return this.place(new PathKindVal({}))
|
|
191
130
|
}
|
|
@@ -193,11 +132,6 @@ class PathVal extends ScalarVal {
|
|
|
193
132
|
} /* node:coverage ignore next 4 */
|
|
194
133
|
|
|
195
134
|
|
|
196
|
-
// The path KIND, `path()`: admits every path value and defaults to
|
|
197
|
-
// nothing, as `string` does. It does NOT promote (ADR-016): a bare
|
|
198
|
-
// string meeting the kind refuses through the generic kind ladder,
|
|
199
|
-
// exactly as `integer & "x"` does -- `path("...")` is the one string
|
|
200
|
-
// conversion, and it happens at the call.
|
|
201
135
|
class PathKindVal extends ScalarKindVal {
|
|
202
136
|
isPathKind = true
|
|
203
137
|
|
package/src/val/PlaceVal.ts
CHANGED
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// THE PLACEHOLDER `_` (G8 phase 3,
|
|
4
|
-
// docs/capability-review/g8-generation.md): a HOLE in a call, filled
|
|
5
|
-
// by whatever the call is unified with.
|
|
6
|
-
//
|
|
7
|
-
// x: {&: {m: _ + 2}} x: a: m: 1 -> a: m: 3
|
|
8
|
-
// greeting: upper(_) & hello -> "HELLO"
|
|
9
|
-
//
|
|
10
|
-
// WHY A HOLE AND NOT A FUNCTION PARAMETER. Aontu has no user-defined
|
|
11
|
-
// functions and will not get them (G8's Boundary): a function value
|
|
12
|
-
// crossing into the data plane is the step that makes a configuration
|
|
13
|
-
// language a programming language. A hole is not a parameter -- it
|
|
14
|
-
// cannot be named, passed, or partially applied. It says only "the
|
|
15
|
-
// value that arrives here", which is what a template needs to compute
|
|
16
|
-
// from the value it lands on.
|
|
17
|
-
//
|
|
18
|
-
// ALONE, `_` IS TOP WITH A MARK: it admits everything and is filled by
|
|
19
|
-
// its peer, exactly as TOP is dropped by one. What makes it different
|
|
20
|
-
// is that a CALL can see it, and a call that holds one waits for a
|
|
21
|
-
// peer to fill it instead of resolving around it. Unfilled at
|
|
22
|
-
// generation it is an error, as TOP is -- a hole is not a value.
|
|
23
3
|
|
|
24
4
|
import type {
|
|
25
5
|
Val,
|
|
@@ -72,17 +52,6 @@ class PlaceVal extends ValBase {
|
|
|
72
52
|
}
|
|
73
53
|
|
|
74
54
|
|
|
75
|
-
// A HOLE BELONGS TO ITS NEAREST ENCLOSING GENERATOR. A `_` inside a
|
|
76
|
-
// generator's template (pack/each, arg 1), condition (filter, arg 1)
|
|
77
|
-
// or rule table (emit, arg 1) is that generator's to bind — "_ is the
|
|
78
|
-
// source child" — so neither the hole test nor the fill walk may cross
|
|
79
|
-
// into those arguments from outside. Before this boundary, `close(pack(d, _ & t))` reported a
|
|
80
|
-
// hole to the OUTER call, so an ordinary overlay statement was
|
|
81
|
-
// absorbed into the template instead of merging with the generated
|
|
82
|
-
// child (use-cases/BUGS.md §10), and an outer pack's fill pass
|
|
83
|
-
// captured a NESTED pack's hole lexically, binding it to the outer
|
|
84
|
-
// source (§34). The data argument (arg 0) is not a binding position,
|
|
85
|
-
// so it stays visible: a hole there is an outer hole as before.
|
|
86
55
|
function boundArgStart(v: any): number {
|
|
87
56
|
return true === v.isPackFunc || true === v.isEachFunc ||
|
|
88
57
|
true === v.isFilterFunc || true === v.isEmitFunc ||
|
|
@@ -90,10 +59,6 @@ function boundArgStart(v: any): number {
|
|
|
90
59
|
}
|
|
91
60
|
|
|
92
61
|
|
|
93
|
-
// Does this value CONTAIN a hole? Asked of a call before it resolves:
|
|
94
|
-
// a call holding one must wait for a peer to fill it. Holes inside a
|
|
95
|
-
// generator's own binding arguments are NOT this value's holes — see
|
|
96
|
-
// boundArgStart above.
|
|
97
62
|
function hasPlace(v: Val): boolean {
|
|
98
63
|
if (true === (v as any).isPlace) {
|
|
99
64
|
return true
|
|
@@ -125,18 +90,8 @@ function hasPlace(v: Val): boolean {
|
|
|
125
90
|
}
|
|
126
91
|
|
|
127
92
|
|
|
128
|
-
// The same tree with every hole filled by `fill`. Answers the value
|
|
129
|
-
// UNCHANGED when it holds no hole, so a caller can test identity to
|
|
130
|
-
// know whether anything was filled -- and so a tree with no hole is
|
|
131
|
-
// never needlessly cloned. A nested generator's binding arguments are
|
|
132
|
-
// left untouched (boundArgStart): those holes are the inner
|
|
133
|
-
// generator's to fill with its OWN source children when it fires.
|
|
134
93
|
function fillPlace(v: Val, fill: Val, ctx: AontuContext): Val {
|
|
135
94
|
if (true === (v as any).isPlace) {
|
|
136
|
-
// A FILL IS A POSITION. The hole knows where it sits in the
|
|
137
|
-
// instance; the datum arriving in it does not, and inserted as it
|
|
138
|
-
// stands it keeps the paths it had at its SOURCE, so every finding
|
|
139
|
-
// under it names a path that does not exist.
|
|
140
95
|
return fill.clone(ctx, { path: [...(v as any).path] })
|
|
141
96
|
}
|
|
142
97
|
|
package/src/val/PlusOpVal.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { IntegerVal } from '../val/IntegerVal'
|
|
|
18
18
|
import { NumberVal } from '../val/NumberVal'
|
|
19
19
|
import { StringVal } from '../val/StringVal'
|
|
20
20
|
import { BooleanVal } from '../val/BooleanVal'
|
|
21
|
+
import { ListVal } from '../val/ListVal'
|
|
21
22
|
import { BigIntegerVal } from '../val/BigIntegerVal'
|
|
22
23
|
import { BigDecimalVal } from '../val/BigDecimalVal'
|
|
23
24
|
import { Decimal, decimalOverBudget } from '../val/Decimal'
|
|
@@ -33,20 +34,6 @@ type OpKind =
|
|
|
33
34
|
'string' | 'boolean' | 'integer' | 'float' | 'biginteger' | 'bigdecimal'
|
|
34
35
|
|
|
35
36
|
|
|
36
|
-
// D6 -- THE EXACT LADDER: integer < biginteger < bigdecimal. A mixed
|
|
37
|
-
// operation between exact leaves promotes to the WIDEST operand and is
|
|
38
|
-
// computed exactly, so `1 + 0d2` is a biginteger and `1 + 0d0.5` a
|
|
39
|
-
// bigdecimal.
|
|
40
|
-
//
|
|
41
|
-
// `float` is deliberately absent: it is OFF the ladder, keeping only its
|
|
42
|
-
// classic contagion against `integer`. Its absence from this table is
|
|
43
|
-
// what makes the float-with-big pairs fall through to the hard error
|
|
44
|
-
// below rather than promoting.
|
|
45
|
-
//
|
|
46
|
-
// Results NEVER demote: `0d5 + -0d2` stays a biginteger even though 3
|
|
47
|
-
// would fit an int64. Demotion would make the result kind depend on the
|
|
48
|
-
// values rather than on the operand kinds, and a document could then
|
|
49
|
-
// change leaf under a value edit.
|
|
50
37
|
const EXACT_RANK: Record<string, number> = {
|
|
51
38
|
integer: 1,
|
|
52
39
|
biginteger: 2,
|
|
@@ -59,13 +46,6 @@ function isBig(k: OpKind): boolean {
|
|
|
59
46
|
}
|
|
60
47
|
|
|
61
48
|
|
|
62
|
-
// Only concrete scalar operands are valid: anything else (kinds, maps,
|
|
63
|
-
// lists, null, top, funcs) must not coerce — the JS `+` would leak
|
|
64
|
-
// internals like "[object Object]" into output. A non-scalar operand
|
|
65
|
-
// leaves the op unresolved, which generate() reports.
|
|
66
|
-
//
|
|
67
|
-
// A pref operand contributes its preferred value (`pref(1)+2`), and
|
|
68
|
-
// therefore that value's kind too.
|
|
69
49
|
function operand(v: any) {
|
|
70
50
|
while (v?.isPref) {
|
|
71
51
|
v = v.peg
|
|
@@ -99,14 +79,6 @@ function opkind(v: any): OpKind | undefined {
|
|
|
99
79
|
}
|
|
100
80
|
|
|
101
81
|
|
|
102
|
-
// THE TEXT `+` WOULD MAKE OF THIS OPERAND, or undefined if `+` would not
|
|
103
|
-
// take it at all.
|
|
104
|
-
//
|
|
105
|
-
// `join` folds with `+` seeded with `""`, so every member goes through
|
|
106
|
-
// concatenation's string branch — and this is the function that branch
|
|
107
|
-
// calls. Exported so that the fold and the operator cannot drift into
|
|
108
|
-
// two answers to "how does a number become text": there is one
|
|
109
|
-
// rendering, `digits` below, and both reach it here.
|
|
110
82
|
function plusText(v: Val): string | undefined {
|
|
111
83
|
const o: any = operand(v)
|
|
112
84
|
const k = opkind(o)
|
|
@@ -134,9 +106,25 @@ class PlusOpVal extends OpBaseVal {
|
|
|
134
106
|
}
|
|
135
107
|
|
|
136
108
|
|
|
137
|
-
operate(ctx: AontuContext, args: Val[]) {
|
|
109
|
+
operate(ctx: AontuContext, args: Val[]): Val | undefined {
|
|
138
110
|
const av: any = operand(args[0])
|
|
139
111
|
const bv: any = operand(args[1])
|
|
112
|
+
|
|
113
|
+
// ABSENCE PROPAGATES (ADR-034).
|
|
114
|
+
if (true === av?.isAbsent) {
|
|
115
|
+
return av
|
|
116
|
+
}
|
|
117
|
+
if (true === bv?.isAbsent) {
|
|
118
|
+
return bv
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Lists concatenate (ADR-037).
|
|
122
|
+
if (true === av?.isList && true === bv?.isList) {
|
|
123
|
+
const peg: Val[] = [...av.peg, ...bv.peg].map(
|
|
124
|
+
(v: Val, i: number) => v.clone(ctx.descend(String(i))))
|
|
125
|
+
return new ListVal({ peg }, ctx)
|
|
126
|
+
}
|
|
127
|
+
|
|
140
128
|
const ak = opkind(av)
|
|
141
129
|
const bk = opkind(bv)
|
|
142
130
|
|
|
@@ -148,12 +136,6 @@ class PlusOpVal extends OpBaseVal {
|
|
|
148
136
|
return new BooleanVal({ peg: av.peg || bv.peg })
|
|
149
137
|
}
|
|
150
138
|
|
|
151
|
-
// STRING CONCATENATION RENDERS DIGITS, NOT KIND DECORATION. The `0d`
|
|
152
|
-
// marker is canon's way of naming the leaf and never belongs in a
|
|
153
|
-
// string, exactly as R4's `.0` float suffix does not ("q" + 0d0.1 is
|
|
154
|
-
// "q0.1", and "q" + 1.0 is "q1"). Decimal.toString() is that
|
|
155
|
-
// marker-free rendering, which is why canon() wraps it rather than
|
|
156
|
-
// the other way round.
|
|
157
139
|
if ('string' === ak || 'string' === bk) {
|
|
158
140
|
return new StringVal({ peg: digits(av, ak) + digits(bv, bk) })
|
|
159
141
|
}
|
|
@@ -163,25 +145,11 @@ class PlusOpVal extends OpBaseVal {
|
|
|
163
145
|
return undefined
|
|
164
146
|
}
|
|
165
147
|
|
|
166
|
-
// FLOAT IS OFF THE EXACT LADDER, and mixing it with either big leaf
|
|
167
|
-
// is a hard error in BOTH operand orders: a big type never silently
|
|
168
|
-
// becomes a binary float. Promotion the other way is no better —
|
|
169
|
-
// binary64 cannot hold every exact value, so either direction throws
|
|
170
|
-
// away exactness the document explicitly asked for by writing `0d`.
|
|
171
|
-
// The error names both leaves in operand order.
|
|
172
148
|
if (('float' === ak && isBig(bk)) || (isBig(ak) && 'float' === bk)) {
|
|
173
149
|
return makeNilErr(ctx, 'exact_float_mix', this, undefined, 'add',
|
|
174
150
|
{ left: ak, right: bk })
|
|
175
151
|
}
|
|
176
152
|
|
|
177
|
-
// Float with float or integer: unchanged R5 contagion, binary64
|
|
178
|
-
// addition, float result (`1 + 2.0` is `3.0`) -- but a sum that
|
|
179
|
-
// leaves binary64's finite range is NOT a value. Aontu is a JSON
|
|
180
|
-
// superset and there is no notation for an infinity, so one here
|
|
181
|
-
// used to escape as `[aontu/internal]` in TypeScript and as Go's
|
|
182
|
-
// raw `json: unsupported value: +Inf` with no code at all
|
|
183
|
-
// (use-cases/BUGS.md 39). The same check governs the arithmetic
|
|
184
|
-
// family (float_overflow, ts/src/val/arith.ts).
|
|
185
153
|
if ('float' === ak || 'float' === bk) {
|
|
186
154
|
const sum = av.peg + bv.peg
|
|
187
155
|
return Number.isFinite(sum) ?
|
|
@@ -211,13 +179,6 @@ class PlusOpVal extends OpBaseVal {
|
|
|
211
179
|
return new BigIntegerVal({ peg: sum })
|
|
212
180
|
}
|
|
213
181
|
|
|
214
|
-
// INTEGER + INTEGER IS COMPUTED EXACTLY, then offered to the integer
|
|
215
|
-
// leaf under the same storage contract R1 applies to a literal.
|
|
216
|
-
// Adding through float64 (as this did) silently rounded sums of
|
|
217
|
-
// exact operands — 4503599627370496 + 4503599627370497 came back as
|
|
218
|
-
// …992 — which is precisely the corruption the tower refuses. The
|
|
219
|
-
// sum that will not fit is an error pointing at `0d`, not a rounded
|
|
220
|
-
// answer.
|
|
221
182
|
return isIntegerStorable(sum) ?
|
|
222
183
|
new IntegerVal({ peg: Number(sum) }) :
|
|
223
184
|
makeNilErr(ctx, 'inexact_integer_sum', this, undefined, 'add',
|
|
@@ -232,19 +193,6 @@ class PlusOpVal extends OpBaseVal {
|
|
|
232
193
|
}
|
|
233
194
|
|
|
234
195
|
|
|
235
|
-
// The digits of an operand for string concatenation: no `0d` marker, no
|
|
236
|
-
// R4 `.0` suffix — the plain rendering of the number, in every leaf.
|
|
237
|
-
//
|
|
238
|
-
// INTEGER KIND GOES THROUGH integerDigits. This was the THIRD site to
|
|
239
|
-
// render an integer-kind peg with JavaScript's shortest round-tripping
|
|
240
|
-
// form, so `"" + 1152921504606846976` produced "1152921504606847000" — a
|
|
241
|
-
// different integer — where Go produced the exact digits. See #21 and
|
|
242
|
-
// integerDigits, which exists so the set of such sites is greppable.
|
|
243
|
-
//
|
|
244
|
-
// The other leaves are already exact or already correct: a bigint
|
|
245
|
-
// stringifies to its exact digits, a Decimal renders its own, and a FLOAT
|
|
246
|
-
// must keep String() because its shortest form is the right answer and is
|
|
247
|
-
// what Go prints too (`"a" + 1.0` is "a1").
|
|
248
196
|
function digits(v: any, k: OpKind): string {
|
|
249
197
|
return 'bigdecimal' === k ? v.peg.toString() :
|
|
250
198
|
'integer' === k ? integerDigits(v.peg) :
|
|
@@ -252,16 +200,11 @@ function digits(v: any, k: OpKind): string {
|
|
|
252
200
|
}
|
|
253
201
|
|
|
254
202
|
|
|
255
|
-
// An exact-ladder operand as an exact integer. Only reached for the two
|
|
256
|
-
// integral leaves; an `integer` peg is integral by construction, so
|
|
257
|
-
// BigInt() is exact.
|
|
258
203
|
function integer(v: any, k: OpKind): bigint {
|
|
259
204
|
return 'biginteger' === k ? v.peg : BigInt(v.peg)
|
|
260
205
|
}
|
|
261
206
|
|
|
262
207
|
|
|
263
|
-
// An exact-ladder operand as a Decimal, for the promotion to bigdecimal.
|
|
264
|
-
// Scale 0 normalises to the one decimal place the leaf keeps.
|
|
265
208
|
function decimal(v: any, k: OpKind): Decimal {
|
|
266
209
|
return 'bigdecimal' === k ? v.peg : new Decimal(integer(v, k), 0)
|
|
267
210
|
} /* node:coverage ignore next 6 */
|
package/src/val/PrefFuncVal.ts
CHANGED
|
@@ -49,7 +49,6 @@ class PrefFuncVal extends FuncBaseVal {
|
|
|
49
49
|
// Wrap every child val in a PrefVal
|
|
50
50
|
out = walk(out, (_key: string | number | undefined, val: Val) => {
|
|
51
51
|
let oval = val
|
|
52
|
-
// console.log('PREFVAL', _key, oval.canon, oval.constructor.name)
|
|
53
52
|
if (
|
|
54
53
|
val.isScalar
|
|
55
54
|
|| val.isPref
|
package/src/val/PrefVal.ts
CHANGED
|
@@ -27,11 +27,6 @@ import { trialUnify } from './FuncBaseVal'
|
|
|
27
27
|
import { superOf } from './SuperFuncVal'
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
// The innermost preferred value under every pref layer: the value a
|
|
31
|
-
// preference of ANY rank ultimately defends, and the one generation
|
|
32
|
-
// emits for it. Shared by the disjunct admission gate (DisjunctVal),
|
|
33
|
-
// the defaulted-scrutinee rule (MatchFuncVal) and the effective-default
|
|
34
|
-
// walk (subsume.ts) so "the default's value" cannot mean three things.
|
|
35
30
|
function prefInnerPeg(v: Val): Val {
|
|
36
31
|
let out: any = v
|
|
37
32
|
while (true === out?.isPref) {
|
|
@@ -41,65 +36,16 @@ function prefInnerPeg(v: Val): Val {
|
|
|
41
36
|
}
|
|
42
37
|
|
|
43
38
|
|
|
44
|
-
// A CONTAINER DEFAULT IS LEAFWISE (ADR-011 R3,
|
|
45
|
-
// docs/design/DEFAULTS.0.md): `*{p:1}` MEANS `{p: *1}` and `*[1]`
|
|
46
|
-
// means `[*1]`, so there is no such thing as a preference whose
|
|
47
|
-
// preferred value is a bag. Shape is not a value and takes no star --
|
|
48
|
-
// key optionality, closedness and a `&:` spread template ride through
|
|
49
|
-
// untouched; only the values a reader could override are defaulted.
|
|
50
|
-
//
|
|
51
|
-
// This is the rule `pref()` already had (its resolve walked and
|
|
52
|
-
// wrapped every scalar child) and the star prefix did not, so the two
|
|
53
|
-
// spellings of one operator disagreed: `pref({p:1}) & {q:2}` kept the
|
|
54
|
-
// `p` default and `*{p:1} & {q:2}` dropped it. Both spellings and the
|
|
55
|
-
// resolve-time case (`*$.shape`) come through here now, so they
|
|
56
|
-
// cannot drift apart again. Wrapping the non-bag arm rather than
|
|
57
|
-
// walking for scalars also closes the other half of that gap:
|
|
58
|
-
// `pref(integer)` and `pref(min(3))` used to answer the bare value,
|
|
59
|
-
// losing the preference outright.
|
|
60
39
|
class PrefVal extends FeatureVal {
|
|
61
40
|
isPref = true
|
|
62
41
|
isGenable = true
|
|
63
42
|
cjo = 30000
|
|
64
43
|
|
|
65
|
-
// The preferred value's own type: the yardstick for "did the peer say
|
|
66
|
-
// anything I did not already say?". A peer that resolves to this (or
|
|
67
|
-
// to the family gate below) leaves the preference standing.
|
|
68
|
-
// Both are assigned by resuper(), called from the constructor.
|
|
69
44
|
superpeg!: Val
|
|
70
45
|
|
|
71
|
-
// THE GATE AN OVERRIDING PEER MUST PASS IS `superpeg` ITSELF — the
|
|
72
|
-
// preferred value's own KIND, not its family.
|
|
73
|
-
//
|
|
74
|
-
// A preference is a DEFAULT, so a concrete peer replaces it, but only
|
|
75
|
-
// where the peer is the same kind of thing: `*lower(1.1) & a` is a
|
|
76
|
-
// conflict, not an override. The number tower made `integer` and
|
|
77
|
-
// `float` disjoint siblings under `number`, and this gate used to
|
|
78
|
-
// widen to that family — so `*2.2 & 3` worked, and so did
|
|
79
|
-
// `*8080 & 3.5`. Those are ONE rule in two directions; no kind-based
|
|
80
|
-
// gate can keep the first and refuse the second.
|
|
81
|
-
//
|
|
82
|
-
// Refusing both is the choice, because the second is the documented
|
|
83
|
-
// default idiom: `port: *8080 | integer` accepted 3.5 in both ports,
|
|
84
|
-
// silently widening every key written that way from integer to
|
|
85
|
-
// number — the finding §6 of the 2026-08-21 status report calls the
|
|
86
|
-
// most consequential, precisely because docs/skill/examples.md
|
|
87
|
-
// teaches the idiom to agents.
|
|
88
|
-
//
|
|
89
|
-
// What the tightening costs is named rather than hidden: mixing the
|
|
90
|
-
// numeric leaves around a preference is now an error instead of a
|
|
91
|
-
// silent widening. `*1.5 & integer` used to answer `integer` and
|
|
92
|
-
// DISCARD a default that could never apply; it now says so.
|
|
93
46
|
|
|
94
47
|
rank: number = 0
|
|
95
48
|
|
|
96
|
-
// THE OVERRIDE SPACE, NARROWED (ADR-011 R1). The second arm of the
|
|
97
|
-
// distribution -- `super(x) & every peer met so far` -- kept here as
|
|
98
|
-
// well as in `superpeg`, because resuper() recomputes the gate from
|
|
99
|
-
// the peg whenever the peg resolves and would otherwise widen it
|
|
100
|
-
// back to `super(x)`: a rank>=2 default, whose peg is itself a
|
|
101
|
-
// preference and so is re-driven, lost its narrowing that way and
|
|
102
|
-
// let a pinned `***false & false` be overridden by `true`.
|
|
103
49
|
narrowed?: Val
|
|
104
50
|
|
|
105
51
|
constructor(
|
|
@@ -107,45 +53,17 @@ class PrefVal extends FeatureVal {
|
|
|
107
53
|
ctx?: AontuContext
|
|
108
54
|
) {
|
|
109
55
|
super(spec, ctx)
|
|
110
|
-
// this.pref = spec.pref || spec.peg
|
|
111
56
|
|
|
112
|
-
// this.superpeg = makeSuper(spec.peg)
|
|
113
57
|
|
|
114
58
|
if (spec.peg instanceof PrefVal) {
|
|
115
59
|
this.rank = 1 + spec.peg.rank
|
|
116
60
|
}
|
|
117
61
|
|
|
118
62
|
this.resuper(ctx)
|
|
119
|
-
// console.log('PVC', this.peg.canon, this.superpeg.canon)
|
|
120
63
|
}
|
|
121
64
|
|
|
122
65
|
|
|
123
|
-
// Recompute the type yardstick and the override gate from the current
|
|
124
|
-
// peg. Called again whenever the peg resolves (e.g. a ref).
|
|
125
|
-
//
|
|
126
|
-
// THE GATE IS super() (ADR-011 R4, docs/design/DEFAULTS.0.md). `*x`
|
|
127
|
-
// is sugar for `*x | super(x)`, so the type an overriding peer must
|
|
128
|
-
// pass is the one the long form spells out loud -- one function, not
|
|
129
|
-
// a second implementation that agrees with it on the common case.
|
|
130
|
-
// Two special cases retired with the switch: a KIND peg gated
|
|
131
|
-
// nothing (`*integer` was overridden by `"s"`) and a CONSTRAINT peg
|
|
132
|
-
// had no gate at all, both written when a kind's superior was top.
|
|
133
|
-
// `super(integer)` is `number`, so `7` still wins and `"s"` refuses.
|
|
134
66
|
private resuper(ctx?: AontuContext) {
|
|
135
|
-
// THE RANK-UNIFORM MEET (ADR-004). The yardstick is the INNERMOST
|
|
136
|
-
// preferred value's kind, whatever the preference's rank: `**1.5`
|
|
137
|
-
// defends `float` exactly as `*1.5` does. The old rule read the
|
|
138
|
-
// immediate peg, and a rank>=2 peg is itself a PrefVal whose
|
|
139
|
-
// superior is top -- so ANY conjunct overrode a ranked default
|
|
140
|
-
// (`**1.5 & float` dropped the default and died as mapval_no_gen;
|
|
141
|
-
// `**2|integer` met by a bare `integer` lost the default the
|
|
142
|
-
// spelling exists to carry -- use-cases/BUGS.md §3), while the
|
|
143
|
-
// rank-1 spelling of the same document kept it. One rule, every
|
|
144
|
-
// rank. Pinned by test/spec/pref.tsv (pref-rank2-* rows, and the
|
|
145
|
-
// flipped pref-nested-concrete-wins).
|
|
146
|
-
// THE RANK-UNIFORM MEET (ADR-004) is unchanged: the yardstick is
|
|
147
|
-
// the INNERMOST preferred value, whatever the rank, so `**1.5`
|
|
148
|
-
// defends `float` exactly as `*1.5` does.
|
|
149
67
|
let peg: any = this.peg
|
|
150
68
|
while (true === peg?.isPref) {
|
|
151
69
|
peg = peg.peg
|
|
@@ -161,14 +79,6 @@ class PrefVal extends FeatureVal {
|
|
|
161
79
|
}
|
|
162
80
|
|
|
163
81
|
|
|
164
|
-
// The default, standing but NARROWED: `*integer & 7` is `*7`, which
|
|
165
|
-
// is what the long form answers (`(integer&7) | (number&7)` keeps
|
|
166
|
-
// the star on the arm that survived). The rank rides across -- a
|
|
167
|
-
// ladder rung that narrows is still that rung.
|
|
168
|
-
// The rank is REBUILT as nesting rather than stamped: canon renders
|
|
169
|
-
// one star per layer (`'*' + peg.canon`), so a rank set directly on
|
|
170
|
-
// a single layer would print `*x` for a rank-2 default and the
|
|
171
|
-
// document would no longer round-trip.
|
|
172
82
|
private restand(met: Val, ctx: AontuContext): Val {
|
|
173
83
|
let out: Val = met
|
|
174
84
|
for (let rI = 0; rI <= this.rank; rI++) {
|
|
@@ -190,28 +100,10 @@ class PrefVal extends FeatureVal {
|
|
|
190
100
|
if (!this.peg.done) {
|
|
191
101
|
const resolved = unite(te ? ctx.clone({ explain: ec(te, 'RES') }) : ctx,
|
|
192
102
|
this.peg, top(), 'pref/resolve')
|
|
193
|
-
// console.log('PREF-RESOLVED', this.peg.canon, '->', resolved)
|
|
194
103
|
this.peg = resolved
|
|
195
104
|
this.resuper(ctx)
|
|
196
105
|
}
|
|
197
106
|
|
|
198
|
-
// A CONTAINER DEFAULT IS LEAFWISE IN EFFECT (ADR-011 R3), and it
|
|
199
|
-
// gets there through the meet above rather than through a rewrite.
|
|
200
|
-
// `*{p:1}` keeps its written shape -- canon prints `*{"p":1}` and
|
|
201
|
-
// reparses to itself, which a rewrite to `{p:*1}` would break, and
|
|
202
|
-
// an alternative still has a star for a disjunction to choose by.
|
|
203
|
-
// What makes it leafwise is that the two arms decide:
|
|
204
|
-
//
|
|
205
|
-
// `& {q:2}` the preferred value ITSELF admits the peer (maps
|
|
206
|
-
// merge), so the default stands as `*{p:1,q:2}` and
|
|
207
|
-
// `p` survives -- it used to be REPLACED outright.
|
|
208
|
-
// `& {p:2}` the preferred value refuses, so the gate answers:
|
|
209
|
-
// `super({p:1})` is `{p:integer}`, which admits it.
|
|
210
|
-
// `& "s"` both arms are empty, so the whole default is --
|
|
211
|
-
// a string used to override a map default silently.
|
|
212
|
-
//
|
|
213
|
-
// Which is every rule R3 asks for, with no bag ever standing where
|
|
214
|
-
// the author wrote a scalar and no canon that fails to round-trip.
|
|
215
107
|
|
|
216
108
|
if (peer instanceof PrefVal) {
|
|
217
109
|
why += 'pref-'
|
|
@@ -235,74 +127,22 @@ class PrefVal extends FeatureVal {
|
|
|
235
127
|
why += 'rank-lose'
|
|
236
128
|
}
|
|
237
129
|
else {
|
|
238
|
-
// console.log('PREF-PEER',
|
|
239
|
-
// this.peg.id, this.peg, this.peg.done,
|
|
240
|
-
// peer.peg.id, peer.peg, peer.peg.done,
|
|
241
|
-
// )
|
|
242
130
|
|
|
243
131
|
const peg = trialUnify(ctx, prefInnerPeg(this).clone(ctx),
|
|
244
132
|
prefInnerPeg(peer))
|
|
245
133
|
|
|
246
|
-
// TWO DEFAULTS OF EQUAL RANK THAT CANNOT AGREE (ADR-011 R2):
|
|
247
|
-
// the refusal is about the DEFAULTS, not about the values they
|
|
248
|
-
// happen to hold, and its hint names the fix -- rank one of
|
|
249
|
-
// them. Compatible pegs still fold (`*1 & *integer` is `*1`),
|
|
250
|
-
// and identical ones collapse, so only a real disagreement
|
|
251
|
-
// reaches this arm. The three spellings of it -- `*1 & *7`,
|
|
252
|
-
// `(*1|integer) & *7` and `*1|*7` -- used to answer a value
|
|
253
|
-
// conflict, the newcomer, and the newcomer again.
|
|
254
134
|
out = undefined === peg
|
|
255
135
|
? makeNilErr(ctx, 'pref_rank_clash', this, peer, 'unify')
|
|
256
136
|
: this.restand(peg, ctx)
|
|
257
|
-
// console.log('PREF-RANK-SAME-OUT', peg, peg.done, out, out.done)
|
|
258
137
|
why += 'rank-same'
|
|
259
138
|
}
|
|
260
139
|
}
|
|
261
140
|
else if (!peer.isTop) {
|
|
262
141
|
why += 'super-'
|
|
263
142
|
|
|
264
|
-
// THE MEET IS THE DESUGARING, DISTRIBUTED (ADR-011 R1,
|
|
265
|
-
// docs/design/DEFAULTS.0.md). `*x` stands for `*x | super(x)`,
|
|
266
|
-
// and a peer meets a disjunction arm by arm:
|
|
267
|
-
//
|
|
268
|
-
// (x & peer) | (super(x) & peer)
|
|
269
|
-
//
|
|
270
|
-
// THE FIRST ARM DECIDES. When the preferred value itself still
|
|
271
|
-
// satisfies the peer the default STANDS -- `*1 & integer`,
|
|
272
|
-
// `*8080 & min(1024)`, `**2 & neq(1)`: the peer narrowed the
|
|
273
|
-
// type without ruling the default out, which is the whole point
|
|
274
|
-
// of writing one. Only when that arm is empty does the second
|
|
275
|
-
// answer, and that is the override. When BOTH are empty nothing
|
|
276
|
-
// remains of the disjunction the star stands for -- `empty`,
|
|
277
|
-
// the same refusal the written-out long form gives.
|
|
278
|
-
//
|
|
279
|
-
// The old rule asked instead whether the peer resolved to
|
|
280
|
-
// exactly `super(x)`, so any narrowing at all counted as an
|
|
281
|
-
// override: `*1 & integer` stood (the peer WAS the gate) but
|
|
282
|
-
// `*8080 & min(1024)` silently dropped the default and answered
|
|
283
|
-
// the bare constraint, and a rank ladder lost its weaker arm to
|
|
284
|
-
// the same rule the moment anything narrowed it.
|
|
285
|
-
//
|
|
286
|
-
// Trialled against a CLONE, on the innermost value (the
|
|
287
|
-
// rank-uniform meet): the preferred value must stay pristine for
|
|
288
|
-
// the arm that stands, and a failed trial must not leave its
|
|
289
|
-
// errors on the context -- the DisjunctVal admission gate's own
|
|
290
|
-
// precedent, and its mechanism.
|
|
291
143
|
const met = trialUnify(ctx, prefInnerPeg(this).clone(ctx), peer)
|
|
292
144
|
|
|
293
145
|
if (undefined !== met) {
|
|
294
|
-
// THE SECOND ARM IS CARRIED FORWARD, not discarded. It is the
|
|
295
|
-
// override space -- everything the peer would still admit
|
|
296
|
-
// INSTEAD of the default -- and meeting a peer narrows it just
|
|
297
|
-
// as it narrows the default: two successive meets compose to
|
|
298
|
-
// `(x & p1 & p2) | (super(x) & p1 & p2)`, which is the
|
|
299
|
-
// distribution over both. Dropping it let a constraint that
|
|
300
|
-
// arrived beside a default vanish: `r:*2` with `r:max(20)`
|
|
301
|
-
// stood as a bare `*2`, and `r:40` then overrode it through a
|
|
302
|
-
// gate that no longer remembered the bound.
|
|
303
|
-
//
|
|
304
|
-
// It cannot fail: the first arm succeeded, so `x & peer` has a
|
|
305
|
-
// value, and that value satisfies `super(x)` and `peer` both.
|
|
306
146
|
const gate = unite(te ? ctx.clone({ explain: ec(te, 'GATE') }) : ctx,
|
|
307
147
|
this.superpeg.clone(ctx), peer, 'pref-gate/' + this.id)
|
|
308
148
|
|
|
@@ -338,7 +178,6 @@ class PrefVal extends FeatureVal {
|
|
|
338
178
|
: makeNilErr(ctx, 'empty', this, peer, 'unify')
|
|
339
179
|
|
|
340
180
|
|
|
341
|
-
|
|
342
181
|
// }
|
|
343
182
|
}
|
|
344
183
|
else {
|
|
@@ -349,7 +188,6 @@ class PrefVal extends FeatureVal {
|
|
|
349
188
|
// superior-unify (mirrored by PrefVal.Unify in go/pref.go).
|
|
350
189
|
out.dc = DONE
|
|
351
190
|
|
|
352
|
-
// console.log('PREFVAL-OUT', why, this.canon, peer.canon, '->', out.canon, out.done)
|
|
353
191
|
|
|
354
192
|
ctx.explain && explainClose(te, out)
|
|
355
193
|
|
|
@@ -372,27 +210,10 @@ class PrefVal extends FeatureVal {
|
|
|
372
210
|
clone(ctx: AontuContext, spec?: ValSpec): Val {
|
|
373
211
|
let out = (super.clone(ctx, spec) as PrefVal)
|
|
374
212
|
|
|
375
|
-
// THE NARROWED OVERRIDE SPACE TRAVELS WITH THE COPY (ADR-011 R1).
|
|
376
|
-
// A default a meet has pinned stays pinned through a reference:
|
|
377
|
-
// without this, `T:{e:***false & false}` copied by `f:$.T` handed
|
|
378
|
-
// back a default whose gate had widened again to `boolean`, and
|
|
379
|
-
// `f:{e:true}` overrode a value the author had pinned. The Go
|
|
380
|
-
// twin carries the same two fields explicitly (clone.go).
|
|
381
213
|
if (null != this.narrowed) {
|
|
382
214
|
out.narrowed = this.narrowed
|
|
383
215
|
out.superpeg = this.superpeg
|
|
384
216
|
}
|
|
385
|
-
// THE PER-DESTINATION INSTANTIATION RULE (ADR-005). The default
|
|
386
|
-
// clone shares the preferred value (`peg: this.peg` in Val.clone)
|
|
387
|
-
// — a cloned pref spread template resolves its inner value at the
|
|
388
|
-
// template's own location, pinned behaviour. But a template
|
|
389
|
-
// INSTANCE must own it: with the peg shared, a rank-2 default
|
|
390
|
-
// (`**key(1) | string`) in a pack template resolved its one
|
|
391
|
-
// shared inner key() at the first destination and every child got
|
|
392
|
-
// the first child's key (use-cases/BUGS.md §9 — rank 1 escaped
|
|
393
|
-
// only because its unify builds a fresh PrefVal per meet). The
|
|
394
|
-
// superpeg yardstick from the shared peg still holds: the clone's
|
|
395
|
-
// innermost value is the same kind.
|
|
396
217
|
if (true === spec?.dup && true === (this.peg as any)?.isVal) {
|
|
397
218
|
out.peg = this.peg.clone(ctx, { dup: true })
|
|
398
219
|
}
|