Skip to content

Instantly share code, notes, and snippets.

@soareschen
Last active August 29, 2015 14:02
Show Gist options
  • Save soareschen/6de09f3caa46bc6739e8 to your computer and use it in GitHub Desktop.
Save soareschen/6de09f3caa46bc6739e8 to your computer and use it in GitHub Desktop.
DSL experiment in JavaScript for building expression AST
/*
* This is a DSL experiment to build
* abstract syntax trees (AST) in Javascript.
* In this example we provide a simplified
* use case of building expression AST.
*
* The expression AST built here are
* equivalent to the following mathematical
* expressions:
*
* circle-area = pi * radius^2
* cylinder-volume = circle-area * height
*
* Or in their JavaScript form:
*/
var circleArea = function(radius) {
return Math.PI * Math.pow(radius, 2)
}
var cylinderVolume = function(radius, height) {
return circleArea(radius) * height
}
/*
* I currently think of two candidate approaches
* to build the AST in JavaScript. The first
* approach is to use the fluent API style of
* chaining methods, demonstrated below:
*/
require('expr-dsl')
.namespace('my-formulas')
.using('math::pi')
.exportTo(module.exports)
.begin(function(define) {
define.binaryOp('circle-area')
.op('*')
.left(define.constant('pi'))
.right(define.exponentiation()
.base(define.variable('radius'))
.exponent(define.constant(2)))
define.binaryOp('cylinder-volume')
.op('*')
.left(define.subexpr('circle-area'))
.right(define.variable('height'))
})
/*
* Another approach is to pass all arguments
* as dictionary for the constructor to build
* the AST in one go, demonstrated below:
*/
require('expr-dsl').begin({
namespace: 'my-formulas',
using: [
'math::pi'
],
exportTo: module.exports
}, function(define) {
define.binaryOp({
name: 'circle-area',
op: '*',
left: define.constant('pi'),
right: define.exponentiation({
base: define.variable('radius')
exponent: define.constant(2)
})
})
define.binaryOp({
name: 'cylinder-volume',
op: '*',
left: define.subexpr('circle-area'),
right: define.variable('height')
})
})
/*
* I would like to hear your opinion on
* which DSL style is more preferrable,
* and the reasons behind. Thanks.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment