1 /* vi: set sw=4 ts=4: */
9 /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */
11 static const char dc_usage[] = "dc expression ...\n"
12 #ifndef BB_FEATURE_TRIVIAL_HELP
13 "\nThis is a Tiny RPN calculator that understands the\n"
14 "following operations: +, -, /, *, and, or, not, eor.\n"
15 "i.e. 'dc 2 2 add' -> 4, and 'dc 8 8 \\* 2 2 + /' -> 16\n"
19 static double stack[100];
20 static unsigned int pointer;
22 static void push(double a)
24 if (pointer >= (sizeof(stack) / sizeof(*stack))) {
25 fprintf(stderr, "dc: stack overflow\n");
34 fprintf(stderr, "dc: stack underflow\n");
37 return stack[--pointer];
47 double subtrahend = pop();
49 push(pop() - subtrahend);
59 double divisor = pop();
61 push(pop() / divisor);
66 push((unsigned int) pop() & (unsigned int) pop());
71 push((unsigned int) pop() | (unsigned int) pop());
76 push((unsigned int) pop() ^ (unsigned int) pop());
81 push(~(unsigned int) pop());
86 printf("%g\n", pop());
94 static const struct op operators[] = {
110 static void stack_machine(const char *argument)
112 char *endPointer = 0;
114 const struct op *o = operators;
121 d = strtod(argument, &endPointer);
123 if (endPointer != argument) {
128 while (o->name != 0) {
129 if (strcmp(o->name, argument) == 0) {
135 fprintf(stderr, "dc: %s: syntax error.\n", argument);
139 /* return pointer to next token in buffer and set *buffer to one char
140 * past the end of the above mentioned token
142 static char *get_token(char **buffer)
145 char *current = *buffer;
147 while (isspace(*current)) { current++; }
150 while (!isspace(*current) && current != 0) { current++; }
156 /* In Perl one might say, scalar m|\s*(\S+)\s*|g */
157 static int number_of_tokens(char *buffer)
161 while (get_token(&b)) { i++; }
165 int dc_main(int argc, char **argv)
167 /* take stuff from stdin if no args are given */
173 while ((line = get_line_from_file(stdin))) {
175 len = number_of_tokens(line);
176 for (i = 0; i < len; i++) {
177 token = get_token(&cursor);
179 stack_machine(token);
187 stack_machine(argv[1]);