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/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': { val: () => new ScalarTypeVal(String) },
79
- 'number': { val: () => new ScalarTypeVal(Number) },
80
- 'integer': { val: () => new ScalarTypeVal(Integer) },
81
- 'boolean': { val: () => new ScalarTypeVal(Boolean) },
82
- 'nil': { val: () => new Nil('literal') },
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) => new ConjunctVal(terms),
111
- 'disjunct-infix': (_op: Op, terms: any) => new DisjunctVal(terms),
112
-
113
- 'dot-prefix': (_op: Op, terms: any) => new RefVal(terms, true),
114
- 'dot-infix': (_op: Op, terms: any) => new RefVal(terms),
115
-
116
- 'star-prefix': (_op: Op, terms: any) => new PrefVal(terms[0]),
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
- return opmap[op.name](op, terms)
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
- // console.log(jsonic.token)
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
- let out = orig_bc.call(this, rule, ctx)
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 = rule.node
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(rule.node)
198
+ valnode = addpath(new StringVal(r.node), r.keep.path)
393
199
  }
394
200
  else if ('number' === valtype) {
395
- if (Number.isInteger(rule.node)) {
396
- valnode = new IntegerVal(rule.node)
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(rule.node)
205
+ valnode = addpath(new NumberVal(r.node), r.keep.path)
400
206
  }
401
207
  }
402
208
  else if ('boolean' === valtype) {
403
- valnode = new BooleanVal(rule.node)
209
+ valnode = addpath(new BooleanVal(r.node), r.keep.path)
404
210
  }
405
211
 
406
- let st = rule.o0
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
- rule.node = valnode
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
- let out = orig_bc ? orig_bc.call(this, rule, ctx) : undefined
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
- rule.node = new MapVal(rule.node)
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
- let rule = rest[0]
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('Ua', a && a.canon, b && b.canon)
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: Val,
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
  }