aontu 0.52.1 → 0.53.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 +88 -0
- package/bin/aontu-mcp.js +4 -0
- package/dist/agentsmd.d.ts +16 -0
- package/dist/agentsmd.js +107 -0
- package/dist/agentsmd.js.map +1 -0
- package/dist/aontu.d.ts +14 -3
- package/dist/aontu.js +96 -4
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +44 -1
- package/dist/cli.js +2401 -44
- package/dist/cli.js.map +1 -1
- package/dist/ctx.d.ts +13 -0
- package/dist/ctx.js +43 -0
- package/dist/ctx.js.map +1 -1
- package/dist/diff.d.ts +22 -0
- package/dist/diff.js +141 -0
- package/dist/diff.js.map +1 -0
- package/dist/err.d.ts +3 -1
- package/dist/err.js +38 -7
- package/dist/err.js.map +1 -1
- package/dist/graph.d.ts +16 -0
- package/dist/graph.js +73 -0
- package/dist/graph.js.map +1 -0
- package/dist/hcanon.d.ts +3 -0
- package/dist/hcanon.js +146 -0
- package/dist/hcanon.js.map +1 -0
- package/dist/hints.js +167 -4
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.d.ts +20 -0
- package/dist/jsonschema.js +391 -0
- package/dist/jsonschema.js.map +1 -0
- package/dist/lang.js +512 -69
- package/dist/lang.js.map +1 -1
- package/dist/lsp.d.ts +9 -2
- package/dist/lsp.js +262 -47
- package/dist/lsp.js.map +1 -1
- package/dist/mcp-server.d.ts +20 -0
- package/dist/mcp-server.js +147 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp.d.ts +42 -0
- package/dist/mcp.js +814 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mod-tool.d.ts +58 -0
- package/dist/mod-tool.js +498 -0
- package/dist/mod-tool.js.map +1 -0
- package/dist/mod.d.ts +31 -0
- package/dist/mod.js +250 -0
- package/dist/mod.js.map +1 -0
- package/dist/patch.d.ts +44 -0
- package/dist/patch.js +506 -0
- package/dist/patch.js.map +1 -0
- package/dist/provenance.d.ts +40 -0
- package/dist/provenance.js +335 -0
- package/dist/provenance.js.map +1 -0
- package/dist/query.d.ts +27 -0
- package/dist/query.js +294 -0
- package/dist/query.js.map +1 -0
- package/dist/reach.d.ts +14 -0
- package/dist/reach.js +140 -0
- package/dist/reach.js.map +1 -0
- package/dist/relation.d.ts +19 -0
- package/dist/relation.js +305 -0
- package/dist/relation.js.map +1 -0
- package/dist/report-sarif.d.ts +14 -0
- package/dist/report-sarif.js +102 -0
- package/dist/report-sarif.js.map +1 -0
- package/dist/site.d.ts +4 -0
- package/dist/site.js +31 -0
- package/dist/site.js.map +1 -1
- package/dist/std.d.ts +1 -0
- package/dist/std.js +73 -0
- package/dist/std.js.map +1 -0
- package/dist/subsume.d.ts +39 -0
- package/dist/subsume.js +526 -0
- package/dist/subsume.js.map +1 -0
- package/dist/trim.d.ts +19 -0
- package/dist/trim.js +155 -0
- package/dist/trim.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type.d.ts +17 -1
- package/dist/type.js.map +1 -1
- package/dist/unify.d.ts +2 -1
- package/dist/unify.js +253 -36
- package/dist/unify.js.map +1 -1
- package/dist/utility.d.ts +9 -1
- package/dist/utility.js +122 -1
- package/dist/utility.js.map +1 -1
- package/dist/val/AggFuncVal.d.ts +33 -0
- package/dist/val/AggFuncVal.js +202 -0
- package/dist/val/AggFuncVal.js.map +1 -0
- package/dist/val/ArithFuncVal.d.ts +31 -0
- package/dist/val/ArithFuncVal.js +62 -0
- package/dist/val/ArithFuncVal.js.map +1 -0
- package/dist/val/BagVal.d.ts +5 -0
- package/dist/val/BagVal.js +96 -5
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +9 -1
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/ConjunctVal.d.ts +1 -1
- package/dist/val/ConjunctVal.js +19 -0
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.d.ts +7 -1
- package/dist/val/ConstraintVal.js +490 -40
- package/dist/val/ConstraintVal.js.map +1 -1
- package/dist/val/CopyFuncVal.d.ts +1 -2
- package/dist/val/CopyFuncVal.js +7 -0
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.d.ts +1 -0
- package/dist/val/Decimal.js +13 -0
- package/dist/val/Decimal.js.map +1 -1
- package/dist/val/DeprecateFuncVal.d.ts +11 -0
- package/dist/val/DeprecateFuncVal.js +47 -0
- package/dist/val/DeprecateFuncVal.js.map +1 -0
- package/dist/val/DisjunctVal.js +130 -21
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/EachFuncVal.d.ts +15 -0
- package/dist/val/EachFuncVal.js +75 -0
- package/dist/val/EachFuncVal.js.map +1 -0
- package/dist/val/ExpectVal.js +27 -4
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FeatureVal.js +1 -1
- package/dist/val/FeatureVal.js.map +1 -1
- package/dist/val/FilterFuncVal.d.ts +15 -0
- package/dist/val/FilterFuncVal.js +91 -0
- package/dist/val/FilterFuncVal.js.map +1 -0
- package/dist/val/FuncBaseVal.d.ts +6 -1
- package/dist/val/FuncBaseVal.js +171 -1
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/HideFuncVal.js.map +1 -1
- package/dist/val/IdFuncVal.d.ts +13 -0
- package/dist/val/IdFuncVal.js +54 -0
- package/dist/val/IdFuncVal.js.map +1 -0
- package/dist/val/JunctionVal.js +7 -1
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.d.ts +1 -1
- package/dist/val/KeyFuncVal.js +38 -30
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +101 -14
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.js +93 -8
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MatchFuncVal.d.ts +15 -0
- package/dist/val/MatchFuncVal.js +107 -0
- package/dist/val/MatchFuncVal.js.map +1 -0
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.js +24 -0
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/OpBaseVal.d.ts +1 -1
- package/dist/val/OpBaseVal.js +19 -1
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/OpenFuncVal.js +4 -1
- package/dist/val/OpenFuncVal.js.map +1 -1
- package/dist/val/PackFuncVal.d.ts +15 -0
- package/dist/val/PackFuncVal.js +108 -0
- package/dist/val/PackFuncVal.js.map +1 -0
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PlaceVal.d.ts +13 -0
- package/dist/val/PlaceVal.js +131 -0
- package/dist/val/PlaceVal.js.map +1 -0
- package/dist/val/PlusOpVal.js +11 -2
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.d.ts +2 -2
- package/dist/val/PrefVal.js +78 -23
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RefVal.d.ts +1 -1
- package/dist/val/RefVal.js +89 -7
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.d.ts +36 -0
- package/dist/val/ReferFuncVal.js +303 -0
- package/dist/val/ReferFuncVal.js.map +1 -0
- package/dist/val/ScalarKindVal.d.ts +1 -2
- package/dist/val/ScalarKindVal.js +0 -11
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/TopVal.js.map +1 -1
- package/dist/val/TypeFuncVal.js.map +1 -1
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +8 -1
- package/dist/val/Val.js +150 -1
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/arith.d.ts +6 -0
- package/dist/val/arith.js +170 -0
- package/dist/val/arith.js.map +1 -0
- package/dist/vet.d.ts +45 -0
- package/dist/vet.js +776 -0
- package/dist/vet.js.map +1 -0
- package/dist/walk.d.ts +2 -0
- package/dist/walk.js +91 -0
- package/dist/walk.js.map +1 -0
- package/grammar/aontu.gbnf +130 -0
- package/grammar/aontu.lark +113 -0
- package/package.json +21 -6
- package/skill/SKILL.md +37 -0
- package/skill/error-codes.md +62 -0
- package/skill/examples.md +99 -0
- package/skill/grammar-card.md +57 -0
- package/src/agentsmd.ts +135 -0
- package/src/aontu.ts +135 -4
- package/src/cli.ts +2858 -71
- package/src/ctx.ts +73 -1
- package/src/diff.ts +196 -0
- package/src/err.ts +42 -7
- package/src/graph.ts +135 -0
- package/src/hcanon.ts +169 -0
- package/src/hints.ts +208 -4
- package/src/jsonschema.ts +511 -0
- package/src/lang.ts +570 -70
- package/src/lsp.ts +281 -48
- package/src/mcp-server.ts +187 -0
- package/src/mcp.ts +993 -0
- package/src/mod-tool.ts +679 -0
- package/src/mod.ts +344 -0
- package/src/patch.ts +624 -0
- package/src/provenance.ts +430 -0
- package/src/query.ts +379 -0
- package/src/reach.ts +184 -0
- package/src/relation.ts +395 -0
- package/src/report-sarif.ts +137 -0
- package/src/site.ts +36 -1
- package/src/std.ts +73 -0
- package/src/subsume.ts +690 -0
- package/src/trim.ts +195 -0
- package/src/tsconfig.json +10 -4
- package/src/type.ts +51 -2
- package/src/unify.ts +274 -36
- package/src/utility.ts +139 -1
- package/src/val/AggFuncVal.ts +319 -0
- package/src/val/ArithFuncVal.ts +108 -0
- package/src/val/BagVal.ts +101 -4
- package/src/val/CloseFuncVal.ts +9 -1
- package/src/val/ConjunctVal.ts +20 -0
- package/src/val/ConstraintVal.ts +542 -43
- package/src/val/CopyFuncVal.ts +7 -1
- package/src/val/Decimal.ts +15 -0
- package/src/val/DeprecateFuncVal.ts +84 -0
- package/src/val/DisjunctVal.ts +139 -28
- package/src/val/EachFuncVal.ts +133 -0
- package/src/val/ExpectVal.ts +28 -6
- package/src/val/FeatureVal.ts +1 -1
- package/src/val/FilterFuncVal.ts +154 -0
- package/src/val/FuncBaseVal.ts +192 -1
- package/src/val/HideFuncVal.ts +0 -2
- package/src/val/IdFuncVal.ts +91 -0
- package/src/val/JunctionVal.ts +7 -1
- package/src/val/KeyFuncVal.ts +39 -35
- package/src/val/ListVal.ts +108 -15
- package/src/val/LowerFuncVal.ts +0 -1
- package/src/val/MapVal.ts +99 -8
- package/src/val/MatchFuncVal.ts +176 -0
- package/src/val/MoveFuncVal.ts +0 -2
- package/src/val/NilVal.ts +25 -0
- package/src/val/OpBaseVal.ts +20 -1
- package/src/val/OpenFuncVal.ts +4 -2
- package/src/val/PackFuncVal.ts +175 -0
- package/src/val/PathFuncVal.ts +0 -1
- package/src/val/PlaceVal.ts +193 -0
- package/src/val/PlusOpVal.ts +11 -2
- package/src/val/PrefFuncVal.ts +0 -1
- package/src/val/PrefVal.ts +79 -36
- package/src/val/RefVal.ts +91 -8
- package/src/val/ReferFuncVal.ts +387 -0
- package/src/val/ScalarKindVal.ts +0 -13
- package/src/val/TopVal.ts +0 -1
- package/src/val/TypeFuncVal.ts +0 -2
- package/src/val/UpperFuncVal.ts +0 -1
- package/src/val/Val.ts +205 -2
- package/src/val/VarVal.ts +0 -1
- package/src/val/arith.ts +316 -0
- package/src/vet.ts +992 -0
- package/src/walk.ts +99 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
// GENERATION: `filter(data, cond)` (G8 phase 2,
|
|
4
|
+
// docs/capability-review/g8-generation.md). The children of `data`
|
|
5
|
+
// that unify with `cond`, keys preserved for a map and order for a
|
|
6
|
+
// list; the children that do not are DROPPED, not refused.
|
|
7
|
+
//
|
|
8
|
+
// debugged: filter($.services, {debug: true})
|
|
9
|
+
// sidecars: pack($.debugged, {image: "acme/debug:1.0"})
|
|
10
|
+
//
|
|
11
|
+
// A CHILD IS KEPT WHEN THE CONDITION CHANGES NOTHING: the meet
|
|
12
|
+
// succeeds AND its answer is the child itself, which is to say the
|
|
13
|
+
// child ALREADY satisfies the condition. Mere unifiability is not the
|
|
14
|
+
// test, and cannot be: a map is open, so `{p:2}` unifies with
|
|
15
|
+
// `{debug:true}` perfectly well by GAINING the key -- and a filter
|
|
16
|
+
// that keeps everything that could be made to match keeps everything.
|
|
17
|
+
// The design named unifiability; its own example
|
|
18
|
+
// (`filter($.services, {debug:true})`) is unsatisfiable under it.
|
|
19
|
+
//
|
|
20
|
+
// There is no predicate language here and there will not be one:
|
|
21
|
+
// `cond` is an ordinary Aontu value, so the constraint atoms compose
|
|
22
|
+
// with it for free (`filter($.deploy, {replicas: min(3)})`), and a
|
|
23
|
+
// document that can filter can be read by anything that can read a
|
|
24
|
+
// document.
|
|
25
|
+
//
|
|
26
|
+
// A FAILED CHILD IS AN ANSWER, not an error. The meet runs in TRIAL
|
|
27
|
+
// MODE -- the mechanism disjunction already uses to try each member
|
|
28
|
+
// against a peer (trialUnify in FuncBaseVal) -- so a child that does
|
|
29
|
+
// not match costs nothing and reports nothing.
|
|
30
|
+
//
|
|
31
|
+
// TOTALITY. `filter` iterates a finite, settled bag and cannot call
|
|
32
|
+
// itself, exactly as `pack` and `each` cannot.
|
|
33
|
+
|
|
34
|
+
import type {
|
|
35
|
+
Val,
|
|
36
|
+
ValSpec,
|
|
37
|
+
} from '../type'
|
|
38
|
+
|
|
39
|
+
import {
|
|
40
|
+
AontuContext,
|
|
41
|
+
} from '../ctx'
|
|
42
|
+
|
|
43
|
+
import { makeNilErr } from '../err'
|
|
44
|
+
import { MapVal } from './MapVal'
|
|
45
|
+
import { ListVal } from './ListVal'
|
|
46
|
+
import { FuncBaseVal, trialUnify } from './FuncBaseVal'
|
|
47
|
+
import { repathInstance } from './Val'
|
|
48
|
+
import { fillPlace } from './PlaceVal'
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class FilterFuncVal extends FuncBaseVal {
|
|
52
|
+
isFilterFunc = true
|
|
53
|
+
|
|
54
|
+
// THE STAGING RULE (G8 phase 0). A subset of a bag that is still
|
|
55
|
+
// being merged into is a subset of the wrong bag.
|
|
56
|
+
staged = true
|
|
57
|
+
|
|
58
|
+
constructor(
|
|
59
|
+
spec: ValSpec,
|
|
60
|
+
ctx?: AontuContext
|
|
61
|
+
) {
|
|
62
|
+
super(spec, ctx)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
funcname() {
|
|
67
|
+
return 'filter'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
// Neither argument is driven by the base: `unify` below drives the
|
|
72
|
+
// DATA by hand, because a staged func must advance the argument it
|
|
73
|
+
// is waiting on every pass rather than only on the one it fires.
|
|
74
|
+
//
|
|
75
|
+
// The CONDITION is not driven at all, and that is deliberate: it is
|
|
76
|
+
// a template, tested against each child at that child's position,
|
|
77
|
+
// so it may hold a `_` (G8 phase 3, the child it is being tested
|
|
78
|
+
// against) or a relative reference — neither of which has an answer
|
|
79
|
+
// at the call site. Driving it there would freeze both.
|
|
80
|
+
prepare(_ctx: AontuContext, _args: Val[]) {
|
|
81
|
+
return null
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
unify(peer: Val, ctx: AontuContext): Val {
|
|
86
|
+
const ready = this.driveStagedArgs(ctx, 1)
|
|
87
|
+
|
|
88
|
+
if (!ready || !ctx.settle) {
|
|
89
|
+
return this.residuate(peer, ctx)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return super.unify(peer, ctx)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
resolve(ctx: AontuContext, args: Val[]) {
|
|
97
|
+
const data: any = args[0]
|
|
98
|
+
const cond: Val = args[1]
|
|
99
|
+
|
|
100
|
+
// The trial is run against CLONES: `unite` refines a bag in place,
|
|
101
|
+
// and a child that failed the test must reach the result -- when
|
|
102
|
+
// it passes -- exactly as it was written.
|
|
103
|
+
//
|
|
104
|
+
// Canon is the comparison because canon is what "the same value"
|
|
105
|
+
// MEANS in this language: it is the form the two ports agree on,
|
|
106
|
+
// the form `aontu diff` compares, and the form a hash is taken of.
|
|
107
|
+
const keeps = (child: Val, kctx: AontuContext): boolean => {
|
|
108
|
+
// `_` inside the condition binds the child being tested (G8
|
|
109
|
+
// phase 3), so a condition can be about the child as a whole
|
|
110
|
+
// rather than only about its shape. The condition is cloned as
|
|
111
|
+
// a FULL instance per trial (`dup`, ADR-005) — a bare clone
|
|
112
|
+
// shares call/pref innards across trials (see PackFuncVal).
|
|
113
|
+
const inst = cond.clone(kctx, { dup: true })
|
|
114
|
+
repathInstance(inst, inst.path)
|
|
115
|
+
const test = fillPlace(inst, child, kctx)
|
|
116
|
+
const met = trialUnify(kctx, child.clone(kctx), test)
|
|
117
|
+
return undefined !== met && met.canon === child.canon
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (true === data?.isMap) {
|
|
121
|
+
const peg: Record<string, Val> = {}
|
|
122
|
+
for (const key of Object.keys(data.peg)) {
|
|
123
|
+
const kctx = ctx.descend(key)
|
|
124
|
+
if (keeps(data.peg[key], kctx)) {
|
|
125
|
+
peg[key] = data.peg[key].clone(kctx)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return new MapVal({ peg }, ctx)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (true === data?.isList) {
|
|
132
|
+
const peg: Val[] = []
|
|
133
|
+
for (const el of data.peg as Val[]) {
|
|
134
|
+
// The element context is the position it will END UP at, which
|
|
135
|
+
// is its index in the RESULT: dropping the third of five moves
|
|
136
|
+
// the fourth up, and a kept element must be pathed where it
|
|
137
|
+
// lands rather than where it came from.
|
|
138
|
+
const ectx = ctx.descend(String(peg.length))
|
|
139
|
+
if (keeps(el, ectx)) {
|
|
140
|
+
peg.push(el.clone(ectx))
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return new ListVal({ peg }, ctx)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return makeNilErr(ctx, 'filter_data', this)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
} /* node:coverage ignore next 5 */
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
export {
|
|
153
|
+
FilterFuncVal,
|
|
154
|
+
}
|
package/src/val/FuncBaseVal.ts
CHANGED
|
@@ -29,12 +29,53 @@ import {
|
|
|
29
29
|
|
|
30
30
|
import { ConjunctVal } from '../val/ConjunctVal'
|
|
31
31
|
import { FeatureVal } from '../val/FeatureVal'
|
|
32
|
+
import { hasPlace, fillPlace } from '../val/PlaceVal'
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// A TRIAL meet: does `a` unify with `b`, and if so as what? Failure is
|
|
36
|
+
// an ANSWER here rather than an error, which is exactly what
|
|
37
|
+
// DisjunctVal already needs when it tries each member against a peer —
|
|
38
|
+
// so this is that mechanism (`ctx._trialMode`, which makes makeNilErr
|
|
39
|
+
// return the shared TRIAL_NIL instead of allocating and recording),
|
|
40
|
+
// lent to the combinators that select by unifiability.
|
|
41
|
+
//
|
|
42
|
+
// The error list and the trial flag are saved and restored in a
|
|
43
|
+
// `finally`: a trial that throws must not leave the surrounding
|
|
44
|
+
// evaluation collapsing every later error into the sentinel.
|
|
45
|
+
function trialUnify(ctx: AontuContext, a: Val, b: Val): Val | undefined {
|
|
46
|
+
const savedErr = ctx.err
|
|
47
|
+
const savedTrial = ctx._trialMode
|
|
48
|
+
const trialErr: any[] = []
|
|
49
|
+
|
|
50
|
+
ctx.err = trialErr
|
|
51
|
+
ctx._trialMode = true
|
|
52
|
+
|
|
53
|
+
let out: Val
|
|
54
|
+
try {
|
|
55
|
+
out = unite(ctx, a, b, 'trial')
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
ctx.err = savedErr
|
|
59
|
+
ctx._trialMode = savedTrial
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return 0 < trialErr.length || out.isNil ? undefined : out
|
|
63
|
+
}
|
|
32
64
|
|
|
33
65
|
|
|
34
66
|
class FuncBaseVal extends FeatureVal {
|
|
35
67
|
isFunc = true
|
|
36
68
|
isGenable = true
|
|
37
69
|
|
|
70
|
+
// THE STAGING RULE (G8 phase 0, see AontuContext.settle). A func
|
|
71
|
+
// whose answer depends on WHERE IT IS -- `key()`, whose answer is a
|
|
72
|
+
// segment of its own path, and the generation combinators, whose
|
|
73
|
+
// data argument can still be merged into by a sibling -- sets this
|
|
74
|
+
// and residuates until the model stops moving. Everything else
|
|
75
|
+
// resolves as soon as its arguments are done, which is the rule that
|
|
76
|
+
// has always been here.
|
|
77
|
+
staged = false
|
|
78
|
+
|
|
38
79
|
constructor(
|
|
39
80
|
spec: ValSpec,
|
|
40
81
|
ctx?: AontuContext
|
|
@@ -58,7 +99,118 @@ class FuncBaseVal extends FeatureVal {
|
|
|
58
99
|
}
|
|
59
100
|
|
|
60
101
|
|
|
102
|
+
// Drive the first `count` arguments IN PLACE, every pass — not only
|
|
103
|
+
// on the settle pass. A staged func waits for the model to settle,
|
|
104
|
+
// and its own arguments are part of that model: leaving them
|
|
105
|
+
// standing until settle would guarantee the model was still moving
|
|
106
|
+
// when settle arrived. Answers whether they are all done, which is
|
|
107
|
+
// the other half of "ready to fire".
|
|
108
|
+
driveStagedArgs(ctx: AontuContext, count: number): boolean {
|
|
109
|
+
const TOP = top()
|
|
110
|
+
let alldone = true
|
|
111
|
+
|
|
112
|
+
// THE SNAPSHOT WAITS FOR THE SOURCE (the spread-then-pack defect,
|
|
113
|
+
// use-cases/BUGS.md pack-refs family). A reference resolving inside
|
|
114
|
+
// a staged argument is this argument's SNAPSHOT of its source, and
|
|
115
|
+
// the snapshot is not part of the tree: a spread-injected relative
|
|
116
|
+
// reference inside a too-early copy dangles at the argument's
|
|
117
|
+
// location (`.containerPort` rebased under the generator, where no
|
|
118
|
+
// root traversal reaches it) and the generator never fires. The
|
|
119
|
+
// `argsnap` flag makes RefVal.find defer until the target has
|
|
120
|
+
// finished resolving IN THE TREE — where its own spreads and
|
|
121
|
+
// relative references answer at their real location — and only then
|
|
122
|
+
// take the copy. Inherited by every descended ctx, so a reference
|
|
123
|
+
// anywhere in the argument subtree waits the same way.
|
|
124
|
+
const actx: AontuContext = ctx.clone({})
|
|
125
|
+
; (actx as any).argsnap = true
|
|
126
|
+
|
|
127
|
+
for (let i = 0; i < count && i < this.peg.length; i++) {
|
|
128
|
+
const arg: Val = this.peg[i]
|
|
129
|
+
if (!arg.done) {
|
|
130
|
+
// Charged to the depth budget, as FuncBaseVal's own arg loop is:
|
|
131
|
+
// this recurses without going through `unite`.
|
|
132
|
+
this.peg[i] = withDepth(ctx, arg, TOP, () => arg.unify(TOP, actx))
|
|
133
|
+
}
|
|
134
|
+
alldone = alldone && true === this.peg[i].done
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return alldone
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
// THE PER-DESTINATION INSTANTIATION RULE (ADR-005). The default
|
|
142
|
+
// clone shares the argument array AND the argument Vals — pinned
|
|
143
|
+
// sharing for the move()/copy() ghost artifacts (test/spec/func.tsv,
|
|
144
|
+
// ghost-*-innard-canon) — but a clone that is a template INSTANCE
|
|
145
|
+
// must own the full inner structure: with the args shared,
|
|
146
|
+
// `pack($.names, close({name: key()}))` resolved key() once inside
|
|
147
|
+
// the one shared inner map and stamped the FIRST child's key on
|
|
148
|
+
// every child (use-cases/BUGS.md §8). The `dup` spec flag asks for
|
|
149
|
+
// that depth; everything else keeps the sharing it has always had.
|
|
150
|
+
clone(ctx: AontuContext, spec?: ValSpec): Val {
|
|
151
|
+
const out = super.clone(ctx, spec) as FuncBaseVal
|
|
152
|
+
if (true === spec?.dup && Array.isArray(this.peg)) {
|
|
153
|
+
// Every argument is a Val by construction (the parser builds
|
|
154
|
+
// them; make() rebuilds from driven Vals), as the Go twin's
|
|
155
|
+
// []Val typing states outright. The instantiation sites then
|
|
156
|
+
// normalise every path in the clone (repathInstance), so the
|
|
157
|
+
// argument-shaped parse paths never leak into an instance.
|
|
158
|
+
out.peg = this.peg.map((a: Val) => a.clone(ctx, { dup: true }))
|
|
159
|
+
}
|
|
160
|
+
return out
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
// The shape a staged func holds while it waits: not done, so the pass
|
|
165
|
+
// loop keeps going; unchanged against TOP, so nothing reads an answer
|
|
166
|
+
// it has not given; and collapsed against an identical twin at the
|
|
167
|
+
// same position, so `key() & key()` does not grow a conjunct per pass.
|
|
168
|
+
residuate(peer: Val, ctx: AontuContext): Val {
|
|
169
|
+
this.notdone()
|
|
170
|
+
|
|
171
|
+
if (peer.isTop || (peer.id === this.id)) {
|
|
172
|
+
// Cloned rather than returned: a driver that met the same object
|
|
173
|
+
// twice in one pass would charge the revisit budget and report
|
|
174
|
+
// `unify_cycle`.
|
|
175
|
+
return this.clone(ctx)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (peer.isNil) {
|
|
179
|
+
return peer
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (peer.isFunc
|
|
183
|
+
&& (peer as any).funcname() === this.funcname()
|
|
184
|
+
&& peer.path.join('.') === this.path.join('.')
|
|
185
|
+
&& peer.canon === this.canon) {
|
|
186
|
+
return this
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return new ConjunctVal({ peg: [this, peer] }, ctx)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
61
193
|
unify(peer: Val, ctx: AontuContext): Val {
|
|
194
|
+
if (this.staged && !ctx.settle) {
|
|
195
|
+
return this.residuate(peer, ctx)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// THE PLACEHOLDER (G8 phase 3, see PlaceVal). A call holding a hole
|
|
199
|
+
// waits for a peer, and the peer is what fills it: the call is
|
|
200
|
+
// rebuilt with the hole replaced and resolved on the spot, so
|
|
201
|
+
// `upper(_) & hello` is `"HELLO"` and not `"HELLO" & "hello"` --
|
|
202
|
+
// the peer went INTO the call, it is not also a constraint on the
|
|
203
|
+
// way out.
|
|
204
|
+
if (!peer.isTop && !peer.isNil && this.id !== peer.id && hasPlace(this)) {
|
|
205
|
+
// TWO HOLES AND NOTHING TO FILL THEM. `upper(_) & lower(_)` has
|
|
206
|
+
// no value on either side, and picking one call to be the other's
|
|
207
|
+
// filling would be inventing an order the language does not have.
|
|
208
|
+
if (hasPlace(peer)) {
|
|
209
|
+
return makeNilErr(ctx, 'place_pair', this, peer)
|
|
210
|
+
}
|
|
211
|
+
return fillPlace(this, peer, ctx).unify(top(), ctx)
|
|
212
|
+
}
|
|
213
|
+
|
|
62
214
|
const TOP = top()
|
|
63
215
|
const te = ctx.explain && explainOpen(ctx, ctx.explain, 'Func:' + this.funcname(), this, peer)
|
|
64
216
|
|
|
@@ -123,7 +275,12 @@ class FuncBaseVal extends FeatureVal {
|
|
|
123
275
|
const resolved = this.resolve(ctx, newpeg)
|
|
124
276
|
// console.log('FUNC-RESOLVED', ctx.cc, resolved?.canon)
|
|
125
277
|
|
|
126
|
-
|
|
278
|
+
// The TOP peer is DROPPED as the unit it is — unless it
|
|
279
|
+
// carries an identity (G4 phase 1), which is content rather
|
|
280
|
+
// than the unit: `id(x) & id(y)` resolves both sides to a
|
|
281
|
+
// top, and taking this shortcut would silently keep one
|
|
282
|
+
// name and lose the other instead of refusing the pair.
|
|
283
|
+
out = resolved.done && peer.isTop && null == peer.entity ? resolved :
|
|
127
284
|
unite(te ? ctx.clone({ explain: ec(te, 'PEG') }) : ctx,
|
|
128
285
|
resolved, peer, 'func-' + this.funcname() + '/' + this.id)
|
|
129
286
|
propagateMarks(this, out)
|
|
@@ -132,6 +289,17 @@ class FuncBaseVal extends FeatureVal {
|
|
|
132
289
|
out.site.row = this.site.row
|
|
133
290
|
out.site.col = this.site.col
|
|
134
291
|
out.site.url = this.site.url
|
|
292
|
+
// THE SPAN COMES WITH THE POSITION, always. Moving row and
|
|
293
|
+
// col onto the result while leaving its own text behind
|
|
294
|
+
// produced a site that contradicted itself: `close({...})`
|
|
295
|
+
// reported the call's column and the map's `{`, so reading
|
|
296
|
+
// the document at (row, col, len) found `c` where `src` said
|
|
297
|
+
// `{`. A consumer following the verification contract would
|
|
298
|
+
// refuse every such repair; one skipping it would edit the
|
|
299
|
+
// wrong token. Whatever the position names, the text names
|
|
300
|
+
// too. Twin: the same assignment in go/func.go.
|
|
301
|
+
out.site.len = this.site.len
|
|
302
|
+
out.site.src = this.site.src
|
|
135
303
|
out.path = this.path
|
|
136
304
|
|
|
137
305
|
why += 'pegdone'
|
|
@@ -144,6 +312,17 @@ class FuncBaseVal extends FeatureVal {
|
|
|
144
312
|
out.site.row = this.site.row
|
|
145
313
|
out.site.col = this.site.col
|
|
146
314
|
out.site.url = this.site.url
|
|
315
|
+
// THE SPAN COMES WITH THE POSITION, always. Moving row and
|
|
316
|
+
// col onto the result while leaving its own text behind
|
|
317
|
+
// produced a site that contradicted itself: `close({...})`
|
|
318
|
+
// reported the call's column and the map's `{`, so reading
|
|
319
|
+
// the document at (row, col, len) found `c` where `src` said
|
|
320
|
+
// `{`. A consumer following the verification contract would
|
|
321
|
+
// refuse every such repair; one skipping it would edit the
|
|
322
|
+
// wrong token. Whatever the position names, the text names
|
|
323
|
+
// too. Twin: the same assignment in go/func.go.
|
|
324
|
+
out.site.len = this.site.len
|
|
325
|
+
out.site.src = this.site.src
|
|
147
326
|
out.path = this.path
|
|
148
327
|
|
|
149
328
|
why += 'top'
|
|
@@ -163,6 +342,17 @@ class FuncBaseVal extends FeatureVal {
|
|
|
163
342
|
out.site.row = this.site.row
|
|
164
343
|
out.site.col = this.site.col
|
|
165
344
|
out.site.url = this.site.url
|
|
345
|
+
// THE SPAN COMES WITH THE POSITION, always. Moving row and
|
|
346
|
+
// col onto the result while leaving its own text behind
|
|
347
|
+
// produced a site that contradicted itself: `close({...})`
|
|
348
|
+
// reported the call's column and the map's `{`, so reading
|
|
349
|
+
// the document at (row, col, len) found `c` where `src` said
|
|
350
|
+
// `{`. A consumer following the verification contract would
|
|
351
|
+
// refuse every such repair; one skipping it would edit the
|
|
352
|
+
// wrong token. Whatever the position names, the text names
|
|
353
|
+
// too. Twin: the same assignment in go/func.go.
|
|
354
|
+
out.site.len = this.site.len
|
|
355
|
+
out.site.src = this.site.src
|
|
166
356
|
out.path = this.path
|
|
167
357
|
|
|
168
358
|
why += 'defer'
|
|
@@ -207,5 +397,6 @@ class FuncBaseVal extends FeatureVal {
|
|
|
207
397
|
|
|
208
398
|
|
|
209
399
|
export {
|
|
400
|
+
trialUnify,
|
|
210
401
|
FuncBaseVal,
|
|
211
402
|
}
|
package/src/val/HideFuncVal.ts
CHANGED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
// THE IDENTITY MARK (G4 phase 1,
|
|
4
|
+
// docs/capability-review/g4-identity-relations.md): `id(name)`
|
|
5
|
+
// declares that the enclosing value is an independent ENTITY named
|
|
6
|
+
// `name`, and every node in one evaluation carrying that name is
|
|
7
|
+
// unified with every other.
|
|
8
|
+
//
|
|
9
|
+
// It is written as a conjunct — `id(svc/auth) & { … }` — so the
|
|
10
|
+
// function itself resolves to the UNIT (top) carrying the name, and
|
|
11
|
+
// the identity rides the meet onto the value, the same channel G3's
|
|
12
|
+
// deprecation record uses. Declaring two nodes the same entity MEANS
|
|
13
|
+
// unifying them, so a contradiction between them is a located error
|
|
14
|
+
// naming both sites: the anti-`owl:sameAs`.
|
|
15
|
+
|
|
16
|
+
import type {
|
|
17
|
+
Val,
|
|
18
|
+
ValSpec,
|
|
19
|
+
} from '../type'
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
AontuContext,
|
|
23
|
+
} from '../ctx'
|
|
24
|
+
|
|
25
|
+
import { makeNilErr } from '../err'
|
|
26
|
+
|
|
27
|
+
import { FuncBaseVal } from './FuncBaseVal'
|
|
28
|
+
import { TopVal } from './TopVal'
|
|
29
|
+
import { nextValId } from './Val'
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
// Letters, digits, `_`, `-`, `/` — and NO DOTS: a dot separates an
|
|
33
|
+
// entity address from a sub-path (G4 phase 2), so a dotted id would
|
|
34
|
+
// make `svc/auth.port` ambiguous between "the entity `svc/auth.port`"
|
|
35
|
+
// and "the port of `svc/auth`".
|
|
36
|
+
const ID_NAME = /^[A-Za-z0-9_/-]+$/
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
// The name an argument spells, or undefined when it does not spell
|
|
40
|
+
// one. A bare `svc/auth` parses as a string, as does `"svc/auth"`;
|
|
41
|
+
// anything else — a number, a map, an unresolved reference — is not a
|
|
42
|
+
// name, and saying so at once beats an entity nobody can address.
|
|
43
|
+
export function idName(v: any): string | undefined {
|
|
44
|
+
if (true !== v?.isScalar || 'string' !== typeof v.peg) {
|
|
45
|
+
return undefined
|
|
46
|
+
}
|
|
47
|
+
return ID_NAME.test(v.peg) ? v.peg : undefined
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class IdFuncVal extends FuncBaseVal {
|
|
52
|
+
isIdFunc = true
|
|
53
|
+
|
|
54
|
+
constructor(
|
|
55
|
+
spec: ValSpec,
|
|
56
|
+
ctx?: AontuContext
|
|
57
|
+
) {
|
|
58
|
+
super(spec, ctx)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
make(_ctx: AontuContext, spec: ValSpec): Val {
|
|
62
|
+
return new IdFuncVal(spec)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
funcname() {
|
|
66
|
+
return 'id'
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
resolve(ctx: AontuContext, args: Val[]) {
|
|
70
|
+
const name = idName(args[0])
|
|
71
|
+
if (undefined === name) {
|
|
72
|
+
return makeNilErr(ctx, 'id_name', this, undefined, 'id')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// THE UNIT, carrying the identity: `id(x) & v` must be `v` with an
|
|
76
|
+
// identity, so the function resolves to what unifies with anything
|
|
77
|
+
// and lets the rider in `unite` do the stamping.
|
|
78
|
+
const out = new TopVal({}, ctx)
|
|
79
|
+
// NOT id 0: TopVal pins that, and `unite`'s fast path returns
|
|
80
|
+
// early for two done Vals sharing an id — which would drop one of
|
|
81
|
+
// two identities before the rider could refuse them.
|
|
82
|
+
out.id = nextValId()
|
|
83
|
+
out.entity = name
|
|
84
|
+
return out
|
|
85
|
+
}
|
|
86
|
+
} /* node:coverage ignore next 6 */
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
IdFuncVal,
|
|
91
|
+
}
|
package/src/val/JunctionVal.ts
CHANGED
|
@@ -33,7 +33,13 @@ abstract class JunctionVal extends FeatureVal {
|
|
|
33
33
|
|
|
34
34
|
clone(ctx: AontuContext, spec?: ValSpec): Val {
|
|
35
35
|
let out = (super.clone(ctx, spec) as JunctionVal)
|
|
36
|
-
|
|
36
|
+
// The instantiation flag descends with the mark (ADR-005): a
|
|
37
|
+
// junction inside a template clones its members as instances (the
|
|
38
|
+
// instantiation sites re-path the whole clone afterwards — see
|
|
39
|
+
// repathInstance in Val.ts).
|
|
40
|
+
const childspec = spec?.mark || spec?.dup ?
|
|
41
|
+
{ mark: spec?.mark, dup: spec?.dup } : {}
|
|
42
|
+
out.peg = this.peg.map((entry: Val) => entry.clone(ctx, childspec))
|
|
37
43
|
return out
|
|
38
44
|
}
|
|
39
45
|
|
package/src/val/KeyFuncVal.ts
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
} from '../ctx'
|
|
13
13
|
|
|
14
14
|
import { StringVal } from '../val/StringVal'
|
|
15
|
-
import { ConjunctVal } from '../val/ConjunctVal'
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
|
|
@@ -41,39 +40,13 @@ class KeyFuncVal extends FuncBaseVal {
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (peer.isTop || (peer.id === this.id)) {
|
|
52
|
-
// TODO: clone needed to avoid triggering unify_cycle - find a better way
|
|
53
|
-
out = this.clone(ctx)
|
|
54
|
-
}
|
|
55
|
-
else if (peer.isNil) {
|
|
56
|
-
out = peer
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
if (
|
|
60
|
-
peer.isKeyFunc
|
|
61
|
-
&& peer.path.join('.') === this.path.join('.')
|
|
62
|
-
&& peer.peg?.[0]?.peg === this.peg?.[0]?.peg
|
|
63
|
-
) {
|
|
64
|
-
out = this
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
out = new ConjunctVal({ peg: [this, peer] }, ctx)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
out = super.unify(peer, ctx)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return out
|
|
76
|
-
}
|
|
43
|
+
// `key()` is the first value to take THE STAGING RULE (G8 phase 0,
|
|
44
|
+
// see AontuContext.settle): its answer is a segment of its own path,
|
|
45
|
+
// so it must not answer while a spread, a reference or a `move` can
|
|
46
|
+
// still move it. It residuates until the model stops changing, and
|
|
47
|
+
// fires on the settle pass. The residuation itself is FuncBaseVal's,
|
|
48
|
+
// shared with the generation combinators.
|
|
49
|
+
staged = true
|
|
77
50
|
|
|
78
51
|
|
|
79
52
|
resolve(ctx: AontuContext, _args: Val[]) {
|
|
@@ -113,7 +86,38 @@ class KeyFuncVal extends FuncBaseVal {
|
|
|
113
86
|
}
|
|
114
87
|
}
|
|
115
88
|
|
|
116
|
-
|
|
89
|
+
// THE PATH IS THE ONE IT IS BEING DRIVEN AT, not the one it
|
|
90
|
+
// remembers. `this.path` is a cache that the residuation clone
|
|
91
|
+
// refreshes each pass, and it is right for a key() the bag walk
|
|
92
|
+
// reaches directly -- but a key() nested inside a function or
|
|
93
|
+
// operator ARGUMENT is never reached that way: it is driven by its
|
|
94
|
+
// enclosing call, which re-paths nothing, so it kept the position
|
|
95
|
+
// the SOURCE TEXT put it at. Inside a template that is fatal: the
|
|
96
|
+
// source position of `&: {k: "x" + key()}` (or of `pack`'s
|
|
97
|
+
// template) is the template, not any of the destinations, and the
|
|
98
|
+
// parse-time path of a function argument is not a document
|
|
99
|
+
// position at all.
|
|
100
|
+
// A stored path is only usable if it IS one: a path segment that is
|
|
101
|
+
// not a key is not a position, and the parse-time path of a value
|
|
102
|
+
// written inside a function ARGUMENT carries exactly that -- the
|
|
103
|
+
// argument has no key, so its segment is not a string. Those values
|
|
104
|
+
// are also the ones the bag walk never re-paths (a call re-paths
|
|
105
|
+
// nothing it holds), which is why the stored path stays wrong
|
|
106
|
+
// forever rather than being refreshed on the next pass. For them
|
|
107
|
+
// the driving context is the only truth. For everything else the
|
|
108
|
+
// stored path stays authoritative, because a TRANSPLANTED value
|
|
109
|
+
// (move(), a shared clone) must answer for where it was put, not
|
|
110
|
+
// for whichever driver happened to reach it first.
|
|
111
|
+
let positioned = true
|
|
112
|
+
for (const seg of this.path) {
|
|
113
|
+
if ('string' !== typeof seg) {
|
|
114
|
+
positioned = false
|
|
115
|
+
break
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const here = positioned ? this.path : ctx.path
|
|
120
|
+
const key = here[here.length - (1 + move)] ?? ''
|
|
117
121
|
// console.log('KEY', this.path, move, key)
|
|
118
122
|
|
|
119
123
|
out = new StringVal({ peg: key })
|