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