Skip to content

Instantly share code, notes, and snippets.

@dgellow
Last active August 29, 2015 14:26
Show Gist options
  • Save dgellow/1d5bbdd9a2b1fd6b7c1e to your computer and use it in GitHub Desktop.
Save dgellow/1d5bbdd9a2b1fd6b7c1e to your computer and use it in GitHub Desktop.
function Expr(operation, left, right) {
return {op: operation, l: left, r: right};
}
var Add = Expr.bind(null, 'add'),
Mult = Expr.bind(null, 'mult');
function Var(name) {
return {name: name};
}
function opAdd(x, y) {
return x + y;
}
function opMult(x, y) {
return x * y;
}
function patterns(op, fn, constructor, left, right) {
return {
'number,number': function() {
return op(left, right);
},
'object,number': function() {
return fn(right, left);
},
'object,object': function() {
return constructor(left, right);
}
};
}
function add(left, right) {
var p = patterns(opAdd, add, Add, left, right);
p['number,object'] = function() {
return left === 0 ? right: Add(left, right);
};
return p[typeof left + ',' + typeof right]();
}
function mult(left, right) {
var p = patterns(opMult, mult, Mult, left, right);
p['number,object'] = function() {
if (left === 1) {
return right;
} else if (left === 0) {
return 0;
} else {
return Mult(left, right);
}
};
return p[typeof left + ',' + typeof right]();
}
function simplify1(obj) {
if (!obj.op) {
return obj;
}
var operations = {
add: add.bind(null, obj.l, obj.r),
mult: mult.bind(null, obj.l, obj.r)
};
return operations[obj.op]();
}
function simplify(obj) {
if (!obj.op) {
return obj;
}
var operations = {
add: simplify1.bind(null, Add(simplify(obj.l), simplify(obj.r))),
mult: simplify1.bind(null, Mult(simplify(obj.l), simplify(obj.r)))
};
return operations[obj.op]();
}
// var e = (1 + 0 * x) * 3 + 12;
var e = Add(Mult(Add(1, Mult(0, Var('x'))), 3), 12);
JSON.stringify(simplify(e));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment