@bablr/bablr-vm 0.23.8 → 0.23.10

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/evaluate.js CHANGED
@@ -3,7 +3,7 @@ import { Coroutine } from '@bablr/coroutine';
3
3
  import {
4
4
  buildAttributeDefinition,
5
5
  buildCloseNodeTag,
6
- buildTypedSpan,
6
+ buildSpan,
7
7
  deepFreeze,
8
8
  } from '@bablr/agast-helpers/builders';
9
9
  import { getStreamIterator, printType, StreamIterable, wait } from '@bablr/agast-helpers/stream';
@@ -18,15 +18,36 @@ import {
18
18
  ShiftTag,
19
19
  AttributeDefinition,
20
20
  } from '@bablr/agast-helpers/symbols';
21
- import { getRoot, treeFromStreamSync } from '@bablr/agast-helpers/tree';
21
+ import { treeFromStreamSync } from '@bablr/agast-helpers/tree';
22
22
  import * as Tags from '@bablr/agast-helpers/tags';
23
- import { getEmbeddedTag } from '@bablr/agast-vm-helpers/deembed';
23
+ import { getEmbeddedRegex, getEmbeddedTag } from '@bablr/agast-vm-helpers/deembed';
24
24
  import { Match } from './match.js';
25
- import { buildWriteEffect } from '@bablr/agast-vm-helpers/builders';
26
- import { has } from '@bablr/agast-helpers/object';
25
+ import { buildEmbeddedRegex, buildWriteEffect } from '@bablr/agast-vm-helpers/builders';
26
+ import { has, isString } from '@bablr/agast-helpers/object';
27
27
  import { reifyBablrOptions } from '@bablr/agast-vm-helpers';
28
- import { buildNode, getTags } from '@bablr/agast-helpers/path';
28
+ import { buildNode, getTags, list } from '@bablr/agast-helpers/path';
29
29
  import * as Spans from '@bablr/agast-helpers/spans';
30
+ import {
31
+ buildAlternative,
32
+ buildAlternatives,
33
+ buildLiteralElements,
34
+ buildPattern,
35
+ } from '@bablr/helpers/builders';
36
+
37
+ let mergePatterns = (a, b) => {
38
+ if (a == null && b == null) return null;
39
+ if (a == null) return b;
40
+ if (b == null) return a;
41
+
42
+ let a_ = isString(a) ? [buildAlternative(buildLiteralElements(a))] : list('alternatives', a);
43
+ let b_ = isString(b) ? [buildAlternative(buildLiteralElements(b))] : list('alternatives', b);
44
+
45
+ return buildEmbeddedRegex(buildPattern(buildAlternatives([...a_, ...b_])));
46
+ };
47
+
48
+ let unwrapPattern = (pattern) => {
49
+ return isString(pattern) ? pattern : getEmbeddedRegex(pattern);
50
+ };
30
51
 
31
52
  const getSourceLength = (tags) => {
32
53
  let i = 0;
@@ -67,7 +88,7 @@ function* __bablr(ctx, rootSource, rootLanguage, strategy, options, registerNode
67
88
  throw new Error('holdUndefinedAttributes not implemented');
68
89
  }
69
90
 
70
- let co = new Coroutine(getStreamIterator(strategy(ctx.getPublic(), rootLanguage, getState)));
91
+ let co = new Coroutine(getStreamIterator(strategy(ctx.getPublic(), getState)));
71
92
 
72
93
  co.advance();
73
94
 
@@ -333,12 +354,23 @@ function* __bablr(ctx, rootSource, rootLanguage, strategy, options, registerNode
333
354
  case 'startSpan': {
334
355
  let { arguments: { 0: name, 1: guard = null, 2: { value: props } } = [] } = instr;
335
356
  deepFreeze(props);
336
- s.spans = Spans.push(s.spans, buildTypedSpan('Instruction', name, guard, props));
357
+ s.spans = Spans.push(s.spans, buildSpan(name, guard, props));
358
+ break;
359
+ }
360
+
361
+ case 'startSubspan': {
362
+ let { arguments: { 0: name, 1: guard = null, 2: { value: props } } = [] } = instr;
363
+ deepFreeze(props);
364
+
365
+ let name_ = name == null ? s.span.name : `${s.span.name}:${name}`;
366
+ let guard_ = mergePatterns(unwrapPattern(guard), unwrapPattern(s.span.guard));
367
+ let props_ = deepFreeze({ ...s.span.props, ...props });
368
+
369
+ s.spans = Spans.push(s.spans, buildSpan(name_, guard_, props_));
337
370
  break;
338
371
  }
339
372
 
340
373
  case 'endSpan': {
341
- if (s.span.type !== 'Instruction') throw new Error();
342
374
  s.spans = Spans.pop(s.spans);
343
375
  break;
344
376
  }
package/lib/facades.js CHANGED
@@ -2,13 +2,15 @@ import * as Tags from '@bablr/agast-helpers/tags';
2
2
  import { buildGapTag, buildPropertyTag } from '@bablr/agast-helpers/builders';
3
3
  import { buildFacadeLayer } from '@bablr/agast-vm-helpers/facades';
4
4
  import { buildNode, getTags, isStubNode } from '@bablr/agast-helpers/path';
5
- import { Property } from '@bablr/agast-helpers/symbols';
5
+ import { GapNode, Property } from '@bablr/agast-helpers/symbols';
6
6
 
7
7
  export const { facades, actuals } = buildFacadeLayer();
8
8
 
9
9
  let gapNodes = new WeakMap();
10
10
 
11
- export const getGapNode = (gap) => gapNodes.get(gap);
11
+ export const getGapNode = (node) => {
12
+ return node.type === GapNode ? gapNodes.get(node) || node : node;
13
+ };
12
14
 
13
15
  export const buildFacadeNode = (node) => {
14
16
  if (!node) return null;
package/lib/match.js CHANGED
@@ -37,7 +37,6 @@ import {
37
37
  Path,
38
38
  TagPath,
39
39
  } from '@bablr/agast-helpers/path';
40
- import { updateSpans } from './spans.js';
41
40
 
42
41
  let facades = new WeakMap();
43
42
 
@@ -84,8 +83,6 @@ export class Match {
84
83
  ? parentMatch.startFrame(s, matcher, effects, isShift ? finishedMatch : null, options)
85
84
  : Match.from(ctx, s, matcher, null, options);
86
85
 
87
- updateSpans(m, 'open');
88
-
89
86
  if (m.name && !getProduction(m.grammar, m.name))
90
87
  throw new Error(`Production {type: ${printType(m.name)}} does not exist`);
91
88
 
@@ -134,7 +131,7 @@ export class Match {
134
131
  normalizeBindingPath(matcher.bindingMatchers).length || !parent ? this : parent.languageMatch;
135
132
  this.agast = null;
136
133
  this.cover =
137
- !parent?.isNode && parent?.cover && matcher.refMatcher?.type !== '#'
134
+ !shiftMatch && !parent?.isNode && parent?.cover && matcher.refMatcher?.type !== '#'
138
135
  ? parent.cover
139
136
  : isCover && parent
140
137
  ? this
@@ -376,8 +373,6 @@ export class Match {
376
373
 
377
374
  if (!m) return m;
378
375
 
379
- updateSpans(finishedMatch, 'close');
380
-
381
376
  if (shouldBranch(finishedMatch.effects)) {
382
377
  if (finishedMatch.effects.success !== 'none') {
383
378
  s = s.accept();
package/lib/state.js CHANGED
@@ -6,11 +6,14 @@ import { reifyExpression } from '@bablr/agast-vm-helpers';
6
6
  import { Matcher, Node, Regex } from '@bablr/agast-vm-helpers/symbols';
7
7
  import { match, guardWithPattern } from './utils/pattern.js';
8
8
  import { getOpenTag } from '@bablr/agast-helpers/path';
9
+ import { buildSpan } from '@bablr/agast-helpers/builders';
10
+
11
+ let { freeze } = Object;
9
12
 
10
13
  export const nodeStates = new WeakMap();
11
14
 
12
15
  export const State = class BABLRState {
13
- static from(source, context, language, spans = Spans.fromValues([])) {
16
+ static from(source, context, language, spans = Spans.fromValues([buildSpan('Bare')])) {
14
17
  return new State(null, source, context, BTree.fromValues([language]), spans);
15
18
  }
16
19
 
@@ -88,19 +91,22 @@ export const State = class BABLRState {
88
91
  getPublic() {
89
92
  let { languages, spans, depths, held, node, source, result, resultPath, status } = this;
90
93
 
91
- return Object.freeze({
94
+ return freeze({
92
95
  languages,
93
96
  span: Spans.getAt(-1, spans),
94
97
  spans: spans,
95
- depths: Object.freeze({ ...depths }),
98
+ depths: freeze({ ...depths }),
96
99
  holding: !!held,
97
100
  held,
98
101
  node,
99
102
  atGap: source.atGap,
100
103
  done: source.done,
101
- sourceIndex: source.index,
104
+ source: freeze({
105
+ index: source.index,
106
+ done: source.done,
107
+ }),
102
108
  result,
103
- resultPath: resultPath?.frames || null,
109
+ resultPath: resultPath?.asPrimitive() || null,
104
110
  status,
105
111
  });
106
112
  }
@@ -131,11 +131,13 @@ function* __stringEqual(str, iterable) {
131
131
  let strStep = strIter.next();
132
132
  step = iter.next();
133
133
 
134
- while (!strStep.done) {
134
+ while (true) {
135
135
  if (step instanceof Promise) {
136
136
  step = yield wait(step);
137
137
  }
138
138
 
139
+ if (strStep.done) break;
140
+
139
141
  if (step.value !== strStep.value) {
140
142
  step = iter.return();
141
143
  if (step instanceof Promise) {
@@ -166,9 +168,11 @@ export const match = (pattern, source) => {
166
168
  ? [buildOpenNodeTag(tokenFlags), buildLiteralTag(pattern), buildCloseNodeTag()]
167
169
  : null;
168
170
  } else if (typeof pattern === 'string') {
169
- return stringEqual(pattern, source)
170
- ? [buildOpenNodeTag(tokenFlags), buildLiteralTag(pattern), buildCloseNodeTag()]
171
- : null;
171
+ return maybeWait(stringEqual(pattern, source), (equal) => {
172
+ return equal
173
+ ? [buildOpenNodeTag(tokenFlags), buildLiteralTag(pattern), buildCloseNodeTag()]
174
+ : null;
175
+ });
172
176
  }
173
177
 
174
178
  const pattern_ =
@@ -197,7 +201,7 @@ export const match = (pattern, source) => {
197
201
 
198
202
  class GuardedIterator {
199
203
  constructor(pattern, source) {
200
- this.pattern = pattern;
204
+ this.pattern = typeof pattern === 'string' ? pattern : pattern.value;
201
205
  this.source = source.branch();
202
206
  this.done = false;
203
207
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bablr/bablr-vm",
3
3
  "description": "A VM for parsing using BABLR languages",
4
- "version": "0.23.8",
4
+ "version": "0.23.10",
5
5
  "author": "Conrad Buck<conartist6@gmail.com>",
6
6
  "type": "module",
7
7
  "files": [
@@ -12,11 +12,11 @@
12
12
  },
13
13
  "sideEffects": false,
14
14
  "dependencies": {
15
- "@bablr/agast-helpers": "0.10.4",
16
- "@bablr/agast-vm": "0.11.4",
17
- "@bablr/agast-vm-helpers": "0.10.4",
15
+ "@bablr/agast-helpers": "0.10.10",
16
+ "@bablr/agast-vm": "0.11.5",
17
+ "@bablr/agast-vm-helpers": "0.10.5",
18
18
  "@bablr/coroutine": "0.1.0",
19
- "@bablr/helpers": "0.25.4",
19
+ "@bablr/helpers": "0.25.5",
20
20
  "@bablr/regex-vm": "0.14.2",
21
21
  "@bablr/stream-iterator": "2.0.0",
22
22
  "@iter-tools/imm-stack": "1.2.0",
package/lib/spans.js DELETED
@@ -1,38 +0,0 @@
1
- import { ReferenceTag } from '@bablr/agast-helpers/symbols';
2
- import * as Spans from '@bablr/agast-helpers/spans';
3
- import { buildTypedSpan } from '@bablr/agast-helpers/builders';
4
-
5
- const popSpan = (s) => {
6
- s.spans = Spans.pop(s.spans);
7
- };
8
-
9
- const pushSpan = (s, type, name, guard) => {
10
- s.spans = Spans.push(s.spans, buildTypedSpan(type, name, guard));
11
- };
12
-
13
- export function updateSpans(m, phase) {
14
- const { state: s } = m;
15
- const refPath = m.reference;
16
-
17
- if (refPath && refPath.tag.type !== ReferenceTag) throw new Error();
18
-
19
- switch (phase) {
20
- case 'open': {
21
- if (m.language !== m.parent?.language) {
22
- pushSpan(s, 'Explicit', 'Bare', null);
23
- }
24
-
25
- break;
26
- }
27
-
28
- case 'close': {
29
- if (m.language !== m.parent?.language) {
30
- popSpan(s);
31
- }
32
-
33
- break;
34
- }
35
- default:
36
- throw new Error();
37
- }
38
- }