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.
Files changed (65) hide show
  1. package/aontu.ts +3 -2
  2. package/dist/aontu.d.ts +2 -2
  3. package/dist/aontu.js +3 -4
  4. package/dist/aontu.js.map +1 -1
  5. package/dist/aontu.min.js +1 -63
  6. package/dist/lib/lang.d.ts +1 -3
  7. package/dist/lib/lang.js +33 -24
  8. package/dist/lib/lang.js.map +1 -1
  9. package/dist/lib/op/disjunct.js +10 -10
  10. package/dist/lib/op/disjunct.js.map +1 -1
  11. package/dist/lib/op/op.d.ts +1 -1
  12. package/dist/lib/op/op.js.map +1 -1
  13. package/dist/lib/op/unite.js +19 -14
  14. package/dist/lib/op/unite.js.map +1 -1
  15. package/dist/lib/type.d.ts +33 -22
  16. package/dist/lib/type.js +22 -76
  17. package/dist/lib/type.js.map +1 -1
  18. package/dist/lib/unify.d.ts +4 -1
  19. package/dist/lib/unify.js +7 -5
  20. package/dist/lib/unify.js.map +1 -1
  21. package/dist/lib/val/ConjunctVal.d.ts +12 -0
  22. package/dist/lib/val/ConjunctVal.js +191 -0
  23. package/dist/lib/val/ConjunctVal.js.map +1 -0
  24. package/dist/lib/val/DisjunctVal.d.ts +12 -0
  25. package/dist/lib/val/DisjunctVal.js +85 -0
  26. package/dist/lib/val/DisjunctVal.js.map +1 -0
  27. package/dist/lib/val/ListVal.d.ts +14 -0
  28. package/dist/lib/val/ListVal.js +91 -0
  29. package/dist/lib/val/ListVal.js.map +1 -0
  30. package/dist/lib/val/MapVal.d.ts +14 -0
  31. package/dist/lib/val/MapVal.js +141 -0
  32. package/dist/lib/val/MapVal.js.map +1 -0
  33. package/dist/lib/val/Nil.d.ts +15 -0
  34. package/dist/lib/val/Nil.js +54 -0
  35. package/dist/lib/val/Nil.js.map +1 -0
  36. package/dist/lib/val/PrefVal.d.ts +12 -0
  37. package/dist/lib/val/PrefVal.js +60 -0
  38. package/dist/lib/val/PrefVal.js.map +1 -0
  39. package/dist/lib/val/RefVal.d.ts +15 -0
  40. package/dist/lib/val/RefVal.js +73 -0
  41. package/dist/lib/val/RefVal.js.map +1 -0
  42. package/dist/lib/val/ValBase.d.ts +22 -0
  43. package/dist/lib/val/ValBase.js +25 -0
  44. package/dist/lib/val/ValBase.js.map +1 -0
  45. package/dist/lib/val.d.ts +5 -92
  46. package/dist/lib/val.js +13 -609
  47. package/dist/lib/val.js.map +1 -1
  48. package/lib/lang.ts +55 -48
  49. package/lib/op/disjunct.ts +14 -8
  50. package/lib/op/op.ts +2 -1
  51. package/lib/op/unite.ts +14 -12
  52. package/lib/type.ts +104 -0
  53. package/lib/unify.ts +10 -8
  54. package/lib/val/ConjunctVal.ts +284 -0
  55. package/lib/val/DisjunctVal.ts +145 -0
  56. package/lib/val/ListVal.ts +154 -0
  57. package/lib/val/MapVal.ts +226 -0
  58. package/lib/val/Nil.ts +94 -0
  59. package/lib/val/PrefVal.ts +113 -0
  60. package/lib/val/RefVal.ts +126 -0
  61. package/lib/val/RefVal.ts~ +319 -0
  62. package/lib/val/ValBase.ts +76 -0
  63. package/lib/val.ts +15 -825
  64. package/package.json +21 -17
  65. 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
- if (null != bv) {
139
- nil.secondary = bv
44
+ import { Nil } from './val/Nil'
140
45
 
141
- let bv_loc_wins =
142
- (nil.url === bv.url) && (
143
- (nil.row < bv.row) ||
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 Val {
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 Val {
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
  }