aontu 0.61.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 +4 -4
- package/dist/agentsmd.d.ts +1 -0
- package/dist/agentsmd.js +7 -28
- package/dist/agentsmd.js.map +1 -1
- package/dist/alias.js.map +1 -1
- package/dist/allow.d.ts +23 -0
- package/dist/allow.js +138 -0
- package/dist/allow.js.map +1 -0
- package/dist/aontu.d.ts +4 -2
- package/dist/aontu.js +4 -80
- 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.d.ts +10 -1
- package/dist/cli.js +877 -479
- 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 +55 -189
- 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.d.ts +16 -0
- package/dist/helpdoc.js +59 -0
- package/dist/helpdoc.js.map +1 -0
- package/dist/hints.d.ts +0 -6
- package/dist/hints.js +59 -47
- 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 +32 -877
- package/dist/lang.js.map +1 -1
- package/dist/lower.d.ts +3 -0
- package/dist/lower.js +14 -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.d.ts +2 -0
- package/dist/relation.js +3 -58
- package/dist/relation.js.map +1 -1
- package/dist/render.js +33 -143
- 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.d.ts +20 -0
- package/dist/val/CmpFuncVal.js +188 -0
- package/dist/val/CmpFuncVal.js.map +1 -0
- 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.d.ts +1 -2
- package/dist/val/EachFuncVal.js +12 -29
- 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 +11 -6
- 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 +2 -36
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/NomFuncVal.d.ts +12 -0
- package/dist/val/NomFuncVal.js +153 -0
- package/dist/val/NomFuncVal.js.map +1 -0
- 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.d.ts +12 -0
- package/dist/val/TranslateFuncVal.js +99 -0
- package/dist/val/TranslateFuncVal.js.map +1 -0
- package/dist/val/UpperFuncVal.js +11 -6
- 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.d.ts +3 -0
- package/dist/val/caserange.js +49 -0
- package/dist/val/caserange.js.map +1 -0
- 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.d.ts +12 -0
- package/dist/vet.js +159 -412
- 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 +9 -7
- package/grammar/aontu.gbnf +5 -5
- package/grammar/aontu.lark +5 -5
- package/grammar/aontu.tmLanguage.json +1 -1
- package/package.json +4 -2
- package/skill/SKILL.md +8 -0
- package/skill/init/check.sh +28 -0
- package/skill/init/data.aon +12 -0
- package/skill/init/model.aon +19 -0
- package/skill/tasks.md +151 -0
- package/src/agentsmd.ts +8 -32
- package/src/alias.ts +0 -39
- package/src/allow.ts +221 -0
- package/src/aontu.ts +10 -108
- package/src/aontumodel.ts +32 -0
- package/src/cli.ts +1009 -540
- 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 +63 -234
- package/src/grammar.ts +72 -0
- package/src/graph.ts +0 -61
- package/src/hcanon.ts +0 -82
- package/src/helpdoc.ts +77 -0
- package/src/hints.ts +72 -49
- package/src/jsonschema.ts +0 -123
- package/src/keyorder.ts +0 -42
- package/src/lang.ts +39 -895
- package/src/lower.ts +15 -65
- 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 +7 -71
- package/src/render.ts +33 -180
- 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 +249 -0
- 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 +12 -53
- 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 +12 -7
- 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 +2 -36
- package/src/val/NomFuncVal.ts +200 -0
- 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 +132 -0
- package/src/val/UpperFuncVal.ts +12 -7
- 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 +53 -0
- 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 +209 -504
- package/src/view.ts +0 -507
- package/src/walk.ts +0 -41
- package/dist/std.d.ts +0 -3
- package/dist/std.js +0 -637
- package/dist/std.js.map +0 -1
- package/dist/val/FormFuncVal.js +0 -55
- package/dist/val/FormFuncVal.js.map +0 -1
- package/src/std.ts +0 -648
- package/src/val/FormFuncVal.ts +0 -119
|
@@ -1,21 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// CONTAINER KINDS (docs/design/PATHS.0.md). `{}` and `[]` are the
|
|
4
|
-
// container UNITS: they admit any map (or list) AND generate empty
|
|
5
|
-
// when nothing arrives. `map()` and `list()` are the container KINDS
|
|
6
|
-
// proper: they admit exactly the same values and default to NOTHING,
|
|
7
|
-
// as `string` does -- the spelling of "this must be a map, and it
|
|
8
|
-
// must be supplied", which the unit cannot say because an unmet unit
|
|
9
|
-
// silently manufactures its empty value.
|
|
10
|
-
//
|
|
11
|
-
// The vacuous call is the kind; the literal is the unit. That is the
|
|
12
|
-
// whole convention, and it is why neither function takes arguments:
|
|
13
|
-
// element constraints already belong to the spreads (`{&: V}`,
|
|
14
|
-
// `[&: V]`), and a second spelling of them here would drift.
|
|
15
|
-
//
|
|
16
|
-
// No null/top/nil arms, as RelVal records: unite's dispatch ladder
|
|
17
|
-
// absorbs those peers before any Val's own unify is consulted, and
|
|
18
|
-
// FuncBaseVal returns a done resolution directly against a top peer.
|
|
19
3
|
|
|
20
4
|
import type {
|
|
21
5
|
Val,
|
|
@@ -53,8 +37,6 @@ class MapKindVal extends FeatureVal {
|
|
|
53
37
|
if (true === p.isMapKind) {
|
|
54
38
|
return this
|
|
55
39
|
}
|
|
56
|
-
// The unit's own refusal code: a kind mismatch here is the same
|
|
57
|
-
// fact `{} & 1` reports, and two codes for one fact would drift.
|
|
58
40
|
return makeNilErr(ctx, 'map', this, peer)
|
|
59
41
|
}
|
|
60
42
|
|
package/src/val/CopyFuncVal.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* Copyright (c) 2021-2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
import type {
|
|
6
5
|
Val,
|
|
7
6
|
ValSpec,
|
|
@@ -14,7 +13,6 @@ import {
|
|
|
14
13
|
import { makeNilErr } from '../err'
|
|
15
14
|
|
|
16
15
|
|
|
17
|
-
|
|
18
16
|
import {
|
|
19
17
|
walk
|
|
20
18
|
} from '../utility'
|
|
@@ -58,18 +56,15 @@ class CopyFuncVal extends FuncBaseVal {
|
|
|
58
56
|
makeNilErr(ctx, 'invalid-arg', this) :
|
|
59
57
|
val.clone(ctx)
|
|
60
58
|
|
|
61
|
-
// console.log('CR', out)
|
|
62
59
|
|
|
63
60
|
if (!out.isRef) {
|
|
64
61
|
walk(out, (_key: string | number | undefined, val: Val) => {
|
|
65
|
-
// console.log('WALK', val)
|
|
66
62
|
val.mark.type = false
|
|
67
63
|
val.mark.hide = false
|
|
68
64
|
return val
|
|
69
65
|
})
|
|
70
66
|
}
|
|
71
67
|
|
|
72
|
-
// console.log('COPY-RESOLVE', ctx.cc, val, out)
|
|
73
68
|
|
|
74
69
|
return out
|
|
75
70
|
}
|
package/src/val/Decimal.ts
CHANGED
|
@@ -1,79 +1,15 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* The exact base-10 decimal value behind the `bigdecimal` leaf, and the
|
|
5
|
-
* parser for the `0d` literal family that reaches both exact leaves.
|
|
6
|
-
*
|
|
7
|
-
* A Decimal is a coefficient and a scale:
|
|
8
|
-
*
|
|
9
|
-
* value = unscaled / 10^scale
|
|
10
|
-
*
|
|
11
|
-
* with `unscaled` a native bigint and `scale` a plain integer. Every
|
|
12
|
-
* operation here is EXACT: aontu's whole numeric operator surface
|
|
13
|
-
* (`+`, `upper()`, `lower()`, unary minus) is exact, so no rounding
|
|
14
|
-
* context, precision or rounding mode exists anywhere in this file --
|
|
15
|
-
* addition aligns scales and adds coefficients, and ceiling/floor is
|
|
16
|
-
* coefficient arithmetic that never lets a float64 near the value.
|
|
17
|
-
* Where an exact answer will not fit the budget the answer is refused,
|
|
18
|
-
* never rounded (see decimalOverBudget).
|
|
19
|
-
*
|
|
20
|
-
* D4 -- ONE VALUE, ONE RENDERING. In a unifier canon must be a function
|
|
21
|
-
* of the value, so scale is presentation and not identity: `0d0.10`,
|
|
22
|
-
* `0d0.1` and `0d1e-1` are the same lattice point and must render
|
|
23
|
-
* identically. A Decimal therefore NORMALISES IN ITS CONSTRUCTOR --
|
|
24
|
-
* every Decimal in existence is in minimal form, which is what makes
|
|
25
|
-
* `equals` a two-field comparison and `same()` correct without any
|
|
26
|
-
* pointer identity (D2).
|
|
27
|
-
*
|
|
28
|
-
* The minimal form keeps ONE decimal place at the bottom. `0d` names the
|
|
29
|
-
* numeric FAMILY, not the leaf, so an integral bigdecimal that rendered
|
|
30
|
-
* as `0d1000` would reparse as a biginteger -- a kind-flipping canon of
|
|
31
|
-
* exactly the sort R4's `.0` suffix exists to prevent. So `0d1e3` canons
|
|
32
|
-
* as `0d1000.0`, and scale is never reduced below 1.
|
|
33
|
-
*
|
|
34
|
-
* Go mirror (D8): a struct of (coeff *big.Int, scale int32) normalised
|
|
35
|
-
* by the same rule -- strip trailing zeros while scale > 1, then raise
|
|
36
|
-
* the scale to 1 when it is lower, zero always at scale 1.
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// D6 -- THE EXACTNESS BUDGET, enforced at parse.
|
|
41
|
-
//
|
|
42
|
-
// Both halves are needed and the scale half is the load-bearing one: a
|
|
43
|
-
// coefficient-only check never fires for `0d1e1000000000`, whose
|
|
44
|
-
// coefficient is one digit, yet plain-form rendering of that value would
|
|
45
|
-
// have to materialise a gigabyte of zeros (and overflow the Go port's
|
|
46
|
-
// int32 scale field) without any arithmetic having occurred.
|
|
47
|
-
//
|
|
48
|
-
// A literal over either bound is a located error, never a rounded or
|
|
49
|
-
// expanded value: this language does not round, so the only honest
|
|
50
|
-
// answer at the limit is refusal.
|
|
3
|
+
|
|
51
4
|
const DECIMAL_COEFFICIENT_BUDGET = 4096
|
|
52
5
|
const DECIMAL_SCALE_BUDGET = 4096
|
|
53
6
|
|
|
54
7
|
|
|
55
|
-
// Powers of ten as bigints, memoised: normalisation of an
|
|
56
|
-
// exponent-bearing literal needs one per parse.
|
|
57
8
|
function pow10(n: number): bigint {
|
|
58
9
|
return 10n ** BigInt(n)
|
|
59
10
|
}
|
|
60
11
|
|
|
61
12
|
|
|
62
|
-
// True when a decimal's SOURCE form is over either budget bound.
|
|
63
|
-
//
|
|
64
|
-
// Every route that builds a Decimal from text must ask this BEFORE
|
|
65
|
-
// constructing one, because normalising an over-budget value is itself
|
|
66
|
-
// the resource event the bound exists to prevent: the constructor folds
|
|
67
|
-
// a negative scale by multiplying the coefficient by 10^-scale, so
|
|
68
|
-
// `1e1000000000` would try to build a billion-digit bigint.
|
|
69
|
-
//
|
|
70
|
-
// Written once and used by both routes -- the `0d` literal and the
|
|
71
|
-
// exact-input API -- because the Go port bounds both (NewBigDecimal
|
|
72
|
-
// shares the literal path's checker) and a TypeScript route that did not
|
|
73
|
-
// would be a silent cross-port divergence as well as a hazard.
|
|
74
|
-
//
|
|
75
|
-
// `scale` may be Infinity or NaN when the exponent digits overflow a JS
|
|
76
|
-
// number; the comparison is written so that either answers "over".
|
|
77
13
|
function overBudget(coeffDigits: number, scale: number): boolean {
|
|
78
14
|
return DECIMAL_COEFFICIENT_BUDGET < coeffDigits ||
|
|
79
15
|
!(Math.abs(scale) <= DECIMAL_SCALE_BUDGET)
|
|
@@ -88,7 +24,6 @@ function coeffDigits(unscaled: bigint): number {
|
|
|
88
24
|
|
|
89
25
|
|
|
90
26
|
class Decimal {
|
|
91
|
-
// value = unscaled / 10^scale, always in minimal form (see above).
|
|
92
27
|
readonly unscaled: bigint
|
|
93
28
|
|
|
94
29
|
// Always >= 1: an integral bigdecimal keeps one decimal place so its
|
|
@@ -100,9 +35,6 @@ class Decimal {
|
|
|
100
35
|
let s = Math.trunc(scale)
|
|
101
36
|
|
|
102
37
|
if (0n === u) {
|
|
103
|
-
// R2/D5: there is no negative zero here to begin with (a bigint
|
|
104
|
-
// has one zero), and every zero is the same lattice point, so it
|
|
105
|
-
// takes the one canonical form `0d0.0`.
|
|
106
38
|
s = 1
|
|
107
39
|
}
|
|
108
40
|
else {
|
|
@@ -148,26 +80,11 @@ class Decimal {
|
|
|
148
80
|
}
|
|
149
81
|
|
|
150
82
|
|
|
151
|
-
// Exact negation, keeping the leaf. -0 folds to 0 (D5) because the
|
|
152
|
-
// normalising constructor sends every zero to the same form.
|
|
153
83
|
negate(): Decimal {
|
|
154
84
|
return new Decimal(-this.unscaled, this.scale)
|
|
155
85
|
}
|
|
156
86
|
|
|
157
87
|
|
|
158
|
-
// D6 -- EXACT ADDITION. Align the scales, add the coefficients. That
|
|
159
|
-
// is the entire algorithm: there is no rounding mode to consult and no
|
|
160
|
-
// precision to run out of, which is why `0d0.1 + 0d0.2` is exactly
|
|
161
|
-
// `0d0.3` here and 0.30000000000000004 in binary64.
|
|
162
|
-
//
|
|
163
|
-
// The work is bounded because both operands are within the parse-time
|
|
164
|
-
// budget, so alignment can inflate a coefficient only by the scale
|
|
165
|
-
// span. The RESULT, however, can be over budget even when both
|
|
166
|
-
// operands are inside it (`0d1e4000 + 0d1e-4000` needs 8001
|
|
167
|
-
// coefficient digits), so every caller must test the result with
|
|
168
|
-
// decimalOverBudget() and report `decimal_budget` rather than store
|
|
169
|
-
// it. Refusal is the only honest answer at the limit: rounding to fit
|
|
170
|
-
// is exactly what this leaf exists to prevent.
|
|
171
88
|
add(peer: Decimal): Decimal {
|
|
172
89
|
const scale = this.scale < peer.scale ? peer.scale : this.scale
|
|
173
90
|
const a = this.unscaled * pow10(scale - this.scale)
|
|
@@ -176,34 +93,11 @@ class Decimal {
|
|
|
176
93
|
}
|
|
177
94
|
|
|
178
95
|
|
|
179
|
-
// D6 -- EXACT MULTIPLICATION. Multiply the coefficients, ADD the
|
|
180
|
-
// scales: (a/10^s)(b/10^t) is ab/10^(s+t), with no alignment step and
|
|
181
|
-
// no rounding mode, exactly as add() has none.
|
|
182
|
-
//
|
|
183
|
-
// The result leaves the budget far more readily than a sum does --
|
|
184
|
-
// scales add rather than taking the maximum, and coefficient digits
|
|
185
|
-
// add too -- so squaring a value at half the budget is already over
|
|
186
|
-
// it. Every caller must test with decimalOverBudget() and report
|
|
187
|
-
// `decimal_budget`, for the same reason add()'s callers must: at the
|
|
188
|
-
// limit, refusing is the only answer that is not a rounded one.
|
|
189
96
|
multiply(peer: Decimal): Decimal {
|
|
190
97
|
return new Decimal(this.unscaled * peer.unscaled, this.scale + peer.scale)
|
|
191
98
|
}
|
|
192
99
|
|
|
193
100
|
|
|
194
|
-
// Exact ceiling and floor, for `upper()`/`lower()`. Coefficient
|
|
195
|
-
// arithmetic only -- Math.ceil of this value would mean rounding it to
|
|
196
|
-
// binary64 first, which for a leaf that exists to escape binary64 is
|
|
197
|
-
// no answer at all.
|
|
198
|
-
//
|
|
199
|
-
// The leaf is kept (R5 contagion): the result is a bigdecimal whose
|
|
200
|
-
// value happens to be integral, so it keeps the one decimal place the
|
|
201
|
-
// family marker requires -- `upper(0d1.1)` is `0d2.0`, not `0d2`.
|
|
202
|
-
//
|
|
203
|
-
// Neither can leave the exactness budget: with scale >= 1 the integer
|
|
204
|
-
// part drops `scale` digits and normalisation adds one back, so the
|
|
205
|
-
// coefficient never grows. That is why these return a Decimal
|
|
206
|
-
// directly while add() makes its caller check.
|
|
207
101
|
ceil(): Decimal {
|
|
208
102
|
return new Decimal(this.intPart(1n), 0)
|
|
209
103
|
}
|
|
@@ -214,11 +108,6 @@ class Decimal {
|
|
|
214
108
|
}
|
|
215
109
|
|
|
216
110
|
|
|
217
|
-
// The integer part, stepped one in the direction of `dir` when a
|
|
218
|
-
// remainder of that sign was discarded. bigint division truncates
|
|
219
|
-
// toward zero and the remainder carries the dividend's sign, so
|
|
220
|
-
// truncation already IS the floor of a positive and the ceiling of a
|
|
221
|
-
// negative; only the other half of each case needs the step.
|
|
222
111
|
private intPart(dir: bigint): bigint {
|
|
223
112
|
const p = pow10(this.scale)
|
|
224
113
|
const q = this.unscaled / p
|
|
@@ -232,11 +121,6 @@ class Decimal {
|
|
|
232
121
|
}
|
|
233
122
|
|
|
234
123
|
|
|
235
|
-
// Plain digits, no `0d` marker: `1000.0`, `-0.1`. Plain form at every
|
|
236
|
-
// magnitude, never scientific -- the budget is what makes that safe.
|
|
237
|
-
// This is also the rendering string concatenation will want in Phase 4
|
|
238
|
-
// (`"q" + 0d0.1` is `"q0.1"`), which is why the marker lives in
|
|
239
|
-
// `canon()` and not here.
|
|
240
124
|
toString(): string {
|
|
241
125
|
const neg = this.unscaled < 0n
|
|
242
126
|
let d = (neg ? -this.unscaled : this.unscaled).toString()
|
|
@@ -256,11 +140,6 @@ class Decimal {
|
|
|
256
140
|
}
|
|
257
141
|
|
|
258
142
|
|
|
259
|
-
// Exact-input construction for library consumers (D8). A JS `number`
|
|
260
|
-
// argument is already rounded before this library could inspect it, so
|
|
261
|
-
// the exact leaves are reachable only from a bigint or from text.
|
|
262
|
-
// Accepts `[+-]?digits[.digits][(e|E)[+-]digits]`, with or without the
|
|
263
|
-
// `0d` marker, and no `_` separators (those are literal syntax).
|
|
264
143
|
static fromString(src: string): Decimal {
|
|
265
144
|
const m = /^([-+]?)(?:0[dD])?([0-9]+)(?:\.([0-9]+))?(?:[eE]([-+]?[0-9]+))?$/
|
|
266
145
|
.exec(src)
|
|
@@ -271,11 +150,6 @@ class Decimal {
|
|
|
271
150
|
const exp = null == m[4] ? 0 : Number(m[4])
|
|
272
151
|
const scale = frac.length - exp
|
|
273
152
|
|
|
274
|
-
// The same bound the `0d` literal obeys (D6). Without it this API
|
|
275
|
-
// route reached the resource exhaustion the budget exists to
|
|
276
|
-
// prevent -- `fromString('1e1000000000')` would normalise by
|
|
277
|
-
// building a billion-digit coefficient -- and disagreed with the Go
|
|
278
|
-
// port, whose NewBigDecimal shares the literal path's checker.
|
|
279
153
|
if (overBudget(m[2].length + frac.length, scale)) {
|
|
280
154
|
throw new Error('decimal-budget: ' + src)
|
|
281
155
|
}
|
|
@@ -286,63 +160,15 @@ class Decimal {
|
|
|
286
160
|
}
|
|
287
161
|
|
|
288
162
|
|
|
289
|
-
// D6 -- THE BUDGET APPLIES TO RESULTS, NOT JUST LITERALS. True when a
|
|
290
|
-
// Decimal produced by arithmetic is over either bound and so must be
|
|
291
|
-
// refused with `decimal_budget`.
|
|
292
|
-
//
|
|
293
|
-
// The test is applied to the NORMAL form -- the representation the value
|
|
294
|
-
// is actually stored and rendered in -- rather than to some minimal
|
|
295
|
-
// re-derived source form. That keeps the rule cheap and mechanical
|
|
296
|
-
// enough for the Go port to mirror exactly (count the coefficient's
|
|
297
|
-
// digits, read the scale), and it bounds precisely the thing the bound
|
|
298
|
-
// exists to bound: the digits plain-form rendering will have to
|
|
299
|
-
// materialise.
|
|
300
|
-
//
|
|
301
|
-
// One consequence is worth naming: a literal is budget-checked on its
|
|
302
|
-
// SOURCE form, so an extreme literal whose normal form is wider than its
|
|
303
|
-
// source (`0d1e4096` -- one written digit, 4098 normalised ones) parses
|
|
304
|
-
// but cannot take part in arithmetic. Both bounds are deliberately far
|
|
305
|
-
// beyond any real document, and the alternative -- re-deriving a minimal
|
|
306
|
-
// form per operation -- only moves the same edge somewhere else
|
|
307
|
-
// (`0d100e4096` has minimal scale -4098, over the bound its source form
|
|
308
|
-
// was under), at the cost of a second normal form that both ports would
|
|
309
|
-
// then have to agree on digit for digit.
|
|
310
163
|
function decimalOverBudget(d: Decimal): boolean {
|
|
311
164
|
return overBudget(coeffDigits(d.unscaled), d.scale)
|
|
312
165
|
}
|
|
313
166
|
|
|
314
167
|
|
|
315
|
-
// D3 -- THE `0d` LITERAL.
|
|
316
|
-
//
|
|
317
|
-
// 0[dD] digits [ . digits ] [ (e|E) [+-] digits ]
|
|
318
|
-
//
|
|
319
|
-
// with single `_` separators between digits, exactly as the landed
|
|
320
|
-
// separator rule allows for ordinary numbers (`[0-9](?:_?[0-9])*` admits
|
|
321
|
-
// `1_000` and refuses `1__0`, `_1`, `1_`).
|
|
322
|
-
//
|
|
323
|
-
// LEAF BY SOURCE, mirroring R1's precedent that the source text and not
|
|
324
|
-
// the value decides the kind: digits only is a biginteger, a `.` or an
|
|
325
|
-
// exponent anywhere makes it a bigdecimal. So `0d5` is a biginteger and
|
|
326
|
-
// `0d1e3` is a bigdecimal whose value happens to be integral.
|
|
327
|
-
//
|
|
328
|
-
// THE SIGN IS NOT PART OF THIS PATTERN, though it is part of the D3
|
|
329
|
-
// grammar: `-0d5` is read as the existing unary-minus prefix applied to
|
|
330
|
-
// `0d5` (see negative-prefix in lang.ts), exactly as `-1.5` already is.
|
|
331
|
-
// Aontu's lexer runs regexp value matchers BEFORE the fixed-token
|
|
332
|
-
// matcher, so a `[-+]?` here would claim the `+` of `0d1 +0d2` as a
|
|
333
|
-
// literal sign and silently turn an addition into an implicit list --
|
|
334
|
-
// while plain `1 +2` stayed an addition. The sign belongs to the same
|
|
335
|
-
// operator for both, which is also what keeps `0d-5` rejected.
|
|
336
|
-
//
|
|
337
|
-
// Kept RE2-compatible (no lookaround, no backreferences) so the Go port
|
|
338
|
-
// can use the byte-identical pattern.
|
|
339
168
|
const BIG_LITERAL_RE =
|
|
340
169
|
/^0[dD]([0-9](?:_?[0-9])*)(?:\.([0-9](?:_?[0-9])*))?(?:[eE]([-+]?[0-9](?:_?[0-9])*))?/
|
|
341
170
|
|
|
342
171
|
|
|
343
|
-
// The outcome of reading a `0d` literal: one of the two exact leaves, or
|
|
344
|
-
// a budget refusal. `undefined` is impossible for text the matcher above
|
|
345
|
-
// claimed, and is reported as an error rather than guessed at.
|
|
346
172
|
type BigLiteral =
|
|
347
173
|
{ leaf: 'biginteger', int: bigint } |
|
|
348
174
|
{ leaf: 'bigdecimal', dec: Decimal } |
|
|
@@ -354,8 +180,6 @@ function stripSep(s: string): string {
|
|
|
354
180
|
}
|
|
355
181
|
|
|
356
182
|
|
|
357
|
-
// Read a `0d` literal from the groups of BIG_LITERAL_RE:
|
|
358
|
-
// 1 integer digits, 2 fraction digits, 3 exponent.
|
|
359
183
|
function readBigLiteral(m: RegExpExecArray | (string | undefined)[]): BigLiteral {
|
|
360
184
|
const intd = stripSep(m[1] as string)
|
|
361
185
|
const fracd = null == m[2] ? undefined : stripSep(m[2])
|
|
@@ -366,18 +190,10 @@ function readBigLiteral(m: RegExpExecArray | (string | undefined)[]): BigLiteral
|
|
|
366
190
|
return { leaf: 'biginteger', int: BigInt(intd) }
|
|
367
191
|
}
|
|
368
192
|
|
|
369
|
-
// The exponent is read as a plain number on purpose: a 4000-digit
|
|
370
|
-
// exponent lands on Infinity, whose absolute value is over budget, so
|
|
371
|
-
// the refusal below fires without any bigint ever being built.
|
|
372
193
|
const exp = undefined === expd ? 0 : Number(expd)
|
|
373
194
|
const fracLen = undefined === fracd ? 0 : fracd.length
|
|
374
195
|
const scale = fracLen - exp
|
|
375
196
|
|
|
376
|
-
// The budget is checked on the SOURCE form, before normalisation:
|
|
377
|
-
// normalising `0d1e1000000000` is itself the resource event the bound
|
|
378
|
-
// exists to prevent. Coefficient digits are counted as written
|
|
379
|
-
// (leading zeros included) so the two ports need not agree on any
|
|
380
|
-
// cleverer rule.
|
|
381
197
|
if (overBudget(intd.length + fracLen, scale)) {
|
|
382
198
|
return { leaf: 'error', code: 'decimal_budget' }
|
|
383
199
|
}
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// The deprecation mark (G3 phase 4,
|
|
4
|
-
// docs/capability-review/g3-subsumption-evolution.md): a function-form
|
|
5
|
-
// builtin, `deprecate(x, m)`, that unifies EXACTLY as `x` while the
|
|
6
|
-
// record `m` rides the result through meets. The record's keys are
|
|
7
|
-
// msg, use and since — all optional, all strings; `use` is a path
|
|
8
|
-
// spelled as a STRING, because a live reference would resolve and
|
|
9
|
-
// unify, which is not wanted. Boolean ValMarks cannot hold a record,
|
|
10
|
-
// so the Val carries one optional field (Val.deprecation), propagated
|
|
11
|
-
// by the same channel as the marks (propagateMarks) and rendered back
|
|
12
|
-
// reparseably by canon (canonRiders).
|
|
13
3
|
|
|
14
4
|
import type {
|
|
15
5
|
Val,
|
package/src/val/DisjunctVal.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* Copyright (c) 2021-2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
import type {
|
|
6
5
|
Val,
|
|
7
6
|
ValSpec,
|
|
@@ -36,8 +35,6 @@ import { PrefVal, prefInnerPeg } from '../val/PrefVal'
|
|
|
36
35
|
import { JunctionVal } from '../val/JunctionVal'
|
|
37
36
|
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
// TODO: move main logic to op/disjunct
|
|
41
38
|
class DisjunctVal extends JunctionVal {
|
|
42
39
|
isDisjunct = true
|
|
43
40
|
isGenable = true
|
|
@@ -45,7 +42,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
45
42
|
|
|
46
43
|
prefsRanked = false
|
|
47
44
|
|
|
48
|
-
// TODO: sites from normalization of orginal Disjuncts, as well as child pegs
|
|
49
45
|
constructor(
|
|
50
46
|
spec: {
|
|
51
47
|
peg: Val[]
|
|
@@ -79,65 +75,18 @@ class DisjunctVal extends JunctionVal {
|
|
|
79
75
|
}
|
|
80
76
|
}
|
|
81
77
|
|
|
82
|
-
// // // console.log('DISJUNCT-unify-A', this.id, this.canon)
|
|
83
78
|
|
|
84
79
|
let done = true
|
|
85
80
|
|
|
86
81
|
let oval: Val[] = []
|
|
87
82
|
|
|
88
|
-
// Conjunction (&) distributes over disjunction (|).
|
|
89
|
-
//
|
|
90
|
-
// Each member is tried against peer in isolation: if that trial
|
|
91
|
-
// produces any errors, the member fails and is marked with a NilVal.
|
|
92
|
-
// Previously this used `ctx?.clone({err: []})` per member - a
|
|
93
|
-
// per-iteration context clone (two Object.creates) just to hold a
|
|
94
|
-
// throwaway error array. For schemas with many disjunctions
|
|
95
|
-
// (e.g. `*true | boolean`, `method: GET | PUT | ...`) this was the
|
|
96
|
-
// single largest source of clones in the unify hot path.
|
|
97
|
-
//
|
|
98
|
-
// Swap-and-restore avoids the clone: the existing ctx's err array
|
|
99
|
-
// is saved, replaced with a fresh array for each trial, then
|
|
100
|
-
// restored. ctx mutation is scoped to this loop and fully undone
|
|
101
|
-
// before return.
|
|
102
83
|
const savedErr = ctx.err
|
|
103
84
|
const savedTrialMode = ctx._trialMode
|
|
104
|
-
// THE SANDBOX MUST NOT OUTLIVE THE TRIAL AS AN OWN PROPERTY.
|
|
105
|
-
// Contexts are made with Object.create(parent) and CACHED per
|
|
106
|
-
// (parent, key) by AontuContext.descend, so `err` and `_trialMode`
|
|
107
|
-
// are normally INHERITED -- and assigning them here, the restore
|
|
108
|
-
// included, creates own properties that shadow the ancestor on
|
|
109
|
-
// every later pass. A child that has run a trial of its own then
|
|
110
|
-
// cannot see the trial its PARENT is running: makeNilErr allocates
|
|
111
|
-
// a real NilVal instead of TRIAL_NIL, the refusal lands on the
|
|
112
|
-
// meet's real error list, and the losing member is kept as though
|
|
113
|
-
// it had survived -- with the nil inside it. A vet run then
|
|
114
|
-
// reported the conflicts of arms that should have dropped out, and
|
|
115
|
-
// called the document invalid where it is incomplete.
|
|
116
|
-
//
|
|
117
|
-
// So the restore DELETES what was inherited rather than writing it
|
|
118
|
-
// back. Both arms of both guards are live: the root meet context
|
|
119
|
-
// has an own `err`, a descended child does not, and `_trialMode`
|
|
120
|
-
// is own exactly when a disjunction is tried inside another
|
|
121
|
-
// disjunction's trial on the same context.
|
|
122
85
|
const ownErr = Object.prototype.hasOwnProperty.call(ctx, 'err')
|
|
123
86
|
const ownTrialMode =
|
|
124
87
|
Object.prototype.hasOwnProperty.call(ctx, '_trialMode')
|
|
125
|
-
// A MEMBER'S TYPE FLOW IS PART OF THAT MEMBER. `refer(t)`/`rel(t)`
|
|
126
|
-
// assert `t` on ANOTHER node, and the assertion may only take
|
|
127
|
-
// effect if the member that makes it survives: committing every
|
|
128
|
-
// member's flow puts `t_A & t_B` on the target, which no reading
|
|
129
|
-
// of `A | B` licenses and which leaves the target MORE constrained
|
|
130
|
-
// than either alternative. The flow record is therefore staged per
|
|
131
|
-
// trial, like `ctx.err`, and only the survivors' records are
|
|
132
|
-
// merged into the real one below.
|
|
133
88
|
const savedFlows: Map<string, Val> | undefined = (ctx as any).referflows
|
|
134
89
|
const staged: (Map<string, Val> | undefined)[] = []
|
|
135
|
-
// C1-inner: tell `makeNilErr` to return TRIAL_NIL in this scope
|
|
136
|
-
// instead of allocating per-failure NilVals. Save/restore so
|
|
137
|
-
// nested DisjunctVal trials (and the outer non-trial code) are
|
|
138
|
-
// not affected. The restore lives in `finally`: if a trial throws,
|
|
139
|
-
// leaving ctx._trialMode=true would collapse every subsequent real
|
|
140
|
-
// error in this ctx to the shared TRIAL_NIL sentinel.
|
|
141
90
|
ctx._trialMode = true
|
|
142
91
|
let gate: number[] | undefined = undefined
|
|
143
92
|
try {
|
|
@@ -153,10 +102,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
153
102
|
oval[vI] = unite(te ? ctx.clone({ explain: ec(te, 'DIST:' + vI) }) : ctx, v, peer, 'dj-peer')
|
|
154
103
|
|
|
155
104
|
if (0 < trialErr.length) {
|
|
156
|
-
// C1: failed-trial marker is never user-visible — it just
|
|
157
|
-
// signals "this disjunct member doesn't match" and is
|
|
158
|
-
// filtered out before the result is built. Use the shared
|
|
159
|
-
// sentinel instead of allocating a fresh NilVal per trial.
|
|
160
105
|
oval[vI] = TRIAL_NIL
|
|
161
106
|
}
|
|
162
107
|
else if (v instanceof PrefVal &&
|
|
@@ -171,23 +116,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
171
116
|
done = done && DONE === oval[vI].dc
|
|
172
117
|
}
|
|
173
118
|
|
|
174
|
-
// THE ADMISSION GATE (ADR-004). A peer that meets a preference
|
|
175
|
-
// INSIDE a disjunction must be admitted by the disjunction: by
|
|
176
|
-
// some sibling alternative (whose own trial above already
|
|
177
|
-
// answers that), or by the preferred value itself (the pref
|
|
178
|
-
// branch's own admitted set). The pref's kind gate alone used to
|
|
179
|
-
// decide, so a same-kind concrete peer replaced the default with
|
|
180
|
-
// the alternatives never consulted -- `k:*'auto'|'literal'|'data'`
|
|
181
|
-
// plus `k:'autoo'` answered "autoo", and `*8080|(integer&neq(80))`
|
|
182
|
-
// admitted 80 (use-cases/BUGS.md §1-2). An inadmissible override
|
|
183
|
-
// now fails the pref member's trial, and when every member is
|
|
184
|
-
// gone the meet is the existing `empty` refusal.
|
|
185
|
-
//
|
|
186
|
-
// SCALAR preferred values only, exactly the kind gate's own
|
|
187
|
-
// boundary (test/spec/pref.tsv, "THE GATE IS A SCALAR GATE"): a
|
|
188
|
-
// structural or kind-peg default stays ungated. A deliberately
|
|
189
|
-
// open default remains spellable as `*x|top` -- the top branch
|
|
190
|
-
// admits every override (the apidef machine-emitted idiom).
|
|
191
119
|
if (undefined !== gate) {
|
|
192
120
|
for (const gI of gate) {
|
|
193
121
|
let admitted = false
|
|
@@ -232,20 +160,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
232
160
|
|
|
233
161
|
// // // console.log('DISJUNCT-unify-B', this.id, oval.map(v => v.canon))
|
|
234
162
|
|
|
235
|
-
// A PREFERENCE CONJOINED WITH A DISJUNCTION IS A PREFERENCE ON THE
|
|
236
|
-
// ALTERNATIVE IT NAMES: `(A|B) & *A` is `*A|B`, the same value the
|
|
237
|
-
// direct spelling `*A|B` denotes. Distribution carries the peer to
|
|
238
|
-
// each member, and a scalar preference meeting a concrete same-kind
|
|
239
|
-
// member is replaced BY that member (the kind gate) -- so the
|
|
240
|
-
// preference simply vanished, and `specversion: ("1.0"|"1.1") &
|
|
241
|
-
// *"1.0"`, the enum-with-default written the other way round, held
|
|
242
|
-
// no default at all. The old generation fold hid it by folding the
|
|
243
|
-
// members together; ADR-007 does not, and a disjunction that has
|
|
244
|
-
// lost its default is not the value the author wrote.
|
|
245
|
-
//
|
|
246
|
-
// A preference naming no alternative is dropped, as it is today: it
|
|
247
|
-
// has nothing to prefer, and the default-validity lint is what
|
|
248
|
-
// reports that shape.
|
|
249
163
|
if (true === (peer as any).isPref) {
|
|
250
164
|
const want: any = prefInnerPeg(peer as PrefVal)
|
|
251
165
|
for (let vI = 0; vI < oval.length; vI++) {
|
|
@@ -279,17 +193,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
279
193
|
continue
|
|
280
194
|
}
|
|
281
195
|
|
|
282
|
-
// TWO PREFERENCES OVER ONE VALUE ARE ONE PREFERENCE, and
|
|
283
|
-
// the lower rank is the one that generates: `*1 | **1` is
|
|
284
|
-
// `*1`. Ranking folds EQUAL ranks (R2); this folds the rest,
|
|
285
|
-
// which R5 stopped discarding.
|
|
286
|
-
//
|
|
287
|
-
// A PLAIN arm holding that same value is NOT a duplicate of
|
|
288
|
-
// it and must not be folded away: it is the sibling that
|
|
289
|
-
// ADMITS an override under ADR-004's gate, which is the
|
|
290
|
-
// whole point of writing `*x | x`. Folding it turned that
|
|
291
|
-
// idiom's own default into a `pref_not_instance` finding,
|
|
292
|
-
// and `*top | top` is pinned as its control.
|
|
293
196
|
const a: any = oval[vI]
|
|
294
197
|
const b: any = oval[kI]
|
|
295
198
|
if (true === a.isPref && true === b.isPref
|
|
@@ -308,10 +211,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
308
211
|
// // // console.log('DISJUNCT-unify-D', this.id, oval.map(v => v.canon))
|
|
309
212
|
}
|
|
310
213
|
|
|
311
|
-
// THE SURVIVORS' FLOWS, AND ONLY THEIRS. Members knocked out by
|
|
312
|
-
// the trial, by the admission gate or by the dedup above are all
|
|
313
|
-
// nil here, so this runs after every one of those and before the
|
|
314
|
-
// filter that drops them.
|
|
315
214
|
if (undefined !== savedFlows) {
|
|
316
215
|
for (let vI = 0; vI < staged.length; vI++) {
|
|
317
216
|
const st = staged[vI]
|
|
@@ -342,13 +241,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
342
241
|
}
|
|
343
242
|
else {
|
|
344
243
|
out = new DisjunctVal({ peg: oval }, ctx)
|
|
345
|
-
// A NARROWED DISJUNCTION IS STILL THAT DISJUNCTION. The meet mints
|
|
346
|
-
// a fresh value, which used to arrive unsited and file-less -- so
|
|
347
|
-
// every finding naming a disjunction that had met anything
|
|
348
|
-
// pointed at row -1 with no file, and an agent handed the report
|
|
349
|
-
// had nowhere to go (the review's finding F). `place` copies the
|
|
350
|
-
// whole site, position and url together, which is what tells the
|
|
351
|
-
// report which document it came from.
|
|
352
244
|
this.place(out)
|
|
353
245
|
}
|
|
354
246
|
|
|
@@ -363,24 +255,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
363
255
|
}
|
|
364
256
|
|
|
365
257
|
|
|
366
|
-
// RANK ORDERS THE SURVIVORS, IT DOES NOT DISCARD AT PARSE (ADR-011
|
|
367
|
-
// R5, docs/design/DEFAULTS.0.md). Every rank is KEPT here, and
|
|
368
|
-
// generation takes the lowest-rank preference still standing -- so
|
|
369
|
-
// eliminating the lower arm PROMOTES the next instead of taking the
|
|
370
|
-
// whole ladder with it. This ran once, before the member trials,
|
|
371
|
-
// and discarded every arm but the lowest: `*1 | **2` met by
|
|
372
|
-
// `neq(1)` lost the default entirely and refused, where the ladder
|
|
373
|
-
// exists precisely to answer 2. Rank is a preference order over
|
|
374
|
-
// WHAT SURVIVES, which is not knowable until the trials have run.
|
|
375
|
-
//
|
|
376
|
-
// Only EQUAL ranks fold, because two defaults at one rank are one
|
|
377
|
-
// decision: compatible pegs merge, and a disagreement is the
|
|
378
|
-
// `pref_rank_clash` refusal (R2), which belongs to the whole
|
|
379
|
-
// disjunction -- there is no alternative to fall back to.
|
|
380
|
-
//
|
|
381
|
-
// Answers the sole surviving preference when the disjunction holds
|
|
382
|
-
// exactly one -- which the RECURSIVE call below consumes to lift a
|
|
383
|
-
// nested disjunct's winner into this one -- or the clash refusal.
|
|
384
258
|
rankPrefs(ctx: AontuContext): Val | undefined {
|
|
385
259
|
// The kept index per rank, so an equal-rank twin folds into the
|
|
386
260
|
// arm already standing for that rank.
|
|
@@ -435,7 +309,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
435
309
|
}
|
|
436
310
|
|
|
437
311
|
|
|
438
|
-
|
|
439
312
|
clone(ctx: AontuContext, spec?: ValSpec): Val {
|
|
440
313
|
let out = (super.clone(ctx, spec) as DisjunctVal)
|
|
441
314
|
return out
|
|
@@ -447,25 +320,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
447
320
|
}
|
|
448
321
|
|
|
449
322
|
|
|
450
|
-
// AN UNRESOLVED DISJUNCTION IS NOT A VALUE (ADR-007).
|
|
451
|
-
//
|
|
452
|
-
// Generation used to FOLD the surviving members together with unify
|
|
453
|
-
// and emit the result. That answer is in no branch of the
|
|
454
|
-
// disjunction: `({x:1}|{y:2}) & {z:3}` generated `{x:1,y:2,z:3}`, a
|
|
455
|
-
// map the model never admits, and `1|2` died as a scalar_value
|
|
456
|
-
// CONFLICT -- the conflict of the fold, not of anything the author
|
|
457
|
-
// wrote. The second half is what made vet decorative: vet's
|
|
458
|
-
// incompleteness check keeps incomplete-class findings, so a missing
|
|
459
|
-
// required enum field (`role: 'a'|'b'` with no data) arrived as a
|
|
460
|
-
// conflict, was filtered out, and vetted VALID with zero findings
|
|
461
|
-
// (use-cases/BUGS.md §13, the review's finding C).
|
|
462
|
-
//
|
|
463
|
-
// What remains after unification is what the model still admits, so
|
|
464
|
-
// more than one surviving alternative means the truth is not yet
|
|
465
|
-
// settled -- incomplete, the same class a bare `string` residue
|
|
466
|
-
// answers, and the same answer CUE gives for a non-concrete export.
|
|
467
|
-
// A preference resolves it (that is what `*` is for), and so does a
|
|
468
|
-
// single surviving member.
|
|
469
323
|
gen(ctx: AontuContext) {
|
|
470
324
|
if (0 < this.peg.length) {
|
|
471
325
|
// Ranking may not have run when gen is reached without a prior
|
|
@@ -477,12 +331,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
477
331
|
|
|
478
332
|
const prefs = this.peg.filter((v: Val) => v instanceof PrefVal)
|
|
479
333
|
|
|
480
|
-
// ALTERNATIVES THAT GENERATE THE SAME VALUE ARE RESOLVED
|
|
481
|
-
// (ADR-007's rule, asked at the moment it matters): `[] | [&:
|
|
482
|
-
// T]` met by an empty list keeps both arms -- they differ as
|
|
483
|
-
// SCHEMAS, which is what stops the dedup collapsing the
|
|
484
|
-
// template away (BUGS.md §52 regime 4) -- but both generate
|
|
485
|
-
// the empty list, and one generated value is one value.
|
|
486
334
|
if (0 === prefs.length && 1 < this.peg.length) {
|
|
487
335
|
const gctx = ctx.clone({ err: [], collect: true })
|
|
488
336
|
let firstOut: any
|
|
@@ -516,9 +364,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
516
364
|
return undefined
|
|
517
365
|
}
|
|
518
366
|
|
|
519
|
-
// THE LOWEST-RANK SURVIVOR (R5). Ranking no longer discards the
|
|
520
|
-
// weaker arms, so the choice is made here, over what is left:
|
|
521
|
-
// `*1 | **2` answers 1, and answers 2 once `*1` is gone.
|
|
522
367
|
let best: any = this.peg[0]
|
|
523
368
|
if (0 < prefs.length) {
|
|
524
369
|
best = prefs[0]
|
|
@@ -536,8 +381,6 @@ class DisjunctVal extends JunctionVal {
|
|
|
536
381
|
} /* node:coverage ignore next 8 */
|
|
537
382
|
|
|
538
383
|
|
|
539
|
-
|
|
540
|
-
|
|
541
384
|
export {
|
|
542
385
|
DisjunctVal,
|
|
543
386
|
}
|