aontu 0.43.0 → 0.45.1
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/dist/ctx.d.ts +2 -5
- package/dist/ctx.js +1 -2
- package/dist/ctx.js.map +1 -1
- package/dist/lang.d.ts +1 -5
- package/dist/lang.js +24 -100
- package/dist/lang.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type.d.ts +0 -5
- package/dist/type.js.map +1 -1
- package/dist/unify.js +13 -292
- package/dist/unify.js.map +1 -1
- package/dist/utility.js +2 -6
- package/dist/utility.js.map +1 -1
- package/dist/val/BagVal.d.ts +3 -0
- package/dist/val/BagVal.js +6 -6
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/ConjunctVal.d.ts +1 -1
- package/dist/val/ConjunctVal.js +14 -137
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/CopyFuncVal.js +2 -3
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/DisjunctVal.js +0 -4
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/ExpectVal.js +3 -16
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/JunctionVal.d.ts +0 -1
- package/dist/val/JunctionVal.js +1 -6
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.js +2 -0
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.d.ts +0 -1
- package/dist/val/ListVal.js +66 -33
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/MapVal.d.ts +2 -3
- package/dist/val/MapVal.js +95 -67
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MoveFuncVal.d.ts +1 -2
- package/dist/val/MoveFuncVal.js +13 -78
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/PathFuncVal.js +4 -25
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PlusOpVal.d.ts +1 -1
- package/dist/val/PrefVal.js +5 -18
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/{PathVal.d.ts → RefVal.d.ts} +3 -4
- package/dist/val/{PathVal.js → RefVal.js} +77 -75
- package/dist/val/RefVal.js.map +1 -0
- package/dist/val/Val.d.ts +1 -2
- package/dist/val/Val.js +8 -7
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js +2 -2
- package/dist/val/VarVal.js.map +1 -1
- package/package.json +6 -5
- package/src/ctx.ts +3 -16
- package/src/lang.ts +23 -113
- package/src/type.ts +0 -5
- package/src/unify.ts +13 -310
- package/src/utility.ts +2 -5
- package/src/val/BagVal.ts +7 -6
- package/src/val/ConjunctVal.ts +13 -131
- package/src/val/CopyFuncVal.ts +2 -3
- package/src/val/DisjunctVal.ts +0 -6
- package/src/val/ExpectVal.ts +4 -18
- package/src/val/JunctionVal.ts +1 -5
- package/src/val/KeyFuncVal.ts +3 -0
- package/src/val/ListVal.ts +88 -38
- package/src/val/MapVal.ts +124 -75
- package/src/val/MoveFuncVal.ts +14 -79
- package/src/val/PathFuncVal.ts +4 -29
- package/src/val/PrefVal.ts +6 -19
- package/src/val/{RefVal.ts.old → RefVal.ts} +19 -30
- package/src/val/Val.ts +9 -9
- package/src/val/VarVal.ts +2 -2
- package/README.md +0 -18
- package/dist/val/PathVal.js.map +0 -1
- package/dist/val/SpreadVal.d.ts +0 -20
- package/dist/val/SpreadVal.js +0 -194
- package/dist/val/SpreadVal.js.map +0 -1
- package/src/val/PathVal.ts +0 -435
- package/src/val/SpreadVal.ts +0 -275
package/src/val/MapVal.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
DONE,
|
|
11
|
+
SPREAD,
|
|
11
12
|
} from '../type'
|
|
12
13
|
|
|
13
14
|
import { AontuContext } from '../ctx'
|
|
@@ -27,13 +28,13 @@ import {
|
|
|
27
28
|
} from './top'
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
import { ConjunctVal } from './ConjunctVal'
|
|
30
32
|
import { NilVal } from './NilVal'
|
|
31
33
|
import { BagVal } from './BagVal'
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
class MapVal extends BagVal {
|
|
35
37
|
isMap = true
|
|
36
|
-
_canonCache?: string
|
|
37
38
|
|
|
38
39
|
constructor(
|
|
39
40
|
spec: ValSpec,
|
|
@@ -47,6 +48,23 @@ class MapVal extends BagVal {
|
|
|
47
48
|
|
|
48
49
|
this.mark.type = !!spec.mark?.type
|
|
49
50
|
this.mark.hide = !!spec.mark?.hide
|
|
51
|
+
|
|
52
|
+
let spread = (this.peg as any)[SPREAD]
|
|
53
|
+
delete (this.peg as any)[SPREAD]
|
|
54
|
+
|
|
55
|
+
if (spread) {
|
|
56
|
+
if ('&' === spread.o) {
|
|
57
|
+
// TODO: handle existing spread!
|
|
58
|
+
this.spread.cj =
|
|
59
|
+
Array.isArray(spread.v) ?
|
|
60
|
+
1 < spread.v.length ?
|
|
61
|
+
new ConjunctVal({ peg: spread.v }, ctx) :
|
|
62
|
+
spread.v[0] :
|
|
63
|
+
spread.v
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// console.log('MAPVAL-ctor', this.type, spec)
|
|
50
68
|
}
|
|
51
69
|
|
|
52
70
|
|
|
@@ -57,23 +75,6 @@ class MapVal extends BagVal {
|
|
|
57
75
|
|
|
58
76
|
const TOP = top()
|
|
59
77
|
peer = peer ?? TOP
|
|
60
|
-
|
|
61
|
-
// Fast path: both maps done, no spreads, peer's keys are a
|
|
62
|
-
// subset of this's keys with the same child references, and
|
|
63
|
-
// neither side has type/hide marks. No new information.
|
|
64
|
-
if (this.done && peer instanceof MapVal && peer.done
|
|
65
|
-
&& !this.mark.type && !this.mark.hide
|
|
66
|
-
&& !peer.mark.type && !peer.mark.hide) {
|
|
67
|
-
let canSkip = true
|
|
68
|
-
for (const k in peer.peg) {
|
|
69
|
-
if (this.peg[k] !== peer.peg[k]) {
|
|
70
|
-
canSkip = false
|
|
71
|
-
break
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (canSkip) return this
|
|
75
|
-
}
|
|
76
|
-
|
|
77
78
|
const te = ctx.explain && explainOpen(ctx, ctx.explain, 'Map', this, peer)
|
|
78
79
|
|
|
79
80
|
let done: boolean = true
|
|
@@ -83,7 +84,8 @@ class MapVal extends BagVal {
|
|
|
83
84
|
let out: MapVal | NilVal = (peer.isTop ? this : new MapVal({ peg: {} }, ctx))
|
|
84
85
|
|
|
85
86
|
out.closed = this.closed
|
|
86
|
-
out.optionalKeys =
|
|
87
|
+
out.optionalKeys = [...this.optionalKeys]
|
|
88
|
+
out.spread.cj = this.spread.cj
|
|
87
89
|
out.site = this.site
|
|
88
90
|
|
|
89
91
|
if (peer instanceof MapVal) {
|
|
@@ -106,47 +108,53 @@ class MapVal extends BagVal {
|
|
|
106
108
|
out = peer.unify(this, te ? ctx.clone({ explain: ec(te, 'SPC') }) : ctx) as MapVal
|
|
107
109
|
exit = true
|
|
108
110
|
}
|
|
111
|
+
|
|
109
112
|
}
|
|
113
|
+
|
|
114
|
+
if (!exit) {
|
|
115
|
+
out.spread.cj = null == out.spread.cj ? peer.spread.cj : (
|
|
116
|
+
null == peer.spread.cj ? out.spread.cj : (
|
|
117
|
+
out.spread.cj =
|
|
118
|
+
unite(te ? ctx.clone({ explain: ec(te, 'SPR') }) : ctx,
|
|
119
|
+
out.spread.cj, peer.spread.cj, 'map-self')
|
|
120
|
+
)
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// console.log('MAPVAL-PEER-OTHER', this.id, this.canon, this.done, peer.id, peer.canon, peer.done)
|
|
110
126
|
}
|
|
111
127
|
|
|
112
128
|
|
|
113
129
|
if (!exit) {
|
|
114
130
|
out.dc = this.dc + 1
|
|
115
131
|
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
let allChildrenDone = true
|
|
120
|
-
for (let key in this.peg) {
|
|
121
|
-
if (DONE !== this.peg[key]?.dc) {
|
|
122
|
-
allChildrenDone = false
|
|
123
|
-
break
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (allChildrenDone) {
|
|
127
|
-
out.dc = DONE
|
|
128
|
-
ctx.explain && explainClose(te, out)
|
|
129
|
-
return out
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
+
// let newtype = this.type || peer.type
|
|
133
|
+
|
|
134
|
+
let spread_cj = out.spread.cj ?? TOP
|
|
132
135
|
|
|
133
|
-
//
|
|
136
|
+
// Always unify own children first
|
|
134
137
|
for (let key in this.peg) {
|
|
135
|
-
const child = this.peg[key]
|
|
136
138
|
const keyctx = ctx.descend(key)
|
|
137
139
|
|
|
140
|
+
const key_spread_cj = spread_cj.spreadClone(keyctx)
|
|
141
|
+
const child = this.peg[key]
|
|
142
|
+
|
|
138
143
|
propagateMarks(this, child)
|
|
139
144
|
|
|
140
145
|
out.peg[key] =
|
|
141
|
-
undefined === child ?
|
|
146
|
+
undefined === child ? key_spread_cj :
|
|
142
147
|
child.isNil ? child :
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
child
|
|
148
|
+
key_spread_cj.isNil ? key_spread_cj :
|
|
149
|
+
key_spread_cj.isTop && child.done ? child :
|
|
150
|
+
child.isTop && key_spread_cj.done ? key_spread_cj :
|
|
151
|
+
unite(te ? keyctx.clone({ explain: ec(te, 'KEY:' + key) }) : keyctx,
|
|
152
|
+
child, key_spread_cj, 'map-own')
|
|
146
153
|
|
|
147
154
|
done = (done && DONE === out.peg[key].dc)
|
|
148
155
|
}
|
|
149
156
|
|
|
157
|
+
const allowedKeys: string[] = this.closed ? Object.keys(this.peg) : []
|
|
150
158
|
let bad: NilVal | undefined = undefined
|
|
151
159
|
|
|
152
160
|
if (peer instanceof MapVal) {
|
|
@@ -157,14 +165,12 @@ class MapVal extends BagVal {
|
|
|
157
165
|
for (let peerkey in upeer.peg) {
|
|
158
166
|
let peerchild = upeer.peg[peerkey]
|
|
159
167
|
|
|
160
|
-
if (this.closed && !(peerkey
|
|
168
|
+
if (this.closed && !allowedKeys.includes(peerkey)) {
|
|
161
169
|
bad = makeNilErr(ctx, 'closed', peerchild, undefined)
|
|
162
170
|
}
|
|
163
171
|
|
|
164
172
|
// key optionality is additive
|
|
165
|
-
if (
|
|
166
|
-
&& upeer.optionalKeys.includes(peerkey)
|
|
167
|
-
&& !out.optionalKeys.includes(peerkey)) {
|
|
173
|
+
if (upeer.optionalKeys.includes(peerkey) && !out.optionalKeys.includes(peerkey)) {
|
|
168
174
|
out.optionalKeys.push(peerkey)
|
|
169
175
|
}
|
|
170
176
|
|
|
@@ -174,11 +180,19 @@ class MapVal extends BagVal {
|
|
|
174
180
|
|
|
175
181
|
let oval = out.peg[peerkey] =
|
|
176
182
|
undefined === child ? this.handleExpectedVal(peerkey, peerchild, this, ctx) :
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
child.isTop && peerchild.done ? peerchild :
|
|
184
|
+
child.isNil ? child :
|
|
185
|
+
peerchild.isNil ? peerchild :
|
|
186
|
+
unite(te ? peerctx.clone({ explain: ec(te, 'CHD') }) : peerctx,
|
|
187
|
+
child, peerchild, 'map-peer')
|
|
188
|
+
|
|
189
|
+
if (this.spread.cj) {
|
|
190
|
+
let key_spread_cj = spread_cj.spreadClone(peerctx)
|
|
191
|
+
|
|
192
|
+
oval = out.peg[peerkey] =
|
|
193
|
+
unite(te ? peerctx.clone({ explain: ec(te, 'PSP:' + peerkey) }) : peerctx,
|
|
194
|
+
oval, key_spread_cj, 'map-peer-spread')
|
|
195
|
+
}
|
|
182
196
|
|
|
183
197
|
propagateMarks(this, oval)
|
|
184
198
|
|
|
@@ -199,41 +213,66 @@ class MapVal extends BagVal {
|
|
|
199
213
|
out.dc = done ? DONE : out.dc
|
|
200
214
|
propagateMarks(peer, out)
|
|
201
215
|
propagateMarks(this, out)
|
|
202
|
-
|
|
203
216
|
}
|
|
204
217
|
}
|
|
205
218
|
|
|
219
|
+
// console.log(
|
|
220
|
+
// 'MAPVAL-OUT', out.canon,
|
|
221
|
+
// '\n SELF', this,
|
|
222
|
+
// '\n PEER', peer,
|
|
223
|
+
// '\n OUT', out,
|
|
224
|
+
// '\n FROM', (out as any).spread.cj
|
|
225
|
+
// )
|
|
226
|
+
|
|
206
227
|
ctx.explain && explainClose(te, out)
|
|
207
228
|
|
|
208
229
|
return out
|
|
209
230
|
}
|
|
210
231
|
|
|
211
232
|
|
|
212
|
-
//
|
|
213
|
-
//
|
|
233
|
+
// Spread clone: return a Val usable as the per-key spread constraint.
|
|
234
|
+
//
|
|
235
|
+
// Three tiers:
|
|
236
|
+
// 1. tree is path-independent (no RefVal/KeyFuncVal/PathFuncVal/
|
|
237
|
+
// MoveFuncVal/SuperFuncVal anywhere below): return `this` directly.
|
|
238
|
+
// Nothing in the unify path mutates the spread root, and no
|
|
239
|
+
// child depends on its own stored .path, so sharing is safe.
|
|
240
|
+
// 2. top-level children are all ScalarKindVal: shallow clone
|
|
241
|
+
// (share children, fresh MapVal wrapper).
|
|
242
|
+
// 3. otherwise: full deep clone via `this.clone(ctx)`.
|
|
243
|
+
//
|
|
244
|
+
// Tier 1 handles the foo-sdk common case of simple type-constraint
|
|
245
|
+
// spreads like `&:{active: *true | boolean, version: *'0.0.1' | string}`,
|
|
246
|
+
// which are cloned thousands of times per run.
|
|
214
247
|
spreadClone(ctx: AontuContext): Val {
|
|
215
248
|
if (!this.isPathDependent) return this
|
|
216
249
|
|
|
250
|
+
let allScalarKind = true
|
|
251
|
+
for (let key in this.peg) {
|
|
252
|
+
if (!(this.peg[key] as any)?.isScalarKind) {
|
|
253
|
+
allScalarKind = false
|
|
254
|
+
break
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (!allScalarKind) {
|
|
259
|
+
return this.clone(ctx)
|
|
260
|
+
}
|
|
261
|
+
|
|
217
262
|
let out = (super.clone(ctx) as MapVal)
|
|
218
263
|
out.peg = {}
|
|
219
264
|
|
|
220
265
|
for (let entry of Object.entries(this.peg)) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
wrapper.mark = { ...child.mark }
|
|
228
|
-
out.peg[entry[0]] = wrapper
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
out.peg[entry[0]] = child
|
|
232
|
-
}
|
|
266
|
+
out.peg[entry[0]] = entry[1]
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Must create a new spread object to avoid mutating the original.
|
|
270
|
+
out.spread = {
|
|
271
|
+
cj: this.spread.cj ? this.spread.cj.spreadClone(ctx) : undefined,
|
|
233
272
|
}
|
|
234
273
|
|
|
235
274
|
out.closed = this.closed
|
|
236
|
-
out.optionalKeys =
|
|
275
|
+
out.optionalKeys = [...this.optionalKeys]
|
|
237
276
|
|
|
238
277
|
return out
|
|
239
278
|
}
|
|
@@ -246,25 +285,36 @@ class MapVal extends BagVal {
|
|
|
246
285
|
for (let entry of Object.entries(this.peg)) {
|
|
247
286
|
out.peg[entry[0]] =
|
|
248
287
|
(entry[1] as any)?.isVal ?
|
|
288
|
+
// (entry[1] as Val).clone(ctx, spec?.mark ? { mark: spec.mark } : {}) :
|
|
249
289
|
(entry[1] as Val).clone(ctx, {
|
|
250
290
|
mark: spec?.mark ?? {},
|
|
251
291
|
path: [...out.path, entry[0]]
|
|
252
292
|
}) :
|
|
253
293
|
entry[1]
|
|
254
294
|
}
|
|
295
|
+
if (this.spread.cj) {
|
|
296
|
+
out.spread.cj = this.spread.cj.clone(ctx, spec?.mark ? { mark: spec.mark } : {})
|
|
297
|
+
}
|
|
255
298
|
|
|
256
299
|
out.closed = this.closed
|
|
257
300
|
out.optionalKeys = [...this.optionalKeys]
|
|
258
301
|
|
|
302
|
+
// out.from = this.from
|
|
303
|
+
|
|
304
|
+
// console.log('MAPVAL-CLONE', this.canon, '->', out.canon)
|
|
259
305
|
return out
|
|
260
306
|
}
|
|
261
307
|
|
|
262
308
|
|
|
263
309
|
get canon() {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
310
|
+
let keys = Object.keys(this.peg)
|
|
311
|
+
return '' +
|
|
312
|
+
// this.errcanon() +
|
|
313
|
+
// (this.mark.type ? '<type>' : '') +
|
|
314
|
+
// (this.id + '=') +
|
|
267
315
|
'{' +
|
|
316
|
+
(this.spread.cj ? '&:' + this.spread.cj.canon +
|
|
317
|
+
(0 < keys.length ? ',' : '') : '') +
|
|
268
318
|
keys
|
|
269
319
|
.map(k => [
|
|
270
320
|
JSON.stringify(k) +
|
|
@@ -273,19 +323,18 @@ class MapVal extends BagVal {
|
|
|
273
323
|
(this.peg[k]?.canon ?? this.peg[k])
|
|
274
324
|
])
|
|
275
325
|
.join(',') +
|
|
276
|
-
'}'
|
|
277
|
-
|
|
278
|
-
return c
|
|
326
|
+
'}' // + '<' + (this.mark.hide ? 'H' : '') + '>'
|
|
327
|
+
|
|
279
328
|
}
|
|
280
329
|
|
|
281
330
|
|
|
282
|
-
inspection(
|
|
283
|
-
return ''
|
|
331
|
+
inspection(d?: number) {
|
|
332
|
+
return this.spread.cj ? '&:' + this.spread.cj.inspect(null == d ? 0 : d + 1) : ''
|
|
284
333
|
}
|
|
285
334
|
|
|
286
335
|
}
|
|
287
336
|
|
|
288
337
|
|
|
289
338
|
export {
|
|
290
|
-
MapVal
|
|
339
|
+
MapVal
|
|
291
340
|
}
|
package/src/val/MoveFuncVal.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
import { makeNilErr } from '../err'
|
|
14
14
|
|
|
15
15
|
import { NilVal } from '../val/NilVal'
|
|
16
|
-
import { PathVal } from '../val/PathVal'
|
|
17
16
|
|
|
18
17
|
import {
|
|
19
18
|
walk
|
|
@@ -27,60 +26,6 @@ import { PrefFuncVal } from './PrefFuncVal'
|
|
|
27
26
|
|
|
28
27
|
|
|
29
28
|
|
|
30
|
-
// Navigate the tree using a PathVal's resolved path and hide the source.
|
|
31
|
-
function hideAtPath(root: Val, pv: PathVal) {
|
|
32
|
-
// Compute the refpath the same way PathVal.find does
|
|
33
|
-
const parts: string[] = []
|
|
34
|
-
for (const part of pv.peg) {
|
|
35
|
-
if ('string' === typeof part) parts.push(part)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let refpath: string[]
|
|
39
|
-
if (pv.absolute) {
|
|
40
|
-
refpath = parts
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
refpath = pv.path.slice(0, -1).concat(parts)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Walk to the source, handling conjuncts/disjuncts
|
|
47
|
-
let node: any = root
|
|
48
|
-
for (let i = 0; i < refpath.length; i++) {
|
|
49
|
-
const part = refpath[i]
|
|
50
|
-
if (node?.isMap || node?.isList) {
|
|
51
|
-
node = node.peg[part]
|
|
52
|
-
}
|
|
53
|
-
else if (node?.isConjunct || node?.isDisjunct) {
|
|
54
|
-
// Search junction terms for the key
|
|
55
|
-
let found = null
|
|
56
|
-
const stack = [...node.peg]
|
|
57
|
-
while (stack.length > 0) {
|
|
58
|
-
const term = stack.pop()
|
|
59
|
-
if (term?.isConjunct || term?.isDisjunct) {
|
|
60
|
-
stack.push(...term.peg)
|
|
61
|
-
}
|
|
62
|
-
else if ((term?.isMap || term?.isList) && term.peg[part] != null) {
|
|
63
|
-
found = term.peg[part]
|
|
64
|
-
break
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
node = found
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
if (node == null) return
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Mark the source value hidden
|
|
76
|
-
node.mark.hide = true
|
|
77
|
-
walk(node, (_key: string | number | undefined, val: Val) => {
|
|
78
|
-
val.mark.hide = true
|
|
79
|
-
return val
|
|
80
|
-
})
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
29
|
class MoveFuncVal extends FuncBaseVal {
|
|
85
30
|
isMoveFunc = true
|
|
86
31
|
|
|
@@ -105,40 +50,30 @@ class MoveFuncVal extends FuncBaseVal {
|
|
|
105
50
|
}
|
|
106
51
|
|
|
107
52
|
resolve(ctx: AontuContext, args: Val[]) {
|
|
108
|
-
let
|
|
109
|
-
if (arg.isNil) return arg
|
|
53
|
+
let out = args[0] ?? makeNilErr(ctx, 'arg', this)
|
|
110
54
|
|
|
111
|
-
|
|
55
|
+
const orig = out
|
|
112
56
|
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
src = arg.find(ctx) as Val
|
|
116
|
-
if (src == null || src.isNil) return makeNilErr(ctx, 'arg', this)
|
|
57
|
+
if (!orig.isNil) {
|
|
58
|
+
const src = orig.clone(ctx)
|
|
117
59
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
else {
|
|
122
|
-
src = arg.clone(ctx)
|
|
60
|
+
if (src.isRef) {
|
|
61
|
+
src.mark._hide_found = true
|
|
62
|
+
}
|
|
123
63
|
|
|
124
|
-
|
|
125
|
-
arg.mark.hide = true
|
|
126
|
-
walk(arg, (_key: string | number | undefined, val: Val) => {
|
|
64
|
+
walk(orig, (_key: string | number | undefined, val: Val) => {
|
|
127
65
|
val.mark.hide = true
|
|
128
66
|
return val
|
|
129
67
|
})
|
|
68
|
+
|
|
69
|
+
// out = new CopyFuncVal({ peg: [src] }, ctx)
|
|
70
|
+
out = new PrefFuncVal({ peg: [src] }, ctx)
|
|
71
|
+
// out = src
|
|
130
72
|
}
|
|
131
73
|
|
|
132
|
-
//
|
|
133
|
-
src.mark.type = false
|
|
134
|
-
src.mark.hide = false
|
|
135
|
-
walk(src, (_key: string | number | undefined, val: Val) => {
|
|
136
|
-
val.mark.type = false
|
|
137
|
-
val.mark.hide = false
|
|
138
|
-
return val
|
|
139
|
-
})
|
|
74
|
+
// console.log('MOVE-resolve', orig, out)
|
|
140
75
|
|
|
141
|
-
return
|
|
76
|
+
return out
|
|
142
77
|
}
|
|
143
78
|
}
|
|
144
79
|
|
package/src/val/PathFuncVal.ts
CHANGED
|
@@ -6,10 +6,6 @@ import type {
|
|
|
6
6
|
ValSpec,
|
|
7
7
|
} from '../type'
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
DONE,
|
|
11
|
-
} from '../type'
|
|
12
|
-
|
|
13
9
|
import {
|
|
14
10
|
AontuContext,
|
|
15
11
|
} from '../ctx'
|
|
@@ -17,7 +13,7 @@ import {
|
|
|
17
13
|
import { makeNilErr } from '../err'
|
|
18
14
|
|
|
19
15
|
import { NilVal } from '../val/NilVal'
|
|
20
|
-
import {
|
|
16
|
+
import { RefVal } from '../val/RefVal'
|
|
21
17
|
import { FuncBaseVal } from './FuncBaseVal'
|
|
22
18
|
|
|
23
19
|
|
|
@@ -49,26 +45,12 @@ class PathFuncVal extends FuncBaseVal {
|
|
|
49
45
|
let arg = args[0]
|
|
50
46
|
|
|
51
47
|
if (0 === this.prepared) {
|
|
52
|
-
if (arg
|
|
53
|
-
|
|
54
|
-
const found = arg.find(ctx)
|
|
55
|
-
if (found != null && !found.isNil) {
|
|
56
|
-
arg = found
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
arg.dc = DONE
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else if (arg.isScalar && arg.peg != null && arg.peg !== ''
|
|
63
|
-
&& ('string' === typeof arg.peg || arg.isNumber)) {
|
|
64
|
-
// String or number arg like path("foo") or path(0.2) — create a path value
|
|
65
|
-
arg = this.place(new PathVal({ peg: [arg], absolute: false })) as PathVal
|
|
66
|
-
arg.dc = DONE
|
|
48
|
+
if (arg.isScalar) {
|
|
49
|
+
arg = this.place(new RefVal({ peg: [arg], absolute: false }))
|
|
67
50
|
}
|
|
68
|
-
else if (arg.
|
|
51
|
+
else if (!arg.isRef) {
|
|
69
52
|
arg = makeNilErr(ctx, 'invalid-arg', this)
|
|
70
53
|
}
|
|
71
|
-
// else: already resolved by preprocessing — pass through
|
|
72
54
|
}
|
|
73
55
|
|
|
74
56
|
args[0] = arg
|
|
@@ -82,13 +64,6 @@ class PathFuncVal extends FuncBaseVal {
|
|
|
82
64
|
resolve(ctx: AontuContext, args: Val[]) {
|
|
83
65
|
let out = args[0] ?? makeNilErr(ctx, 'arg', this)
|
|
84
66
|
|
|
85
|
-
if (out instanceof PathVal) {
|
|
86
|
-
const found = out.find(ctx)
|
|
87
|
-
if (found != null && !found.isNil) {
|
|
88
|
-
out = found
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
67
|
return out
|
|
93
68
|
}
|
|
94
69
|
|
package/src/val/PrefVal.ts
CHANGED
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
|
|
23
23
|
import { top } from './top'
|
|
24
24
|
|
|
25
|
-
import { ConjunctVal } from './ConjunctVal'
|
|
26
25
|
import { FeatureVal } from './FeatureVal'
|
|
27
26
|
|
|
28
27
|
|
|
@@ -65,13 +64,10 @@ class PrefVal extends FeatureVal {
|
|
|
65
64
|
if (!this.peg.done) {
|
|
66
65
|
const resolved = unite(te ? ctx.clone({ explain: ec(te, 'RES') }) : ctx,
|
|
67
66
|
this.peg, top(), 'pref/resolve')
|
|
67
|
+
// console.log('PREF-RESOLVED', this.peg.canon, '->', resolved)
|
|
68
68
|
this.peg = resolved
|
|
69
69
|
this.superpeg = this.peg.superior()
|
|
70
70
|
}
|
|
71
|
-
else if (this.superpeg.isTop && !this.peg.isTop) {
|
|
72
|
-
// Stale superpeg from pre-resolved PathVal — recalculate
|
|
73
|
-
this.superpeg = this.peg.superior()
|
|
74
|
-
}
|
|
75
71
|
|
|
76
72
|
if (peer instanceof PrefVal) {
|
|
77
73
|
why += 'pref-'
|
|
@@ -110,20 +106,11 @@ class PrefVal extends FeatureVal {
|
|
|
110
106
|
else if (!peer.isTop) {
|
|
111
107
|
why += 'super-'
|
|
112
108
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
out =
|
|
117
|
-
|
|
118
|
-
why += 'defer'
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
out = unite(te ? ctx.clone({ explain: ec(te, 'SUPER') }) : ctx,
|
|
122
|
-
this.superpeg, peer, 'pref-super/' + this.id)
|
|
123
|
-
if (out.same(this.superpeg)) {
|
|
124
|
-
out = this.peg
|
|
125
|
-
why += 'same'
|
|
126
|
-
}
|
|
109
|
+
out = unite(te ? ctx.clone({ explain: ec(te, 'SUPER') }) : ctx,
|
|
110
|
+
this.superpeg, peer, 'pref-super/' + this.id)
|
|
111
|
+
if (out.same(this.superpeg)) {
|
|
112
|
+
out = this.peg
|
|
113
|
+
why += 'same'
|
|
127
114
|
}
|
|
128
115
|
|
|
129
116
|
// }
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* Copyright (c) 2021-2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
import Util from 'node:util'
|
|
5
|
+
|
|
4
6
|
import {
|
|
5
7
|
walk,
|
|
6
8
|
explainOpen,
|
|
@@ -14,7 +16,6 @@ import type {
|
|
|
14
16
|
ValSpec,
|
|
15
17
|
} from '../type'
|
|
16
18
|
|
|
17
|
-
|
|
18
19
|
import {
|
|
19
20
|
DONE,
|
|
20
21
|
} from '../type'
|
|
@@ -136,23 +137,10 @@ class RefVal extends FeatureVal {
|
|
|
136
137
|
unify(peer: Val, ctx: AontuContext): Val {
|
|
137
138
|
peer = peer ?? top()
|
|
138
139
|
|
|
139
|
-
// TEMPORARY: nerf RefVals to verify spread-first resolution
|
|
140
|
-
return makeNilErr(ctx, 'ref_test_block', this, peer)
|
|
141
|
-
|
|
142
140
|
const te = ctx.explain && explainOpen(ctx, ctx.explain, 'Ref', this, peer)
|
|
143
141
|
let out: Val = this
|
|
144
142
|
let why = 'id'
|
|
145
143
|
|
|
146
|
-
// Defer ref resolution on first pass and while spreads remain
|
|
147
|
-
if (0 === ctx.cc || 0 < ctx.sc) {
|
|
148
|
-
if (!peer.isTop && this.id !== peer.id) {
|
|
149
|
-
out = new ConjunctVal({ peg: [this, peer] }, ctx)
|
|
150
|
-
}
|
|
151
|
-
out.dc = DONE === out.dc ? DONE : this.dc + 1
|
|
152
|
-
explainClose(te, out)
|
|
153
|
-
return out
|
|
154
|
-
}
|
|
155
|
-
|
|
156
144
|
if (this.id !== peer.id) {
|
|
157
145
|
|
|
158
146
|
// TODO: not resolved when all Vals in path are done is an error
|
|
@@ -371,30 +359,31 @@ class RefVal extends FeatureVal {
|
|
|
371
359
|
if (this.mark.type || this.mark.hide) {
|
|
372
360
|
out.mark.type = this.mark.type
|
|
373
361
|
out.mark.hide = this.mark.hide
|
|
362
|
+
|
|
363
|
+
// walk(out, (_key: string | number | undefined, val: Val) => {
|
|
364
|
+
// val.mark.type = this.mark.type
|
|
365
|
+
// val.mark.hide = this.mark.hide
|
|
366
|
+
// return val
|
|
367
|
+
// })
|
|
374
368
|
}
|
|
375
369
|
|
|
376
370
|
if (this.mark._hide_found) {
|
|
377
371
|
out.mark.hide = true
|
|
378
372
|
}
|
|
379
373
|
|
|
380
|
-
//
|
|
381
|
-
const cacheKey = this.id + '|' + out.id
|
|
382
|
-
const cache = ctx._refCloneCache
|
|
383
|
-
const cached = cache?.get(cacheKey)
|
|
384
|
-
if (cached !== undefined) {
|
|
385
|
-
out = cached
|
|
386
|
-
}
|
|
387
|
-
else {
|
|
388
|
-
out = out.clone(ctx)
|
|
374
|
+
// console.log('FOUND-B', out)
|
|
389
375
|
|
|
390
|
-
|
|
391
|
-
val.mark.type = false
|
|
392
|
-
val.mark.hide = false
|
|
393
|
-
return val
|
|
394
|
-
})
|
|
376
|
+
out = out.clone(ctx)
|
|
395
377
|
|
|
396
|
-
|
|
397
|
-
|
|
378
|
+
// if (this.mark.type || this.mark.hide) {
|
|
379
|
+
walk(out, (_key: string | number | undefined, val: Val) => {
|
|
380
|
+
val.mark.type = false
|
|
381
|
+
val.mark.hide = false
|
|
382
|
+
return val
|
|
383
|
+
})
|
|
384
|
+
//}
|
|
385
|
+
|
|
386
|
+
// onsole.log('FOUND-C', out)
|
|
398
387
|
}
|
|
399
388
|
}
|
|
400
389
|
}
|