1 /* vi: set sw=4 ts=4: */
9 /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */
11 static double stack[100];
12 static unsigned int pointer;
14 static void push(double a)
16 if (pointer >= (sizeof(stack) / sizeof(*stack))) {
17 errorMsg("stack overflow\n");
26 errorMsg("stack underflow\n");
29 return stack[--pointer];
39 double subtrahend = pop();
41 push(pop() - subtrahend);
51 double divisor = pop();
53 push(pop() / divisor);
58 push((unsigned int) pop() & (unsigned int) pop());
63 push((unsigned int) pop() | (unsigned int) pop());
68 push((unsigned int) pop() ^ (unsigned int) pop());
73 push(~(unsigned int) pop());
78 printf("%g\n", pop());
86 static const struct op operators[] = {
102 static void stack_machine(const char *argument)
104 char *endPointer = 0;
106 const struct op *o = operators;
113 d = strtod(argument, &endPointer);
115 if (endPointer != argument) {
120 while (o->name != 0) {
121 if (strcmp(o->name, argument) == 0) {
127 errorMsg("%s: syntax error.\n", argument);
131 /* return pointer to next token in buffer and set *buffer to one char
132 * past the end of the above mentioned token
134 static char *get_token(char **buffer)
137 char *current = *buffer;
139 while (isspace(*current)) { current++; }
142 while (!isspace(*current) && current != 0) { current++; }
148 /* In Perl one might say, scalar m|\s*(\S+)\s*|g */
149 static int number_of_tokens(char *buffer)
153 while (get_token(&b)) { i++; }
157 int dc_main(int argc, char **argv)
159 /* take stuff from stdin if no args are given */
165 while ((line = get_line_from_file(stdin))) {
167 len = number_of_tokens(line);
168 for (i = 0; i < len; i++) {
169 token = get_token(&cursor);
171 stack_machine(token);
179 stack_machine(argv[1]);