aontu 0.30.2 → 0.32.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.
Files changed (63) hide show
  1. package/dist/aontu.js +1 -0
  2. package/dist/aontu.js.map +1 -1
  3. package/dist/ctx.d.ts +3 -2
  4. package/dist/ctx.js +3 -2
  5. package/dist/ctx.js.map +1 -1
  6. package/dist/hints.js +7 -1
  7. package/dist/hints.js.map +1 -1
  8. package/dist/unify.js +14 -8
  9. package/dist/unify.js.map +1 -1
  10. package/dist/utility.js +17 -7
  11. package/dist/utility.js.map +1 -1
  12. package/dist/val/ConjunctVal.js +4 -4
  13. package/dist/val/ConjunctVal.js.map +1 -1
  14. package/dist/val/CopyFuncVal.d.ts +2 -1
  15. package/dist/val/CopyFuncVal.js +14 -6
  16. package/dist/val/CopyFuncVal.js.map +1 -1
  17. package/dist/val/FuncBaseVal.d.ts +2 -2
  18. package/dist/val/FuncBaseVal.js +22 -18
  19. package/dist/val/FuncBaseVal.js.map +1 -1
  20. package/dist/val/JunctionVal.js +2 -2
  21. package/dist/val/JunctionVal.js.map +1 -1
  22. package/dist/val/KeyFuncVal.d.ts +1 -0
  23. package/dist/val/KeyFuncVal.js +36 -6
  24. package/dist/val/KeyFuncVal.js.map +1 -1
  25. package/dist/val/ListVal.js +10 -1
  26. package/dist/val/ListVal.js.map +1 -1
  27. package/dist/val/MapVal.d.ts +1 -1
  28. package/dist/val/MapVal.js +42 -8
  29. package/dist/val/MapVal.js.map +1 -1
  30. package/dist/val/MoveFuncVal.d.ts +1 -0
  31. package/dist/val/MoveFuncVal.js +11 -8
  32. package/dist/val/MoveFuncVal.js.map +1 -1
  33. package/dist/val/PrefVal.js +19 -11
  34. package/dist/val/PrefVal.js.map +1 -1
  35. package/dist/val/RefVal.js +50 -16
  36. package/dist/val/RefVal.js.map +1 -1
  37. package/dist/val/ScalarVal.js +1 -0
  38. package/dist/val/ScalarVal.js.map +1 -1
  39. package/dist/val/TopVal.d.ts +1 -1
  40. package/dist/val/TopVal.js +2 -2
  41. package/dist/val/TopVal.js.map +1 -1
  42. package/dist/val/Val.d.ts +3 -2
  43. package/dist/val/Val.js +37 -18
  44. package/dist/val/Val.js.map +1 -1
  45. package/package.json +1 -2
  46. package/src/aontu.ts +1 -0
  47. package/src/ctx.ts +6 -4
  48. package/src/hints.ts +11 -1
  49. package/src/unify.ts +17 -9
  50. package/src/utility.ts +19 -9
  51. package/src/val/ConjunctVal.ts +5 -5
  52. package/src/val/CopyFuncVal.ts +20 -7
  53. package/src/val/FuncBaseVal.ts +30 -24
  54. package/src/val/JunctionVal.ts +2 -2
  55. package/src/val/KeyFuncVal.ts +42 -6
  56. package/src/val/ListVal.ts +14 -1
  57. package/src/val/MapVal.ts +63 -9
  58. package/src/val/MoveFuncVal.ts +12 -8
  59. package/src/val/PrefVal.ts +25 -14
  60. package/src/val/RefVal.ts +69 -17
  61. package/src/val/ScalarVal.ts +2 -0
  62. package/src/val/TopVal.ts +2 -2
  63. package/src/val/Val.ts +42 -18
@@ -27,7 +27,6 @@ import {
27
27
  top
28
28
  } from './top'
29
29
 
30
- import { NilVal } from '../val/NilVal'
31
30
  import { ConjunctVal } from '../val/ConjunctVal'
32
31
  import { FeatureVal } from '../val/FeatureVal'
33
32
 
@@ -59,6 +58,7 @@ class FuncBaseVal extends FeatureVal {
59
58
 
60
59
 
61
60
  unify(peer: Val, ctx: AontuContext): Val {
61
+ const TOP = top()
62
62
  const te = ctx.explain && explainOpen(ctx, ctx.explain, 'Func:' + this.funcname(), this, peer)
63
63
 
64
64
  // const sc = this.id + '=' + this.canon
@@ -71,6 +71,8 @@ class FuncBaseVal extends FeatureVal {
71
71
 
72
72
  // console.log('FBV', this.id, this.constructor.name, this.mark.type, this.peg?.canon, 'PEER', peer.id, peer.canon)
73
73
 
74
+ let pegdone = true
75
+
74
76
  if (this.id !== peer.id) {
75
77
 
76
78
  if (peer.isTop && (this.mark.type || this.mark.hide)) {
@@ -78,25 +80,34 @@ class FuncBaseVal extends FeatureVal {
78
80
  }
79
81
 
80
82
  else {
81
- let pegdone = true
83
+
82
84
  let newpeg: Val[] = []
83
85
  let newtype = this.mark.type
84
86
  let newhide = this.mark.hide
85
87
 
86
- this.peg = this.prepare(ctx, this.peg)
87
-
88
- for (let arg of this.peg) {
89
- // console.log('FUNCBASE-UNIFY-PEG-A', arg.canon)
88
+ let pegprep = this.prepare(ctx, this.peg)
90
89
 
91
- let newarg = arg
92
- if (!arg.done) {
93
- newarg = arg.unify(top(), ctx.clone({ explain: ec(te, 'ARG') }))
94
- newtype = newtype || newarg.mark.type
95
- newhide = newhide || newarg.mark.hide
96
- // console.log('FUNCBASE-UNIFY-PEG-B', arg.canon, '->', newarg.canon)
90
+ if (null === pegprep) {
91
+ pegdone = true
92
+ newpeg = this.peg
93
+ }
94
+ else {
95
+ this.peg = pegprep
96
+
97
+ for (let arg of this.peg) {
98
+ // console.log('FUNCBASE-UNIFY-PEG-A', arg.canon)
99
+
100
+ let newarg = arg
101
+ if (!arg.done) {
102
+ newarg = arg.unify(TOP, ctx.clone({ explain: ec(te, 'ARG') }))
103
+ newtype = newtype || newarg.mark.type
104
+ newhide = newhide || newarg.mark.hide
105
+ // console.log('FUNCBASE-UNIFY-PEG-B', arg.canon, arg.done, '->', newarg.canon, newarg.done)
106
+ }
107
+ // pegdone &&= arg.done
108
+ pegdone &&= newarg.done
109
+ newpeg.push(newarg)
97
110
  }
98
- pegdone &&= arg.done
99
- newpeg.push(newarg)
100
111
  }
101
112
 
102
113
  // console.log('FUNCBASE-PEG', this.id, pegdone, this.peg.map((p: any) => p?.canon))
@@ -106,15 +117,10 @@ class FuncBaseVal extends FeatureVal {
106
117
  // console.log('FUNC-RESOLVED', ctx.cc, resolved?.canon)
107
118
 
108
119
  out = resolved.done && peer.isTop ? resolved :
109
- unite(ctx.clone({ explain: ec(te, 'PEG') }), resolved, peer, 'func-' + this.funcname() + '/' + this.id)
120
+ unite(ctx.clone({ explain: ec(te, 'PEG') }),
121
+ resolved, peer, 'func-' + this.funcname() + '/' + this.id)
110
122
  propagateMarks(this, out)
111
123
 
112
- // const unified =
113
- // unite(ctx, resolved, peer, 'func-' + this.funcname() + '/' + this.id)
114
- // out = unified
115
- // propagateMarks(unified, out)
116
- // propagateMarks(this, out)
117
-
118
124
  // TODO: make should handle this using ctx?
119
125
  out.site.row = this.site.row
120
126
  out.site.col = this.site.col
@@ -157,7 +163,7 @@ class FuncBaseVal extends FeatureVal {
157
163
  }
158
164
  }
159
165
 
160
- // console.log('FUNC-UNIFY-OUT', this.funcname(), this.id, this.canon, 'W=', why, peer.id, peer.canon, 'O=', out.dc, out.id, out.canon)
166
+ // console.log('FUNC-UNIFY-OUT', ctx.cc, this.funcname(), this.id, this.canon, 'D=', pegdone, 'W=', why, peer.id, peer.canon, 'O=', out.dc, out.id, out.canon)
161
167
 
162
168
  explainClose(te, out)
163
169
 
@@ -180,12 +186,12 @@ class FuncBaseVal extends FeatureVal {
180
186
  }
181
187
 
182
188
 
183
- prepare(_ctx: AontuContext | undefined, args: Val[]): Val[] {
189
+ prepare(_ctx: AontuContext, args: Val[]): Val[] | null {
184
190
  return args
185
191
  }
186
192
 
187
193
 
188
- resolve(ctx: AontuContext | undefined, _args: Val[]): Val {
194
+ resolve(ctx: AontuContext, _args: Val[]): Val {
189
195
  return makeNilErr(ctx, 'func:' + this.funcname(), this, undefined, 'resolve')
190
196
  }
191
197
 
@@ -40,8 +40,8 @@ abstract class JunctionVal extends FeatureVal {
40
40
  get canon() {
41
41
  return this.peg.map((v: Val) => {
42
42
  return (v as any).isJunction && Array.isArray(v.peg) && 1 < v.peg.length ?
43
- '(' + v.canon + ')' : v.canon
44
- }).join(this.getJunctionSymbol())
43
+ '(' + v.canon + ')' : v.canon // v.id + '=' + v.canon
44
+ }).join(this.getJunctionSymbol()) // + '<' + (this.mark.hide ? 'H' : '') + '>'
45
45
  }
46
46
 
47
47
  // Abstract method to be implemented by subclasses to define their junction symbol
@@ -12,6 +12,7 @@ import {
12
12
  } from '../ctx'
13
13
 
14
14
  import { StringVal } from '../val/StringVal'
15
+ import { ConjunctVal } from '../val/ConjunctVal'
15
16
 
16
17
 
17
18
 
@@ -39,17 +40,52 @@ class KeyFuncVal extends FuncBaseVal {
39
40
  }
40
41
 
41
42
 
43
+ unify(peer: Val, ctx: AontuContext): Val {
44
+ // TODO: this delay makes keys in spreads and refs work, but it is a hack - find a better way.
45
+ let out: Val = this
46
+
47
+ if (ctx.cc < 3) {
48
+ this.notdone()
49
+
50
+ if (peer.isTop || (peer.id === this.id)) {
51
+ // TODO: clone needed to avoid triggering unify_cycle - find a better way
52
+ out = this.clone(ctx)
53
+ }
54
+ else if (peer.isNil) {
55
+ out = peer
56
+ }
57
+ else {
58
+ if (
59
+ peer.isKeyFunc
60
+ && peer.path.join('.') === this.path.join('.')
61
+ && peer.peg?.[0]?.peg === this.peg?.[0]?.peg
62
+ ) {
63
+ out = this
64
+ }
65
+ else {
66
+ out = new ConjunctVal({ peg: [this, peer] }, ctx)
67
+ }
68
+ }
69
+ }
70
+ else {
71
+ out = super.unify(peer, ctx)
72
+ }
73
+
74
+ return out
75
+ }
76
+
42
77
 
43
78
  resolve(_ctx: AontuContext, _args: Val[]) {
44
79
  let out: Val = this
45
80
 
46
- if (!this.mark.type && !this.mark.hide) {
47
- let move = this.peg?.[0]?.peg
48
- move = isNaN(move) ? 1 : +move
49
- const key = this.path[this.path.length - (1 + move)] ?? ''
81
+ // if (!this.mark.type && !this.mark.hide) {
82
+ let move = this.peg?.[0]?.peg
83
+ move = isNaN(move) ? 1 : +move
84
+ const key = this.path[this.path.length - (1 + move)] ?? ''
85
+ // console.log('KEY', this.path, move, key)
50
86
 
51
- out = new StringVal({ peg: key })
52
- }
87
+ out = new StringVal({ peg: key })
88
+ // }
53
89
 
54
90
  return out
55
91
  }
@@ -243,7 +243,20 @@ class ListVal extends BagVal {
243
243
 
244
244
  const optional = this.optionalKeys.includes('' + i)
245
245
 
246
- if (child.isScalar
246
+ // Optional unresolved disjuncts are not an error, just dropped.
247
+ if (child.isDisjunct && optional) {
248
+ const dctx = ctx.clone({ err: [] })
249
+
250
+ let cval = child.gen(dctx)
251
+
252
+ if (undefined === cval) {
253
+ continue
254
+ }
255
+
256
+ out.push(cval)
257
+ }
258
+
259
+ else if (child.isScalar
247
260
  || child.isMap
248
261
  || child.isList
249
262
  || child.isPref
package/src/val/MapVal.ts CHANGED
@@ -77,6 +77,8 @@ class MapVal extends BagVal {
77
77
  // NOTE: order of keys is not preserved!
78
78
  // not possible in any case - consider {a,b} unify {b,a}
79
79
  unify(peer: Val, ctx: AontuContext): Val {
80
+ // console.log('MAPVAL-UNIFY', this.id, this.canon, peer.id, peer.canon)
81
+
80
82
  const TOP = top()
81
83
  peer = peer ?? TOP
82
84
  const te = ctx.explain && explainOpen(ctx, ctx.explain, 'Map', this, peer)
@@ -92,7 +94,19 @@ class MapVal extends BagVal {
92
94
 
93
95
  out.spread.cj = this.spread.cj
94
96
 
97
+ // TODO: some spreads (no path refs etc) could self unified
98
+ /*
99
+ if (out.spread.cj && !out.spread.cj.mark._self_unified) {
100
+ // console.log('MAPVAL-SPR-START', out.spread.cj.mark)
101
+ out.spread.cj = out.spread.cj.unify(TOP, ctx.clone({ explain: ec(te, 'SPR-SELF-UNIFY') }))
102
+ out.spread.cj.mark._self_unified = true
103
+ // console.log('MAPVAL-SU', out.spread.cj.id, out.spread.cj.canon, out.spread.cj.done)
104
+ }
105
+ */
106
+
95
107
  if (peer instanceof MapVal) {
108
+ // console.log('MAPVAL-PEER-MAPVAL', this.id, this.canon, this.done, peer.id, peer.canon, peer.done)
109
+
96
110
  if (!this.closed && peer.closed) {
97
111
  out = peer.unify(this, ctx.clone({ explain: ec(te, 'PMC') })) as MapVal
98
112
  exit = true
@@ -119,11 +133,16 @@ class MapVal extends BagVal {
119
133
  out.spread.cj = null == out.spread.cj ? peer.spread.cj : (
120
134
  null == peer.spread.cj ? out.spread.cj : (
121
135
  out.spread.cj =
122
- unite(ctx.clone({ explain: ec(te, 'SPR') }), out.spread.cj, peer.spread.cj, 'map-self')
136
+ unite(ctx.clone({ explain: ec(te, 'SPR') }),
137
+ out.spread.cj, peer.spread.cj, 'map-self')
123
138
  )
124
139
  )
125
140
  }
126
141
  }
142
+ else {
143
+ // console.log('MAPVAL-PEER-OTHER', this.id, this.canon, this.done, peer.id, peer.canon, peer.done)
144
+ }
145
+
127
146
 
128
147
  if (!exit) {
129
148
  out.dc = this.dc + 1
@@ -135,7 +154,10 @@ class MapVal extends BagVal {
135
154
  // Always unify own children first
136
155
  for (let key in this.peg) {
137
156
  const keyctx = ctx.descend(key)
157
+
138
158
  const key_spread_cj = spread_cj.clone(keyctx)
159
+ // console.log('MAPVAL-SPREAD', this.id, key, key_spread_cj.id, key_spread_cj.canon, key_spread_cj.done)
160
+
139
161
  const child = this.peg[key]
140
162
 
141
163
  propagateMarks(this, child)
@@ -146,7 +168,7 @@ class MapVal extends BagVal {
146
168
  key_spread_cj.isNil ? key_spread_cj :
147
169
  key_spread_cj.isTop && child.done ? child :
148
170
  child.isTop && key_spread_cj.done ? key_spread_cj :
149
- unite(keyctx.clone({ explain: ec(te, 'PEG:' + key) }),
171
+ unite(keyctx.clone({ explain: ec(te, 'KEY:' + key) }),
150
172
  child, key_spread_cj, 'map-own')
151
173
 
152
174
  done = (done && DONE === out.peg[key].dc)
@@ -184,6 +206,9 @@ class MapVal extends BagVal {
184
206
  if (this.spread.cj) {
185
207
  let key_ctx = ctx.descend(peerkey)
186
208
  let key_spread_cj = spread_cj.clone(key_ctx)
209
+
210
+ // console.log('MAPVAL-PEER-SPR', peerkey, key_spread_cj.id, key_spread_cj.canon, key_spread_cj.done)
211
+
187
212
  oval = out.peg[peerkey] =
188
213
  unite(key_ctx.clone({ explain: ec(te, 'PSP:' + peerkey) }),
189
214
  oval, key_spread_cj, 'map-peer-spread')
@@ -222,9 +247,16 @@ class MapVal extends BagVal {
222
247
  clone(ctx: AontuContext, spec?: ValSpec): Val {
223
248
  let out = (super.clone(ctx, spec) as MapVal)
224
249
  out.peg = {}
250
+
225
251
  for (let entry of Object.entries(this.peg)) {
226
252
  out.peg[entry[0]] =
227
- (entry[1] as any)?.isVal ? (entry[1] as Val).clone(ctx, spec?.mark ? { mark: spec.mark } : {}) : entry[1]
253
+ (entry[1] as any)?.isVal ?
254
+ // (entry[1] as Val).clone(ctx, spec?.mark ? { mark: spec.mark } : {}) :
255
+ (entry[1] as Val).clone(ctx, {
256
+ mark: spec?.mark ?? {},
257
+ path: [...out.path, entry[0]]
258
+ }) :
259
+ entry[1]
228
260
  }
229
261
  if (this.spread.cj) {
230
262
  out.spread.cj = this.spread.cj.clone(ctx, spec?.mark ? { mark: spec.mark } : {})
@@ -255,16 +287,19 @@ class MapVal extends BagVal {
255
287
  (this.peg[k]?.canon ?? this.peg[k])
256
288
  ])
257
289
  .join(',') +
258
- '}'
290
+ '}' // + '<' + (this.mark.hide ? 'H' : '') + '>'
291
+
259
292
  }
260
293
 
261
294
 
262
- inspection(inspect: Function) {
263
- return this.spread.cj ? '&:' + inspect(this.spread.cj) : ''
295
+ inspection(d?: number) {
296
+ return this.spread.cj ? '&:' + this.spread.cj.inspect(null == d ? 0 : d + 1) : ''
264
297
  }
265
298
 
266
299
 
267
300
  gen(ctx: AontuContext) {
301
+ // console.log('MAPVAL-gen')
302
+
268
303
  let out: any = {}
269
304
  if (this.mark.type || this.mark.hide) {
270
305
  return undefined
@@ -272,13 +307,32 @@ class MapVal extends BagVal {
272
307
 
273
308
  for (let p in this.peg) {
274
309
  const child = this.peg[p]
310
+
275
311
  if (child.mark.type || child.mark.hide) {
276
312
  continue
277
313
  }
278
314
 
279
315
  const optional = this.optionalKeys.includes(p)
280
316
 
281
- if (child.isScalar
317
+ // console.log('MAPVAL-gen-p', p, optional, child.isDisjunct, child)
318
+
319
+
320
+ // Optional unresolved disjuncts are not an error, just dropped.
321
+ if (child.isDisjunct && optional) {
322
+ const dctx = ctx.clone({ err: [], collect: true })
323
+
324
+ let cval = child.gen(dctx)
325
+
326
+ // console.log('CVAL', cval, ctx.err, dctx.err, child.err)
327
+
328
+ if (undefined === cval) {
329
+ continue
330
+ }
331
+
332
+ out[p] = cval
333
+ }
334
+
335
+ else if (child.isScalar
282
336
  || child.isMap
283
337
  || child.isList
284
338
  || child.isPref
@@ -286,9 +340,9 @@ class MapVal extends BagVal {
286
340
  || child.isDisjunct
287
341
  || child.isNil
288
342
  ) {
289
- const cval = child.gen(ctx)
343
+ let cval = child.gen(ctx)
290
344
 
291
- if (optional && empty(cval)) {
345
+ if (optional && (undefined === cval || empty(cval))) {
292
346
  continue
293
347
  }
294
348
 
@@ -22,6 +22,7 @@ import {
22
22
 
23
23
  import { FuncBaseVal } from './FuncBaseVal'
24
24
  import { CopyFuncVal } from './CopyFuncVal'
25
+ import { PrefFuncVal } from './PrefFuncVal'
25
26
 
26
27
 
27
28
 
@@ -44,30 +45,33 @@ class MoveFuncVal extends FuncBaseVal {
44
45
  return 'move'
45
46
  }
46
47
 
48
+ prepare(_ctx: AontuContext, _args: Val[]) {
49
+ return null
50
+ }
47
51
 
48
52
  resolve(ctx: AontuContext, args: Val[]) {
49
53
  let out = args[0] ?? makeNilErr(ctx, 'arg', this)
50
54
 
51
55
  const orig = out
52
- const origcanon = orig.canon
53
56
 
54
57
  if (!orig.isNil) {
55
58
  const src = orig.clone(ctx)
56
59
 
60
+ if (src.isRef) {
61
+ src.mark._hide_found = true
62
+ }
63
+
57
64
  walk(orig, (_key: string | number | undefined, val: Val) => {
58
65
  val.mark.hide = true
59
66
  return val
60
67
  })
61
68
 
62
- out = new CopyFuncVal({ peg: [src] }, ctx)
69
+ // out = new CopyFuncVal({ peg: [src] }, ctx)
70
+ out = new PrefFuncVal({ peg: [src] }, ctx)
71
+ // out = src
63
72
  }
64
73
 
65
- Object.defineProperty(out, 'canon', {
66
- get: () => 'move(' + origcanon + ')',
67
- configurable: true
68
- })
69
-
70
- // console.log('MOVE-resolve', out)
74
+ // console.log('MOVE-resolve', orig, out)
71
75
 
72
76
  return out
73
77
  }
@@ -59,17 +59,27 @@ class PrefVal extends FeatureVal {
59
59
  let out: Val = this
60
60
  let why = ''
61
61
 
62
-
63
62
  if (!this.peg.done) {
64
- const resolved = unite(ctx.clone({ explain: ec(te, 'RES') }), this.peg, top(), 'pref/resolve')
63
+ const resolved = unite(ctx.clone({ explain: ctx.explain && ec(te, 'RES') }),
64
+ this.peg, top(), 'pref/resolve')
65
65
  // console.log('PREF-RESOLVED', this.peg.canon, '->', resolved)
66
66
  this.peg = resolved
67
67
  }
68
68
 
69
-
70
69
  if (peer instanceof PrefVal) {
71
70
  why += 'pref-'
72
- if (this.rank < peer.rank) {
71
+ if (this.id === peer.id) {
72
+ out = this
73
+ why += 'same'
74
+ }
75
+
76
+ // Avoid MAXCYCLE errors
77
+ else if (this.peg.id === peer.peg.id) {
78
+ out = this
79
+ why += 'same-peg'
80
+ }
81
+
82
+ else if (this.rank < peer.rank) {
73
83
  out = this
74
84
  why += 'rank-win'
75
85
  }
@@ -78,22 +88,23 @@ class PrefVal extends FeatureVal {
78
88
  why += 'rank-lose'
79
89
  }
80
90
  else {
81
- let peg = unite(ctx.clone({ explain: ec(te, 'PEER') }), this.peg, peer.peg, 'pref-peer/' + this.id)
91
+ // console.log('PREF-PEER',
92
+ // this.peg.id, this.peg, this.peg.done,
93
+ // peer.peg.id, peer.peg, peer.peg.done,
94
+ // )
95
+
96
+ let peg = unite(ctx.clone({ explain: ctx.explain && ec(te, 'PREF-PEER') }),
97
+ this.peg, peer.peg, 'pref-peer/' + this.id)
82
98
  out = new PrefVal({ peg }, ctx)
99
+ // console.log('PREF-RANK-SAME-OUT', peg, peg.done, out, out.done)
83
100
  why += 'rank-same'
84
101
  }
85
102
  }
86
103
  else if (!peer.isTop) {
87
104
  why += 'super-'
88
105
 
89
- // if (this.superpeg instanceof Nil) {
90
- // out = peer
91
- // why += 'nil'
92
- // }
93
- // else {
94
- // why += 'unify'
95
-
96
- out = unite(ctx.clone({ explain: ec(te, 'SUPER') }), this.superpeg, peer, 'pref-super/' + this.id)
106
+ out = unite(ctx.clone({ explain: ctx.explain && ec(te, 'SUPER') }),
107
+ this.superpeg, peer, 'pref-super/' + this.id)
97
108
  if (out.same(this.superpeg)) {
98
109
  out = this.peg
99
110
  why += 'same'
@@ -109,7 +120,7 @@ class PrefVal extends FeatureVal {
109
120
 
110
121
  // console.log('PREFVAL-OUT', why, this.canon, peer.canon, '->', out.canon, out.done)
111
122
 
112
- explainClose(te, out)
123
+ ctx.explain && explainClose(te, out)
113
124
 
114
125
  return out
115
126
  }
package/src/val/RefVal.ts CHANGED
@@ -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,
@@ -135,7 +137,7 @@ class RefVal extends FeatureVal {
135
137
 
136
138
  const te = ctx.explain && explainOpen(ctx, ctx.explain, 'Ref', this, peer)
137
139
  let out: Val = this
138
- // let why = 'id'
140
+ let why = 'id'
139
141
 
140
142
  if (this.id !== peer.id) {
141
143
 
@@ -152,35 +154,36 @@ class RefVal extends FeatureVal {
152
154
  else if (resolved instanceof RefVal) {
153
155
  if (peer.isTop) {
154
156
  out = this
155
- // why = 'pt'
157
+ why = 'pt'
156
158
  }
157
159
  else if (peer.isNil) {
158
160
  out = makeNilErr(ctx, 'ref[' + this.peg + ']', this, peer)
159
- // why = 'pn'
161
+ why = 'pn'
160
162
  }
161
163
 
162
164
  // same path
163
- // else if (this.peg === peer.peg) {
164
165
  else if (this.canon === peer.canon) {
165
166
  out = this
166
- // why = 'pp'
167
+ why = 'pp'
167
168
  }
168
169
 
169
170
  else {
170
171
  // Ensure RefVal done is incremented
171
172
  this.dc = DONE === this.dc ? DONE : this.dc + 1
172
173
  out = new ConjunctVal({ peg: [this, peer] }, ctx)
173
- // why = 'cj'
174
+ why = 'cj'
174
175
  }
175
176
  }
176
177
  else {
177
178
  out = unite(ctx.clone({ explain: ec(te, 'RES') }), resolved, peer, 'ref')
178
- // why = 'u'
179
+ why = 'u'
179
180
  }
180
181
 
181
182
  out.dc = DONE === out.dc ? DONE : this.dc + 1
182
183
  }
183
184
 
185
+ // console.log('REFVAL-UNIFY-OUT', ctx.cc, this.id, this.canon, this.done, 'P=', peer.id, peer.canon, peer.done, '->', out.id, out.canon, out.done)
186
+
184
187
  explainClose(te, out)
185
188
  return out
186
189
  }
@@ -189,7 +192,15 @@ class RefVal extends FeatureVal {
189
192
  find(ctx: AontuContext) {
190
193
  let out: Val | undefined = undefined
191
194
 
192
- if (this.path.join('.').startsWith(this.peg.join('.'))) {
195
+ const selfpath = this.path.join('.')
196
+ const pegpath = this.peg.join('.')
197
+ const isprefixpath = selfpath.startsWith(pegpath)
198
+
199
+ let refpath: string[] = []
200
+ let pI = 0
201
+ // let descent = ''
202
+
203
+ if (isprefixpath) {
193
204
  out = makeNilErr(ctx, 'path_cycle', this)
194
205
  }
195
206
  else {
@@ -248,8 +259,6 @@ class RefVal extends FeatureVal {
248
259
  }
249
260
  }
250
261
 
251
- let refpath: string[] = []
252
-
253
262
  if (this.absolute) {
254
263
  refpath = parts
255
264
  }
@@ -282,43 +291,86 @@ class RefVal extends FeatureVal {
282
291
  }
283
292
 
284
293
  let node = ctx.root as Val
285
- let pI = 0
294
+
295
+ let nopath = false
286
296
 
287
297
  if (null != node) {
288
298
  for (; pI < refpath.length; pI++) {
289
299
  let part = refpath[pI]
300
+ // console.log('PART', pI, part, node)
290
301
 
291
- if (null == node) {
292
- break
293
- }
294
- else if (node.isMap) {
302
+ // descent += (' | ' + pI + '=' + node.canon) // Util.inspect(node))
303
+
304
+ if (node.isMap) {
295
305
  node = node.peg[part]
296
306
  }
297
307
  else if (node.isList) {
298
308
  node = node.peg[part]
299
309
  }
310
+ else if (node.done) {
311
+ nopath = true
312
+ break;
313
+ }
300
314
  else {
301
315
  break;
302
316
  }
317
+
318
+ if (null == node) {
319
+ nopath = true
320
+ break
321
+ }
322
+
303
323
  }
304
324
  }
305
325
 
306
- if (pI === refpath.length) {
326
+ // console.log('REFPATH', ctx.cc, pI, refpath, nopath, ctx.root, node)
327
+
328
+
329
+ if (nopath) {
330
+ out = makeNilErr(ctx, 'no_path', this)
331
+ }
332
+ else if (pI === refpath.length) {
307
333
  out = node
308
334
 
309
335
  // Types and hidden values are cloned and made concrete
310
- if (null != out && (out.mark.type || out.mark.hide)) {
336
+ if (null != out) { // && (out.mark.type || out.mark.hide)) {
337
+
338
+ // console.log('FOUND-A', out)
339
+
340
+ if (this.mark.type || this.mark.hide) {
341
+ out.mark.type = this.mark.type
342
+ out.mark.hide = this.mark.hide
343
+
344
+ // walk(out, (_key: string | number | undefined, val: Val) => {
345
+ // val.mark.type = this.mark.type
346
+ // val.mark.hide = this.mark.hide
347
+ // return val
348
+ // })
349
+ }
350
+
351
+ if (this.mark._hide_found) {
352
+ out.mark.hide = true
353
+ }
354
+
355
+ // console.log('FOUND-B', out)
356
+
311
357
  out = out.clone(ctx)
312
358
 
359
+ // if (this.mark.type || this.mark.hide) {
313
360
  walk(out, (_key: string | number | undefined, val: Val) => {
314
361
  val.mark.type = false
315
362
  val.mark.hide = false
316
363
  return val
317
364
  })
365
+ //}
366
+
367
+ // onsole.log('FOUND-C', out)
318
368
  }
319
369
  }
320
370
  }
321
371
 
372
+ // console.log('REF-FIND', ctx.cc, this.id, selfpath, 'PEG=', pegpath, 'RP', pI, refpath.join('.'), descent, 'O=', out?.id, out?.canon, out?.done)
373
+
322
374
  return out
323
375
  }
324
376
 
@@ -68,6 +68,8 @@ class ScalarVal extends Val {
68
68
  ((peer as any).kind === this.kind ? 'value' : 'kind'), this, peer)
69
69
  }
70
70
 
71
+ // console.log('SCALAR', this.canon, peer.canon, '->', out.canon)
72
+
71
73
  explainClose(te, out)
72
74
 
73
75
  return out