Mirror: The magical sticky regex-based parser generator 🧙

Move expression execution templating to codegen.js

+22 -16
+4 -4
src/babel/__snapshots__/plugin.test.js.snap
··· 96 96 97 97 var ln2 = node.length; 98 98 99 - alternation_3: { 99 + alt_3: { 100 100 block_3: { 101 101 var idx3 = state.index; 102 102 ··· 108 108 break block_3; 109 109 } 110 110 111 - break alternation_3; 111 + break alt_3; 112 112 } 113 113 114 114 loop_3: for (var j3 = 0; 1; j3++) { ··· 182 182 var node = []; 183 183 var x; 184 184 185 - alternation_2: { 185 + alt_2: { 186 186 block_2: { 187 187 var idx2 = state.index; 188 188 ··· 202 202 } 203 203 } 204 204 205 - break alternation_2; 205 + break alt_2; 206 206 } 207 207 208 208 loop_2: for (var j2 = 0; 1; j2++) {
+4 -2
src/babel/transform.js
··· 158 158 const binding = path.scope.getBinding(id.name); 159 159 if (binding && t.isVariableDeclarator(binding.path.node)) { 160 160 const matchPath = binding.path.get('init'); 161 - if (this.isMatch(matchPath)) return `${id.name}(state)`; 161 + if (this.isMatch(matchPath)) { 162 + return { fn: true, id: id.name }; 163 + } 162 164 } 163 165 164 166 const input = t.isStringLiteral(id) 165 167 ? JSON.stringify(id.value) 166 168 : id.name; 167 - return `${ids.exec.name}(state, ${input})`; 169 + return { fn: false, id: input }; 168 170 }); 169 171 }, 170 172
+8 -3
src/codegen.js
··· 1 + export const _exec = '_exec'; 1 2 const _state = 'state'; 2 3 const _node = 'node'; 3 4 const _match = 'x'; ··· 42 43 ${opts.abort} 43 44 `; 44 45 46 + const expression = ast.expression.fn 47 + ? `${ast.expression.id}(${_state})` 48 + : `${_exec}(${_state}, ${ast.expression.id})`; 49 + 45 50 if (!opts.capture) { 46 51 return js` 47 - if (!(${ast.expression})) { 52 + if (!${expression}) { 48 53 ${abort} 49 54 } 50 55 `; 51 56 } 52 57 53 58 return js` 54 - if (${_match} = ${ast.expression}) { 59 + if (${_match} = ${expression}) { 55 60 ${_node}.push(${_match}); 56 61 } else { 57 62 ${abort} ··· 155 160 }; 156 161 157 162 const astSequence = (ast, depth, opts) => { 158 - const alternation = ast.alternation ? `alternation_${depth}` : ''; 163 + const alternation = ast.alternation ? `alt_${depth}` : ''; 159 164 160 165 let body = ''; 161 166 for (; ast; ast = ast.alternation) {
+6 -7
src/core.js
··· 1 - import { astRoot } from './codegen'; 1 + import { astRoot, _exec as execId } from './codegen'; 2 2 import { parse as parseDSL } from './parser'; 3 3 4 4 const isStickySupported = typeof /./g.sticky === 'boolean'; ··· 40 40 export const match = (name, transform) => (quasis, ...expressions) => { 41 41 const ast = parseDSL( 42 42 quasis, 43 - expressions.map((expression, i) => 44 - typeof expression === 'function' && expression.length 45 - ? `_${i}(state)` 46 - : `_e(state, _${i})` 47 - ) 43 + expressions.map((expression, i) => ({ 44 + fn: typeof expression === 'function' && expression.length, 45 + id: `_${i}`, 46 + })) 48 47 ); 49 48 50 49 const makeMatcher = new Function( 51 - '_e,_n,_t,' + expressions.map((_expression, i) => `_${i}`).join(','), 50 + execId + ',_n,_t,' + expressions.map((_expression, i) => `_${i}`).join(','), 52 51 'return ' + astRoot(ast, '_n', transform ? '_t' : null) 53 52 ); 54 53