rpn-cli
Version:
Command line RPN calculator using math.js engine. example: '$ rpn 1 2 +'
102 lines (79 loc) • 4.63 kB
JavaScript
#!/usr/bin/env node
// Generated by CoffeeScript 2.4.1
//!/usr/bin/env coffee
var E, T, appName, command, debugConsole, e, formula, input, opt, optSymbols, options, parse, parsedInput, precision, readFromStdin, regex;
opt = require('getopt');
command = 'normal';
debugConsole = null;
readFromStdin = false;
precision = 14;
T = console.log;
E = console.error;
process.argv.shift();
appName = require('path').basename(process.argv.shift());
optSymbols = 'h?dsb';
regex = /^-[h\?dsb]+$/;
formula = process.argv.filter(function(x) {
return !x.match(regex);
});
options = process.argv.filter(function(x) {
return x.match(regex);
});
opt.setopt(optSymbols, options);
opt.getopt(function(o, p) {
switch (o) {
case 'h':
case '?':
return command = 'usage';
case 'd':
return debugConsole = console.error;
case 's':
return readFromStdin = true;
case 'b':
return precision = 64;
}
});
parse = function(formula) {
var s;
s = formula.join(' ');
s = s.replace(/([^-0-9.e])/g, ' $1');
s = s.replace(/([^e, ])-/g, '$1 - ');
s = s.replace(/(-?[0-9.]+e?-?[0-9.]*)/g, ' $1');
s = s.replace(/,/g, ' ');
return s.split(/ +/).filter(function(x) {
return x.length > 0;
});
};
formula = parse(formula);
if (typeof debugConsole === "function") {
debugConsole(`params:${formula.join(' ')}`);
}
if (readFromStdin) {
input = require('fs').readFileSync('/dev/stdin', 'utf8');
parsedInput = input.split(/[\s\n]+/).filter(function(x) {
return x.length > 0;
});
parsedInput = parse(parsedInput);
if (typeof debugConsole === "function") {
debugConsole(`stdin:${parsedInput.join(' ')}`);
}
formula = parsedInput.concat(formula);
}
if (typeof debugConsole === "function") {
debugConsole(`formula:${formula.join(' ')}`);
}
if (formula.length === 0 && !readFromStdin) {
command = 'usage';
}
switch (command) {
case 'usage':
console.log(`${appName} [-${optSymbols}] <formula>\nversion 2.1.2\nCopyright(c) 2017-2019 @kssfilo(https://kanasys.com/gtech/)\n\noptions:\n -d:debug\n -s:mix stdin "<stdin formula> <command line formula>"\n -b:64 digits precition mode (default:14 digits)\n -h/-?:this help\n\noperators:\n +:add last two stack elements\n -:subtract element 1 from element 2\n x:multiply last two stack elements (* is ok but need escape in bash)\n /:divide element 2 by element 1\n %:element 2 mod element 1\n\n ^:raise element 2 to the power of element 1\n v:n-th root (element 1 root of element 2)\n 2v:(combination) squrare root\n\n n:Negate last element\n i:Invert last element\n a:Absolute value (last element)\n l:Log e (last element)\n L:exponent of e (last element,reverse function of Log e)\n f:Factorial (last element,! is ok but need escape in bash)\n\n s:Sin (last element,ragian)\n c:Cos (last element,ragian)\n t:Tan (last element,radian)\n S:arcSin (last element,radian)\n C:arcCos (last element,radian)\n T:arcTan (last element,radian)\n P/180x:(combination) radian -> degree (last element)\n 180/Px:(combination) degree -> radian (last element)\n\n _:floor last element\n =:round last element\n 1+_:(combination) ceil last element\n\n w:sWap last 2 elements\n r:Rotate all elements(1 2 3 -> 3 1 2)\n R:Rotate all elements(1 2 3 -> 2 3 1)\n d:Drop last element\n D:Drop all elements\n V:Drop except last elements\n p:duP last element\n\n Y:move last element to 0th Register\n y:recall from 0th Register\n Q:move element 2 to <element 1>th Register\n q:recall from <element 1>th Register\n\n N:couNt all elements and push to stack\n M:find Max of all elements and push to stack\n m:find Min of all elements and push to stack\n A:sum of All elements and push to stack\n X:product of all elements and push to stack\n\n F:apply next operator to all elements(1,2,3,F,1,+ -> 2,3,4)\n\n NyAY/V:(combination) arithmetic mean(avarage)\n NyXYvV:(combination) geometric mean\n NyAY/F-F2^AY1-/2vV:(combination) standard deviation\n\nconstants:\n P:Pi\n 1L:(combination) base of natural logarithm(e)\n\nnumber:\n e:Exponent (5e3 -> 5000/5e-3 -> 0.005)\n -:negative(<any operator/number>- -> subtract,for example:1-1 -> 1 - 1 but 1 -1 -> 1 -1)\n\nexample:\n ${appName} 1 2 + #result:3\n ${appName} 1 2 1++ #result:4\n ${appName} 1,2,1++ #result:4\n \n ${appName} 1 2 1 + +|${appName} -s 3 + #pipeline:same as ${appName} 1 2 1 + + 3 +\n ${appName} -s <<<'1 2 +' #dc style\n \n ${appName} 5e3 5 / #same as ${appName} 5000 5 /\n ${appName} 10 3 /= #round:3.3333 -> 3\n`);
break;
default:
try {
T(require('./rpn')({formula, debugConsole, precision}).join(' '));
} catch (error) {
e = error;
E(e);
}
}