AST Reducer
A Tool to process AST or any other recursive data structure in JavaScript.
Features
- An EDSL to define reduce rules
- Pure functional:
- state is managed via simulating a state monad (the
state
field in context) - global constants is managed via simulating a reader monad (the
env
field in context)
- state is managed via simulating a state monad (the
- Derivable Reducer
- Pretty and helpful error message
- Configuable node parsing logic (the
parseNode
field in opts) - Configuable default rule (the
defaultRule
field in opts)
Install
npm install ast-reducer
Usage
In CoffeeScript
Simple Usage
require'ast-reducer' evalExpr = defineReducername: 'ArithCalc' def'+' @a + @b def'-' @a - @b def'const' parseFloata ast = '+''-''const'1'const'2'+''const''4''const''8'consolelog evalExprevalast # output: 11
Use State
evalExpr = defineReducername: 'ArithCalc0' def'+' state.cnt += 1; @a + @b def'-' state.cnt += 1; @a - @b def'const' parseFloata context = env: initState: -> cnt: 0consolelog evalExprrunStateastcontext # output: { result: 11, state: { cnt: 3 } }
Derive Reducer
evalExpr2 = evalExprderivename: 'ArithCalc1' def'*' state.cnt += 1; @a * @b ast2 = '+''-''const'1'const'2'*''const''4''const''8'consolelog evalExpr2runStateast2context # output: { result: 31, state: { cnt: 3 } }
Error Report
consolelog evalExprrunStateast2context ### error message: ReduceError: [reducer]: "ArithCalc0" [path]: ["+","*"] [state]: {"cnt":2} [current]: ["*",["const","4"],["const","8"]] [input]: ["+",["-",["const",1],["const",2]],["*",["const","4"],["const","8"]]] Caused By: UnimplementedRule: * at Function.defaultRule (the/long/long/path/to/reducer.coffee:34:13) at reduce (the/long/long/path/to/reducer.coffee:42:11) at Object.runState (the/long/long/path/to/reducer.coffee:47:31) ...###