#include "internal.h" #include #include #include #include /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ static const char math_usage[] = "math expression ..."; static double stack[100]; static unsigned int pointer; static void push(double a) { if ( pointer >= (sizeof(stack) / sizeof(*stack)) ) { fprintf(stderr, "math: stack overflow\n"); exit(-1); } else stack[pointer++] = a; } static double pop() { if ( pointer == 0 ) { fprintf(stderr, "math: stack underflow\n"); exit(-1); } return stack[--pointer]; } static void add() { push(pop() + pop()); } static void sub() { double subtrahend = pop(); push(pop() - subtrahend); } static void mul() { push(pop() * pop()); } static void divide() { double divisor = pop(); push(pop() / divisor); } static void and() { push((unsigned int)pop() & (unsigned int)pop()); } static void or() { push((unsigned int)pop() | (unsigned int)pop()); } static void eor() { push((unsigned int)pop() ^ (unsigned int)pop()); } static void not() { push(~(unsigned int)pop()); } static void print() { printf("%g\n", pop()); } struct op { const char * name; void (*function)(); }; static const struct op operators[] = { { "add", add }, { "and", and }, { "div", divide }, { "eor", eor }, { "mul", mul }, { "not", not }, { "or", or }, { "sub", sub }, { 0, 0 } }; static void stack_machine(const char * argument) { char * endPointer = 0; double d; const struct op * o = operators; if ( argument == 0 ) { print(); return; } d = strtod(argument, &endPointer); if ( endPointer != argument ) { push(d); return; } while ( o->name != 0 ) { if ( strcmp(o->name, argument) == 0 ) { (*(o->function))(); return; } o++; } fprintf(stderr, "math: %s: syntax error.\n", argument); exit(-1); } int math_main(int argc, char * * argv) { while ( argc >= 2 ) { stack_machine(argv[1]); argv++; argc--; } stack_machine(0); return 0; }