···
-
const makeOpts = (prev, next) => {
-
for (const key in prev) output[key] = prev[key];
-
for (const key in next) output[key] = next[key];
const assignIndex = (depth) =>
···
const astGroup = (ast, depth, opts) => {
const capture = !!opts.capture && !ast.capture;
if (!opts.length && capture) {
${js`var length_${depth} = ${_node}.length;`}
const astChild = (ast, depth, opts) =>
ast.expression ? astExpression(ast, depth, opts) : astGroup(ast, depth, opts);
-
const astRepeating = (ast, depth, opts) => {
-
const label = `loop_${depth}`;
const count = `count_${depth}`;
-
${label}: for (var ${count} = 0; true; ${count}++) {
-
const astMultiple = (ast, depth, opts) => {
-
const label = `loop_${depth}`;
-
${label}: while (true) {
-
abort: js`break ${label};`,
-
const astOptional = (ast, depth, opts) => js`
-
const astQuantifier = (ast, depth, opts) => {
-
const { index, abort } = opts;
-
const label = `invert_${depth}`;
if (ast.capture === '!') {
-
opts = makeOpts(opts, {
-
abort: js`break ${label};`,
if (ast.quantifier === '+') {
-
child = astRepeating(ast, depth, opts);
-
} else if (ast.quantifier === '*') child = astMultiple(ast, depth, opts);
-
else if (ast.quantifier === '?') child = astOptional(ast, depth, opts);
-
else child = astChild(ast, depth, opts);
if (ast.capture === '!') {
···
-
childOpts = makeOpts(opts, {
-
abort: js`break ${block};`,
···
+
const copy = (prev) => {
+
for (const key in prev) next[key] = prev[key];
const assignIndex = (depth) =>
···
const astGroup = (ast, depth, opts) => {
const capture = !!opts.capture && !ast.capture;
+
opts.capture = capture;
if (!opts.length && capture) {
${js`var length_${depth} = ${_node}.length;`}
+
${astSequence(ast.sequence, depth + 1, opts)}
+
return astSequence(ast.sequence, depth + 1, opts);
const astChild = (ast, depth, opts) =>
ast.expression ? astExpression(ast, depth, opts) : astGroup(ast, depth, opts);
+
const astQuantifier = (ast, depth, opts) => {
+
const { index, abort, onAbort } = opts;
+
const invert = `invert_${depth}`;
+
const loop = `loop_${depth}`;
const count = `count_${depth}`;
if (ast.capture === '!') {
+
opts.abort = js`break ${invert}`;
if (ast.quantifier === '+') {
+
${loop}: for (var ${count} = 0; true; ${count}++) {
+
${astChild(ast, depth, opts)}
+
} else if (ast.quantifier === '*') {
+
opts.abort = js`break ${loop};`;
+
${loop}: while (true) {
+
${astChild(ast, depth, opts)}
+
} else if (ast.quantifier === '?') {
+
${astChild(ast, depth, opts)}
+
child = astChild(ast, depth, opts);
if (ast.capture === '!') {
···
+
childOpts = copy(opts);
+
childOpts.index = depth;
+
childOpts.abort = js`break ${block};`;
+
childOpts.onAbort = '';