enhancers.js
1 import { 2 enhanceStrategyBuilderWithDebugLogging as logStrategy, 3 enhanceStrategyBuilderWithEmittedLogging as logEmitted, 4 } from '@bablr/strategy_enhancer-debug-log'; 5 import { enhanceProductionWithDebugLogging as createProductionLogger } from '@bablr/language_enhancer-debug-log'; 6 import { mapProductions } from './grammar.js'; 7 8 export const memoize = (original) => { 9 const cache = new WeakMap(); 10 const memoized = (...args) => { 11 if (args.length > 1) throw new Error('A memoized function accepts only one argument'); 12 const arg = args[0]; 13 14 if (cache.has(arg)) { 15 return cache.get(arg); 16 } else { 17 return original(arg); 18 } 19 }; 20 return memoized; 21 }; 22 23 const identity = (x) => x; 24 25 export const compose = (functions) => { 26 let first = true; 27 let f = identity; 28 for (const g of functions) { 29 if (first) { 30 f = g; 31 } else { 32 const f_ = f; 33 f = (x) => f_(g(x)); 34 } 35 first = false; 36 } 37 38 return f; 39 }; 40 41 export const debugEnhancers = { 42 // bablr: (strategy) => logStrategy(strategy, '<<< '), 43 createBablrStrategy: (strategy) => (matcher, props) => 44 logStrategy(strategy(matcher, props), ' >>> '), 45 bablrProduction: createProductionLogger('>>> '), 46 }; 47 48 export const stateEnhancer = (hooks, grammar) => { 49 let state; 50 return mapProductions((production) => { 51 return function* (props) { 52 let prevState = props.state; 53 54 if (!state) { 55 hooks.buildState?.(props.state); 56 } else if (props.state !== state) { 57 hooks.branchState?.(state, props.state); 58 } 59 60 state = props.state; 61 62 try { 63 yield* production(props); 64 65 hooks.acceptState?.(props.state, state); 66 } catch (e) { 67 hooks.rejectState?.(props.state); 68 } 69 70 state = prevState; 71 }; 72 }, grammar); 73 };