aontu 0.12.0 → 0.13.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 +9 -3
- package/dist/aontu.d.ts +3 -0
- package/dist/aontu.js +7 -2
- package/dist/aontu.js.map +1 -1
- package/dist/aontu.min.js +1 -1
- package/dist/lib/err.js +1 -1
- package/dist/lib/err.js.map +1 -1
- package/dist/lib/lang.js +80 -32
- package/dist/lib/lang.js.map +1 -1
- package/dist/lib/op/disjunct.js +2 -2
- package/dist/lib/op/disjunct.js.map +1 -1
- package/dist/lib/op/op.js +1 -1
- package/dist/lib/op/op.js.map +1 -1
- package/dist/lib/op/unite.js +36 -6
- package/dist/lib/op/unite.js.map +1 -1
- package/dist/lib/type.d.ts +10 -8
- package/dist/lib/type.js +2 -27
- package/dist/lib/type.js.map +1 -1
- package/dist/lib/unify.d.ts +7 -4
- package/dist/lib/unify.js +17 -28
- package/dist/lib/unify.js.map +1 -1
- package/dist/lib/val/ConjunctVal.d.ts +7 -4
- package/dist/lib/val/ConjunctVal.js +62 -31
- package/dist/lib/val/ConjunctVal.js.map +1 -1
- package/dist/lib/val/DisjunctVal.d.ts +5 -2
- package/dist/lib/val/DisjunctVal.js +15 -7
- package/dist/lib/val/DisjunctVal.js.map +1 -1
- package/dist/lib/val/ListVal.d.ts +5 -2
- package/dist/lib/val/ListVal.js +39 -19
- package/dist/lib/val/ListVal.js.map +1 -1
- package/dist/lib/val/MapVal.d.ts +5 -2
- package/dist/lib/val/MapVal.js +59 -30
- package/dist/lib/val/MapVal.js.map +1 -1
- package/dist/lib/val/Nil.d.ts +3 -2
- package/dist/lib/val/Nil.js +19 -5
- package/dist/lib/val/Nil.js.map +1 -1
- package/dist/lib/val/PrefVal.d.ts +6 -2
- package/dist/lib/val/PrefVal.js +18 -8
- package/dist/lib/val/PrefVal.js.map +1 -1
- package/dist/lib/val/RefVal.d.ts +11 -5
- package/dist/lib/val/RefVal.js +187 -39
- package/dist/lib/val/RefVal.js.map +1 -1
- package/dist/lib/val/ValBase.d.ts +10 -9
- package/dist/lib/val/ValBase.js +25 -6
- package/dist/lib/val/ValBase.js.map +1 -1
- package/dist/lib/val/VarVal.d.ts +14 -0
- package/dist/lib/val/VarVal.js +68 -0
- package/dist/lib/val/VarVal.js.map +1 -0
- package/dist/lib/val.d.ts +42 -8
- package/dist/lib/val.js +64 -18
- package/dist/lib/val.js.map +1 -1
- package/lib/err.ts +1 -1
- package/lib/lang.ts +91 -38
- package/lib/op/disjunct.ts +10 -3
- package/lib/op/op.ts +1 -1
- package/lib/op/unite.ts +44 -4
- package/lib/type.ts +12 -40
- package/lib/unify.ts +70 -28
- package/lib/val/ConjunctVal.ts +83 -46
- package/lib/val/DisjunctVal.ts +35 -12
- package/lib/val/ListVal.ts +57 -22
- package/lib/val/MapVal.ts +82 -51
- package/lib/val/Nil.ts +29 -9
- package/lib/val/PrefVal.ts +38 -14
- package/lib/val/RefVal.ts +254 -55
- package/lib/val/ValBase.ts +33 -28
- package/lib/val/VarVal.ts +139 -0
- package/lib/val.ts +116 -25
- package/package.json +8 -8
- package/dist/lib/common.d.ts +0 -8
- package/dist/lib/common.js +0 -3
- package/dist/lib/common.js.map +0 -1
package/lib/lang.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Copyright (c) 2021-
|
|
1
|
+
/* Copyright (c) 2021-2023 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
Jsonic,
|
|
@@ -42,20 +42,21 @@ import type {
|
|
|
42
42
|
Options,
|
|
43
43
|
} from './type'
|
|
44
44
|
|
|
45
|
-
import {
|
|
46
|
-
TOP
|
|
47
|
-
} from './type'
|
|
48
45
|
|
|
49
|
-
|
|
46
|
+
|
|
50
47
|
import { DisjunctVal } from './val/DisjunctVal'
|
|
51
|
-
import {
|
|
48
|
+
import { ConjunctVal } from './val/ConjunctVal'
|
|
52
49
|
import { ListVal } from './val/ListVal'
|
|
50
|
+
import { MapVal } from './val/MapVal'
|
|
51
|
+
import { Nil } from './val/Nil'
|
|
53
52
|
import { PrefVal } from './val/PrefVal'
|
|
54
53
|
import { RefVal } from './val/RefVal'
|
|
55
|
-
import {
|
|
54
|
+
import { VarVal } from './val/VarVal'
|
|
55
|
+
import { ValBase } from './val/ValBase'
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
import {
|
|
59
|
+
TOP,
|
|
59
60
|
ScalarTypeVal,
|
|
60
61
|
Integer,
|
|
61
62
|
StringVal,
|
|
@@ -80,11 +81,10 @@ class Site {
|
|
|
80
81
|
this.col = val.col
|
|
81
82
|
this.url = val.url
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
|
|
87
|
+
|
|
88
88
|
let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
89
89
|
|
|
90
90
|
jsonic.use(Path)
|
|
@@ -102,19 +102,19 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
102
102
|
// TODO: jsonic should be able to pass context into these
|
|
103
103
|
'string': {
|
|
104
104
|
val: (r: Rule) =>
|
|
105
|
-
addpath(new ScalarTypeVal(String), r.keep.path)
|
|
105
|
+
addpath(new ScalarTypeVal({ peg: String }), r.keep.path)
|
|
106
106
|
},
|
|
107
107
|
'number': {
|
|
108
108
|
val: (r: Rule) =>
|
|
109
|
-
addpath(new ScalarTypeVal(Number), r.keep.path)
|
|
109
|
+
addpath(new ScalarTypeVal({ peg: Number }), r.keep.path)
|
|
110
110
|
},
|
|
111
111
|
'integer': {
|
|
112
112
|
val: (r: Rule) =>
|
|
113
|
-
addpath(new ScalarTypeVal(Integer), r.keep.path)
|
|
113
|
+
addpath(new ScalarTypeVal({ peg: Integer }), r.keep.path)
|
|
114
114
|
},
|
|
115
115
|
'boolean': {
|
|
116
116
|
val: (r: Rule) =>
|
|
117
|
-
addpath(new ScalarTypeVal(Boolean), r.keep.path)
|
|
117
|
+
addpath(new ScalarTypeVal({ peg: Boolean }), r.keep.path)
|
|
118
118
|
},
|
|
119
119
|
'nil': {
|
|
120
120
|
val: (r: Rule) =>
|
|
@@ -132,7 +132,23 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
132
132
|
let cval = (curr as Val)
|
|
133
133
|
|
|
134
134
|
if (pval?.isVal && cval?.isVal) {
|
|
135
|
-
|
|
135
|
+
|
|
136
|
+
// TODO: test multi element conjuncts work
|
|
137
|
+
if (pval instanceof ConjunctVal && cval instanceof ConjunctVal) {
|
|
138
|
+
pval.append(cval)
|
|
139
|
+
return pval
|
|
140
|
+
}
|
|
141
|
+
else if (pval instanceof ConjunctVal) {
|
|
142
|
+
pval.append(cval)
|
|
143
|
+
return pval
|
|
144
|
+
}
|
|
145
|
+
// else if (cval instanceof ConjunctVal) {
|
|
146
|
+
// cval.append(pval)
|
|
147
|
+
// return cval
|
|
148
|
+
// }
|
|
149
|
+
else {
|
|
150
|
+
return addpath(new ConjunctVal({ peg: [pval, cval] }), prev.path)
|
|
151
|
+
}
|
|
136
152
|
}
|
|
137
153
|
|
|
138
154
|
// Handle defered conjuncts, where MapVal does not yet
|
|
@@ -149,17 +165,31 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
149
165
|
|
|
150
166
|
let opmap: any = {
|
|
151
167
|
'conjunct-infix': (r: Rule, _op: Op, terms: any) =>
|
|
152
|
-
addpath(new ConjunctVal(terms), r.keep.path),
|
|
168
|
+
addpath(new ConjunctVal({ peg: terms }), r.keep.path),
|
|
153
169
|
'disjunct-infix': (r: Rule, _op: Op, terms: any) =>
|
|
154
|
-
addpath(new DisjunctVal(terms), r.keep.path),
|
|
170
|
+
addpath(new DisjunctVal({ peg: terms }), r.keep.path),
|
|
155
171
|
|
|
156
|
-
'dot-prefix': (r: Rule, _op: Op, terms: any) =>
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
172
|
+
'dot-prefix': (r: Rule, _op: Op, terms: any) => {
|
|
173
|
+
// console.log('DP', terms)
|
|
174
|
+
return addpath(new RefVal({ peg: terms, prefix: true }), r.keep.path)
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
'dot-infix': (r: Rule, _op: Op, terms: any) => {
|
|
178
|
+
// console.log('DI', terms)
|
|
179
|
+
return addpath(new RefVal({ peg: terms }), r.keep.path)
|
|
180
|
+
},
|
|
160
181
|
|
|
161
182
|
'star-prefix': (r: Rule, _op: Op, terms: any) =>
|
|
162
|
-
addpath(new PrefVal(terms[0]), r.keep.path),
|
|
183
|
+
addpath(new PrefVal({ peg: terms[0] }), r.keep.path),
|
|
184
|
+
|
|
185
|
+
'dollar-prefix': (r: Rule, _op: Op, terms: any) => {
|
|
186
|
+
// $.a.b absolute path
|
|
187
|
+
if (terms[0] instanceof RefVal) {
|
|
188
|
+
terms[0].absolute = true
|
|
189
|
+
return terms[0]
|
|
190
|
+
}
|
|
191
|
+
return addpath(new VarVal({ peg: terms[0] }), r.keep.path)
|
|
192
|
+
},
|
|
163
193
|
}
|
|
164
194
|
|
|
165
195
|
|
|
@@ -168,29 +198,34 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
168
198
|
op: {
|
|
169
199
|
// disjunct > conjunct: c & b|a -> c & (b|a)
|
|
170
200
|
'conjunct': {
|
|
171
|
-
infix: true, src: '&', left:
|
|
201
|
+
infix: true, src: '&', left: 14_000_000, right: 15_000_000
|
|
172
202
|
},
|
|
173
203
|
'disjunct': {
|
|
174
|
-
|
|
175
|
-
|
|
204
|
+
infix: true, src: '|', left: 16_000_000, right: 17_000_000
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
'dollar-prefix': {
|
|
208
|
+
src: '$',
|
|
209
|
+
prefix: true,
|
|
210
|
+
right: 31_000_000,
|
|
176
211
|
},
|
|
177
212
|
|
|
178
213
|
'dot-infix': {
|
|
179
214
|
src: '.',
|
|
180
215
|
infix: true,
|
|
181
|
-
left:
|
|
182
|
-
right:
|
|
216
|
+
left: 25_000_000,
|
|
217
|
+
right: 24_000_000,
|
|
183
218
|
},
|
|
184
219
|
'dot-prefix': {
|
|
185
220
|
src: '.',
|
|
186
221
|
prefix: true,
|
|
187
|
-
right:
|
|
222
|
+
right: 24_000_000,
|
|
188
223
|
},
|
|
189
224
|
|
|
190
225
|
'star': {
|
|
191
226
|
src: '*',
|
|
192
227
|
prefix: true,
|
|
193
|
-
right:
|
|
228
|
+
right: 24_000_000,
|
|
194
229
|
},
|
|
195
230
|
},
|
|
196
231
|
evaluate: (r: Rule, op: Op, terms: any) => {
|
|
@@ -215,18 +250,18 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
215
250
|
let valtype = typeof valnode
|
|
216
251
|
|
|
217
252
|
if ('string' === valtype) {
|
|
218
|
-
valnode = addpath(new StringVal(r.node), r.keep.path)
|
|
253
|
+
valnode = addpath(new StringVal({ peg: r.node }), r.keep.path)
|
|
219
254
|
}
|
|
220
255
|
else if ('number' === valtype) {
|
|
221
256
|
if (Number.isInteger(r.node)) {
|
|
222
|
-
valnode = addpath(new IntegerVal(r.node), r.keep.path)
|
|
257
|
+
valnode = addpath(new IntegerVal({ peg: r.node }), r.keep.path)
|
|
223
258
|
}
|
|
224
259
|
else {
|
|
225
|
-
valnode = addpath(new NumberVal(r.node), r.keep.path)
|
|
260
|
+
valnode = addpath(new NumberVal({ peg: r.node }), r.keep.path)
|
|
226
261
|
}
|
|
227
262
|
}
|
|
228
263
|
else if ('boolean' === valtype) {
|
|
229
|
-
valnode = addpath(new BooleanVal(r.node), r.keep.path)
|
|
264
|
+
valnode = addpath(new BooleanVal({ peg: r.node }), r.keep.path)
|
|
230
265
|
}
|
|
231
266
|
|
|
232
267
|
let st = r.o0
|
|
@@ -262,11 +297,15 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
262
297
|
if (mo.___merge) {
|
|
263
298
|
let mop = { ...mo }
|
|
264
299
|
delete mop.___merge
|
|
265
|
-
|
|
266
|
-
|
|
300
|
+
|
|
301
|
+
// TODO: needs addpath?
|
|
302
|
+
let mopv = new MapVal({ peg: mop })
|
|
303
|
+
|
|
304
|
+
r.node =
|
|
305
|
+
addpath(new ConjunctVal({ peg: [mopv, ...mo.___merge] }), r.keep.path)
|
|
267
306
|
}
|
|
268
307
|
else {
|
|
269
|
-
r.node = addpath(new MapVal(mo), r.keep.path)
|
|
308
|
+
r.node = addpath(new MapVal({ peg: mo }), r.keep.path)
|
|
270
309
|
}
|
|
271
310
|
|
|
272
311
|
// return out
|
|
@@ -283,7 +322,7 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
283
322
|
// let out = orig_bc ? orig_bc.call(this, rule, ctx) : undefined
|
|
284
323
|
|
|
285
324
|
rs.bc((r: Rule) => {
|
|
286
|
-
r.node = addpath(new ListVal(r.node), r.keep.path)
|
|
325
|
+
r.node = addpath(new ListVal({ peg: r.node }), r.keep.path)
|
|
287
326
|
|
|
288
327
|
// return out
|
|
289
328
|
return undefined
|
|
@@ -293,10 +332,22 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
293
332
|
})
|
|
294
333
|
|
|
295
334
|
|
|
296
|
-
|
|
297
335
|
jsonic.rule('pair', (rs: RuleSpec) => {
|
|
298
336
|
rs
|
|
299
|
-
.open([{
|
|
337
|
+
.open([{
|
|
338
|
+
s: [CJ, CL], p: 'val',
|
|
339
|
+
// pair:true not set, so key ignored by normal pair close
|
|
340
|
+
u: { spread: true },
|
|
341
|
+
g: 'spread'
|
|
342
|
+
}])
|
|
343
|
+
|
|
344
|
+
// NOTE: manually adjust path - @jsonic/path ignores as not pair:true
|
|
345
|
+
.ao((r) => {
|
|
346
|
+
if (0 < r.d && r.use.spread) {
|
|
347
|
+
r.child.keep.path = [...r.keep.path, '&']
|
|
348
|
+
r.child.keep.key = '&'
|
|
349
|
+
}
|
|
350
|
+
})
|
|
300
351
|
|
|
301
352
|
.bc((rule: Rule) => {
|
|
302
353
|
// TRAVERSE PARENTS TO GET PATH
|
|
@@ -304,6 +355,7 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
|
|
|
304
355
|
if (rule.use.spread) {
|
|
305
356
|
rule.node[MapVal.SPREAD] =
|
|
306
357
|
(rule.node[MapVal.SPREAD] || { o: rule.o0.src, v: [] })
|
|
358
|
+
|
|
307
359
|
rule.node[MapVal.SPREAD].v.push(rule.child.node)
|
|
308
360
|
}
|
|
309
361
|
|
|
@@ -370,6 +422,7 @@ function makeModelResolver(options: any) {
|
|
|
370
422
|
) {
|
|
371
423
|
|
|
372
424
|
let path = 'string' === typeof spec ? spec : spec?.peg
|
|
425
|
+
// console.log('MR', path, ctx.meta)
|
|
373
426
|
|
|
374
427
|
let search: any = []
|
|
375
428
|
let res = memResolver(path, popts, rule, ctx, jsonic)
|
package/lib/op/disjunct.ts
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
|
-
/* Copyright (c) 2021 Richard Rodger, MIT License */
|
|
1
|
+
/* Copyright (c) 2021-2023 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
import type { Val } from '../type'
|
|
5
5
|
|
|
6
6
|
import { Site } from '../lang'
|
|
7
7
|
import { Context } from '../unify'
|
|
8
|
-
import { DisjunctVal } from '../val/DisjunctVal'
|
|
9
8
|
import { Operation } from './op'
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
|
|
12
|
+
import { DisjunctVal } from '../val/DisjunctVal'
|
|
13
|
+
import { ConjunctVal } from '../val/ConjunctVal'
|
|
14
|
+
import { ListVal } from '../val/ListVal'
|
|
15
|
+
import { MapVal } from '../val/MapVal'
|
|
16
|
+
import { Nil } from '../val/Nil'
|
|
17
|
+
import { PrefVal } from '../val/PrefVal'
|
|
18
|
+
import { RefVal } from '../val/RefVal'
|
|
13
19
|
import { ValBase } from '../val/ValBase'
|
|
14
20
|
|
|
15
21
|
|
|
22
|
+
|
|
16
23
|
const disjunct: Operation = (ctx?: Context, a?: Val, b?: Val) => {
|
|
17
24
|
let peers: Val[] = []
|
|
18
25
|
let origsites: Site[] = []
|
|
19
26
|
// origsites.push(append(peers, a))
|
|
20
27
|
// origsites.push(append(peers, b))
|
|
21
|
-
let out = new DisjunctVal(peers, ctx, origsites)
|
|
28
|
+
let out = new DisjunctVal({ peg: peers }, ctx, origsites)
|
|
22
29
|
return out
|
|
23
30
|
}
|
|
24
31
|
|
package/lib/op/op.ts
CHANGED
package/lib/op/unite.ts
CHANGED
|
@@ -1,28 +1,39 @@
|
|
|
1
|
-
/* Copyright (c) 2021-
|
|
1
|
+
/* Copyright (c) 2021-2023 Richard Rodger, MIT License */
|
|
2
|
+
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
import type { Val } from '../type'
|
|
5
6
|
|
|
6
|
-
import { DONE
|
|
7
|
+
import { DONE } from '../type'
|
|
7
8
|
import { Context } from '../unify'
|
|
8
9
|
|
|
10
|
+
|
|
9
11
|
import { ConjunctVal } from '../val/ConjunctVal'
|
|
10
12
|
import { DisjunctVal } from '../val/DisjunctVal'
|
|
13
|
+
import { ListVal } from '../val/ListVal'
|
|
14
|
+
import { MapVal } from '../val/MapVal'
|
|
15
|
+
import { Nil } from '../val/Nil'
|
|
11
16
|
import { PrefVal } from '../val/PrefVal'
|
|
12
17
|
import { RefVal } from '../val/RefVal'
|
|
13
|
-
import {
|
|
18
|
+
import { ValBase } from '../val/ValBase'
|
|
14
19
|
|
|
15
20
|
|
|
21
|
+
import {
|
|
22
|
+
TOP,
|
|
23
|
+
} from '../val'
|
|
16
24
|
|
|
17
25
|
|
|
18
26
|
import { Operation } from './op'
|
|
19
27
|
|
|
20
28
|
|
|
29
|
+
let uc = 0
|
|
30
|
+
|
|
31
|
+
|
|
21
32
|
// Vals should only have to unify downwards (in .unify) over Vals they understand.
|
|
22
33
|
// and for complex Vals, TOP, which means self unify if not yet done
|
|
23
34
|
const unite: Operation = (ctx: Context, a?: Val, b?: Val, whence?: string) => {
|
|
24
35
|
let out = a
|
|
25
|
-
|
|
36
|
+
let why = 'u'
|
|
26
37
|
// console.log('AA OP unite IN', a?.canon, b?.canon,
|
|
27
38
|
// 'W', whence,
|
|
28
39
|
// 'E', 0 < ctx?.err?.length ? ctx.err.map((e: Val) => e.canon) : '')
|
|
@@ -31,23 +42,28 @@ const unite: Operation = (ctx: Context, a?: Val, b?: Val, whence?: string) => {
|
|
|
31
42
|
if (b && (TOP === a || !a)) {
|
|
32
43
|
//console.log('Utb', b.canon)
|
|
33
44
|
out = b
|
|
45
|
+
why = 'b'
|
|
34
46
|
}
|
|
35
47
|
|
|
36
48
|
else if (a && (TOP === b || !b)) {
|
|
37
49
|
//console.log('Uta', a.canon)
|
|
38
50
|
out = a
|
|
51
|
+
why = 'a'
|
|
39
52
|
}
|
|
40
53
|
|
|
41
54
|
else if (a && b && TOP !== b) {
|
|
42
55
|
if (a instanceof Nil) {
|
|
43
56
|
out = update(a, b)
|
|
57
|
+
why = 'an'
|
|
44
58
|
}
|
|
45
59
|
else if (b instanceof Nil) {
|
|
46
60
|
out = update(b, a)
|
|
61
|
+
why = 'bn'
|
|
47
62
|
}
|
|
48
63
|
else if (a instanceof ConjunctVal) {
|
|
49
64
|
// console.log('Q', a.canon, b.canon)
|
|
50
65
|
out = a.unify(b, ctx)
|
|
66
|
+
why = 'acj'
|
|
51
67
|
}
|
|
52
68
|
else if (
|
|
53
69
|
b instanceof ConjunctVal ||
|
|
@@ -60,29 +76,53 @@ const unite: Operation = (ctx: Context, a?: Val, b?: Val, whence?: string) => {
|
|
|
60
76
|
// return b.unify(a, ctx)
|
|
61
77
|
out = b.unify(a, ctx)
|
|
62
78
|
// console.log('UO', out.canon)
|
|
79
|
+
why = 'bv'
|
|
63
80
|
}
|
|
64
81
|
|
|
65
82
|
// Exactly equal scalars.
|
|
66
83
|
else if (a.constructor === b.constructor && a.peg === b.peg) {
|
|
67
84
|
out = update(a, b)
|
|
85
|
+
why = 'up'
|
|
68
86
|
}
|
|
69
87
|
|
|
70
88
|
else {
|
|
71
89
|
out = a.unify(b, ctx)
|
|
90
|
+
why = 'ab'
|
|
72
91
|
}
|
|
73
92
|
}
|
|
74
93
|
|
|
75
94
|
if (!out || !out.unify) {
|
|
76
95
|
out = Nil.make(ctx, 'unite', a, b)
|
|
96
|
+
why += 'N'
|
|
77
97
|
}
|
|
78
98
|
|
|
79
99
|
if (DONE !== out.done) {
|
|
80
100
|
out = out.unify(TOP, ctx)
|
|
101
|
+
why += 'T'
|
|
81
102
|
}
|
|
82
103
|
|
|
83
104
|
// console.log('AA OP unite OUT', a?.canon, b?.canon, '->', out && out.canon,
|
|
84
105
|
// 0 < ctx?.err?.length ? ctx.err.map((e: Val) => e.canon) : '')
|
|
85
106
|
|
|
107
|
+
uc++
|
|
108
|
+
|
|
109
|
+
// TODO: KEEP THIS! print in debug mode! push to ctx.log?
|
|
110
|
+
/*
|
|
111
|
+
console.log(
|
|
112
|
+
'U',
|
|
113
|
+
('' + ctx.cc).padStart(2),
|
|
114
|
+
('' + uc).padStart(4),
|
|
115
|
+
(whence || '').substring(0, 16).padEnd(16),
|
|
116
|
+
why.padEnd(6),
|
|
117
|
+
ctx.path.join('.').padEnd(16),
|
|
118
|
+
(a || '').constructor.name.substring(0, 3),
|
|
119
|
+
'&',
|
|
120
|
+
(b || '').constructor.name.substring(0, 3),
|
|
121
|
+
'|',
|
|
122
|
+
' '.repeat(ctx.path.length),
|
|
123
|
+
a?.canon, '&', b?.canon, '->', out.canon)
|
|
124
|
+
*/
|
|
125
|
+
|
|
86
126
|
return out
|
|
87
127
|
}
|
|
88
128
|
|
package/lib/type.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Copyright (c) 2022 Richard Rodger, MIT License */
|
|
1
|
+
/* Copyright (c) 2022-2023 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
// TODO: refactor these out
|
|
@@ -33,25 +33,30 @@ interface Val {
|
|
|
33
33
|
col: number
|
|
34
34
|
url: string
|
|
35
35
|
|
|
36
|
-
top
|
|
36
|
+
top: boolean
|
|
37
37
|
|
|
38
38
|
// Actual native value.
|
|
39
|
-
peg
|
|
39
|
+
peg: any
|
|
40
40
|
|
|
41
41
|
// TODO: used for top level result - not great
|
|
42
|
-
err
|
|
42
|
+
err: any[]
|
|
43
43
|
deps?: any
|
|
44
44
|
|
|
45
45
|
same(peer: Val): boolean
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
// TODO: reverse args, as spec is mostly only used internally?
|
|
48
|
+
clone(spec?: ValSpec, ctx?: Context): Val
|
|
48
49
|
|
|
50
|
+
// get site(): Site
|
|
49
51
|
unify(peer: Val, ctx?: Context): Val
|
|
50
52
|
get canon(): string
|
|
51
53
|
gen(ctx?: Context): any
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
|
|
56
|
+
type ValSpec = {
|
|
57
|
+
peg?: any,
|
|
58
|
+
[name: string]: any,
|
|
59
|
+
} | null
|
|
55
60
|
type ValMap = { [key: string]: Val }
|
|
56
61
|
type ValList = Val[]
|
|
57
62
|
|
|
@@ -60,41 +65,9 @@ type ValList = Val[]
|
|
|
60
65
|
const DONE = -1
|
|
61
66
|
|
|
62
67
|
|
|
63
|
-
// There can be only one.
|
|
64
|
-
const TOP: Val = {
|
|
65
|
-
isVal: true,
|
|
66
|
-
|
|
67
|
-
id: 0,
|
|
68
|
-
top: true,
|
|
69
|
-
peg: undefined,
|
|
70
|
-
done: DONE,
|
|
71
|
-
path: [],
|
|
72
|
-
row: -1,
|
|
73
|
-
col: -1,
|
|
74
|
-
url: '',
|
|
75
|
-
|
|
76
|
-
unify(peer: Val, _ctx: Context): Val {
|
|
77
|
-
return peer
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
get canon() { return 'top' },
|
|
81
|
-
|
|
82
|
-
get site() { return new Site(this) },
|
|
83
|
-
|
|
84
|
-
same(peer: Val): boolean {
|
|
85
|
-
return TOP === peer
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
gen: (_ctx?: Context) => {
|
|
89
|
-
return undefined
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
68
|
export type {
|
|
97
69
|
Val,
|
|
70
|
+
ValSpec,
|
|
98
71
|
ValMap,
|
|
99
72
|
ValList,
|
|
100
73
|
Options,
|
|
@@ -102,7 +75,6 @@ export type {
|
|
|
102
75
|
|
|
103
76
|
export {
|
|
104
77
|
DONE,
|
|
105
|
-
TOP,
|
|
106
78
|
Resolver,
|
|
107
79
|
}
|
|
108
80
|
|
package/lib/unify.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
/* Copyright (c) 2021 Richard Rodger, MIT License */
|
|
1
|
+
/* Copyright (c) 2021-2023 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
import type { Val } from './type'
|
|
5
5
|
|
|
6
|
-
import { DONE,
|
|
6
|
+
import { DONE, } from './type'
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
import {
|
|
10
|
+
TOP
|
|
11
|
+
} from './val'
|
|
12
|
+
|
|
9
13
|
import {
|
|
10
14
|
Lang
|
|
11
15
|
} from './lang'
|
|
@@ -16,8 +20,10 @@ import {
|
|
|
16
20
|
|
|
17
21
|
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
// import { MapVal } from '../lib/val/MapVal'
|
|
26
|
+
// import { RefVal } from '../lib/val/RefVal'
|
|
21
27
|
import { Nil } from '../lib/val/Nil'
|
|
22
28
|
|
|
23
29
|
|
|
@@ -30,18 +36,27 @@ class Context {
|
|
|
30
36
|
path: Path // Path to current Val.
|
|
31
37
|
err: Nil[] // Nil error log of current unify.
|
|
32
38
|
vc: number // Val counter to create unique val ids.
|
|
39
|
+
cc: number = -1
|
|
40
|
+
var: Record<string, Val> = {}
|
|
33
41
|
|
|
34
42
|
constructor(cfg: {
|
|
35
|
-
root: Val
|
|
43
|
+
root: Val,
|
|
44
|
+
path?: Path,
|
|
36
45
|
err?: Nil[],
|
|
37
|
-
vc?: number
|
|
46
|
+
vc?: number,
|
|
47
|
+
cc?: number,
|
|
48
|
+
var?: Record<string, Val>
|
|
38
49
|
}) {
|
|
39
50
|
this.root = cfg.root
|
|
40
|
-
this.path = []
|
|
51
|
+
this.path = cfg.path || []
|
|
41
52
|
this.err = cfg.err || []
|
|
42
53
|
|
|
43
54
|
// Multiple unify passes will keep incrementing Val counter.
|
|
44
55
|
this.vc = null == cfg.vc ? 1_000_000_000 : cfg.vc
|
|
56
|
+
|
|
57
|
+
this.cc = null == cfg.cc ? this.cc : cfg.cc
|
|
58
|
+
|
|
59
|
+
this.var = cfg.var || this.var
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
|
|
@@ -52,8 +67,11 @@ class Context {
|
|
|
52
67
|
}): Context {
|
|
53
68
|
return new Context({
|
|
54
69
|
root: cfg.root || this.root,
|
|
70
|
+
path: cfg.path,
|
|
55
71
|
err: cfg.err || this.err,
|
|
56
72
|
vc: this.vc,
|
|
73
|
+
cc: this.cc,
|
|
74
|
+
var: { ...this.var },
|
|
57
75
|
})
|
|
58
76
|
}
|
|
59
77
|
|
|
@@ -66,27 +84,49 @@ class Context {
|
|
|
66
84
|
}
|
|
67
85
|
|
|
68
86
|
|
|
69
|
-
|
|
87
|
+
// TODO: move to RefVal
|
|
88
|
+
/*
|
|
89
|
+
xfind(ref: RefVal) {
|
|
70
90
|
// TODO: relative paths
|
|
71
91
|
// if (this.root instanceof MapVal && ref.absolute) {
|
|
92
|
+
|
|
93
|
+
// NOTE: path *to* the ref, not the ref itself!
|
|
94
|
+
let fullpath = ref.path
|
|
95
|
+
|
|
72
96
|
if (ref.absolute) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
else {
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
97
|
+
fullpath = ref.parts.slice(1) // ignore '$' at start
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
fullpath = fullpath.concat(ref.parts)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log('FP', ref.absolute, ref.parts, fullpath)
|
|
84
104
|
|
|
85
|
-
|
|
86
|
-
|
|
105
|
+
let node = this.root
|
|
106
|
+
let pI = 0
|
|
107
|
+
for (; pI < ref.parts.length; pI++) {
|
|
108
|
+
let part = ref.parts[pI]
|
|
109
|
+
if (node instanceof MapVal) {
|
|
110
|
+
node = node.peg[part]
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// console.log(
|
|
114
|
+
// 'FIND', ref.parts, pI, node.constructor.name,
|
|
115
|
+
// node.peg.map(
|
|
116
|
+
// (n: any) =>
|
|
117
|
+
// n.constructor.name + ':' + n.done +
|
|
118
|
+
// ' {' + Object.keys(n.peg) + '}'
|
|
119
|
+
// )
|
|
120
|
+
// )
|
|
121
|
+
break;
|
|
87
122
|
}
|
|
88
123
|
}
|
|
89
|
-
|
|
124
|
+
|
|
125
|
+
if (pI === ref.parts.length) {
|
|
126
|
+
return node
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
*/
|
|
90
130
|
}
|
|
91
131
|
|
|
92
132
|
|
|
@@ -94,10 +134,10 @@ class Unify {
|
|
|
94
134
|
root: Val
|
|
95
135
|
res: Val
|
|
96
136
|
err: Nil[]
|
|
97
|
-
|
|
137
|
+
cc: number
|
|
98
138
|
lang: Lang
|
|
99
139
|
|
|
100
|
-
constructor(root: Val | string, lang?: Lang) {
|
|
140
|
+
constructor(root: Val | string, lang?: Lang, ctx?: Context) {
|
|
101
141
|
this.lang = lang || new Lang()
|
|
102
142
|
if ('string' === typeof root) {
|
|
103
143
|
root = this.lang.parse(root)
|
|
@@ -108,7 +148,8 @@ class Unify {
|
|
|
108
148
|
this.err = []
|
|
109
149
|
|
|
110
150
|
let res = root
|
|
111
|
-
|
|
151
|
+
|
|
152
|
+
ctx = ctx || new Context({
|
|
112
153
|
root: res,
|
|
113
154
|
err: this.err,
|
|
114
155
|
})
|
|
@@ -118,11 +159,12 @@ class Unify {
|
|
|
118
159
|
// perhaps parse should count intial vals, paths, etc?
|
|
119
160
|
|
|
120
161
|
|
|
121
|
-
let maxdc =
|
|
122
|
-
for (this.
|
|
162
|
+
let maxdc = 9 // 99
|
|
163
|
+
for (this.cc = 0; this.cc < maxdc && DONE !== res.done; this.cc++) {
|
|
164
|
+
// console.log('\n\nRES', this.dc)
|
|
123
165
|
// console.log('\n\nRES', this.dc, res.canon)
|
|
124
166
|
// console.dir(res, { depth: null })
|
|
125
|
-
|
|
167
|
+
ctx.cc = this.cc
|
|
126
168
|
res = unite(ctx, res, TOP)
|
|
127
169
|
ctx = ctx.clone({ root: res })
|
|
128
170
|
}
|