You are not logged in.
Pages: 1
I was doing some cruft-cleaning when I discovered this in my project directory. As far as I can tell, it's a basic RPN calculator written in C++. The modification timestamp dates it back to about a year ago, at which point I was still dicking around with PHP under OS X. There are no comments and I apparently hadn't figured out the purpose of std::vector at the time. Enjoy!
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <readline/readline.h>
#include <readline/history.h>
#include <stack>
using namespace std;
#define STR_MAXLEN 64
#define NUM_TOKENS 512
#define T_NONE 0
#define T_OPERAND 1
#define T_ADD 2
#define T_SUBTRACT 3
#define T_MULTIPLY 4
#define T_DIVIDE 5
#define T_POW 6
#define T_ROOT 7
struct token {
int type;
long double value;
};
#define IS_NUMERIC(n) ((n) == '0' || (n) == '1' || (n) == '2' || (n) == '3' || \
(n) == '4' || (n) == '5' || (n) == '6' || (n) == '7' || (n) == '8' || \
(n) == '9')
int main(int argc, char *argv[]) {
stack<long double> values;
token tokens[NUM_TOKENS];
string input = "", value = "";
char c, cstr[64] = "", *rl_input = (char *)NULL;
int i, t;
long double op1, op2;
bool raised10;
rl_bind_key('\t', rl_insert);
while(true) {
rl_input = readline(": ");
if(rl_input == NULL) {
cout << "\n";
exit(0);
}
input.assign(rl_input);
free(rl_input);
rl_input = (char *)NULL;
for(i = 0;
i < NUM_TOKENS;
i++) {
tokens[i].type = T_NONE;
tokens[i].value = 0.0;
}
for(i = 0, t = 0;
i < input.length();
i++) {
c = input.at(i);
switch(c) {
case '+':
tokens[t].type = T_ADD;
t++;
break;
case '*':
tokens[t].type = T_MULTIPLY;
t++;
break;
case '/':
tokens[t].type = T_DIVIDE;
t++;
break;
case '^':
tokens[t].type = T_POW;
t++;
break;
case '?':
tokens[t].type = T_ROOT;
t++;
break;
case '(':
case ')':
case ',':
break;
default:
if(IS_NUMERIC(c) || c == '-') {
sprintf(cstr, "%c", c);
raised10 = false;
for(i++;
i < input.length();
i++) {
if(input.at(i) == 'e') {
raised10 = true;
}
if((!IS_NUMERIC(input.at(i)) && input.at(i) != '.' && input.at(i) != 'e' && input.at(i) != '-') || (input.at(i) == '-' && !raised10)) {
i--;
break;
}
sprintf(cstr, "%s%c", cstr, input.at(i));
}
if(cstr[0] == '-' && strlen(cstr) == 1) {
tokens[t].type = T_SUBTRACT;
t++;
} else {
tokens[t].type = T_OPERAND;
tokens[t].value = strtold(cstr, NULL);
t++;
}
} else if(c != ' ' && c != '\t' && c != '\n') {
cout << "Unexpected character in input: " << c << "\n";
goto loopcont;
}
break;
}
}
for(t = 0;
t < NUM_TOKENS && tokens[t].type != T_NONE;
t++) {
if(tokens[t].type == T_OPERAND) {
values.push(tokens[t].value);
} else {
if(values.size() < 2) {
cout << "Too few arguments provided (token " << t << ")\n";
goto loopcont;
}
op2 = values.top();
values.pop();
op1 = values.top();
values.pop();
switch(tokens[t].type) {
case T_ADD:
values.push(op1 + op2);
break;
case T_SUBTRACT:
values.push(op1 - op2);
break;
case T_MULTIPLY:
values.push(op1 * op2);
break;
case T_DIVIDE:
if(op2 == 0) {
cout << "Division by zero\n";
goto loopcont;
}
values.push(op1 / op2);
break;
case T_POW:
values.push(pow(op1, op2));
break;
case T_ROOT:
values.push(pow(op1, (1 / op2)));
break;
}
}
tokens[t].type = T_NONE;
tokens[t].value = 0.0;
}
if(values.size()) {
cout << values.top() << "\n";
}
loopcont:
if(input.length()) {
add_history(input.c_str());
}
while(!values.empty()) {
values.pop();
}
}
return 0;
}
To compile:
g++ something.cpp -o something -l readline
Last edited by Peasantoid (2009-09-21 23:28:10)
Offline
Cool! I was just reading about RPN today; I'll definitely have to learn it now. Thanks Peasantoid.
If anyone is having trouble compiling this:
g++ -lreadline file.cpp
Offline
Cool! I was just reading about RPN today; I'll definitely have to learn it now. Thanks Peasantoid.
Okay, you're welcome, but first you must promise to write better code than the above.
If anyone is having trouble compiling this:
g++ -lreadline file.cpp
Oh yes, I forgot about that. Added to OP.
Offline
Pages: 1