aontu 0.0.7 → 0.1.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/lib/lang.ts CHANGED
@@ -12,6 +12,16 @@ import {
12
12
  MultiSource
13
13
  } from '@jsonic/multisource'
14
14
 
15
+ import {
16
+ makeFileResolver
17
+ } from '@jsonic/multisource/dist/resolver/file'
18
+
19
+ import {
20
+ Expr,
21
+ Op,
22
+ } from '@jsonic/expr'
23
+
24
+
15
25
 
16
26
  import {
17
27
  Options
@@ -36,30 +46,56 @@ import {
36
46
 
37
47
 
38
48
 
49
+ class Site {
50
+ row: number = -1
51
+ col: number = -1
52
+ url: string = ''
53
+
54
+ static NONE = new Site(TOP)
55
+
56
+ constructor(val: Val) {
57
+ // TODO: logic to select most meaningful site if val has no site,
58
+ // but has peg children that do.
59
+ this.row = val.row
60
+ this.col = val.col
61
+ this.url = val.url
62
+ }
63
+
64
+
65
+ }
66
+
67
+
39
68
  let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
40
69
 
41
70
  jsonic.options({
42
71
  value: {
43
- src: {
72
+ // JSONIC-UPDATE: map: { val: ... }
73
+ map: {
44
74
  // NOTE: specify with functions as jsonic/deep will
45
75
  // remove class prototype as options are assumed plain
46
76
  // (except for functions).
47
- 'string': () => new ScalarTypeVal(String),
48
- 'number': () => new ScalarTypeVal(Number),
49
- 'integer': () => new ScalarTypeVal(Integer),
50
- 'boolean': () => new ScalarTypeVal(Boolean),
51
- 'nil': () => new Nil(),
52
- 'top': () => TOP,
77
+ // 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') },
83
+ 'top': { val: () => TOP },
53
84
  }
54
85
  },
55
86
 
56
- token: {
57
- '#A&': { c: '&' },
58
- '#A|': { c: '|' },
59
- '#A/': { c: '/' },
60
- '#A*': { c: '*' },
61
- },
62
-
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
63
99
  map: {
64
100
  merge: (prev: any, curr: any) => {
65
101
  let pval = (prev as Val)
@@ -70,211 +106,286 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
70
106
  })
71
107
 
72
108
 
73
- let NR = jsonic.token.NR
74
- let TX = jsonic.token.TX
75
- let ST = jsonic.token.ST
76
- let VL = jsonic.token.VL
77
- let OB = jsonic.token.OB
78
- let OS = jsonic.token.OS
79
-
80
- let CJ = jsonic.token['#A&']
81
- let DJ = jsonic.token['#A|']
82
- let FS = jsonic.token['#A/']
83
-
84
- let AK = jsonic.token['#A*']
85
-
86
-
87
- jsonic.rule('expr', () => {
88
- return new RuleSpec({
89
- open: [
90
- { s: [[CJ, DJ, AK]], p: 'disjunct', b: 1, n: { expr: 1 } },
91
- ],
92
- close: [
93
- { s: [] }
94
- ],
109
+ let opmap: any = {
110
+ 'conjunct-infix': (_op: Op, terms: any) => new ConjunctVal(terms),
111
+ 'disjunct-infix': (_op: Op, terms: any) => new DisjunctVal(terms),
95
112
 
96
- // NOTE: expr node are meta structures, not Vals
97
- // t=most recent term on the left, o=Val
98
- bo: (r: Rule) => r.node = { t: r.node },
113
+ 'dot-prefix': (_op: Op, terms: any) => new RefVal(terms, true),
114
+ 'dot-infix': (_op: Op, terms: any) => new RefVal(terms),
99
115
 
100
- ac: (r: Rule) => {
101
- let cn = r.child.node.o
102
-
103
- if (cn instanceof PrefVal) {
104
- return { err: 'single-pref' }
105
- }
106
-
107
- // replace first val with expr val
108
- r.node = cn
109
- },
110
- })
111
- })
116
+ 'star-prefix': (_op: Op, terms: any) => new PrefVal(terms[0]),
117
+ }
112
118
 
113
119
 
114
- jsonic.rule('disjunct', () => {
115
- return new RuleSpec({
116
- open: [
117
- {
118
- s: [CJ], p: 'conjunct', b: 1
119
- },
120
- {
121
- s: [AK], p: 'pref', b: 1
122
- },
123
- {
124
- s: [DJ, AK], p: 'pref', b: 1,
125
- a: (r: Rule) => {
126
- // Append to existing or start new
127
- r.node.o = r.node.o instanceof DisjunctVal ?
128
- r.node.o : new DisjunctVal([r.node.t])
129
- }
120
+ jsonic
121
+ .use(Expr, {
122
+ op: {
123
+ 'conjunct': {
124
+ infix: true, src: '&', left: 14000, right: 15000
130
125
  },
131
- {
132
- s: [DJ, [NR, TX, ST, VL, OB, OS]], b: 1,
133
- p: 'val',
134
- a: (r: Rule) => {
135
- // Append to existing or start new
136
- r.node.o = r.node.o instanceof DisjunctVal ?
137
- r.node.o : new DisjunctVal([r.node.t])
138
- }
126
+ 'disjunct': {
127
+ infix: true, src: '|', left: 14000, right: 15000
139
128
  },
140
- ],
141
- close: [
142
- {
143
- s: [DJ], r: 'disjunct', b: 1, a: (r: Rule) => {
144
- // higher precedence term (e.g &) was on the left
145
- let cn = r.child.node?.o || r.child.node
146
- r.node.t = cn
147
- }
148
- },
149
- {
150
- s: [CJ], r: 'disjunct', b: 1, a: (r: Rule) => {
151
- // & with higher precedence to the right
152
- let cn = r.child.node?.o || r.child.node
153
- r.node.t = cn
154
- r.child.node = null
155
- }
156
- },
157
- {}
158
- ],
159
- ac: (r: Rule) => {
160
- // child values may be normal or expr metas
161
- let cn = r.child.node?.o || r.child.node
162
- if (cn) {
163
- if (r.node.o instanceof DisjunctVal) {
164
- r.node.o.val.push(cn)
165
- }
166
- else {
167
- // this rule was just a pass-through
168
- r.node.o = cn
169
- }
170
- }
171
- }
172
- })
173
- })
174
-
175
129
 
176
-
177
- jsonic.rule('conjunct', () => {
178
- return new RuleSpec({
179
- open: [
180
- {
181
- s: [CJ, [NR, TX, ST, VL, OB, OS, FS]], b: 1,
182
- p: 'val',
183
- a: (r: Rule) => {
184
- r.node = {
185
- o: r.node.o instanceof ConjunctVal ?
186
- r.node.o : new ConjunctVal([r.node.t])
187
- }
188
- }
189
- },
190
- ],
191
- close: [
192
- {
193
- s: [CJ], r: 'conjunct', b: 1
130
+ 'dot-infix': {
131
+ src: '.',
132
+ infix: true,
133
+ left: 15_000_000,
134
+ right: 14_000_000,
194
135
  },
195
- {}
196
- ],
197
- ac: (r: Rule) => {
198
- let cn = r.child.node?.o || r.child.node
199
- if (cn) {
200
- if (r.node.o instanceof ConjunctVal) {
201
- r.node.o.val.push(cn)
202
- }
203
- else {
204
- r.node.o = cn
205
- }
206
- }
207
- }
208
- })
209
- })
210
-
211
-
212
-
213
- jsonic.rule('path', () => {
214
- return new RuleSpec({
215
- open: [
216
- { s: [FS, [TX, ST, NR, VL]], p: 'part', b: 2 }
217
- ],
218
- bo: (r: Rule) => r.node = new RefVal('/')
219
- })
220
- })
221
-
222
-
223
- jsonic.rule('part', () => {
224
- return new RuleSpec({
225
- open: [
226
- {
227
- s: [FS, [TX, ST, NR, VL]], r: 'part', a: (r: Rule) => {
228
- r.node.append(r.open[1].src)
229
- }
136
+ 'dot-prefix': {
137
+ src: '.',
138
+ prefix: true,
139
+ right: 14_000_000,
230
140
  },
231
- {}, // no more parts
232
- ],
233
- })
234
- })
235
141
 
236
-
237
- // pref is a unary operator: *1
238
- jsonic.rule('pref', () => {
239
- return new RuleSpec({
240
- open: [
241
- {
242
- s: [AK, [NR, TX, ST, VL, OB, OS, FS]], b: 1,
243
- p: 'val',
142
+ 'star': {
143
+ src: '*',
144
+ prefix: true,
145
+ right: 14_000_000,
244
146
  },
245
- ],
246
- close: [
247
- // Can't be in a conjunct
248
- { s: [CJ], e: (r: Rule) => r.open[1] },
249
- {}
250
- ],
251
- ac: (r: Rule) => {
252
- r.node = new PrefVal(r.child.node)
147
+ },
148
+ evaluate: (op: Op, terms: any) => {
149
+ // console.log('LANG EVAL', op, terms)
150
+ return opmap[op.name](op, terms)
253
151
  }
254
152
  })
255
- })
256
153
 
154
+ // console.log(jsonic.token)
155
+ let CJ = jsonic.token['#E&']
156
+ let CL = jsonic.token.CL
157
+
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
+ // })
257
365
 
258
366
 
259
- jsonic.rule('val', (rs: RuleSpec) => {
260
- rs.def.open.unshift(
261
- // Prefs are always within an expression
262
- { s: [AK, [NR, TX, ST, VL, OB, OS, FS]], p: 'expr', b: 2 },
263
- { s: [FS, [TX, ST, NR, VL]], p: 'path', b: 2 },
264
- )
265
- rs.def.close.unshift(
266
- {
267
- s: [[CJ, DJ]], p: 'expr', b: 1, c: (r: Rule) => {
268
- return null == r.n.expr || 0 === r.n.expr
269
- }
270
- },
271
- )
272
367
 
273
- let orig_bc = rs.def.bc
368
+ 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
+
383
+ // TODO: wrap utility needed for jsonic to do this?
384
+ let orig_bc: any = rs.def.bc
274
385
  rs.def.bc = function(rule: Rule, ctx: Context) {
275
386
  let out = orig_bc.call(this, rule, ctx)
276
387
 
277
- let valnode = rule.node
388
+ let valnode: Val = rule.node
278
389
  let valtype = typeof valnode
279
390
 
280
391
  if ('string' === valtype) {
@@ -292,6 +403,13 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
292
403
  valnode = new BooleanVal(rule.node)
293
404
  }
294
405
 
406
+ let st = rule.o0
407
+ valnode.row = st.rI
408
+ valnode.col = st.cI
409
+
410
+ // JSONIC-UPDATE: still valid? check multisource
411
+ valnode.url = ctx.meta.multisource && ctx.meta.multisource.path
412
+
295
413
  rule.node = valnode
296
414
 
297
415
  return out
@@ -300,6 +418,7 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
300
418
  })
301
419
 
302
420
 
421
+
303
422
  jsonic.rule('map', (rs: RuleSpec) => {
304
423
  let orig_bc = rs.def.bc
305
424
  rs.def.bc = function(rule: Rule, ctx: Context) {
@@ -312,42 +431,72 @@ let AontuJsonic: Plugin = function aontu(jsonic: Jsonic) {
312
431
  return rs
313
432
  })
314
433
 
434
+
435
+ jsonic.rule('pair', (rs: RuleSpec) => {
436
+ let orig_bc: any = rs.def.bc
437
+ rs
438
+ .open([{ s: [CJ, CL], p: 'val', u: { spread: true }, g: 'spread' }])
439
+ .bc((...rest: any) => {
440
+ orig_bc(...rest)
441
+
442
+ let rule = rest[0]
443
+ if (rule.use.spread) {
444
+ rule.node[MapVal.SPREAD] =
445
+ (rule.node[MapVal.SPREAD] || { o: rule.o0.src, v: [] })
446
+ rule.node[MapVal.SPREAD].v.push(rule.child.node)
447
+ }
448
+ })
449
+ return rs
450
+ })
451
+
315
452
  }
316
453
 
317
454
 
455
+ const includeFileResolver = makeFileResolver((spec: any) => {
456
+ return 'string' === typeof spec ? spec : spec?.peg
457
+ })
318
458
 
319
459
 
320
460
  class Lang {
321
461
  jsonic: Jsonic
462
+ options: Options = {
463
+ src: '',
464
+ print: -1,
465
+ }
322
466
 
323
467
  constructor(options?: Partial<Options>) {
468
+ this.options = Object.assign({}, this.options, options)
324
469
  this.jsonic = Jsonic.make()
325
470
  .use(AontuJsonic)
326
471
  .use(MultiSource, {
327
- resolver: options ? options.resolver : undefined
472
+ resolver: options?.resolver || includeFileResolver
328
473
  })
329
474
  }
330
475
 
331
- parse<T extends string | string[]>(src: T, opts?: any):
332
- (T extends string ? Val : Val[]) {
476
+ parse(src: string, opts?: any): Val {
333
477
 
334
- let jm: any = {}
478
+ // JSONIC-UPDATE - check meta
479
+ let jm: any = {
480
+ multisource: {
481
+ // NOTE: multisource has property `path` NOT `base`
482
+ path: this.options.base,
483
+ deps: (opts && opts.deps) || undefined
484
+ }
485
+ }
335
486
 
487
+ // Pass through Jsonic debug log value
336
488
  if (opts && null != opts.log && Number.isInteger(opts.log)) {
337
489
  jm.log = opts.log
338
490
  }
339
491
 
340
- if (Array.isArray(src)) {
341
- return (src.map(s => this.jsonic(s, jm)) as any)
342
- }
343
- else {
344
- return this.jsonic(src, jm)
345
- }
492
+ let val = this.jsonic(src, jm)
346
493
 
494
+ return val
347
495
  }
348
496
  }
349
497
 
350
-
351
498
  export {
352
- Lang
499
+ Lang,
500
+ Site,
501
+ includeFileResolver,
353
502
  }
@@ -0,0 +1,39 @@
1
+ /* Copyright (c) 2021 Richard Rodger, MIT License */
2
+
3
+
4
+ import { Site } from '../lang'
5
+ import { Context } from '../unify'
6
+ import { Val, DisjunctVal } from '../val'
7
+ import { Operation } from './op'
8
+
9
+
10
+ const disjunct: Operation = (ctx?: Context, a?: Val, b?: Val) => {
11
+ let peers: Val[] = []
12
+ let origsites: Site[] = []
13
+ origsites.push(append(peers, a))
14
+ origsites.push(append(peers, b))
15
+ let out = new DisjunctVal(peers, ctx, origsites)
16
+ return out
17
+ }
18
+
19
+
20
+ function append(peers: Val[], v?: Val) {
21
+ let origsite: Site = Site.NONE
22
+
23
+ if (v instanceof DisjunctVal) {
24
+ peers.push(...v.peg)
25
+ origsite = v.site
26
+ }
27
+
28
+ // TODO: handle no-error Nil (drop) and error Nil (keep and become)
29
+ else if (v instanceof Val) {
30
+ peers.push(v)
31
+ }
32
+
33
+ return origsite
34
+ }
35
+
36
+
37
+ export {
38
+ disjunct
39
+ }