@bablr/helpers 0.20.6 → 0.21.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/decorators.js CHANGED
@@ -14,8 +14,9 @@ export const AllowEmpty = (desc, context) => {
14
14
  };
15
15
 
16
16
  export const CoveredBy = (type) => {
17
- if (!/^[a-zA-Z]+$/.test(printType(type))) throw new Error();
18
17
  return (desc, context) => {
18
+ if (!/^[a-zA-Z]+$/.test(printType(type))) throw new Error();
19
+
19
20
  context.addInitializer(function () {
20
21
  let covers = this.covers;
21
22
 
package/lib/enhancers.js CHANGED
@@ -3,9 +3,7 @@ import {
3
3
  enhanceStrategyBuilderWithEmittedLogging as logEmitted,
4
4
  } from '@bablr/strategy_enhancer-debug-log';
5
5
  import { enhanceProductionWithDebugLogging as createProductionLogger } from '@bablr/language_enhancer-debug-log';
6
- import { getOwnPropertySymbols, getPrototypeOf } from './object.js';
7
-
8
- const { getOwnPropertyNames, hasOwn } = Object;
6
+ import { mapProductions } from './grammar.js';
9
7
 
10
8
  export const memoize = (original) => {
11
9
  const cache = new WeakMap();
@@ -40,40 +38,10 @@ export const compose = (functions) => {
40
38
  return f;
41
39
  };
42
40
 
43
- export const mapProductions = (fn, Grammar) => {
44
- let { prototype } = Grammar;
45
-
46
- class MappedGrammar extends Grammar {}
47
-
48
- const mapped = MappedGrammar.prototype;
49
-
50
- while (prototype && prototype !== Object.prototype) {
51
- for (const key of [...getOwnPropertyNames(prototype), ...getOwnPropertySymbols(prototype)]) {
52
- if (!hasOwn(mapped, key)) {
53
- mapped[key] = fn(prototype[key], key);
54
- }
55
- }
56
- prototype = getPrototypeOf(prototype);
57
- }
58
-
59
- return MappedGrammar;
60
- };
61
-
62
- export function* generateProductions(Grammar) {
63
- let { prototype } = Grammar;
64
-
65
- while (prototype && prototype !== Object.prototype) {
66
- for (const key of [...getOwnPropertyNames(prototype), ...getOwnPropertySymbols(prototype)]) {
67
- let value = prototype[key];
68
- if (key !== 'constructor') yield [key, value];
69
- }
70
- prototype = getPrototypeOf(prototype);
71
- }
72
- }
73
-
74
41
  export const debugEnhancers = {
75
- // agast: (strategy) => logEmitted(strategy, '<<< '),
76
- createBablrStrategy: (strategy) => logStrategy(strategy, ' >>> '),
42
+ // bablr: (strategy) => logStrategy(strategy, '<<< '),
43
+ createBablrStrategy: (strategy) => (matcher, props) =>
44
+ logStrategy(strategy(matcher, props), ' >>> '),
77
45
  bablrProduction: createProductionLogger('>>> '),
78
46
  };
79
47
 
package/lib/grammar.js CHANGED
@@ -1,15 +1,55 @@
1
1
  import every from 'iter-tools-es/methods/every';
2
2
  import isString from 'iter-tools-es/methods/is-string';
3
- import { getPrototypeOf, objectEntries } from './object.js';
4
- import { OpenNodeTag, CloseNodeTag } from './symbols.js';
3
+ import { getOwnPropertySymbols, getPrototypeOf, objectEntries } from './object.js';
4
+ import { OpenNodeTag, CloseNodeTag, NullTag } from './symbols.js';
5
+ import { buildExpression } from './builders.js';
6
+ import { buildEmbeddedObject } from '@bablr/agast-helpers/tree';
5
7
 
6
8
  export * from './decorators.js';
7
9
 
10
+ const { getOwnPropertyNames, hasOwn } = Object;
11
+
8
12
  const { isArray } = Array;
9
13
  const isSymbol = (value) => typeof value === 'symbol';
10
14
  const isType = (value) => isString(value) || isSymbol(value);
11
15
 
16
+ export const notNull = (facade) => {
17
+ return facade && (facade.type !== null || facade.openTag.type !== NullTag);
18
+ };
19
+
20
+ export const mapProductions = (fn, Grammar) => {
21
+ let { prototype } = Grammar;
22
+
23
+ class MappedGrammar extends Grammar {}
24
+
25
+ const mapped = MappedGrammar.prototype;
26
+
27
+ while (prototype && prototype !== Object.prototype) {
28
+ for (const key of [...getOwnPropertyNames(prototype), ...getOwnPropertySymbols(prototype)]) {
29
+ if (!hasOwn(mapped, key)) {
30
+ mapped[key] = fn(prototype[key], key);
31
+ }
32
+ }
33
+ prototype = getPrototypeOf(prototype);
34
+ }
35
+
36
+ return MappedGrammar;
37
+ };
38
+
39
+ export function* generateProductions(Grammar) {
40
+ let { prototype } = Grammar;
41
+
42
+ while (prototype && prototype !== Object.prototype) {
43
+ for (const key of [...getOwnPropertyNames(prototype), ...getOwnPropertySymbols(prototype)]) {
44
+ let value = prototype[key];
45
+ if (key !== 'constructor') yield [key, value];
46
+ }
47
+ prototype = getPrototypeOf(prototype);
48
+ }
49
+ }
50
+
12
51
  export const resolveLanguage = (context, language, path) => {
52
+ const { languages } = context;
13
53
  if (isString(path)) {
14
54
  if (language.canonicalURL === path) {
15
55
  return language;
@@ -24,16 +64,18 @@ export const resolveLanguage = (context, language, path) => {
24
64
  throw new Error();
25
65
  }
26
66
 
67
+ let segments = isString(path) ? [path] : isArray(path) ? path : null;
68
+
27
69
  if (path == null) {
28
70
  return language;
29
- } else if (isString(path)) {
30
- l = l.dependencies[path];
31
- } else if (isArray(path)) {
32
- for (const segment of path) {
33
- l = l.dependencies[segment];
34
- }
35
71
  } else {
36
- throw new Error();
72
+ for (const segment of segments) {
73
+ if (isString(l.dependencies[segment])) {
74
+ l = languages.get(l.dependencies[segment]);
75
+ } else {
76
+ l = l.dependencies[segment];
77
+ }
78
+ }
37
79
  }
38
80
 
39
81
  return l;
@@ -91,7 +133,11 @@ export const getProduction = (grammar, type) => {
91
133
  };
92
134
 
93
135
  const __buildDependentLanguages = (language, languages = new Map()) => {
136
+ languages.set(language.canonicalURL, language);
137
+
94
138
  for (const dependentLanguage of Object.values(language.dependencies || {})) {
139
+ if (isString(dependentLanguage)) continue;
140
+
95
141
  const { canonicalURL } = dependentLanguage;
96
142
  if (languages.has(canonicalURL) && dependentLanguage !== languages.get(canonicalURL)) {
97
143
  throw new Error();
@@ -101,15 +147,25 @@ const __buildDependentLanguages = (language, languages = new Map()) => {
101
147
  __buildDependentLanguages(dependentLanguage, languages);
102
148
  }
103
149
  }
104
- languages.set(language.canonicalURL, language);
105
150
 
106
151
  return languages;
107
152
  };
108
153
 
109
- export const buildDependentLanguages = (language, transformLanguage = (l) => l) => {
154
+ export const buildDependentLanguages = (language) => {
110
155
  return __buildDependentLanguages(language);
111
156
  };
112
157
 
158
+ export const extendLanguage = (language, extension) => {
159
+ return {
160
+ ...language,
161
+ dependencies: extension.dependencies
162
+ ? { ...language.dependencies, ...extension.dependencies }
163
+ : language.dependencies,
164
+ canonicalURL: extension.canonicalURL || language.canonicalURL,
165
+ grammar: extension.grammar,
166
+ };
167
+ };
168
+
113
169
  const arrayLast = (arr) => arr[arr.length - 1];
114
170
 
115
171
  export function* zipLanguages(tags, rootLanguage) {
@@ -139,3 +195,53 @@ export function* zipLanguages(tags, rootLanguage) {
139
195
  yield [tag, arrayLast(languages)];
140
196
  }
141
197
  }
198
+
199
+ const safeShallowEmbed = (value) => {
200
+ if (typeof value !== 'object') {
201
+ return buildExpression(value);
202
+ } else {
203
+ return value;
204
+ }
205
+ };
206
+
207
+ const __buildCall = (verb, ...args) => {
208
+ while (args.length && args[args.length - 1] === undefined) {
209
+ args.pop();
210
+ }
211
+
212
+ return { verb, arguments: args };
213
+ };
214
+
215
+ export const eat = (matcher, value, options) => {
216
+ return __buildCall('eat', matcher, value, options);
217
+ };
218
+
219
+ export const eatMatch = (matcher, value, options) => {
220
+ return __buildCall('eatMatch', matcher, value, options);
221
+ };
222
+
223
+ export const match = (matcher, value, options) => {
224
+ return __buildCall('match', matcher, value, options);
225
+ };
226
+
227
+ export const guard = (matcher, value, options) => {
228
+ return __buildCall('guard', matcher, value, options);
229
+ };
230
+
231
+ export const holdForMatch = (matcher, value, options) => {
232
+ return __buildCall('holdForMatch', matcher, value, options);
233
+ };
234
+
235
+ export const fail = () => {
236
+ return __buildCall('fail');
237
+ };
238
+
239
+ export const bindAttribute = (key, value) => {
240
+ return __buildCall('bindAttribute', key, value);
241
+ };
242
+
243
+ export const write = (value) => {
244
+ return __buildCall('write', value);
245
+ };
246
+
247
+ export const o = buildEmbeddedObject;
@@ -1,127 +1,64 @@
1
1
  /* @macrome
2
2
  * @generatedby @bablr/macrome-generator-bablr
3
- * @generatedfrom ./productions.macro.js#ab30a55dff3676ff2418023be450dabe54386ee0
3
+ * @generatedfrom ./productions.macro.js#92256720d76d33560908ff2f462d2e33fc77b865
4
4
  * This file is autogenerated. Please do not edit it directly.
5
5
  * When editing run `npx macrome watch` then change the file this is generated from.
6
6
  */
7
- import { interpolateArray as _interpolateArray, interpolateFragmentChildren as _interpolateFragmentChildren, interpolateString as _interpolateString } from "@bablr/agast-helpers/template";
8
- import * as _l from "@bablr/agast-vm-helpers/languages";
9
- import * as _t from "@bablr/agast-helpers/shorthand";
7
+ import { spam as m } from '@bablr/boot';
8
+ import { buildEmbeddedMatcher, getCooked } from '@bablr/agast-helpers/tree';
9
+ import { eat, eatMatch } from './grammar.js';
10
+ import { EmbeddedMatcher } from './symbols.js';
11
+ import { getEmbeddedMatcher, getEmbeddedObject } from '@bablr/agast-vm-helpers/deembed';
12
+ import { buildPropertyMatcher } from './builders.js';
10
13
  export function* List({
11
- value: props,
12
- ctx
14
+ value: props
13
15
  }) {
14
16
  const {
15
17
  element,
16
18
  separator,
17
19
  allowHoles = false,
18
20
  allowTrailingSeparator = true
19
- } = ctx.unbox(props);
20
- yield _t.node(_l.Instruction, "Call", [_t.ref`verb`, _t.ref`arguments`], {
21
- verb: _t.s_node(_l.Instruction, "Identifier", "eat"),
22
- arguments: _t.node(_l.Instruction, "Tuple", [9, [[_t.ref`openToken`, _t.ref`values[]`, _t.arr(), _t.ref`values[]`], [_t.ref`separators[]`, _t.arr(), _t.ref`separators[]`, _t.ref`values[]`, _t.ref`closeToken`]]], {
23
- openToken: _t.s_node(_l.Instruction, "Punctuator", "("),
24
- values: [_t.node(_l.Instruction, "Array", [_t.ref`openToken`, _t.ref`closeToken`], {
25
- openToken: _t.s_node(_l.Instruction, "Punctuator", "["),
26
- closeToken: _t.s_node(_l.Instruction, "Punctuator", "]")
27
- }, {}), _t.node(_l.CSTML, "String", [_t.ref`openToken`, _t.ref`content`, _t.ref`closeToken`], {
28
- openToken: _t.s_node(_l.CSTML, "Punctuator", "'"),
29
- content: _t.node(_l.CSTML, "Content", [_t.lit("separators[]")], {}, {}),
30
- closeToken: _t.s_node(_l.CSTML, "Punctuator", "'")
31
- }, {})],
32
- separators: [_t.node(_l.Instruction, "Separator", [_t.embedded(_t.node(_l.Instruction, "Space", [_t.lit(" ")], {}, {}))], {}, {})],
33
- closeToken: _t.s_node(_l.Instruction, "Punctuator", ")")
34
- }, {})
35
- }, {});
21
+ } = getEmbeddedObject(props);
22
+ if (!['#', '@'].includes(getCooked(getEmbeddedMatcher(separator).properties.refMatcher.node.properties.name.node))) {
23
+ yield eat(buildEmbeddedMatcher(buildPropertyMatcher(getEmbeddedMatcher(separator).properties.refMatcher.node, m.ArrayNodeMatcher`[]`)));
24
+ }
25
+ yield eat(buildEmbeddedMatcher(buildPropertyMatcher(getEmbeddedMatcher(element).properties.refMatcher.node, m.ArrayNodeMatcher`[]`)));
36
26
  let sep,
37
27
  it,
38
28
  anySep = false;
39
29
  for (;;) {
40
- it = yield _t.node(_l.Instruction, "Call", [_t.ref`verb`, _t.ref`arguments`], {
41
- verb: _t.s_node(_l.Instruction, "Identifier", "eatMatch"),
42
- arguments: _t.node(_l.Instruction, "Tuple", [_t.ref`openToken`, _t.ref`values[]`, _t.arr(), ..._interpolateFragmentChildren(element, _t.ref`values[]`), _t.ref`closeToken`], {
43
- openToken: _t.s_node(_l.Instruction, "Punctuator", "("),
44
- values: [..._interpolateArray(element)],
45
- closeToken: _t.s_node(_l.Instruction, "Punctuator", ")")
46
- }, {})
47
- }, {});
30
+ it = yield eatMatch(element);
48
31
  if (it || allowTrailingSeparator) {
49
- sep = yield _t.node(_l.Instruction, "Call", [_t.ref`verb`, _t.ref`arguments`], {
50
- verb: _t.s_node(_l.Instruction, "Identifier", "eatMatch"),
51
- arguments: _t.node(_l.Instruction, "Tuple", [9, [[_t.ref`openToken`, _t.ref`values[]`, _t.arr(), ..._interpolateFragmentChildren(separator, _t.ref`values[]`)], [_t.ref`separators[]`, _t.arr(), _t.ref`separators[]`, _t.ref`values[]`, _t.ref`closeToken`]]], {
52
- openToken: _t.s_node(_l.Instruction, "Punctuator", "("),
53
- values: [..._interpolateArray(separator), _t.node(_l.CSTML, "String", [_t.ref`openToken`, _t.ref`content`, _t.ref`closeToken`], {
54
- openToken: _t.s_node(_l.CSTML, "Punctuator", "'"),
55
- content: _t.node(_l.CSTML, "Content", [_t.lit("separators[]")], {}, {}),
56
- closeToken: _t.s_node(_l.CSTML, "Punctuator", "'")
57
- }, {})],
58
- separators: [_t.node(_l.Instruction, "Separator", [_t.embedded(_t.node(_l.Instruction, "Space", [_t.lit(" ")], {}, {}))], {}, {})],
59
- closeToken: _t.s_node(_l.Instruction, "Punctuator", ")")
60
- }, {})
61
- }, {});
32
+ sep = yield eatMatch(separator);
62
33
  anySep ||= sep;
34
+ } else {
35
+ sep = null;
63
36
  }
64
37
  if (!(sep || allowHoles)) break;
65
38
  }
66
39
  }
67
40
  export function* Any({
68
- value: matchers,
69
- ctx
41
+ value: alternatives
70
42
  }) {
71
- for (const matcher of ctx.unbox(matchers)) {
72
- if (yield _t.node(_l.Instruction, "Call", [_t.ref`verb`, _t.ref`arguments`], {
73
- verb: _t.s_node(_l.Instruction, "Identifier", "eatMatch"),
74
- arguments: _t.node(_l.Instruction, "Tuple", [_t.ref`openToken`, _t.ref`values[]`, _t.arr(), ..._interpolateFragmentChildren(matcher, _t.ref`values[]`), _t.ref`closeToken`], {
75
- openToken: _t.s_node(_l.Instruction, "Punctuator", "("),
76
- values: [..._interpolateArray(matcher)],
77
- closeToken: _t.s_node(_l.Instruction, "Punctuator", ")")
78
- }, {})
79
- }, {})) break;
43
+ for (const alternative of alternatives) {
44
+ if (alternative.type === EmbeddedMatcher) {
45
+ if (yield eatMatch(alternative)) break;
46
+ } else {
47
+ throw new Error();
48
+ }
80
49
  }
81
50
  }
82
51
  export function* All({
83
- value: matchers,
84
- ctx
52
+ value: matchers
85
53
  }) {
86
- for (const matcher of ctx.unbox(matchers)) {
87
- yield _t.node(_l.Instruction, "Call", [_t.ref`verb`, _t.ref`arguments`], {
88
- verb: _t.s_node(_l.Instruction, "Identifier", "eat"),
89
- arguments: _t.node(_l.Instruction, "Tuple", [_t.ref`openToken`, _t.ref`values[]`, _t.arr(), ..._interpolateFragmentChildren(matcher, _t.ref`values[]`), _t.ref`closeToken`], {
90
- openToken: _t.s_node(_l.Instruction, "Punctuator", "("),
91
- values: [..._interpolateArray(matcher)],
92
- closeToken: _t.s_node(_l.Instruction, "Punctuator", ")")
93
- }, {})
94
- }, {});
54
+ for (const matcher of matchers) {
55
+ yield eat(m`.[]: ${getEmbeddedMatcher(matcher).properties.nodeMatcher.node}`);
95
56
  }
96
57
  }
97
58
  export function* Punctuator({
98
59
  intrinsicValue
99
60
  }) {
100
61
  if (!intrinsicValue) throw new Error('Intrinsic productions must have value');
101
- yield _t.node(_l.Instruction, "Call", [_t.ref`verb`, _t.ref`arguments`], {
102
- verb: _t.s_node(_l.Instruction, "Identifier", "eat"),
103
- arguments: _t.node(_l.Instruction, "Tuple", [_t.ref`openToken`, _t.ref`values[]`, _t.arr(), ..._interpolateFragmentChildren(intrinsicValue, _t.ref`values[]`), _t.ref`closeToken`], {
104
- openToken: _t.s_node(_l.Instruction, "Punctuator", "("),
105
- values: [..._interpolateArray(intrinsicValue)],
106
- closeToken: _t.s_node(_l.Instruction, "Punctuator", ")")
107
- }, {})
108
- }, {});
62
+ yield eat(intrinsicValue);
109
63
  }
110
- export const Keyword = Punctuator;
111
- export function* Optional({
112
- value: matchers,
113
- ctx
114
- }) {
115
- const matchers_ = ctx.unbox(matchers);
116
- if (matchers_.length > 1) {
117
- throw new Error('Optional only allows one matcher');
118
- }
119
- yield _t.node(_l.Instruction, "Call", [_t.ref`verb`, _t.ref`arguments`], {
120
- verb: _t.s_node(_l.Instruction, "Identifier", "eatMatch"),
121
- arguments: _t.node(_l.Instruction, "Tuple", [_t.ref`openToken`, _t.ref`values[]`, _t.arr(), ..._interpolateFragmentChildren(matchers_[0], _t.ref`values[]`), _t.ref`closeToken`], {
122
- openToken: _t.s_node(_l.Instruction, "Punctuator", "("),
123
- values: [..._interpolateArray(matchers_[0])],
124
- closeToken: _t.s_node(_l.Instruction, "Punctuator", ")")
125
- }, {})
126
- }, {});
127
- }
64
+ export const Keyword = Punctuator;
@@ -1,52 +1,77 @@
1
- import { i } from '@bablr/boot/shorthand.macro';
1
+ import { spam as m } from '@bablr/boot';
2
+ import { buildEmbeddedMatcher, getCooked } from '@bablr/agast-helpers/tree';
3
+ import { eat, eatMatch } from './grammar.js';
4
+ import { EmbeddedMatcher } from './symbols.js';
5
+ import { getEmbeddedMatcher, getEmbeddedObject } from '@bablr/agast-vm-helpers/deembed';
6
+ import { buildPropertyMatcher } from './builders.js';
2
7
 
3
- export function* List({ value: props, ctx }) {
8
+ export function* List({ value: props }) {
4
9
  const {
5
10
  element,
6
11
  separator,
7
12
  allowHoles = false,
8
13
  allowTrailingSeparator = true,
9
- } = ctx.unbox(props);
14
+ } = getEmbeddedObject(props);
10
15
 
11
- yield i`eat([] 'separators[]')`;
16
+ if (
17
+ !['#', '@'].includes(
18
+ getCooked(getEmbeddedMatcher(separator).properties.refMatcher.node.properties.name.node),
19
+ )
20
+ ) {
21
+ yield eat(
22
+ buildEmbeddedMatcher(
23
+ buildPropertyMatcher(
24
+ getEmbeddedMatcher(separator).properties.refMatcher.node,
25
+ m.ArrayNodeMatcher`[]`,
26
+ ),
27
+ ),
28
+ );
29
+ }
30
+
31
+ yield eat(
32
+ buildEmbeddedMatcher(
33
+ buildPropertyMatcher(
34
+ getEmbeddedMatcher(element).properties.refMatcher.node,
35
+ m.ArrayNodeMatcher`[]`,
36
+ ),
37
+ ),
38
+ );
12
39
 
13
40
  let sep,
14
41
  it,
15
42
  anySep = false;
16
43
  for (;;) {
17
- it = yield i`eatMatch(${element})`;
44
+ it = yield eatMatch(element);
18
45
  if (it || allowTrailingSeparator) {
19
- sep = yield i`eatMatch(${separator} 'separators[]')`;
46
+ sep = yield eatMatch(separator);
20
47
  anySep ||= sep;
48
+ } else {
49
+ sep = null;
21
50
  }
22
51
  if (!(sep || allowHoles)) break;
23
52
  }
24
53
  }
25
54
 
26
- export function* Any({ value: matchers, ctx }) {
27
- for (const matcher of ctx.unbox(matchers)) {
28
- if (yield i`eatMatch(${matcher})`) break;
55
+ export function* Any({ value: alternatives }) {
56
+ for (const alternative of alternatives) {
57
+ if (alternative.type === EmbeddedMatcher) {
58
+ if (yield eatMatch(alternative)) break;
59
+ } else {
60
+ throw new Error();
61
+ }
29
62
  }
30
63
  }
31
64
 
32
- export function* All({ value: matchers, ctx }) {
33
- for (const matcher of ctx.unbox(matchers)) {
34
- yield i`eat(${matcher})`;
65
+ export function* All({ value: matchers }) {
66
+ for (const matcher of matchers) {
67
+ yield eat(m`.[]: ${getEmbeddedMatcher(matcher).properties.nodeMatcher.node}`);
35
68
  }
36
69
  }
37
70
 
38
71
  export function* Punctuator({ intrinsicValue }) {
39
72
  if (!intrinsicValue) throw new Error('Intrinsic productions must have value');
40
73
 
41
- yield i`eat(${intrinsicValue})`;
74
+ yield eat(intrinsicValue);
42
75
  }
43
76
 
44
77
  export const Keyword = Punctuator;
45
-
46
- export function* Optional({ value: matchers, ctx }) {
47
- const matchers_ = ctx.unbox(matchers);
48
- if (matchers_.length > 1) {
49
- throw new Error('Optional only allows one matcher');
50
- }
51
- yield i`eatMatch(${matchers_[0]})`;
52
- }
package/lib/shorthand.js CHANGED
@@ -1,3 +1 @@
1
- import * as boot from '@bablr/boot';
2
-
3
- export const { i, re, spam } = boot;
1
+ export { i, re, spam } from '@bablr/boot';
package/lib/source.js CHANGED
@@ -92,8 +92,50 @@ function* __embeddedSourceFrom(iterable) {
92
92
 
93
93
  export const embeddedSourceFrom = (iterable) => new StreamIterable(__embeddedSourceFrom(iterable));
94
94
 
95
- function* __sourceFromTokenStream(Tags) {
96
- let iter = getStreamIterator(Tags);
95
+ function* __printEmbeddedSource(chrs) {
96
+ let iter = getStreamIterator(chrs);
97
+ let part = '';
98
+
99
+ let step;
100
+ for (;;) {
101
+ step = iter.next();
102
+
103
+ if (step instanceof Promise) {
104
+ step = yield step;
105
+ }
106
+
107
+ if (step.done) break;
108
+
109
+ const chr = step.value;
110
+
111
+ if (chr === null) {
112
+ if (part) {
113
+ yield `'`;
114
+ yield* part;
115
+ yield `'<//>`;
116
+
117
+ part = '';
118
+ }
119
+ } else if (chr === '\\' || chr === "'") {
120
+ part += `\\${chr}`;
121
+ } else {
122
+ part += chr;
123
+ }
124
+ }
125
+
126
+ if (part) {
127
+ yield `'`;
128
+ yield* part;
129
+ yield `'`;
130
+ }
131
+ }
132
+
133
+ export const printEmbeddedSource = (chrs) => {
134
+ return __printEmbeddedSource(chrs);
135
+ };
136
+
137
+ function* __sourceFromTokenStream(tags) {
138
+ let iter = getStreamIterator(tags);
97
139
  let step;
98
140
 
99
141
  for (;;) {
@@ -115,7 +157,7 @@ function* __sourceFromTokenStream(Tags) {
115
157
  }
116
158
  }
117
159
 
118
- export const sourceFromTokenStream = (Tags) => new StreamIterable(__sourceFromTokenStream(Tags));
160
+ export const sourceFromTokenStream = (tags) => new StreamIterable(__sourceFromTokenStream(tags));
119
161
 
120
162
  function* __sourceFromQuasis(quasis) {
121
163
  let first = true;
package/lib/stream.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Coroutine } from '@bablr/coroutine';
2
2
  import {
3
- generatePrettyCSTML as generatePrettyCSTMLStream,
4
- generateCSTML as generateCSTMLStream,
3
+ generatePrettyCSTML as agastGeneratePrettyCSTML,
4
+ generateCSTML as agastGenerateCSTML,
5
5
  stringFromStream,
6
6
  getStreamIterator,
7
7
  StreamIterable,
@@ -14,7 +14,6 @@ import { unresolveLanguage } from './grammar.js';
14
14
 
15
15
  const { freeze } = Object;
16
16
 
17
- // bad: wrecks tree by breaking weak linkages
18
17
  function* __resolveTags(ctx, tags) {
19
18
  const co = new Coroutine(getStreamIterator(tags));
20
19
  let languages = emptyStack;
@@ -31,7 +30,7 @@ function* __resolveTags(ctx, tags) {
31
30
  const tag = co.value;
32
31
 
33
32
  if (tag.type === DoctypeTag) {
34
- languages = languages.push(ctx.languages.get(tag.value.attributes['bablr-language']));
33
+ languages = languages.push(ctx.languages.get(tag.value.attributes.bablrLanguage));
35
34
  }
36
35
 
37
36
  if (tag.type === CloseNodeTag) {
@@ -69,20 +68,19 @@ export const resolveTags = (ctx, tags) => {
69
68
  export const generatePrettyCSTML = (tags, options = {}) => {
70
69
  const { ctx } = options;
71
70
 
72
- return generatePrettyCSTMLStream(ctx ? resolveTags(ctx, tags) : tags, options);
71
+ return agastGeneratePrettyCSTML(ctx ? resolveTags(ctx, tags) : tags, options);
73
72
  };
74
73
 
75
74
  export const printPrettyCSTML = (tags, options = {}) => {
76
- const { ctx } = options;
77
- return stringFromStream(generatePrettyCSTMLStream(ctx ? resolveTags(ctx, tags) : tags, options));
75
+ return stringFromStream(generatePrettyCSTML(tags, options));
78
76
  };
79
77
 
80
78
  export const generateCSTML = (tags, options = {}) => {
81
79
  const { ctx } = options;
82
80
 
83
- return generateCSTMLStream(ctx ? resolveTags(ctx, tags) : tags, options);
81
+ return agastGenerateCSTML(ctx ? resolveTags(ctx, tags) : tags, options);
84
82
  };
85
83
 
86
84
  export const printCSTML = (tags, options = {}) => {
87
- return stringFromStream(generateCSTMLStream(tags, options));
85
+ return stringFromStream(generateCSTML(tags, options));
88
86
  };