Mirror: The magical sticky regex-based parser generator 🧙

Move expression execution templating to codegen.js

Changed files
+22 -16
src
+4 -4
src/babel/__snapshots__/plugin.test.js.snap
···
var ln2 = node.length;
-
alternation_3: {
+
alt_3: {
block_3: {
var idx3 = state.index;
···
break block_3;
}
-
break alternation_3;
+
break alt_3;
}
loop_3: for (var j3 = 0; 1; j3++) {
···
var node = [];
var x;
-
alternation_2: {
+
alt_2: {
block_2: {
var idx2 = state.index;
···
}
}
-
break alternation_2;
+
break alt_2;
}
loop_2: for (var j2 = 0; 1; j2++) {
+4 -2
src/babel/transform.js
···
const binding = path.scope.getBinding(id.name);
if (binding && t.isVariableDeclarator(binding.path.node)) {
const matchPath = binding.path.get('init');
-
if (this.isMatch(matchPath)) return `${id.name}(state)`;
+
if (this.isMatch(matchPath)) {
+
return { fn: true, id: id.name };
+
}
}
const input = t.isStringLiteral(id)
? JSON.stringify(id.value)
: id.name;
-
return `${ids.exec.name}(state, ${input})`;
+
return { fn: false, id: input };
});
},
+8 -3
src/codegen.js
···
+
export const _exec = '_exec';
const _state = 'state';
const _node = 'node';
const _match = 'x';
···
${opts.abort}
`;
+
const expression = ast.expression.fn
+
? `${ast.expression.id}(${_state})`
+
: `${_exec}(${_state}, ${ast.expression.id})`;
+
if (!opts.capture) {
return js`
-
if (!(${ast.expression})) {
+
if (!${expression}) {
${abort}
}
`;
}
return js`
-
if (${_match} = ${ast.expression}) {
+
if (${_match} = ${expression}) {
${_node}.push(${_match});
} else {
${abort}
···
};
const astSequence = (ast, depth, opts) => {
-
const alternation = ast.alternation ? `alternation_${depth}` : '';
+
const alternation = ast.alternation ? `alt_${depth}` : '';
let body = '';
for (; ast; ast = ast.alternation) {
+6 -7
src/core.js
···
-
import { astRoot } from './codegen';
+
import { astRoot, _exec as execId } from './codegen';
import { parse as parseDSL } from './parser';
const isStickySupported = typeof /./g.sticky === 'boolean';
···
export const match = (name, transform) => (quasis, ...expressions) => {
const ast = parseDSL(
quasis,
-
expressions.map((expression, i) =>
-
typeof expression === 'function' && expression.length
-
? `_${i}(state)`
-
: `_e(state, _${i})`
-
)
+
expressions.map((expression, i) => ({
+
fn: typeof expression === 'function' && expression.length,
+
id: `_${i}`,
+
}))
);
const makeMatcher = new Function(
-
'_e,_n,_t,' + expressions.map((_expression, i) => `_${i}`).join(','),
+
execId + ',_n,_t,' + expressions.map((_expression, i) => `_${i}`).join(','),
'return ' + astRoot(ast, '_n', transform ? '_t' : null)
);