Skip to content

Instantly share code, notes, and snippets.

@guipn

guipn/rpn.js Secret

Created March 10, 2013 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guipn/58bc57ba5fb161c9e58a to your computer and use it in GitHub Desktop.
Save guipn/58bc57ba5fb161c9e58a to your computer and use it in GitHub Desktop.
function Stack() {
var items = [];
return (function () {
return {
push: function (item) {
if (typeof item !== 'string' &&
typeof item !== 'number') {
throw {
name: 'RPN Stack Error',
message: 'Invalid element type'
};
}
items.push(item);
return this;
},
pop: function () {
if (items.length === 0) {
throw {
name: 'RPN Stack Error',
message: 'Stack Underflow'
};
}
return items.pop();
},
all: function () {
return items.slice();
},
flush: function () {
var current = this.all();
items = [];
return current;
}
};
}());
}
function RPN(stack, operations) {
return {
apply: function (expr) {
expr
.split(/\s+/)
.reduce(function (s, next) {
var numVal = parseFloat(next, 10);
return isNaN(numVal) ?
s.push(operations[next](s)) :
s.push(numVal);
}, stack);
},
eval: function (expr) {
this.apply(expr);
return stack.flush();
},
show: function () {
return stack.all();
},
register: function (op) {
if (typeof op.name !== 'string') {
throw {
name: 'RPN Error',
message: 'Invalid operation name.'
};
}
if (typeof op.logic !== 'function') {
throw {
name: 'RPN Error',
message: 'Invalid operation logic.'
};
}
operations[op.name] = op.logic;
return this;
}
};
}
var calc = new RPN(new Stack, {
'+': function (s) {
return s.pop() + s.pop();
},
'-': function (s) {
var one = s.pop(),
other = s.pop();
return other - one;
},
'*': function (s) {
return s.pop() + s.pop();
},
'/': function (s) {
var one = s.pop(),
other = s.pop();
return other / one;
},
'sum': function (s) {
return s
.flush()
.reduce(function (sum, next) {
return sum + next;
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment