@bablr/bablr-vm 0.20.1 → 0.22.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.
@@ -1,9 +1,13 @@
1
1
  import isString from 'iter-tools-es/methods/is-string';
2
2
  import isEmpty from 'iter-tools-es/methods/is-empty';
3
3
  import { generateMatches } from '@bablr/regex-vm';
4
- import { getStreamIterator, maybeWait, printType } from '@bablr/agast-helpers/stream';
5
- import * as sumtree from '@bablr/agast-helpers/sumtree';
6
- import * as l from '@bablr/agast-vm-helpers/languages';
4
+ import {
5
+ getStreamIterator,
6
+ maybeWait,
7
+ printType,
8
+ StreamIterable,
9
+ } from '@bablr/agast-helpers/stream';
10
+ import * as Tags from '@bablr/agast-helpers/tags';
7
11
  import {
8
12
  buildAlternative,
9
13
  buildAlternatives,
@@ -14,10 +18,41 @@ import {
14
18
  } from '@bablr/helpers/builders';
15
19
  import { buildEmbeddedRegex } from '@bablr/agast-vm-helpers/builders';
16
20
  import { GapTag, LiteralTag } from '@bablr/agast-helpers/symbols';
21
+ import {
22
+ buildCloseNodeTag,
23
+ buildLiteralTag,
24
+ buildOpenNodeTag,
25
+ tokenFlags,
26
+ } from '@bablr/agast-helpers/builders';
27
+ import { streamIteratorSymbol } from '@bablr/stream-iterator';
28
+
29
+ function* __wrapSource(source) {
30
+ let source_ = source.source || source;
31
+ if ('\r\n'.includes(source_.prevValue)) {
32
+ yield '\n';
33
+ } else if (source_.index === 0) {
34
+ yield Symbol.for('BOS');
35
+ } else {
36
+ yield '';
37
+ }
38
+ let iter = getStreamIterator(source);
17
39
 
18
- export const assertValidRegex = (expr) => {
19
- const { flags } = expr;
40
+ let step = iter.next();
41
+ while (!step.done) {
42
+ yield step.value;
43
+ step = iter.next();
44
+ }
45
+
46
+ iter.return();
47
+
48
+ yield Symbol.for('EOS');
49
+ }
20
50
 
51
+ export const wrapSource = (source) => {
52
+ return new StreamIterable(__wrapSource(source));
53
+ };
54
+
55
+ export const assertValidRegex = (expr) => {
21
56
  if (!expr.language === 'Spamex' && expr.type === 'Regex') {
22
57
  throw new Error();
23
58
  }
@@ -28,7 +63,7 @@ export const assertValidRegex = (expr) => {
28
63
  const buildStringRegex = (str) => {
29
64
  return buildPattern(
30
65
  buildAlternatives([
31
- buildAlternative(buildElements([...str].map((chr) => buildToken(l.Regex, 'Character', chr)))),
66
+ buildAlternative(buildElements([...str].map((chr) => buildToken('Character', chr)))),
32
67
  ]),
33
68
  );
34
69
  };
@@ -38,10 +73,10 @@ const buildFragmentRegex = (frag) => {
38
73
  buildAlternatives([
39
74
  buildAlternative(
40
75
  buildElements(
41
- [...sumtree.traverse(frag.children)].flatMap((tag) => {
76
+ [...Tags.traverse(frag.tags)].flatMap((tag) => {
42
77
  if (tag.type === LiteralTag) {
43
78
  let str = tag.value;
44
- return [...str].map((chr) => buildToken(l.Regex, 'Character', chr));
79
+ return [...str].map((chr) => buildToken('Character', chr));
45
80
  } else if (tag.type === GapTag) {
46
81
  return [buildRegexGap()];
47
82
  } else {
@@ -54,7 +89,64 @@ const buildFragmentRegex = (frag) => {
54
89
  );
55
90
  };
56
91
 
92
+ const promiseCo = (gen) => {
93
+ return (...args) => {
94
+ let generator = gen(...args);
95
+
96
+ const fn = (step) => {
97
+ if (step.done) {
98
+ return step.value;
99
+ } else if (step.value instanceof Promise) {
100
+ return step.value.then((value) => {
101
+ return fn(generator.next(value));
102
+ });
103
+ }
104
+ };
105
+
106
+ return fn(generator.next());
107
+ };
108
+ };
109
+
110
+ function* __stringEqual(str, iterable) {
111
+ let strIter = str[Symbol.iterator]();
112
+ let iter = getStreamIterator(iterable);
113
+
114
+ let strStep = strIter.next();
115
+ let step = iter.next();
116
+
117
+ while (!strStep.done) {
118
+ if (step instanceof Promise) {
119
+ step = yield step;
120
+ }
121
+
122
+ if (step.value !== strStep.value) {
123
+ iter.return();
124
+ return false;
125
+ }
126
+
127
+ strStep = strIter.next();
128
+ step = iter.next();
129
+ }
130
+
131
+ iter.return();
132
+ return true;
133
+ }
134
+
135
+ const stringEqual = (str, iterable) => {
136
+ return promiseCo(__stringEqual)(str, iterable);
137
+ };
138
+
57
139
  export const match = (pattern, source) => {
140
+ if (typeof pattern === 'string' && pattern.length === 1) {
141
+ return pattern === source.value
142
+ ? [buildOpenNodeTag(tokenFlags), buildLiteralTag(pattern), buildCloseNodeTag()]
143
+ : null;
144
+ } else if (typeof pattern === 'string') {
145
+ return stringEqual(pattern, source)
146
+ ? [buildOpenNodeTag(tokenFlags), buildLiteralTag(pattern), buildCloseNodeTag()]
147
+ : null;
148
+ }
149
+
58
150
  const pattern_ =
59
151
  pattern.type === null && pattern.flags.token
60
152
  ? buildFragmentRegex(pattern)
@@ -66,12 +158,13 @@ export const match = (pattern, source) => {
66
158
 
67
159
  assertValidRegex(pattern_);
68
160
 
69
- const iter = getStreamIterator(generateMatches(buildEmbeddedRegex(pattern_), source));
161
+ const iter = getStreamIterator(generateMatches(buildEmbeddedRegex(pattern_), wrapSource(source)));
70
162
 
71
163
  const step = iter.next();
72
164
 
73
165
  return maybeWait(step, (step) => {
74
166
  const result = step.done ? null : step.value[0];
167
+ iter.return();
75
168
  return isEmpty(result) ? null : result;
76
169
  });
77
170
  };
@@ -79,35 +172,40 @@ export const match = (pattern, source) => {
79
172
  class GuardedIterator {
80
173
  constructor(pattern, source) {
81
174
  this.pattern = pattern;
82
- this.fork = source.fork.clone();
175
+ this.source = source.branch();
83
176
  this.done = false;
84
177
  }
85
178
 
179
+ get value() {
180
+ return this.source.value;
181
+ }
182
+
86
183
  next() {
87
- const { pattern, fork } = this;
184
+ const { pattern, source } = this;
88
185
 
89
- const guardMatch = match(pattern, fork.clone());
186
+ const guardMatch = match(pattern, source);
90
187
 
91
188
  return maybeWait(guardMatch, (guardMatch) => {
92
- if (guardMatch || fork.done) {
189
+ if (guardMatch || source.done) {
93
190
  this.done = true;
191
+ source.release();
94
192
  return { value: undefined, done: true };
95
193
  } else {
96
- const { value } = fork;
97
- return maybeWait(fork.advance(), (_) => ({ value, done: false }));
194
+ const { value } = source;
195
+ return maybeWait(source.advance(), (_) => ({ value, done: false }));
98
196
  }
99
197
  });
100
198
  }
101
199
 
102
200
  return() {
103
- this.fork.return();
201
+ this.source.release();
104
202
  }
105
203
 
106
- [Symbol.for('@@streamIterator')]() {
204
+ [streamIteratorSymbol]() {
107
205
  return this;
108
206
  }
109
207
  }
110
208
 
111
209
  export const guardWithPattern = (pattern, source) => {
112
- return new GuardedIterator(pattern, source.branch());
210
+ return new GuardedIterator(pattern, source);
113
211
  };
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.20.1",
4
+ "version": "0.22.0",
5
5
  "author": "Conrad Buck<conartist6@gmail.com>",
6
6
  "type": "module",
7
7
  "files": [
@@ -12,14 +12,14 @@
12
12
  },
13
13
  "sideEffects": false,
14
14
  "dependencies": {
15
- "@bablr/agast-helpers": "0.7.1",
16
- "@bablr/agast-vm": "0.8.1",
17
- "@bablr/agast-vm-helpers": "0.7.1",
15
+ "@bablr/agast-helpers": "0.9.0",
16
+ "@bablr/agast-vm": "0.10.0",
17
+ "@bablr/agast-vm-helpers": "0.9.0",
18
18
  "@bablr/coroutine": "0.1.0",
19
- "@bablr/helpers": "0.22.1",
20
- "@bablr/regex-vm": "0.11.1",
21
- "@bablr/weak-stack": "1.0.0",
22
- "@iter-tools/imm-stack": "1.1.0",
19
+ "@bablr/helpers": "0.24.0",
20
+ "@bablr/regex-vm": "0.13.0",
21
+ "@bablr/weak-stack": "1.0.1",
22
+ "@iter-tools/imm-stack": "1.2.0",
23
23
  "iter-tools-es": "7.5.3"
24
24
  },
25
25
  "devDependencies": {
@@ -1,13 +0,0 @@
1
- export const isArray = Array;
2
-
3
- export const notEmpty = (arr) => arr != null && arr.length > 0;
4
-
5
- export const nullOr = (arr) => (arr.length === 0 ? null : arr);
6
-
7
- export function* arraySlice(arr, start, end) {
8
- const increment = end > start ? 1 : -1;
9
-
10
- for (let i = start; i < end; i += increment) {
11
- yield arr[i];
12
- }
13
- }
@@ -1,9 +0,0 @@
1
- export const formatType = (type) => {
2
- return typeof type === 'symbol' ? `${type.description.replace(/^@bablr\//y, '')}` : `'${type}'`;
3
- };
4
-
5
- export const formatGraveString = (str) => {
6
- return `\`${str
7
- .replace(/`/g, '\\`')
8
- .replace(/[\r\n\u{00}\u{08}\u{0B}\u{0C}\u{0E}-\u{1F}]/gu, '')}\``;
9
- };
@@ -1,97 +0,0 @@
1
- export const { hasOwn, freeze, isFrozen, seal, isSealed, getOwnPropertySymbols } = Object;
2
- export const { isArray } = Array;
3
-
4
- const intFrom = (str) => {
5
- const value = parseInt(str, 10);
6
- return isNaN(value) ? null : value;
7
- };
8
-
9
- export const has = (obj, property) => {
10
- let value = obj;
11
- for (const part of property.split('.')) {
12
- if (!hasOwn(value, part)) return false;
13
- value = value[part];
14
- }
15
- return true;
16
- };
17
-
18
- export const get = (obj, property) => {
19
- let value = obj;
20
- for (const part of property.split('.')) {
21
- value = value[part];
22
- }
23
- return value;
24
- };
25
-
26
- export const set = (obj, property, value) => {
27
- const parts = property.split('.');
28
- let obj_ = obj;
29
-
30
- let lastKey;
31
- for (let i = 0; i < parts.length; i++) {
32
- const intKey = intFrom(parts[i]);
33
- const key = intKey !== null ? intKey : parts[i];
34
- let value = obj_[key];
35
-
36
- if (parts.length - 1 === i) {
37
- lastKey = key;
38
- } else if (value !== undefined) {
39
- obj_ = value;
40
- } else if (intFrom(parts[i + 1]) !== null) {
41
- obj_ = value = obj_[key] = [];
42
- } else {
43
- throw new Error(`Unable to set {property: '${property}'} in obj`);
44
- }
45
- }
46
-
47
- obj_[lastKey] = value;
48
- };
49
-
50
- export function objectKeys(obj) {
51
- return {
52
- *[Symbol.iterator]() {
53
- for (let key in obj) if (hasOwn(obj, key)) yield key;
54
- yield* getOwnPropertySymbols(obj);
55
- },
56
- };
57
- }
58
-
59
- export function objectValues(obj) {
60
- return {
61
- *[Symbol.iterator]() {
62
- for (let key in obj) if (hasOwn(obj, key)) yield obj[key];
63
- yield* getOwnPropertySymbols(obj).map((sym) => obj[sym]);
64
- },
65
- };
66
- }
67
-
68
- export function objectEntries(obj) {
69
- return {
70
- *[Symbol.iterator]() {
71
- for (let key in obj) if (hasOwn(obj, key)) yield [key, obj[key]];
72
- yield* getOwnPropertySymbols(obj).map((sym) => [sym, obj[sym]]);
73
- },
74
- };
75
- }
76
-
77
- export const isObject = (obj) => obj !== null && typeof obj === 'object';
78
- export const isFunction = (obj) => typeof obj === 'function';
79
- export const isSymbol = (obj) => typeof obj === 'symbol';
80
- export const isString = (obj) => typeof obj === 'string';
81
- export const isType = (obj) => isSymbol(obj) || isString(obj);
82
- export const isRegex = (obj) => obj instanceof RegExp;
83
- export const isPattern = (obj) => isString(obj) || isRegex(obj);
84
-
85
- export const memoize = (fn) => {
86
- const cache = new WeakMap();
87
- return (obj) => {
88
- let result;
89
- if (cache.has(obj)) {
90
- result = cache.get(obj);
91
- } else {
92
- result = fn(obj);
93
- cache.set(obj, result);
94
- }
95
- return result;
96
- };
97
- };
package/lib/utils/pump.js DELETED
@@ -1,20 +0,0 @@
1
- export class Pump {
2
- constructor() {
3
- this.held = [];
4
- }
5
-
6
- queue(value) {
7
- this.held.push(value);
8
- }
9
-
10
- next() {
11
- const held = this.held[0];
12
- if (!held) throw new Error();
13
- this.held.shift();
14
- return { done: false, value: held };
15
- }
16
-
17
- [Symbol.iterator]() {
18
- return this;
19
- }
20
- }
@@ -1,30 +0,0 @@
1
- import { buildLiteralTag, buildGapTag } from '@bablr/agast-helpers/builders';
2
-
3
- export const isNewlineToken = (token) => /^\r|\r\n|\n$/.test(token.value);
4
-
5
- export function* ownChildrenFor(range) {
6
- throw new Error('unimplemented');
7
- }
8
-
9
- export function* allChildrenFor(range) {
10
- throw new Error('unimplemented');
11
- }
12
-
13
- export function* buildTokens(chrs) {
14
- let str = '';
15
- for (const chr of chrs) {
16
- if (chr == null) {
17
- if (str) {
18
- yield buildLiteralTag(str);
19
- str = '';
20
- }
21
- yield buildGapTag();
22
- } else {
23
- str += chr;
24
- }
25
- }
26
-
27
- if (str) {
28
- yield buildLiteralTag(str);
29
- }
30
- }