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