aontu 0.5.0 → 0.6.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/aontu.ts +3 -2
- package/dist/aontu.d.ts +2 -2
- package/dist/aontu.js +3 -4
- package/dist/aontu.js.map +1 -1
- package/dist/aontu.min.js +1 -63
- package/dist/lib/lang.d.ts +1 -3
- package/dist/lib/lang.js +33 -24
- package/dist/lib/lang.js.map +1 -1
- package/dist/lib/op/disjunct.js +10 -10
- package/dist/lib/op/disjunct.js.map +1 -1
- package/dist/lib/op/op.d.ts +1 -1
- package/dist/lib/op/op.js.map +1 -1
- package/dist/lib/op/unite.js +19 -14
- package/dist/lib/op/unite.js.map +1 -1
- package/dist/lib/type.d.ts +33 -22
- package/dist/lib/type.js +22 -76
- package/dist/lib/type.js.map +1 -1
- package/dist/lib/unify.d.ts +4 -1
- package/dist/lib/unify.js +7 -5
- package/dist/lib/unify.js.map +1 -1
- package/dist/lib/val/ConjunctVal.d.ts +12 -0
- package/dist/lib/val/ConjunctVal.js +191 -0
- package/dist/lib/val/ConjunctVal.js.map +1 -0
- package/dist/lib/val/DisjunctVal.d.ts +12 -0
- package/dist/lib/val/DisjunctVal.js +85 -0
- package/dist/lib/val/DisjunctVal.js.map +1 -0
- package/dist/lib/val/ListVal.d.ts +14 -0
- package/dist/lib/val/ListVal.js +91 -0
- package/dist/lib/val/ListVal.js.map +1 -0
- package/dist/lib/val/MapVal.d.ts +14 -0
- package/dist/lib/val/MapVal.js +141 -0
- package/dist/lib/val/MapVal.js.map +1 -0
- package/dist/lib/val/Nil.d.ts +15 -0
- package/dist/lib/val/Nil.js +54 -0
- package/dist/lib/val/Nil.js.map +1 -0
- package/dist/lib/val/PrefVal.d.ts +12 -0
- package/dist/lib/val/PrefVal.js +60 -0
- package/dist/lib/val/PrefVal.js.map +1 -0
- package/dist/lib/val/RefVal.d.ts +15 -0
- package/dist/lib/val/RefVal.js +73 -0
- package/dist/lib/val/RefVal.js.map +1 -0
- package/dist/lib/val/ValBase.d.ts +22 -0
- package/dist/lib/val/ValBase.js +25 -0
- package/dist/lib/val/ValBase.js.map +1 -0
- package/dist/lib/val.d.ts +5 -92
- package/dist/lib/val.js +13 -609
- package/dist/lib/val.js.map +1 -1
- package/lib/lang.ts +55 -48
- package/lib/op/disjunct.ts +14 -8
- package/lib/op/op.ts +2 -1
- package/lib/op/unite.ts +14 -12
- package/lib/type.ts +104 -0
- package/lib/unify.ts +10 -8
- package/lib/val/ConjunctVal.ts +284 -0
- package/lib/val/DisjunctVal.ts +145 -0
- package/lib/val/ListVal.ts +154 -0
- package/lib/val/MapVal.ts +226 -0
- package/lib/val/Nil.ts +94 -0
- package/lib/val/PrefVal.ts +113 -0
- package/lib/val/RefVal.ts +126 -0
- package/lib/val/RefVal.ts~ +319 -0
- package/lib/val/ValBase.ts +76 -0
- package/lib/val.ts +15 -825
- package/package.json +21 -17
- package/lib/common.ts +0 -19
package/lib/val.ts
CHANGED
|
@@ -21,6 +21,15 @@ TOP -> Scalar/Boolean -> BooleanVal
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
import type {
|
|
25
|
+
Val,
|
|
26
|
+
} from './type'
|
|
27
|
+
|
|
28
|
+
import {
|
|
29
|
+
DONE,
|
|
30
|
+
TOP,
|
|
31
|
+
} from './type'
|
|
32
|
+
|
|
24
33
|
import {
|
|
25
34
|
Context,
|
|
26
35
|
} from './unify'
|
|
@@ -31,156 +40,18 @@ import {
|
|
|
31
40
|
} from './lang'
|
|
32
41
|
|
|
33
42
|
|
|
34
|
-
import {
|
|
35
|
-
unite
|
|
36
|
-
} from './op/op'
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
type ValMap = { [key: string]: Val }
|
|
40
|
-
type ValList = Val[]
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const DONE = -1
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// There can be only one.
|
|
47
|
-
const TOP: Val = {
|
|
48
|
-
id: 0,
|
|
49
|
-
top: true,
|
|
50
|
-
peg: undefined,
|
|
51
|
-
done: DONE,
|
|
52
|
-
path: [],
|
|
53
|
-
row: -1,
|
|
54
|
-
col: -1,
|
|
55
|
-
url: '',
|
|
56
|
-
|
|
57
|
-
unify(peer: Val, _ctx: Context): Val {
|
|
58
|
-
return peer
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
get canon() { return 'top' },
|
|
62
|
-
|
|
63
|
-
get site() { return new Site(this) },
|
|
64
|
-
|
|
65
|
-
same(peer: Val): boolean {
|
|
66
|
-
return TOP === peer
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
gen: (_ctx?: Context) => {
|
|
70
|
-
return undefined
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// TODO: extends Val ???
|
|
77
|
-
abstract class Val {
|
|
78
|
-
id: number
|
|
79
|
-
done: number = 0
|
|
80
|
-
path: string[]
|
|
81
|
-
row: number = -1
|
|
82
|
-
col: number = -1
|
|
83
|
-
url: string = ''
|
|
84
|
-
|
|
85
|
-
top?: boolean
|
|
86
|
-
|
|
87
|
-
// Actual native value.
|
|
88
|
-
peg?: any
|
|
89
|
-
|
|
90
|
-
// TODO: used for top level result - not great
|
|
91
|
-
err?: any[]
|
|
92
|
-
deps?: any
|
|
93
|
-
|
|
94
|
-
constructor(peg?: any, ctx?: Context) {
|
|
95
|
-
this.peg = peg
|
|
96
|
-
this.path = (ctx && ctx.path) || []
|
|
97
|
-
this.id = (ctx && ctx.vc++) || (9e9 + Math.floor(Math.random() * (1e9)))
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
same(peer: Val): boolean {
|
|
101
|
-
// return this === peer
|
|
102
|
-
return null == peer ? false : this.id === peer.id
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
get site(): Site {
|
|
106
|
-
return new Site(this)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// TODO: can ctx be optional?
|
|
111
|
-
abstract unify(peer: Val, ctx: Context): Val
|
|
112
|
-
abstract get canon(): string
|
|
113
|
-
abstract gen(ctx?: Context): any
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
class Nil extends Val {
|
|
119
|
-
nil = true
|
|
120
|
-
why: any
|
|
121
|
-
primary?: Val
|
|
122
|
-
secondary?: Val
|
|
123
|
-
|
|
124
|
-
// TODO: include Val generating nil, thus capture type
|
|
125
|
-
static make = (ctx?: Context, why?: any, av?: Val, bv?: Val) => {
|
|
126
|
-
let nil = new Nil(why, ctx)
|
|
127
|
-
|
|
128
|
-
// TODO: this should be done lazily, for multiple terms
|
|
129
|
-
|
|
130
|
-
// Terms later in same file are considered the primary error location.
|
|
131
|
-
if (null != av) {
|
|
132
|
-
nil.row = av.row
|
|
133
|
-
nil.col = av.col
|
|
134
|
-
nil.url = av.url
|
|
135
|
-
|
|
136
|
-
nil.primary = av
|
|
137
43
|
|
|
138
|
-
|
|
139
|
-
nil.secondary = bv
|
|
44
|
+
import { Nil } from './val/Nil'
|
|
140
45
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
(nil.row === bv.row && nil.col < bv.col)
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
if (bv_loc_wins) {
|
|
148
|
-
nil.row = bv.row
|
|
149
|
-
nil.col = bv.col
|
|
150
|
-
nil.url = bv.url
|
|
151
|
-
nil.primary = bv
|
|
152
|
-
nil.secondary = av
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (ctx) {
|
|
158
|
-
ctx.err.push(nil)
|
|
159
|
-
}
|
|
46
|
+
import {
|
|
47
|
+
ValBase,
|
|
48
|
+
} from './val/ValBase'
|
|
160
49
|
|
|
161
|
-
return nil
|
|
162
|
-
}
|
|
163
50
|
|
|
164
|
-
constructor(why?: any, ctx?: Context) {
|
|
165
|
-
super(null, ctx)
|
|
166
|
-
this.why = why
|
|
167
51
|
|
|
168
|
-
// Nil is always DONE, by definition.
|
|
169
|
-
this.done = DONE
|
|
170
|
-
}
|
|
171
52
|
|
|
172
|
-
unify(_peer: Val, _ctx: Context) {
|
|
173
|
-
return this
|
|
174
|
-
}
|
|
175
53
|
|
|
176
|
-
get canon() {
|
|
177
|
-
return 'nil'
|
|
178
|
-
}
|
|
179
54
|
|
|
180
|
-
gen(_ctx?: Context) {
|
|
181
|
-
return undefined
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
55
|
|
|
185
56
|
|
|
186
57
|
// A ScalarType for integers. Number includes floats.
|
|
@@ -195,7 +66,7 @@ type ScalarConstructor =
|
|
|
195
66
|
(typeof Integer.constructor)
|
|
196
67
|
|
|
197
68
|
|
|
198
|
-
class ScalarTypeVal extends
|
|
69
|
+
class ScalarTypeVal extends ValBase {
|
|
199
70
|
constructor(peg: ScalarConstructor, ctx?: Context) {
|
|
200
71
|
super(peg, ctx)
|
|
201
72
|
this.done = DONE
|
|
@@ -240,7 +111,7 @@ class ScalarTypeVal extends Val {
|
|
|
240
111
|
}
|
|
241
112
|
|
|
242
113
|
|
|
243
|
-
class ScalarVal<T> extends
|
|
114
|
+
class ScalarVal<T> extends ValBase {
|
|
244
115
|
type: any
|
|
245
116
|
constructor(peg: T, type: ScalarConstructor, ctx?: Context) {
|
|
246
117
|
super(peg, ctx)
|
|
@@ -336,694 +207,13 @@ class BooleanVal extends ScalarVal<boolean> {
|
|
|
336
207
|
|
|
337
208
|
|
|
338
209
|
|
|
339
|
-
class MapVal extends Val {
|
|
340
|
-
static SPREAD = Symbol('spread')
|
|
341
|
-
|
|
342
|
-
spread = {
|
|
343
|
-
cj: (undefined as Val | undefined),
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
constructor(peg: ValMap, ctx?: Context) {
|
|
347
|
-
super(peg, ctx)
|
|
348
|
-
|
|
349
|
-
let spread = (this.peg as any)[MapVal.SPREAD]
|
|
350
|
-
delete (this.peg as any)[MapVal.SPREAD]
|
|
351
|
-
|
|
352
|
-
if (spread) {
|
|
353
|
-
if ('&' === spread.o) {
|
|
354
|
-
// TODO: handle existing spread!
|
|
355
|
-
this.spread.cj =
|
|
356
|
-
new ConjunctVal(Array.isArray(spread.v) ? spread.v : [spread.v], ctx)
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// NOTE: order of keys is not preserved!
|
|
362
|
-
// not possible in any case - consider {a,b} unify {b,a}
|
|
363
|
-
unify(peer: Val, ctx: Context): Val {
|
|
364
|
-
let done: boolean = true
|
|
365
|
-
let out: MapVal = TOP === peer ? this : new MapVal({}, ctx)
|
|
366
|
-
|
|
367
|
-
out.spread.cj = this.spread.cj
|
|
368
|
-
|
|
369
|
-
if (peer instanceof MapVal) {
|
|
370
|
-
out.spread.cj = null == out.spread.cj ? peer.spread.cj : (
|
|
371
|
-
null == peer.spread.cj ? out.spread.cj : (
|
|
372
|
-
out.spread.cj = new ConjunctVal([out.spread.cj, peer.spread.cj], ctx)
|
|
373
|
-
)
|
|
374
|
-
)
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
out.done = this.done + 1
|
|
379
|
-
|
|
380
|
-
if (this.spread.cj) {
|
|
381
|
-
//out.spread.cj =
|
|
382
|
-
// DONE !== this.spread.cj.done ? this.spread.cj.unify(TOP, ctx) :
|
|
383
|
-
// this.spread.cj
|
|
384
|
-
out.spread.cj =
|
|
385
|
-
DONE !== this.spread.cj.done ? unite(ctx, this.spread.cj) :
|
|
386
|
-
this.spread.cj
|
|
387
|
-
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
// console.log(
|
|
392
|
-
// (' '.repeat(ctx.path.length)),
|
|
393
|
-
// 'MV spread', this.id, peer.id, out.id, '|',
|
|
394
|
-
// this.canon, peer.canon, out.canon, '|',
|
|
395
|
-
// (this.spread.cj || {}).done,
|
|
396
|
-
// (this.spread.cj || {}).canon, (out.spread.cj || {}).canon)
|
|
397
|
-
|
|
398
|
-
let spread_cj = out.spread.cj || TOP
|
|
399
|
-
|
|
400
|
-
// Always unify children first
|
|
401
|
-
for (let key in this.peg) {
|
|
402
|
-
//let oval = out.peg[key] = this.peg[key].unify(spread_cj, ctx.descend(key))
|
|
403
|
-
//let oval =
|
|
404
|
-
|
|
405
|
-
out.peg[key] =
|
|
406
|
-
unite(ctx.descend(key), this.peg[key], spread_cj)
|
|
407
|
-
|
|
408
|
-
done = (done && DONE === out.peg[key].done)
|
|
409
|
-
|
|
410
|
-
//if (oval instanceof Nil) {
|
|
411
|
-
// ctx.err.push(oval)
|
|
412
|
-
//}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// console.log(
|
|
416
|
-
// (' '.repeat(ctx.path.length)),
|
|
417
|
-
// 'MV child ', this.id, peer.id, out.id, '|',
|
|
418
|
-
// this.canon, peer.canon, out.canon, '|',
|
|
419
|
-
// this.constructor.name,
|
|
420
|
-
// peer.constructor.name,
|
|
421
|
-
// out.constructor.name,
|
|
422
|
-
// )
|
|
423
|
-
|
|
424
|
-
if (peer instanceof MapVal) {
|
|
425
|
-
//let upeer: MapVal = (peer.unify(TOP, ctx) as MapVal)
|
|
426
|
-
let upeer: MapVal = (unite(ctx, peer) as MapVal)
|
|
427
|
-
|
|
428
|
-
// console.log(
|
|
429
|
-
// (' '.repeat(ctx.path.length)),
|
|
430
|
-
// 'MV peer A', this.id, peer.id, out.id, '|',
|
|
431
|
-
// Object.keys(this.peg), Object.keys(upeer.peg), Object.keys(out.peg))
|
|
432
|
-
|
|
433
|
-
for (let peerkey in upeer.peg) {
|
|
434
|
-
let peerchild = upeer.peg[peerkey]
|
|
435
|
-
let child = out.peg[peerkey]
|
|
436
|
-
|
|
437
|
-
let oval = out.peg[peerkey] =
|
|
438
|
-
undefined === child ? peerchild :
|
|
439
|
-
child instanceof Nil ? child :
|
|
440
|
-
peerchild instanceof Nil ? peerchild :
|
|
441
|
-
//child.unify(peerchild, ctx.descend(peerkey))
|
|
442
|
-
unite(ctx.descend(peerkey), child, peerchild)
|
|
443
|
-
|
|
444
|
-
if (this.spread.cj) {
|
|
445
|
-
//out.peg[peerkey] = out.peg[peerkey].unify(spread_cj, ctx)
|
|
446
|
-
out.peg[peerkey] = unite(ctx, out.peg[peerkey], spread_cj)
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
done = (done && DONE === oval.done)
|
|
450
|
-
|
|
451
|
-
if (oval instanceof Nil) {
|
|
452
|
-
// ctx.err.push(oval)
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// console.log(
|
|
458
|
-
// (' '.repeat(ctx.path.length)),
|
|
459
|
-
// 'MV peer B', this.id, peer.id, out.id, '|',
|
|
460
|
-
// Object.keys(this.peg), Object.keys(upeer.peg), Object.keys(out.peg))
|
|
461
|
-
|
|
462
|
-
//out.done = done ? DONE : out.done
|
|
463
|
-
|
|
464
|
-
// console.log(' '.repeat(W) + 'MV OUT A', this.id, out.done, out.id, out.canon)//this.spread.cj, out.spread.cj)
|
|
465
|
-
|
|
466
|
-
// console.log(
|
|
467
|
-
// (' '.repeat(ctx.path.length)),
|
|
468
|
-
// 'MV out ', this.id, peer.id, out.id, '|',
|
|
469
|
-
// this.canon, peer.canon, out.canon, '|',
|
|
470
|
-
// this.constructor.name,
|
|
471
|
-
// peer.constructor.name,
|
|
472
|
-
// out.constructor.name,
|
|
473
|
-
// )
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
477
|
-
else if (TOP !== peer) {
|
|
478
|
-
//out.done = done ? DONE : out.done
|
|
479
|
-
|
|
480
|
-
//return (UNIFIER(out, peer, ctx) as MapVal)
|
|
481
|
-
|
|
482
|
-
return Nil.make(ctx, 'map', this, peer)
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
out.done = done ? DONE : out.done
|
|
486
|
-
return out
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
get canon() {
|
|
490
|
-
let keys = Object.keys(this.peg)
|
|
491
|
-
return '{' +
|
|
492
|
-
(this.spread.cj ? '&:' + this.spread.cj.canon +
|
|
493
|
-
(0 < keys.length ? ',' : '') : '') +
|
|
494
|
-
keys
|
|
495
|
-
.map(k => [JSON.stringify(k) + ':' + this.peg[k].canon]).join(',') +
|
|
496
|
-
'}'
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
gen(ctx?: Context) {
|
|
500
|
-
let out: any = {}
|
|
501
|
-
for (let p in this.peg) {
|
|
502
|
-
out[p] = this.peg[p].gen(ctx)
|
|
503
|
-
}
|
|
504
|
-
return out
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
class ListVal extends Val {
|
|
511
|
-
static SPREAD = Symbol('spread')
|
|
512
|
-
|
|
513
|
-
spread = {
|
|
514
|
-
cj: (undefined as Val | undefined),
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
constructor(peg: ValList, ctx?: Context) {
|
|
518
|
-
super(peg, ctx)
|
|
519
|
-
|
|
520
|
-
let spread = (this.peg as any)[ListVal.SPREAD]
|
|
521
|
-
delete (this.peg as any)[ListVal.SPREAD]
|
|
522
|
-
|
|
523
|
-
if (spread) {
|
|
524
|
-
if ('&' === spread.o) {
|
|
525
|
-
// TODO: handle existing spread!
|
|
526
|
-
this.spread.cj =
|
|
527
|
-
new ConjunctVal(Array.isArray(spread.v) ? spread.v : [spread.v], ctx)
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
// NOTE: order of keys is not preserved!
|
|
533
|
-
// not possible in any case - consider {a,b} unify {b,a}
|
|
534
|
-
unify(peer: Val, ctx: Context): Val {
|
|
535
|
-
let done: boolean = true
|
|
536
|
-
let out: ListVal = TOP === peer ? this : new ListVal([], ctx)
|
|
537
|
-
|
|
538
|
-
out.spread.cj = this.spread.cj
|
|
539
|
-
|
|
540
|
-
if (peer instanceof ListVal) {
|
|
541
|
-
out.spread.cj = null == out.spread.cj ? peer.spread.cj : (
|
|
542
|
-
null == peer.spread.cj ? out.spread.cj : (
|
|
543
|
-
out.spread.cj = new ConjunctVal([out.spread.cj, peer.spread.cj], ctx)
|
|
544
|
-
)
|
|
545
|
-
)
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
out.done = this.done + 1
|
|
550
|
-
|
|
551
|
-
if (this.spread.cj) {
|
|
552
|
-
out.spread.cj =
|
|
553
|
-
DONE !== this.spread.cj.done ? unite(ctx, this.spread.cj) :
|
|
554
|
-
this.spread.cj
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
let spread_cj = out.spread.cj || TOP
|
|
558
|
-
|
|
559
|
-
// Always unify children first
|
|
560
|
-
for (let key in this.peg) {
|
|
561
|
-
out.peg[key] =
|
|
562
|
-
unite(ctx.descend(key), this.peg[key], spread_cj)
|
|
563
|
-
|
|
564
|
-
done = (done && DONE === out.peg[key].done)
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
if (peer instanceof ListVal) {
|
|
568
|
-
let upeer: ListVal = (unite(ctx, peer) as ListVal)
|
|
569
|
-
|
|
570
|
-
for (let peerkey in upeer.peg) {
|
|
571
|
-
let peerchild = upeer.peg[peerkey]
|
|
572
|
-
let child = out.peg[peerkey]
|
|
573
|
-
|
|
574
|
-
let oval = out.peg[peerkey] =
|
|
575
|
-
undefined === child ? peerchild :
|
|
576
|
-
child instanceof Nil ? child :
|
|
577
|
-
peerchild instanceof Nil ? peerchild :
|
|
578
|
-
unite(ctx.descend(peerkey), child, peerchild)
|
|
579
|
-
|
|
580
|
-
if (this.spread.cj) {
|
|
581
|
-
out.peg[peerkey] = unite(ctx, out.peg[peerkey], spread_cj)
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
done = (done && DONE === oval.done)
|
|
585
|
-
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
else if (TOP !== peer) {
|
|
589
|
-
return Nil.make(ctx, 'map', this, peer)
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
out.done = done ? DONE : out.done
|
|
593
|
-
return out
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
get canon() {
|
|
597
|
-
let keys = Object.keys(this.peg)
|
|
598
|
-
return '[' +
|
|
599
|
-
(this.spread.cj ? '&:' + this.spread.cj.canon +
|
|
600
|
-
(0 < keys.length ? ',' : '') : '') +
|
|
601
|
-
keys
|
|
602
|
-
// NOTE: handle array non-index key vals
|
|
603
|
-
// .map(k => [JSON.stringify(k) + ':' + this.peg[k].canon]).join(',') +
|
|
604
|
-
.map(k => [this.peg[k].canon]).join(',') +
|
|
605
|
-
']'
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
gen(ctx?: Context) {
|
|
609
|
-
let out: any = this.peg.map((v: Val) => v.gen(ctx))
|
|
610
|
-
// for (let p in this.peg) {
|
|
611
|
-
// out[p] = this.peg[p].gen(ctx)
|
|
612
|
-
// }
|
|
613
|
-
|
|
614
|
-
return out
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
// TODO: move main logic to op/conjunct
|
|
622
|
-
class ConjunctVal extends Val {
|
|
623
|
-
constructor(peg: Val[], ctx?: Context) {
|
|
624
|
-
super(peg, ctx)
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
// NOTE: mutation!
|
|
628
|
-
append(peer: Val): ConjunctVal {
|
|
629
|
-
this.peg.push(peer)
|
|
630
|
-
return this
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
unify(peer: Val, ctx: Context): Val {
|
|
634
|
-
let done = true
|
|
635
|
-
|
|
636
|
-
// Unify each term of conjunct against peer
|
|
637
|
-
let upeer: Val[] = []
|
|
638
|
-
|
|
639
|
-
for (let vI = 0; vI < this.peg.length; vI++) {
|
|
640
|
-
// upeer[vI] = this.peg[vI].unify(peer, ctx)
|
|
641
|
-
upeer[vI] = unite(ctx, this.peg[vI], peer)
|
|
642
|
-
done = done && DONE === upeer[vI].done
|
|
643
|
-
// // console.log('Ca', vI, this.peg[vI].canon, peer.canon, upeer[vI].canon)
|
|
644
|
-
|
|
645
|
-
if (upeer[vI] instanceof Nil) {
|
|
646
|
-
return Nil.make(
|
|
647
|
-
ctx,
|
|
648
|
-
'&peer[' + upeer[vI].canon + ',' + peer.canon + ']',
|
|
649
|
-
this.peg[vI],
|
|
650
|
-
peer
|
|
651
|
-
)
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
// // console.log('Cb', upeer.map(x => x.canon))
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
// TODO: FIX: conjuncts get replicated inside each other
|
|
659
|
-
// 1&/x => CV[CV[1&/x]]
|
|
660
|
-
|
|
661
|
-
// Unify each term of conjunct against following sibling,
|
|
662
|
-
// reducing to smallest conjunct or single val
|
|
663
|
-
let outvals: Val[] = 0 < upeer.length ? [upeer[0]] : []
|
|
664
|
-
|
|
665
|
-
let oI = 0
|
|
666
|
-
for (let uI = 1; uI < upeer.length; uI++) {
|
|
667
|
-
// // console.log('Cu', oI, uI, outvals.map(x => x.canon))
|
|
668
|
-
|
|
669
|
-
if (outvals[oI] instanceof ConjunctVal) {
|
|
670
|
-
outvals.splice(oI, 0, ...outvals[oI].peg)
|
|
671
|
-
oI += outvals[oI].peg.length
|
|
672
|
-
done = false
|
|
673
|
-
}
|
|
674
|
-
else {
|
|
675
|
-
outvals[oI] = null == outvals[oI] ? upeer[uI] :
|
|
676
|
-
//outvals[oI].unify(upeer[uI], ctx)
|
|
677
|
-
unite(ctx, outvals[oI], upeer[uI])
|
|
678
|
-
done = done && DONE === outvals[oI].done
|
|
679
|
-
|
|
680
|
-
// Conjuct fails
|
|
681
|
-
if (outvals[oI] instanceof Nil) {
|
|
682
|
-
return outvals[oI]
|
|
683
|
-
|
|
684
|
-
/*
|
|
685
|
-
return Nil.make(
|
|
686
|
-
ctx,
|
|
687
|
-
'&reduce[' + outvals[oI].canon + ',' + upeer[uI].canon + ']',
|
|
688
|
-
outvals[oI],
|
|
689
|
-
upeer[uI]
|
|
690
|
-
)
|
|
691
|
-
*/
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
// // console.log('Cc', outvals.map(x => x.canon), outvals)
|
|
697
|
-
|
|
698
|
-
let out: Val
|
|
699
|
-
|
|
700
|
-
//let why = ''
|
|
701
|
-
|
|
702
|
-
if (0 === outvals.length) {
|
|
703
|
-
//out = Nil.make(ctx, '&empty', this)
|
|
704
|
-
|
|
705
|
-
// Empty conjuncts evaporate.
|
|
706
|
-
out = TOP
|
|
707
|
-
//why += 'A'
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
// TODO: corrects CV[CV[1&/x]] issue above, but swaps term order!
|
|
711
|
-
else if (1 === outvals.length) {
|
|
712
|
-
out = outvals[0]
|
|
713
|
-
//why += 'B'
|
|
714
|
-
}
|
|
715
|
-
else {
|
|
716
|
-
out = new ConjunctVal(outvals, ctx)
|
|
717
|
-
//why += 'C'
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
// // console.log('Cd', why, out.peg)
|
|
721
|
-
|
|
722
|
-
out.done = done ? DONE : this.done + 1
|
|
723
|
-
|
|
724
|
-
return out
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// TODO: need a well-defined val order so conjunt canon is always the same
|
|
728
|
-
get canon() {
|
|
729
|
-
return this.peg.map((v: Val) => v.canon).join('&')
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
gen(ctx?: Context) {
|
|
733
|
-
if (0 < this.peg.length) {
|
|
734
|
-
|
|
735
|
-
// Default is just the first term - does this work?
|
|
736
|
-
// TODO: maybe use a PrefVal() ?
|
|
737
|
-
let v: Val = this.peg[0]
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
let out = undefined
|
|
741
|
-
if (undefined !== v && !(v instanceof Nil)) {
|
|
742
|
-
out = v.gen(ctx)
|
|
743
|
-
}
|
|
744
|
-
return out
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
return undefined
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
// TODO: move main logic to op/disjunct
|
|
754
|
-
class DisjunctVal extends Val {
|
|
755
|
-
// TODO: sites from normalization of orginal Disjuncts, as well as child pegs
|
|
756
|
-
constructor(peg: Val[], ctx?: Context, _sites?: Site[]) {
|
|
757
|
-
super(peg, ctx)
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
// NOTE: mutation!
|
|
761
|
-
append(peer: Val): DisjunctVal {
|
|
762
|
-
this.peg.push(peer)
|
|
763
|
-
return this
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
unify(peer: Val, ctx: Context): Val {
|
|
767
|
-
let done = true
|
|
768
|
-
|
|
769
|
-
let oval: Val[] = []
|
|
770
|
-
|
|
771
|
-
// console.log('oval', this.canon, peer.canon)
|
|
772
|
-
|
|
773
|
-
// Conjunction (&) distributes over disjunction (|)
|
|
774
|
-
for (let vI = 0; vI < this.peg.length; vI++) {
|
|
775
|
-
//oval[vI] = this.peg[vI].unify(peer, ctx)
|
|
776
|
-
oval[vI] = unite(ctx, this.peg[vI], peer)
|
|
777
|
-
// console.log('ovalA', vI, this.peg[vI].canon, peer.canon, oval[vI].canon)
|
|
778
|
-
|
|
779
|
-
done = done && DONE === oval[vI].done
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
// console.log('ovalB', oval.map(v => v.canon))
|
|
783
|
-
|
|
784
|
-
// Remove duplicates, and normalize
|
|
785
|
-
if (1 < oval.length) {
|
|
786
|
-
for (let vI = 0; vI < oval.length; vI++) {
|
|
787
|
-
if (oval[vI] instanceof DisjunctVal) {
|
|
788
|
-
oval.splice(vI, 1, ...oval[vI].peg)
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
//console.log('ovalC', oval.map(v => v.canon))
|
|
793
|
-
|
|
794
|
-
// TODO: not an error Nil!
|
|
795
|
-
let remove = new Nil()
|
|
796
|
-
for (let vI = 0; vI < oval.length; vI++) {
|
|
797
|
-
for (let kI = vI + 1; kI < oval.length; kI++) {
|
|
798
|
-
if (oval[kI].same(oval[vI])) {
|
|
799
|
-
oval[kI] = remove
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
//console.log('ovalD', oval.map(v => v.canon))
|
|
805
|
-
|
|
806
|
-
oval = oval.filter(v => !(v instanceof Nil))
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
let out: Val
|
|
810
|
-
|
|
811
|
-
if (1 == oval.length) {
|
|
812
|
-
out = oval[0]
|
|
813
|
-
}
|
|
814
|
-
else if (0 == oval.length) {
|
|
815
|
-
return Nil.make(ctx, '|:empty', this)
|
|
816
|
-
}
|
|
817
|
-
else {
|
|
818
|
-
out = new DisjunctVal(oval, ctx)
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
out.done = done ? DONE : this.done + 1
|
|
822
|
-
|
|
823
|
-
return out
|
|
824
|
-
}
|
|
825
|
-
get canon() {
|
|
826
|
-
return this.peg.map((v: Val) => v.canon).join('|')
|
|
827
|
-
}
|
|
828
|
-
gen(ctx?: Context) {
|
|
829
|
-
if (0 < this.peg.length) {
|
|
830
|
-
|
|
831
|
-
let vals = this.peg.filter((v: Val) => v instanceof PrefVal)
|
|
832
|
-
|
|
833
|
-
vals = 0 === vals.length ? this.peg : vals
|
|
834
|
-
|
|
835
|
-
let val = vals[0]
|
|
836
|
-
|
|
837
|
-
for (let vI = 1; vI < this.peg.length; vI++) {
|
|
838
|
-
val = val.unify(this.peg[vI])
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
return val.gen(ctx)
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
return undefined
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
class RefVal extends Val {
|
|
851
|
-
parts: string[]
|
|
852
|
-
absolute: boolean
|
|
853
|
-
sep = '.'
|
|
854
|
-
|
|
855
|
-
constructor(peg: any[], abs?: boolean) {
|
|
856
|
-
super('')
|
|
857
|
-
this.absolute = true === abs
|
|
858
|
-
this.parts = []
|
|
859
|
-
|
|
860
|
-
for (let part of peg) {
|
|
861
|
-
this.append(part)
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
append(part: any) {
|
|
867
|
-
//console.log('APPEND 0', part)
|
|
868
|
-
|
|
869
|
-
if ('string' === typeof part) {
|
|
870
|
-
this.parts.push(part)
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
else if (part instanceof StringVal) {
|
|
874
|
-
this.parts.push(part.peg)
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
else if (part instanceof RefVal) {
|
|
878
|
-
this.parts.push(...part.parts)
|
|
879
|
-
|
|
880
|
-
if (part.absolute) {
|
|
881
|
-
this.absolute = true
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
this.peg = (this.absolute ? this.sep : '') + this.parts.join(this.sep)
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
unify(peer: Val, ctx: Context): Val {
|
|
889
|
-
let resolved: Val | undefined = null == ctx ? this : ctx.find(this)
|
|
890
|
-
|
|
891
|
-
// TODO: large amount of reruns needed? why?
|
|
892
|
-
resolved = null == resolved && 999 < this.done ?
|
|
893
|
-
Nil.make(ctx, 'no-path', this, peer) : (resolved || this)
|
|
894
|
-
let out: Val
|
|
895
|
-
|
|
896
|
-
if (resolved instanceof RefVal) {
|
|
897
|
-
if (TOP === peer) {
|
|
898
|
-
out = this
|
|
899
|
-
}
|
|
900
|
-
else if (peer instanceof Nil) {
|
|
901
|
-
out = Nil.make(ctx, 'ref[' + this.peg + ']', this, peer)
|
|
902
|
-
}
|
|
903
|
-
else {
|
|
904
|
-
// Ensure RefVal done is incremented
|
|
905
|
-
this.done = DONE === this.done ? DONE : this.done + 1
|
|
906
|
-
out = new ConjunctVal([this, peer], ctx)
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
else {
|
|
910
|
-
out = unite(ctx, resolved, peer)
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
out.done = DONE === out.done ? DONE : this.done + 1
|
|
914
|
-
|
|
915
|
-
return out
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
same(peer: Val): boolean {
|
|
920
|
-
return null == peer ? false : this.peg === peer.peg
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
get canon() {
|
|
925
|
-
return this.peg
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
gen(_ctx?: Context) {
|
|
930
|
-
return undefined
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
class PrefVal extends Val {
|
|
936
|
-
pref: Val
|
|
937
|
-
constructor(peg: any, pref?: any, ctx?: Context) {
|
|
938
|
-
super(peg, ctx)
|
|
939
|
-
this.pref = pref || peg
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
// PrefVal unify always returns a PrefVal
|
|
943
|
-
// PrefVals can only be removed by becoming Nil in a Disjunct
|
|
944
|
-
unify(peer: Val, ctx: Context): Val {
|
|
945
|
-
let done = true
|
|
946
|
-
let out: Val
|
|
947
|
-
|
|
948
|
-
if (peer instanceof PrefVal) {
|
|
949
|
-
out = new PrefVal(
|
|
950
|
-
unite(ctx, this.peg, peer.peg, 'Pref000'),
|
|
951
|
-
unite(ctx, this.pref, peer.pref, 'Pref010'),
|
|
952
|
-
ctx
|
|
953
|
-
)
|
|
954
|
-
|
|
955
|
-
}
|
|
956
|
-
else {
|
|
957
|
-
out = new PrefVal(
|
|
958
|
-
// TODO: find a better way to drop Nil non-errors
|
|
959
|
-
unite(ctx?.clone({ err: [] }), this.peg, peer, 'Pref020'),
|
|
960
|
-
unite(ctx?.clone({ err: [] }), this.pref, peer, 'Pref030'),
|
|
961
|
-
ctx
|
|
962
|
-
)
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
done = done && DONE === out.peg.done &&
|
|
966
|
-
(null != (out as PrefVal).pref ? DONE === (out as PrefVal).pref.done : true)
|
|
967
|
-
|
|
968
|
-
if (out.peg instanceof Nil) {
|
|
969
|
-
out = (out as PrefVal).pref
|
|
970
|
-
}
|
|
971
|
-
else if ((out as PrefVal).pref instanceof Nil) {
|
|
972
|
-
out = out.peg
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
out.done = done ? DONE : this.done + 1
|
|
976
|
-
|
|
977
|
-
return out
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
same(peer: Val): boolean {
|
|
982
|
-
if (null == peer) {
|
|
983
|
-
return false
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
let pegsame = (this.peg === peer.peg) ||
|
|
987
|
-
(this.peg instanceof Val && this.peg.same(peer.peg))
|
|
988
|
-
|
|
989
|
-
let prefsame = peer instanceof PrefVal &&
|
|
990
|
-
((this.pref === peer.pref) ||
|
|
991
|
-
(this.pref instanceof Val && this.pref.same(peer.pref)))
|
|
992
|
-
|
|
993
|
-
return pegsame && prefsame
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
get canon() {
|
|
998
|
-
return this.pref instanceof Nil ? this.peg.canon : '*' + this.pref.canon
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
gen(ctx?: Context) {
|
|
1002
|
-
let val = !(this.pref instanceof Nil) ? this.pref :
|
|
1003
|
-
!(this.peg instanceof Nil) ? this.peg :
|
|
1004
|
-
undefined
|
|
1005
|
-
|
|
1006
|
-
return undefined === val ? undefined : val.gen(ctx)
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
210
|
|
|
1011
211
|
|
|
1012
212
|
export {
|
|
1013
|
-
DONE,
|
|
1014
213
|
Integer,
|
|
1015
|
-
Val,
|
|
1016
|
-
TOP,
|
|
1017
|
-
Nil,
|
|
1018
214
|
ScalarTypeVal,
|
|
1019
215
|
NumberVal,
|
|
1020
216
|
StringVal,
|
|
1021
217
|
BooleanVal,
|
|
1022
218
|
IntegerVal,
|
|
1023
|
-
MapVal,
|
|
1024
|
-
ListVal,
|
|
1025
|
-
ConjunctVal,
|
|
1026
|
-
DisjunctVal,
|
|
1027
|
-
RefVal,
|
|
1028
|
-
PrefVal,
|
|
1029
219
|
}
|