···
12
-
const makeOpts = (prev, next) => {
14
-
for (const key in prev) output[key] = prev[key];
15
-
for (const key in next) output[key] = next[key];
12
+
const copy = (prev) => {
14
+
for (const key in prev) next[key] = prev[key];
const assignIndex = (depth) =>
···
const astGroup = (ast, depth, opts) => {
const capture = !!opts.capture && !ast.capture;
69
+
opts.capture = capture;
if (!opts.length && capture) {
73
+
opts.length = depth;
${js`var length_${depth} = ${_node}.length;`}
76
+
${astSequence(ast.sequence, depth + 1, opts)}
80
+
return astSequence(ast.sequence, depth + 1, opts);
const astChild = (ast, depth, opts) =>
ast.expression ? astExpression(ast, depth, opts) : astGroup(ast, depth, opts);
96
-
const astRepeating = (ast, depth, opts) => {
97
-
const label = `loop_${depth}`;
86
+
const astQuantifier = (ast, depth, opts) => {
87
+
const { index, abort, onAbort } = opts;
88
+
const invert = `invert_${depth}`;
89
+
const loop = `loop_${depth}`;
const count = `count_${depth}`;
100
-
${label}: for (var ${count} = 0; true; ${count}++) {
101
-
${assignIndex(depth)}
108
-
${restoreIndex(depth)}
111
-
${opts.onAbort || ''}
120
-
const astMultiple = (ast, depth, opts) => {
121
-
const label = `loop_${depth}`;
123
-
${label}: while (true) {
124
-
${assignIndex(depth)}
131
-
abort: js`break ${label};`,
139
-
const astOptional = (ast, depth, opts) => js`
140
-
${assignIndex(depth)}
152
-
const astQuantifier = (ast, depth, opts) => {
153
-
const { index, abort } = opts;
154
-
const label = `invert_${depth}`;
if (ast.capture === '!') {
157
-
opts = makeOpts(opts, {
159
-
abort: js`break ${label};`,
95
+
opts.abort = js`break ${invert}`;
if (ast.quantifier === '+') {
165
-
child = astRepeating(ast, depth, opts);
166
-
} else if (ast.quantifier === '*') child = astMultiple(ast, depth, opts);
167
-
else if (ast.quantifier === '?') child = astOptional(ast, depth, opts);
168
-
else child = astChild(ast, depth, opts);
102
+
${restoreIndex(depth)}
110
+
${loop}: for (var ${count} = 0; true; ${count}++) {
111
+
${assignIndex(depth)}
112
+
${astChild(ast, depth, opts)}
115
+
} else if (ast.quantifier === '*') {
117
+
opts.index = depth;
118
+
opts.abort = js`break ${loop};`;
122
+
${loop}: while (true) {
123
+
${assignIndex(depth)}
124
+
${astChild(ast, depth, opts)}
127
+
} else if (ast.quantifier === '?') {
128
+
opts.index = depth;
133
+
${assignIndex(depth)}
134
+
${astChild(ast, depth, opts)}
137
+
child = astChild(ast, depth, opts);
if (ast.capture === '!') {
···
199
-
childOpts = makeOpts(opts, {
201
-
abort: js`break ${block};`,
169
+
childOpts = copy(opts);
170
+
childOpts.index = depth;
171
+
childOpts.abort = js`break ${block};`;
172
+
childOpts.onAbort = '';