Last active
August 29, 2015 14:26
-
-
Save wavebeem/759592dcd20cf4d38e9d to your computer and use it in GitHub Desktop.
RPN calculator in JS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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