Skip to content

Instantly share code, notes, and snippets.

@wavebeem
Last active August 29, 2015 14:26
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 wavebeem/759592dcd20cf4d38e9d to your computer and use it in GitHub Desktop.
Save wavebeem/759592dcd20cf4d38e9d to your computer and use it in GitHub Desktop.
RPN calculator in JS
/// Consider that the JavaScript version contains far fewer assertions than the
/// Squiggle version. Squiggle automatically asserts that a key is an own
/// property of the object before retreiving it (e.g. x[0], foo.bar, keys must
/// exist or it throws). Also, functions will throw unless called with the
/// correct number of arguments. Arrays and objects created through Squiggle are
/// also implicitly frozen, so you can't accidentally mutate them.
var _ = require("lodash");
var text = "2 3 4 * 3 - +";
var table = {
"+": function(a, b) { return a + b; },
"-": function(a, b) { return a - b; },
"*": function(a, b) { return a * b; },
"/": function(a, b) { return a / b; },
};
function tokenize(text) {
return text.split(" ").map(tokenValue);
}
function tokenValue(token) {
if (table.hasOwnProperty(token)) {
return table[token];
} else {
return Number(token);
}
}
function evaluateWithStack(stack, values) {
if (values.length === 0) {
return stack[0];
}
var i = stack.length;
var x = values[0];
var v = values.slice(1);
if (_.isFunction(x)) {
var a = stack[i - 1];
var b = stack[i - 2];
var y = x(a, b);
return evaluateWithStack(stack.slice(0, i - 2).concat([y]), v);
} else {
return evaluateWithStack(stack.concat([x]), v);
}
}
function evaluate(text) {
return evaluateWithStack([], tokenize(text));
}
console.log(evaluate(text));
let (
isFunction = require("lodash").isFunction,
Number = global.Number,
text = "2 3 4 * 3 - +",
table = {
"+": fn(a, b) a + b,
"-": fn(a, b) a - b,
"*": fn(a, b) a * b,
"/": fn(a, b) a / b
},
# You have to explicitly ignore arguments with an underscore in Squiggle.
tokenize = fn(text) text.split(" ").map(fn(x, _i, _a) tokenValue(x)),
tokenValue = fn(token)
if (table.hasOwnProperty(token))
table[token]
else
Number(token),
evaluateWithStack = fn(stack, values)
if (values.length = 0)
stack[0]
else let (
i = stack.length,
x = values[0],
v = values.slice(1)
) if (isFunction(x))
let (
a = stack[i - 1],
b = stack[i - 2],
y = x(a, b)
) evaluateWithStack(stack.slice(0, i - 2) ++ [y], v)
else
evaluateWithStack(stack ++ [x], v),
evaluate = fn(text) evaluateWithStack([], tokenize(text))
) console.log(evaluate(text))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment