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.
- 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 +47 -30
- 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 -90
- package/dist/lib/val.js +13 -593
- package/dist/lib/val.js.map +1 -1
- package/lib/lang.ts +77 -59
- 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 -802
- package/package.json +27 -23
- package/lib/common.ts +0 -19
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/* Copyright (c) 2021-2022 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Val,
|
|
6
|
+
ValMap,
|
|
7
|
+
ValList,
|
|
8
|
+
} from '../type'
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
DONE,
|
|
12
|
+
TOP,
|
|
13
|
+
} from '../type'
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
ValBase,
|
|
17
|
+
} from '../val/ValBase'
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
Nil,
|
|
21
|
+
} from '../val/Nil'
|
|
22
|
+
|
|
23
|
+
// import { RefVal } from '../val/RefVal'
|
|
24
|
+
import { MapVal } from '../val/MapVal'
|
|
25
|
+
|
|
26
|
+
import {
|
|
27
|
+
Context,
|
|
28
|
+
} from '../unify'
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
import {
|
|
32
|
+
Site
|
|
33
|
+
} from '../lang'
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
import {
|
|
37
|
+
unite
|
|
38
|
+
} from '../op/op'
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
// TODO: move main logic to op/conjunct
|
|
44
|
+
class ConjunctVal extends ValBase {
|
|
45
|
+
constructor(peg: Val[], ctx?: Context) {
|
|
46
|
+
super(peg, ctx)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// NOTE: mutation!
|
|
50
|
+
append(peer: Val): ConjunctVal {
|
|
51
|
+
this.peg.push(peer)
|
|
52
|
+
return this
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
unify(peer: Val, ctx: Context): Val {
|
|
56
|
+
let done = true
|
|
57
|
+
|
|
58
|
+
// Unify each term of conjunct against peer
|
|
59
|
+
let upeer: Val[] = []
|
|
60
|
+
|
|
61
|
+
for (let vI = 0; vI < this.peg.length; vI++) {
|
|
62
|
+
// upeer[vI] = this.peg[vI].unify(peer, ctx)
|
|
63
|
+
upeer[vI] = unite(ctx, this.peg[vI], peer)
|
|
64
|
+
done = done && DONE === upeer[vI].done
|
|
65
|
+
// // console.log('Ca', vI, this.peg[vI].canon, peer.canon, upeer[vI].canon)
|
|
66
|
+
|
|
67
|
+
if (upeer[vI] instanceof Nil) {
|
|
68
|
+
return Nil.make(
|
|
69
|
+
ctx,
|
|
70
|
+
'&peer[' + upeer[vI].canon + ',' + peer.canon + ']',
|
|
71
|
+
this.peg[vI],
|
|
72
|
+
peer
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// // console.log('Cb', upeer.map(x => x.canon))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
upeer = norm(upeer)
|
|
81
|
+
|
|
82
|
+
// console.log('CJ AA', upeer.map(x => x.canon))
|
|
83
|
+
|
|
84
|
+
let outvals: Val[] = []
|
|
85
|
+
let val: Val
|
|
86
|
+
|
|
87
|
+
next_term:
|
|
88
|
+
for (let pI = 0; pI < upeer.length; pI++) {
|
|
89
|
+
let t0 = upeer[pI]
|
|
90
|
+
|
|
91
|
+
// console.log('CJ unify QQ', mark, uc, 't0', pI, t0.canon)
|
|
92
|
+
|
|
93
|
+
if (DONE !== t0.done) {
|
|
94
|
+
let u0 = unite(ctx, t0, TOP)
|
|
95
|
+
|
|
96
|
+
if (
|
|
97
|
+
DONE !== u0.done
|
|
98
|
+
|
|
99
|
+
// Maps and Lists are still unified so that path refs will work
|
|
100
|
+
&& !(u0 instanceof MapVal) // TODO: || ListVal - test!
|
|
101
|
+
) {
|
|
102
|
+
outvals.push(u0)
|
|
103
|
+
continue next_term
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
t0 = u0
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
let t1 = upeer[pI + 1]
|
|
112
|
+
|
|
113
|
+
// console.log('CJ unify WW', mark, uc, 't1', pI + 1, t1?.canon)
|
|
114
|
+
|
|
115
|
+
// if (
|
|
116
|
+
// null == t1 ||
|
|
117
|
+
// t0.id === t1.id ||
|
|
118
|
+
// t0 instanceof RefVal
|
|
119
|
+
// ) {
|
|
120
|
+
// if (DONE !== t0.done) {
|
|
121
|
+
// let u0 = unite(ctx, t0, TOP)
|
|
122
|
+
// // console.log('CJ unify EE', mark, uc, 't0', t0.canon, 'u0', u0.canon)
|
|
123
|
+
// outvals.push(u0)
|
|
124
|
+
// }
|
|
125
|
+
// else {
|
|
126
|
+
// outvals.push(t0)
|
|
127
|
+
// }
|
|
128
|
+
// pI++
|
|
129
|
+
// }
|
|
130
|
+
|
|
131
|
+
// else if (DONE !== t0.done || DONE != t1.done) {
|
|
132
|
+
// if (DONE !== t0.done) {
|
|
133
|
+
// let u0 = unite(ctx, t0, TOP)
|
|
134
|
+
// // console.log('CJ unify FF', mark, uc, 't0', t0.canon, 'u0', u0.canon)
|
|
135
|
+
// outvals.push(u0)
|
|
136
|
+
// }
|
|
137
|
+
// else {
|
|
138
|
+
// outvals.push(t0)
|
|
139
|
+
// }
|
|
140
|
+
// }
|
|
141
|
+
|
|
142
|
+
if (null == t1) {
|
|
143
|
+
outvals.push(t0)
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// console.log('CJS unify0', t0?.canon, t1?.canon)
|
|
147
|
+
val = unite(ctx, t0, t1)
|
|
148
|
+
done = done && DONE === val.done
|
|
149
|
+
|
|
150
|
+
if (val instanceof ConjunctVal) {
|
|
151
|
+
if (t0.id === val.peg[0].id) {
|
|
152
|
+
val = t0
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else if (val instanceof Nil) {
|
|
156
|
+
return val
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// TODO: t0 should become this to avoid unnecessary repasses
|
|
160
|
+
outvals.push(val)
|
|
161
|
+
|
|
162
|
+
pI++
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
// console.log('CJ BB', outvals.map(x => x.canon))
|
|
168
|
+
|
|
169
|
+
// // TODO: FIX: conjuncts get replicated inside each other
|
|
170
|
+
// // 1&/x => CV[CV[1&/x]]
|
|
171
|
+
|
|
172
|
+
// // Unify each term of conjunct against following sibling,
|
|
173
|
+
// // reducing to smallest conjunct or single val
|
|
174
|
+
// let outvals: Val[] = 0 < upeer.length ? [upeer[0]] : []
|
|
175
|
+
|
|
176
|
+
// let oI = 0
|
|
177
|
+
// for (let uI = 1; uI < upeer.length; uI++) {
|
|
178
|
+
// // // console.log('Cu', oI, uI, outvals.map(x => x.canon))
|
|
179
|
+
|
|
180
|
+
// if (outvals[oI] instanceof ConjunctVal) {
|
|
181
|
+
// outvals.splice(oI, 0, ...outvals[oI].peg)
|
|
182
|
+
// oI += outvals[oI].peg.length
|
|
183
|
+
// done = false
|
|
184
|
+
// }
|
|
185
|
+
// else {
|
|
186
|
+
// outvals[oI] = null == outvals[oI] ? upeer[uI] :
|
|
187
|
+
// //outvals[oI].unify(upeer[uI], ctx)
|
|
188
|
+
// unite(ctx, outvals[oI], upeer[uI])
|
|
189
|
+
// done = done && DONE === outvals[oI].done
|
|
190
|
+
|
|
191
|
+
// // Conjuct fails
|
|
192
|
+
// if (outvals[oI] instanceof Nil) {
|
|
193
|
+
// return outvals[oI]
|
|
194
|
+
|
|
195
|
+
// /*
|
|
196
|
+
// return Nil.make(
|
|
197
|
+
// ctx,
|
|
198
|
+
// '&reduce[' + outvals[oI].canon + ',' + upeer[uI].canon + ']',
|
|
199
|
+
// outvals[oI],
|
|
200
|
+
// upeer[uI]
|
|
201
|
+
// )
|
|
202
|
+
// */
|
|
203
|
+
// }
|
|
204
|
+
// }
|
|
205
|
+
// }
|
|
206
|
+
|
|
207
|
+
// // console.log('Cc', outvals.map(x => x.canon), outvals)
|
|
208
|
+
|
|
209
|
+
let out: Val
|
|
210
|
+
|
|
211
|
+
//let why = ''
|
|
212
|
+
|
|
213
|
+
if (0 === outvals.length) {
|
|
214
|
+
//out = Nil.make(ctx, '&empty', this)
|
|
215
|
+
|
|
216
|
+
// Empty conjuncts evaporate.
|
|
217
|
+
out = TOP
|
|
218
|
+
//why += 'A'
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// TODO: corrects CV[CV[1&/x]] issue above, but swaps term order!
|
|
222
|
+
else if (1 === outvals.length) {
|
|
223
|
+
out = outvals[0]
|
|
224
|
+
//why += 'B'
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
out = new ConjunctVal(outvals, ctx)
|
|
228
|
+
//why += 'C'
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// // console.log('Cd', why, out.peg)
|
|
232
|
+
|
|
233
|
+
out.done = done ? DONE : this.done + 1
|
|
234
|
+
|
|
235
|
+
return out
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// TODO: need a well-defined val order so conjunt canon is always the same
|
|
239
|
+
get canon() {
|
|
240
|
+
return this.peg.map((v: Val) => v.canon).join('&')
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
gen(ctx?: Context) {
|
|
244
|
+
if (0 < this.peg.length) {
|
|
245
|
+
|
|
246
|
+
// Default is just the first term - does this work?
|
|
247
|
+
// TODO: maybe use a PrefVal() ?
|
|
248
|
+
let v: Val = this.peg[0]
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
let out = undefined
|
|
252
|
+
if (undefined !== v && !(v instanceof Nil)) {
|
|
253
|
+
out = v.gen(ctx)
|
|
254
|
+
}
|
|
255
|
+
return out
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return undefined
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
function norm(terms: Val[]): Val[] {
|
|
264
|
+
// console.log('CJ norm', terms.map((t: Val) => t.canon))
|
|
265
|
+
|
|
266
|
+
let expand: Val[] = []
|
|
267
|
+
for (let tI = 0, pI = 0; tI < terms.length; tI++, pI++) {
|
|
268
|
+
if (terms[tI] instanceof ConjunctVal) {
|
|
269
|
+
expand.push(...terms[tI].peg)
|
|
270
|
+
pI += terms[tI].peg.length - 1
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
expand[pI] = terms[tI]
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return expand
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
export {
|
|
282
|
+
norm,
|
|
283
|
+
ConjunctVal,
|
|
284
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/* Copyright (c) 2021-2022 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Val,
|
|
6
|
+
} from '../type'
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
DONE,
|
|
10
|
+
} from '../type'
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
Context,
|
|
14
|
+
} from '../unify'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
Site
|
|
19
|
+
} from '../lang'
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
unite
|
|
24
|
+
} from '../op/op'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
import {
|
|
28
|
+
ValBase,
|
|
29
|
+
} from '../val/ValBase'
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
import { Nil } from './Nil'
|
|
33
|
+
import { PrefVal } from './PrefVal'
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
// TODO: move main logic to op/disjunct
|
|
41
|
+
class DisjunctVal extends ValBase {
|
|
42
|
+
// TODO: sites from normalization of orginal Disjuncts, as well as child pegs
|
|
43
|
+
constructor(peg: Val[], ctx?: Context, _sites?: Site[]) {
|
|
44
|
+
super(peg, ctx)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// NOTE: mutation!
|
|
48
|
+
append(peer: Val): DisjunctVal {
|
|
49
|
+
this.peg.push(peer)
|
|
50
|
+
return this
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
unify(peer: Val, ctx: Context): Val {
|
|
54
|
+
let done = true
|
|
55
|
+
|
|
56
|
+
let oval: Val[] = []
|
|
57
|
+
|
|
58
|
+
// console.log('oval', this.canon, peer.canon)
|
|
59
|
+
|
|
60
|
+
// Conjunction (&) distributes over disjunction (|)
|
|
61
|
+
for (let vI = 0; vI < this.peg.length; vI++) {
|
|
62
|
+
//oval[vI] = this.peg[vI].unify(peer, ctx)
|
|
63
|
+
oval[vI] = unite(ctx, this.peg[vI], peer)
|
|
64
|
+
// console.log('ovalA', vI, this.peg[vI].canon, peer.canon, oval[vI].canon)
|
|
65
|
+
|
|
66
|
+
done = done && DONE === oval[vI].done
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// console.log('ovalB', oval.map(v => v.canon))
|
|
70
|
+
|
|
71
|
+
// Remove duplicates, and normalize
|
|
72
|
+
if (1 < oval.length) {
|
|
73
|
+
for (let vI = 0; vI < oval.length; vI++) {
|
|
74
|
+
if (oval[vI] instanceof DisjunctVal) {
|
|
75
|
+
oval.splice(vI, 1, ...oval[vI].peg)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//console.log('ovalC', oval.map(v => v.canon))
|
|
80
|
+
|
|
81
|
+
// TODO: not an error Nil!
|
|
82
|
+
let remove = new Nil()
|
|
83
|
+
for (let vI = 0; vI < oval.length; vI++) {
|
|
84
|
+
for (let kI = vI + 1; kI < oval.length; kI++) {
|
|
85
|
+
if (oval[kI].same(oval[vI])) {
|
|
86
|
+
oval[kI] = remove
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//console.log('ovalD', oval.map(v => v.canon))
|
|
92
|
+
|
|
93
|
+
oval = oval.filter(v => !(v instanceof Nil))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let out: Val
|
|
97
|
+
|
|
98
|
+
if (1 == oval.length) {
|
|
99
|
+
out = oval[0]
|
|
100
|
+
}
|
|
101
|
+
else if (0 == oval.length) {
|
|
102
|
+
return Nil.make(ctx, '|:empty', this)
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
out = new DisjunctVal(oval, ctx)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
out.done = done ? DONE : this.done + 1
|
|
109
|
+
|
|
110
|
+
return out
|
|
111
|
+
}
|
|
112
|
+
get canon() {
|
|
113
|
+
return this.peg.map((v: Val) => v.canon).join('|')
|
|
114
|
+
}
|
|
115
|
+
gen(ctx?: Context) {
|
|
116
|
+
|
|
117
|
+
// TODO: this is not right - unresolved Disjuncts eval to undef
|
|
118
|
+
if (0 < this.peg.length) {
|
|
119
|
+
|
|
120
|
+
let vals = this.peg.filter((v: Val) => v instanceof PrefVal)
|
|
121
|
+
|
|
122
|
+
vals = 0 === vals.length ? this.peg : vals
|
|
123
|
+
|
|
124
|
+
// console.log(vals.map((m: any) => m.canon))
|
|
125
|
+
|
|
126
|
+
let val = vals[0]
|
|
127
|
+
|
|
128
|
+
for (let vI = 1; vI < this.peg.length; vI++) {
|
|
129
|
+
val = val.unify(this.peg[vI], ctx)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return val.gen(ctx)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return undefined
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
export {
|
|
144
|
+
DisjunctVal,
|
|
145
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* Copyright (c) 2021-2022 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Val,
|
|
6
|
+
ValMap,
|
|
7
|
+
ValList,
|
|
8
|
+
} from '../type'
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
DONE,
|
|
12
|
+
TOP,
|
|
13
|
+
} from '../type'
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
Context,
|
|
17
|
+
} from '../unify'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
Site
|
|
22
|
+
} from '../lang'
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
unite
|
|
27
|
+
} from '../op/op'
|
|
28
|
+
|
|
29
|
+
import { Nil } from '../val/Nil'
|
|
30
|
+
|
|
31
|
+
import {
|
|
32
|
+
ValBase,
|
|
33
|
+
} from '../val/ValBase'
|
|
34
|
+
|
|
35
|
+
import { ConjunctVal } from '../val/ConjunctVal'
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ListVal extends ValBase {
|
|
42
|
+
static SPREAD = Symbol('spread')
|
|
43
|
+
|
|
44
|
+
spread = {
|
|
45
|
+
cj: (undefined as Val | undefined),
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
constructor(peg: ValList, ctx?: Context) {
|
|
49
|
+
super(peg, ctx)
|
|
50
|
+
|
|
51
|
+
let spread = (this.peg as any)[ListVal.SPREAD]
|
|
52
|
+
delete (this.peg as any)[ListVal.SPREAD]
|
|
53
|
+
|
|
54
|
+
if (spread) {
|
|
55
|
+
if ('&' === spread.o) {
|
|
56
|
+
// TODO: handle existing spread!
|
|
57
|
+
this.spread.cj =
|
|
58
|
+
new ConjunctVal(Array.isArray(spread.v) ? spread.v : [spread.v], ctx)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// NOTE: order of keys is not preserved!
|
|
64
|
+
// not possible in any case - consider {a,b} unify {b,a}
|
|
65
|
+
unify(peer: Val, ctx: Context): Val {
|
|
66
|
+
let done: boolean = true
|
|
67
|
+
let out: ListVal = TOP === peer ? this : new ListVal([], ctx)
|
|
68
|
+
|
|
69
|
+
out.spread.cj = this.spread.cj
|
|
70
|
+
|
|
71
|
+
if (peer instanceof ListVal) {
|
|
72
|
+
out.spread.cj = null == out.spread.cj ? peer.spread.cj : (
|
|
73
|
+
null == peer.spread.cj ? out.spread.cj : (
|
|
74
|
+
out.spread.cj = new ConjunctVal([out.spread.cj, peer.spread.cj], ctx)
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
out.done = this.done + 1
|
|
81
|
+
|
|
82
|
+
if (this.spread.cj) {
|
|
83
|
+
out.spread.cj =
|
|
84
|
+
DONE !== this.spread.cj.done ? unite(ctx, this.spread.cj) :
|
|
85
|
+
this.spread.cj
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let spread_cj = out.spread.cj || TOP
|
|
89
|
+
|
|
90
|
+
// Always unify children first
|
|
91
|
+
for (let key in this.peg) {
|
|
92
|
+
out.peg[key] =
|
|
93
|
+
unite(ctx.descend(key), this.peg[key], spread_cj)
|
|
94
|
+
|
|
95
|
+
done = (done && DONE === out.peg[key].done)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (peer instanceof ListVal) {
|
|
99
|
+
let upeer: ListVal = (unite(ctx, peer) as ListVal)
|
|
100
|
+
|
|
101
|
+
for (let peerkey in upeer.peg) {
|
|
102
|
+
let peerchild = upeer.peg[peerkey]
|
|
103
|
+
let child = out.peg[peerkey]
|
|
104
|
+
|
|
105
|
+
let oval = out.peg[peerkey] =
|
|
106
|
+
undefined === child ? peerchild :
|
|
107
|
+
child instanceof Nil ? child :
|
|
108
|
+
peerchild instanceof Nil ? peerchild :
|
|
109
|
+
unite(ctx.descend(peerkey), child, peerchild)
|
|
110
|
+
|
|
111
|
+
if (this.spread.cj) {
|
|
112
|
+
out.peg[peerkey] = unite(ctx, out.peg[peerkey], spread_cj)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
done = (done && DONE === oval.done)
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (TOP !== peer) {
|
|
120
|
+
return Nil.make(ctx, 'map', this, peer)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
out.done = done ? DONE : out.done
|
|
124
|
+
return out
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get canon() {
|
|
128
|
+
let keys = Object.keys(this.peg)
|
|
129
|
+
return '[' +
|
|
130
|
+
(this.spread.cj ? '&:' + this.spread.cj.canon +
|
|
131
|
+
(0 < keys.length ? ',' : '') : '') +
|
|
132
|
+
keys
|
|
133
|
+
// NOTE: handle array non-index key vals
|
|
134
|
+
// .map(k => [JSON.stringify(k) + ':' + this.peg[k].canon]).join(',') +
|
|
135
|
+
.map(k => [this.peg[k].canon]).join(',') +
|
|
136
|
+
']'
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
gen(ctx?: Context) {
|
|
140
|
+
let out: any = this.peg.map((v: Val) => v.gen(ctx))
|
|
141
|
+
// for (let p in this.peg) {
|
|
142
|
+
// out[p] = this.peg[p].gen(ctx)
|
|
143
|
+
// }
|
|
144
|
+
|
|
145
|
+
return out
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
export {
|
|
153
|
+
ListVal,
|
|
154
|
+
}
|