aontu 0.1.1 → 0.3.0
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 +5 -1
- package/dist/aontu.js +3 -1
- package/dist/aontu.js.map +1 -1
- package/dist/lib/lang.d.ts +1 -1
- package/dist/lib/lang.js +82 -241
- package/dist/lib/lang.js.map +1 -1
- package/dist/lib/op/op.d.ts +1 -1
- package/dist/lib/op/unite.js +8 -3
- package/dist/lib/op/unite.js.map +1 -1
- package/dist/lib/unify.d.ts +2 -1
- package/dist/lib/unify.js +3 -3
- package/dist/lib/unify.js.map +1 -1
- package/dist/lib/val.d.ts +12 -1
- package/dist/lib/val.js +88 -45
- package/dist/lib/val.js.map +1 -1
- package/lib/lang.ts +121 -278
- package/lib/op/op.ts +2 -1
- package/lib/op/unite.ts +12 -4
- package/lib/unify.ts +6 -8
- package/lib/val.ts +127 -57
- package/package.json +11 -10
package/lib/lang.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
Rule,
|
|
7
7
|
RuleSpec,
|
|
8
8
|
Context,
|
|
9
|
-
} from 'jsonic'
|
|
9
|
+
} from '@jsonic/jsonic-next'
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
MultiSource
|
|
@@ -21,6 +21,10 @@ import {
|
|
|
21
21
|
Op,
|
|
22
22
|
} from '@jsonic/expr'
|
|
23
23
|
|
|
24
|
+
import {
|
|
25
|
+
Path
|
|
26
|
+
} from '@jsonic/path'
|
|
27
|
+
|
|
24
28
|
|
|
25
29
|
|
|
26
30
|
import {
|
|
@@ -32,6 +36,7 @@ import {
|
|
|
32
36
|
Nil,
|
|
33
37
|
TOP,
|
|
34
38
|
MapVal,
|
|
39
|
+
ListVal,
|
|
35
40
|
ScalarTypeVal,
|
|
36
41
|
Integer,
|
|
37
42
|
StringVal,
|
|
@@ -45,7 +50,6 @@ import {
|
|
|
45
50
|
} from './val'
|
|
46
51
|
|
|
47
52
|
|
|
48
|
-
|
|
49
53
|
class Site {
|
|
50
54
|
row: number = -1
|
|
51
55
|
col: number = -1
|
|
@@ -67,64 +71,81 @@ class Site {
|
|
|
67
71
|
|
|
68
72
|
let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
69
73
|
|
|
74
|
+
jsonic.use(Path)
|
|
75
|
+
|
|
76
|
+
// TODO: refactor Val constructor
|
|
77
|
+
let addpath = (v: Val, p: string[]) => (v.path = [...(p || [])], v)
|
|
78
|
+
|
|
79
|
+
|
|
70
80
|
jsonic.options({
|
|
71
81
|
value: {
|
|
72
|
-
// JSONIC-UPDATE: map: { val: ... }
|
|
73
82
|
map: {
|
|
74
83
|
// NOTE: specify with functions as jsonic/deep will
|
|
75
84
|
// remove class prototype as options are assumed plain
|
|
76
85
|
// (except for functions).
|
|
77
86
|
// TODO: jsonic should be able to pass context into these
|
|
78
|
-
'string': {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
'
|
|
87
|
+
'string': {
|
|
88
|
+
val: (r: Rule) =>
|
|
89
|
+
addpath(new ScalarTypeVal(String), r.keep.path)
|
|
90
|
+
},
|
|
91
|
+
'number': {
|
|
92
|
+
val: (r: Rule) =>
|
|
93
|
+
addpath(new ScalarTypeVal(Number), r.keep.path)
|
|
94
|
+
},
|
|
95
|
+
'integer': {
|
|
96
|
+
val: (r: Rule) =>
|
|
97
|
+
addpath(new ScalarTypeVal(Integer), r.keep.path)
|
|
98
|
+
},
|
|
99
|
+
'boolean': {
|
|
100
|
+
val: (r: Rule) =>
|
|
101
|
+
addpath(new ScalarTypeVal(Boolean), r.keep.path)
|
|
102
|
+
},
|
|
103
|
+
'nil': {
|
|
104
|
+
val: (r: Rule) =>
|
|
105
|
+
addpath(new Nil('literal'), r.keep.path)
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
// TODO: FIX: need a TOP instance to hold path
|
|
83
109
|
'top': { val: () => TOP },
|
|
84
110
|
}
|
|
85
111
|
},
|
|
86
112
|
|
|
87
|
-
// // JSONIC-UPDATE: fixed: { token }
|
|
88
|
-
// fixed: {
|
|
89
|
-
// token: {
|
|
90
|
-
// '#A&': '&',
|
|
91
|
-
// '#A|': '|',
|
|
92
|
-
// '#A/': '/',
|
|
93
|
-
// '#A*': '*', // TODO: REVIEW char as * is a bit overloaded
|
|
94
|
-
// '#A=': '=',
|
|
95
|
-
// }
|
|
96
|
-
// },
|
|
97
|
-
|
|
98
|
-
// JSONIC-UPDATE: check impl
|
|
99
113
|
map: {
|
|
100
114
|
merge: (prev: any, curr: any) => {
|
|
101
115
|
let pval = (prev as Val)
|
|
102
116
|
let cval = (curr as Val)
|
|
103
|
-
return new ConjunctVal([pval, cval])
|
|
117
|
+
return addpath(new ConjunctVal([pval, cval]), prev.path)
|
|
104
118
|
}
|
|
105
119
|
}
|
|
106
120
|
})
|
|
107
121
|
|
|
108
122
|
|
|
109
123
|
let opmap: any = {
|
|
110
|
-
'conjunct-infix': (_op: Op, terms: any) =>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
'conjunct-infix': (r: Rule, _op: Op, terms: any) =>
|
|
125
|
+
addpath(new ConjunctVal(terms), r.keep.path),
|
|
126
|
+
'disjunct-infix': (r: Rule, _op: Op, terms: any) =>
|
|
127
|
+
addpath(new DisjunctVal(terms), r.keep.path),
|
|
128
|
+
|
|
129
|
+
'dot-prefix': (r: Rule, _op: Op, terms: any) =>
|
|
130
|
+
addpath(new RefVal(terms, true), r.keep.path),
|
|
131
|
+
'dot-infix': (r: Rule, _op: Op, terms: any) =>
|
|
132
|
+
addpath(new RefVal(terms), r.keep.path),
|
|
133
|
+
|
|
134
|
+
'star-prefix': (r: Rule, _op: Op, terms: any) =>
|
|
135
|
+
addpath(new PrefVal(terms[0]), r.keep.path),
|
|
117
136
|
}
|
|
118
137
|
|
|
119
138
|
|
|
120
139
|
jsonic
|
|
121
140
|
.use(Expr, {
|
|
122
141
|
op: {
|
|
142
|
+
// disjunct > conjunct: c & b|a -> c & (b|a)
|
|
123
143
|
'conjunct': {
|
|
124
144
|
infix: true, src: '&', left: 14000, right: 15000
|
|
125
145
|
},
|
|
126
146
|
'disjunct': {
|
|
127
|
-
infix: true, src: '|', left: 14000, right: 15000
|
|
147
|
+
// infix: true, src: '|', left: 14000, right: 15000
|
|
148
|
+
infix: true, src: '|', left: 16000, right: 17000
|
|
128
149
|
},
|
|
129
150
|
|
|
130
151
|
'dot-infix': {
|
|
@@ -145,307 +166,127 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
145
166
|
right: 14_000_000,
|
|
146
167
|
},
|
|
147
168
|
},
|
|
148
|
-
evaluate: (op: Op, terms: any) => {
|
|
149
|
-
// console.log('LANG EVAL', op, terms)
|
|
150
|
-
|
|
169
|
+
evaluate: (r: Rule, op: Op, terms: any) => {
|
|
170
|
+
// console.log('LANG EVAL', r.keep, op, terms)
|
|
171
|
+
let val: Val = opmap[op.name](r, op, terms)
|
|
172
|
+
// console.dir(val, { depth: null })
|
|
173
|
+
|
|
174
|
+
return val
|
|
151
175
|
}
|
|
152
176
|
})
|
|
153
177
|
|
|
154
|
-
|
|
178
|
+
|
|
155
179
|
let CJ = jsonic.token['#E&']
|
|
156
180
|
let CL = jsonic.token.CL
|
|
157
181
|
|
|
158
|
-
// let NR = jsonic.token.NR
|
|
159
|
-
// let TX = jsonic.token.TX
|
|
160
|
-
// let ST = jsonic.token.ST
|
|
161
|
-
// let VL = jsonic.token.VL
|
|
162
|
-
// let OB = jsonic.token.OB
|
|
163
|
-
// let OS = jsonic.token.OS
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// let DJ = jsonic.token['#A|']
|
|
167
|
-
// let FS = jsonic.token['#A/']
|
|
168
|
-
// let AK = jsonic.token['#A*']
|
|
169
|
-
// let EQ = jsonic.token['#A=']
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// JSONIC-UPDATE: rule.open[], rule.close[] - replace with rule.oN|cN
|
|
173
|
-
|
|
174
|
-
// jsonic.rule('expr', (rs: RuleSpec) => {
|
|
175
|
-
// rs
|
|
176
|
-
// .open([
|
|
177
|
-
// { s: [[CJ, DJ, AK]], p: 'disjunct', b: 1, n: { expr: 1 } },
|
|
178
|
-
// ])
|
|
179
|
-
|
|
180
|
-
// .close([
|
|
181
|
-
// { s: [] }
|
|
182
|
-
// ])
|
|
183
|
-
|
|
184
|
-
// // NOTE: expr node are meta structures, not Vals
|
|
185
|
-
// // t=most recent term on the left, o=Val
|
|
186
|
-
// .bo((r: Rule) => r.node = { t: r.node })
|
|
187
|
-
|
|
188
|
-
// .ac((r: Rule) => {
|
|
189
|
-
// let cn = r.child.node.o
|
|
190
|
-
|
|
191
|
-
// if (cn instanceof PrefVal) {
|
|
192
|
-
// return r.o0.bad('single-pref')
|
|
193
|
-
// }
|
|
194
|
-
|
|
195
|
-
// // replace first val with expr val
|
|
196
|
-
// r.node = cn
|
|
197
|
-
|
|
198
|
-
// if ('val' === r.parent?.name) {
|
|
199
|
-
// r.parent.node = r.node
|
|
200
|
-
// }
|
|
201
|
-
// })
|
|
202
|
-
|
|
203
|
-
// })
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
// jsonic.rule('disjunct', (rs: RuleSpec) => {
|
|
207
|
-
// rs
|
|
208
|
-
// .open([
|
|
209
|
-
// {
|
|
210
|
-
// s: [CJ], p: 'conjunct', b: 1
|
|
211
|
-
// },
|
|
212
|
-
// {
|
|
213
|
-
// s: [AK], p: 'pref', b: 1
|
|
214
|
-
// },
|
|
215
|
-
// {
|
|
216
|
-
// s: [DJ, AK], p: 'pref', b: 1,
|
|
217
|
-
// a: (r: Rule) => {
|
|
218
|
-
// // Append to existing or start new
|
|
219
|
-
// r.node.o = r.node.o instanceof DisjunctVal ?
|
|
220
|
-
// r.node.o : new DisjunctVal([r.node.t])
|
|
221
|
-
// }
|
|
222
|
-
// },
|
|
223
|
-
// {
|
|
224
|
-
// s: [DJ, [NR, TX, ST, VL, OB, OS]], b: 1,
|
|
225
|
-
// p: 'val',
|
|
226
|
-
// a: (r: Rule) => {
|
|
227
|
-
// // Append to existing or start new
|
|
228
|
-
// r.node.o = r.node.o instanceof DisjunctVal ?
|
|
229
|
-
// r.node.o : new DisjunctVal([r.node.t])
|
|
230
|
-
// }
|
|
231
|
-
// },
|
|
232
|
-
// ])
|
|
233
|
-
|
|
234
|
-
// .close([
|
|
235
|
-
// {
|
|
236
|
-
// s: [DJ], r: 'disjunct', b: 1, a: (r: Rule) => {
|
|
237
|
-
// // higher precedence term (e.g &) was on the left
|
|
238
|
-
// let cn = r.child.node?.o || r.child.node
|
|
239
|
-
// r.node.t = cn
|
|
240
|
-
// }
|
|
241
|
-
// },
|
|
242
|
-
// {
|
|
243
|
-
// s: [CJ], r: 'disjunct', b: 1, a: (r: Rule) => {
|
|
244
|
-
// // & with higher precedence to the right
|
|
245
|
-
// let cn = r.child.node?.o || r.child.node
|
|
246
|
-
// r.node.t = cn
|
|
247
|
-
// r.child.node = null
|
|
248
|
-
// }
|
|
249
|
-
// },
|
|
250
|
-
// {}
|
|
251
|
-
// ])
|
|
252
|
-
// .ac((r: Rule) => {
|
|
253
|
-
// // child values may be normal or expr metas
|
|
254
|
-
// let cn = r.child.node?.o || r.child.node
|
|
255
|
-
// if (cn) {
|
|
256
|
-
// if (r.node.o instanceof DisjunctVal) {
|
|
257
|
-
// r.node.o.append(cn)
|
|
258
|
-
// }
|
|
259
|
-
// else {
|
|
260
|
-
// // this rule was just a pass-through
|
|
261
|
-
// r.node.o = cn
|
|
262
|
-
// }
|
|
263
|
-
// }
|
|
264
|
-
// })
|
|
265
|
-
// })
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
// jsonic.rule('conjunct', (rs: RuleSpec) => {
|
|
270
|
-
// rs
|
|
271
|
-
// .open([
|
|
272
|
-
// {
|
|
273
|
-
// s: [CJ, [NR, TX, ST, VL, OB, OS, FS]], b: 1,
|
|
274
|
-
// p: 'val',
|
|
275
|
-
// a: (r: Rule) => {
|
|
276
|
-
// r.node = {
|
|
277
|
-
// o: r.node.o instanceof ConjunctVal ?
|
|
278
|
-
// r.node.o : new ConjunctVal([r.node.t])
|
|
279
|
-
// }
|
|
280
|
-
// }
|
|
281
|
-
// },
|
|
282
|
-
// ])
|
|
283
|
-
// .close([
|
|
284
|
-
// {
|
|
285
|
-
// s: [CJ], r: 'conjunct', b: 1
|
|
286
|
-
// },
|
|
287
|
-
// {}
|
|
288
|
-
// ])
|
|
289
|
-
// .ac((r: Rule) => {
|
|
290
|
-
// let cn = r.child.node?.o || r.child.node
|
|
291
|
-
// if (cn) {
|
|
292
|
-
// if (r.node.o instanceof ConjunctVal) {
|
|
293
|
-
// r.node.o.append(cn)
|
|
294
|
-
// }
|
|
295
|
-
// else {
|
|
296
|
-
// r.node.o = cn
|
|
297
|
-
// }
|
|
298
|
-
// }
|
|
299
|
-
// })
|
|
300
|
-
// })
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
// jsonic.rule('path', (rs: RuleSpec) => {
|
|
304
|
-
// rs
|
|
305
|
-
// .open([
|
|
306
|
-
// { s: [FS, [TX, ST, NR, VL]], p: 'part', b: 2 }
|
|
307
|
-
// ])
|
|
308
|
-
// .bo((r: Rule) => r.node = new RefVal('/'))
|
|
309
|
-
// })
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// jsonic.rule('part', (rs: RuleSpec) => {
|
|
313
|
-
// rs.
|
|
314
|
-
// open([
|
|
315
|
-
// {
|
|
316
|
-
// s: [FS, [TX, ST, NR, VL]], r: 'part', a: (r: Rule) => {
|
|
317
|
-
// r.node.append(r.o1.src)
|
|
318
|
-
// }
|
|
319
|
-
// },
|
|
320
|
-
// {}, // no more parts
|
|
321
|
-
// ])
|
|
322
|
-
// })
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
// // rs.def.open.unshift({
|
|
327
|
-
// // s: [[CJ, DJ], EQ], p: 'val', u: { spread: true }
|
|
328
|
-
// // })
|
|
329
|
-
|
|
330
|
-
// // // TODO: make before/after function[]
|
|
331
|
-
// // let orig_bc: any = rs.def.bc
|
|
332
|
-
// // rs.def.bc = function(rule: Rule, ctx: Context) {
|
|
333
|
-
// // let out = orig_bc.call(this, rule, ctx)
|
|
334
|
-
|
|
335
|
-
// // if (rule.use.spread) {
|
|
336
|
-
// // rule.node[MapVal.SPREAD] =
|
|
337
|
-
// // (rule.node[MapVal.SPREAD] || { o: rule.o0.src, v: [] })
|
|
338
|
-
// // rule.node[MapVal.SPREAD].v.push(rule.child.node)
|
|
339
|
-
// // }
|
|
340
|
-
|
|
341
|
-
// // return out
|
|
342
|
-
// // }
|
|
343
|
-
|
|
344
|
-
// return rs
|
|
345
|
-
// })
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
// jsonic.rule('pref', (rs: RuleSpec) => {
|
|
349
|
-
// rs
|
|
350
|
-
// .open([
|
|
351
|
-
// {
|
|
352
|
-
// s: [AK, [NR, TX, ST, VL, OB, OS, FS]], b: 1,
|
|
353
|
-
// p: 'val',
|
|
354
|
-
// },
|
|
355
|
-
// ])
|
|
356
|
-
// .close([
|
|
357
|
-
// // Can't be in a conjunct
|
|
358
|
-
// { s: [CJ], e: (r: Rule) => r.o1 },
|
|
359
|
-
// {}
|
|
360
|
-
// ])
|
|
361
|
-
// .ac((r: Rule) => {
|
|
362
|
-
// r.node = new PrefVal(r.child.node)
|
|
363
|
-
// })
|
|
364
|
-
// })
|
|
365
|
-
|
|
366
|
-
|
|
367
182
|
|
|
368
183
|
jsonic.rule('val', (rs: RuleSpec) => {
|
|
369
|
-
// rs.def.open.unshift(
|
|
370
|
-
// // Prefs are always within an expression
|
|
371
|
-
// { s: [AK, [NR, TX, ST, VL, OB, OS, FS]], p: 'expr', b: 2 },
|
|
372
|
-
// { s: [FS, [TX, ST, NR, VL]], p: 'path', b: 2 },
|
|
373
|
-
// )
|
|
374
|
-
// rs.def.close.unshift(
|
|
375
|
-
// {
|
|
376
|
-
// s: [[CJ, DJ]], p: 'expr', b: 1, c: (r: Rule) => {
|
|
377
|
-
// return null == r.n.expr || 0 === r.n.expr
|
|
378
|
-
// }
|
|
379
|
-
// },
|
|
380
|
-
// )
|
|
381
|
-
|
|
382
184
|
|
|
383
185
|
// TODO: wrap utility needed for jsonic to do this?
|
|
384
|
-
let orig_bc: any = rs.def.bc
|
|
385
|
-
rs.def.bc = function(rule: Rule, ctx: Context) {
|
|
386
|
-
|
|
186
|
+
// let orig_bc: any = rs.def.bc
|
|
187
|
+
// rs.def.bc = function(rule: Rule, ctx: Context) {
|
|
188
|
+
// let out = orig_bc.call(this, rule, ctx)
|
|
189
|
+
|
|
190
|
+
rs.bc(false, (r: Rule, ctx: Context) => {
|
|
387
191
|
|
|
388
|
-
let valnode: Val =
|
|
192
|
+
let valnode: Val = r.node
|
|
389
193
|
let valtype = typeof valnode
|
|
390
194
|
|
|
195
|
+
// console.log('VAL RULE', rule.use, rule.node)
|
|
196
|
+
|
|
391
197
|
if ('string' === valtype) {
|
|
392
|
-
valnode = new StringVal(
|
|
198
|
+
valnode = addpath(new StringVal(r.node), r.keep.path)
|
|
393
199
|
}
|
|
394
200
|
else if ('number' === valtype) {
|
|
395
|
-
if (Number.isInteger(
|
|
396
|
-
valnode = new IntegerVal(
|
|
201
|
+
if (Number.isInteger(r.node)) {
|
|
202
|
+
valnode = addpath(new IntegerVal(r.node), r.keep.path)
|
|
397
203
|
}
|
|
398
204
|
else {
|
|
399
|
-
valnode = new NumberVal(
|
|
205
|
+
valnode = addpath(new NumberVal(r.node), r.keep.path)
|
|
400
206
|
}
|
|
401
207
|
}
|
|
402
208
|
else if ('boolean' === valtype) {
|
|
403
|
-
valnode = new BooleanVal(
|
|
209
|
+
valnode = addpath(new BooleanVal(r.node), r.keep.path)
|
|
404
210
|
}
|
|
405
211
|
|
|
406
|
-
let st =
|
|
212
|
+
let st = r.o0
|
|
407
213
|
valnode.row = st.rI
|
|
408
214
|
valnode.col = st.cI
|
|
409
215
|
|
|
410
216
|
// JSONIC-UPDATE: still valid? check multisource
|
|
411
217
|
valnode.url = ctx.meta.multisource && ctx.meta.multisource.path
|
|
412
218
|
|
|
413
|
-
|
|
219
|
+
r.node = valnode
|
|
220
|
+
|
|
221
|
+
// return out
|
|
222
|
+
return undefined
|
|
223
|
+
})
|
|
414
224
|
|
|
415
|
-
return out
|
|
416
|
-
}
|
|
417
225
|
return rs
|
|
418
226
|
})
|
|
419
227
|
|
|
420
228
|
|
|
421
229
|
|
|
422
230
|
jsonic.rule('map', (rs: RuleSpec) => {
|
|
423
|
-
let orig_bc = rs.def.bc
|
|
424
|
-
rs.def.bc = function(rule: Rule, ctx: Context) {
|
|
425
|
-
|
|
231
|
+
// let orig_bc = rs.def.bc
|
|
232
|
+
// rs.def.bc = function(rule: Rule, ctx: Context) {
|
|
233
|
+
// let out = orig_bc ? orig_bc.call(this, rule, ctx) : undefined
|
|
426
234
|
|
|
427
|
-
|
|
235
|
+
rs.bc(false, (r: Rule) => {
|
|
236
|
+
|
|
237
|
+
// console.log('MAP RULE', rule.use, rule.node)
|
|
238
|
+
r.node = addpath(new MapVal(r.node), r.keep.path)
|
|
239
|
+
|
|
240
|
+
// return out
|
|
241
|
+
return undefined
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
return rs
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
jsonic.rule('list', (rs: RuleSpec) => {
|
|
249
|
+
// let orig_bc = rs.def.bc
|
|
250
|
+
// rs.def.bc = function(rule: Rule, ctx: Context) {
|
|
251
|
+
// let out = orig_bc ? orig_bc.call(this, rule, ctx) : undefined
|
|
252
|
+
|
|
253
|
+
rs.bc(false, (r: Rule) => {
|
|
254
|
+
r.node = addpath(new ListVal(r.node), r.keep.path)
|
|
255
|
+
|
|
256
|
+
// return out
|
|
257
|
+
return undefined
|
|
258
|
+
})
|
|
428
259
|
|
|
429
|
-
return out
|
|
430
|
-
}
|
|
431
260
|
return rs
|
|
432
261
|
})
|
|
433
262
|
|
|
434
263
|
|
|
264
|
+
|
|
435
265
|
jsonic.rule('pair', (rs: RuleSpec) => {
|
|
436
|
-
let orig_bc: any = rs.def.bc
|
|
266
|
+
// let orig_bc: any = rs.def.bc
|
|
437
267
|
rs
|
|
438
268
|
.open([{ s: [CJ, CL], p: 'val', u: { spread: true }, g: 'spread' }])
|
|
439
|
-
.bc((...rest: any) => {
|
|
440
|
-
orig_bc(...rest)
|
|
441
269
|
|
|
442
|
-
|
|
270
|
+
// .bc((...rest: any) => {
|
|
271
|
+
// orig_bc(...rest)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
.bc(false, (rule: Rule) => {
|
|
275
|
+
// let rule = rest[0]
|
|
276
|
+
// console.log('PAIR RULE', rule.use, rule.node,
|
|
277
|
+
// rule.parent.name, rule.parent.use)
|
|
278
|
+
|
|
279
|
+
// TRAVERSE PARENTS TO GET PATH
|
|
280
|
+
|
|
443
281
|
if (rule.use.spread) {
|
|
444
282
|
rule.node[MapVal.SPREAD] =
|
|
445
283
|
(rule.node[MapVal.SPREAD] || { o: rule.o0.src, v: [] })
|
|
446
284
|
rule.node[MapVal.SPREAD].v.push(rule.child.node)
|
|
447
285
|
}
|
|
286
|
+
|
|
287
|
+
return undefined
|
|
448
288
|
})
|
|
289
|
+
|
|
449
290
|
return rs
|
|
450
291
|
})
|
|
451
292
|
|
|
@@ -489,6 +330,8 @@ class Lang {
|
|
|
489
330
|
jm.log = opts.log
|
|
490
331
|
}
|
|
491
332
|
|
|
333
|
+
// jm.log = -1
|
|
334
|
+
|
|
492
335
|
let val = this.jsonic(src, jm)
|
|
493
336
|
|
|
494
337
|
return val
|
package/lib/op/op.ts
CHANGED
|
@@ -8,10 +8,11 @@ import { disjunct } from './disjunct'
|
|
|
8
8
|
import { unite } from './unite'
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
type Operation = (ctx: Context, a?: Val, b?: Val) => Val
|
|
11
|
+
type Operation = (ctx: Context, a?: Val, b?: Val, whence?: string) => Val
|
|
12
12
|
|
|
13
13
|
export {
|
|
14
14
|
Operation,
|
|
15
15
|
disjunct,
|
|
16
16
|
unite,
|
|
17
17
|
}
|
|
18
|
+
|
package/lib/op/unite.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { Context } from '../unify'
|
|
6
6
|
import {
|
|
7
7
|
Val,
|
|
8
|
-
MapVal,
|
|
9
8
|
ConjunctVal,
|
|
10
9
|
DisjunctVal,
|
|
11
10
|
RefVal,
|
|
@@ -19,10 +18,13 @@ import { Operation } from './op'
|
|
|
19
18
|
|
|
20
19
|
// Vals should only have to unify downwards (in .unify) over Vals they understand.
|
|
21
20
|
// and for complex Vals, TOP, which means self unify if not yet done
|
|
22
|
-
const unite: Operation = (ctx: Context, a?: Val, b?: Val) => {
|
|
21
|
+
const unite: Operation = (ctx: Context, a?: Val, b?: Val, whence?: string) => {
|
|
23
22
|
let out = a
|
|
24
23
|
|
|
25
|
-
//console.log('
|
|
24
|
+
// console.log('AA OP unite IN', a?.canon, b?.canon,
|
|
25
|
+
// 'W', whence,
|
|
26
|
+
// 'E', 0 < ctx?.err?.length ? ctx.err.map((e: Val) => e.canon) : '')
|
|
27
|
+
|
|
26
28
|
|
|
27
29
|
if (b && (TOP === a || !a)) {
|
|
28
30
|
//console.log('Utb', b.canon)
|
|
@@ -51,15 +53,18 @@ const unite: Operation = (ctx: Context, a?: Val, b?: Val) => {
|
|
|
51
53
|
//console.log('U', a.canon, b.canon)
|
|
52
54
|
return b.unify(a, ctx)
|
|
53
55
|
}
|
|
56
|
+
|
|
57
|
+
// Exactly equal scalars.
|
|
54
58
|
else if (a.constructor === b.constructor && a.peg === b.peg) {
|
|
55
59
|
out = update(a, b)
|
|
56
60
|
}
|
|
61
|
+
|
|
57
62
|
else {
|
|
58
63
|
out = a.unify(b, ctx)
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
|
|
62
|
-
if (!out) {
|
|
67
|
+
if (!out || !out.unify) {
|
|
63
68
|
out = Nil.make(ctx, 'unite', a, b)
|
|
64
69
|
}
|
|
65
70
|
|
|
@@ -67,6 +72,9 @@ const unite: Operation = (ctx: Context, a?: Val, b?: Val) => {
|
|
|
67
72
|
out = out.unify(TOP, ctx)
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
// console.log('AA OP unite OUT', a?.canon, b?.canon, '->', out && out.canon,
|
|
76
|
+
// 0 < ctx?.err?.length ? ctx.err.map((e: Val) => e.canon) : '')
|
|
77
|
+
|
|
70
78
|
return out
|
|
71
79
|
}
|
|
72
80
|
|
package/lib/unify.ts
CHANGED
|
@@ -30,7 +30,6 @@ class Context {
|
|
|
30
30
|
err: Nil[] // Nil error log of current unify.
|
|
31
31
|
vc: number // Val counter to create unique val ids.
|
|
32
32
|
|
|
33
|
-
|
|
34
33
|
constructor(cfg: {
|
|
35
34
|
root: Val
|
|
36
35
|
err?: Nil[],
|
|
@@ -46,12 +45,13 @@ class Context {
|
|
|
46
45
|
|
|
47
46
|
|
|
48
47
|
clone(cfg: {
|
|
49
|
-
root
|
|
50
|
-
path?: Path
|
|
48
|
+
root?: Val,
|
|
49
|
+
path?: Path,
|
|
50
|
+
err?: Nil[],
|
|
51
51
|
}): Context {
|
|
52
52
|
return new Context({
|
|
53
|
-
root: cfg.root,
|
|
54
|
-
err: this.err,
|
|
53
|
+
root: cfg.root || this.root,
|
|
54
|
+
err: cfg.err || this.err,
|
|
55
55
|
vc: this.vc,
|
|
56
56
|
})
|
|
57
57
|
}
|
|
@@ -66,6 +66,7 @@ class Context {
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
find(ref: RefVal) {
|
|
69
|
+
// console.log('FIND', ref.path, ref.peg)
|
|
69
70
|
|
|
70
71
|
// TODO: relative paths
|
|
71
72
|
if (this.root instanceof MapVal && ref.absolute) {
|
|
@@ -112,11 +113,8 @@ class Unify {
|
|
|
112
113
|
// perhaps parse should count intial vals, paths, etc?
|
|
113
114
|
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
|
|
117
116
|
let maxdc = 999
|
|
118
117
|
for (this.dc = 0; this.dc < maxdc && DONE !== res.done; this.dc++) {
|
|
119
|
-
//res = res.unify(TOP, ctx)
|
|
120
118
|
res = unite(ctx, res, TOP)
|
|
121
119
|
ctx = ctx.clone({ root: res })
|
|
122
120
|
}
|