dcn@ihuxl.UUCP (Dave Newkirk) (11/17/83)
/* dc - desk calculator * * Adapted from C Reference Manual * (must be linked to flt.lib) * * Supports +,-,* and / on integer and * floating point. Commands include: * d - duplicate top of stack (TOS) * p - print TOS * f - print all stack entries * c - clear stack * q - quit */ #include "stdio.h" /* contains extra defines for EOF, etc */ #define MAXOP 20 #define NUMBER '0' #define TOOBIG '9' main() { int type ; char s[MAXOP] ; double op2, atof(), pop(), push() ; while( (type = getop(s,MAXOP)) != EOF ) switch( type ) { case NUMBER: push( atof(s) ) ; break ; case '+': push( pop() + pop() ) ; break ; case '*': push( pop() * pop() ) ; break ; case '-': op2 = pop() ; push( pop() - op2 ) ; break ; case '/': op2 = pop() ; if( op2 != 0.0 ) push( pop() / op2 ) ; else fprintf(stderr, "dc: divide by zero\n"); break ; case 'd': push( push( pop() ) ) ; break ; case 'p': top() ; break ; case 'f': print() ; break ; case 'c': empty() ; break ; case 'q': printf("\n") ; exit(0) ; case TOOBIG: fprintf(stderr, "dc: %.20s is too long\n", s ) ; break ; default: fprintf(stderr, "dc: unknown commnd %c\n", type ) ; break ; } } /* end main */ /* stack declarations */ #define STACKSIZE 100 int sp = 0 ; double stack[STACKSIZE] ; /* push - push new value on stack */ double push(f) double f ; { if( sp < STACKSIZE ) return stack[sp++] = f ; else { printf("dc: stack is full\n"); empty() ; return 0 ; } } /* end push */ /* pop - return top of stack */ double pop() { if( sp > 0 ) return stack[--sp] ; else { printf("dc: stack empty\n") ; empty() ; return 0 ; } } /* end pop */ /* empty - empty the stack */ empty() { sp = 0 ; } /* top - print top stack entry */ top() { int i ; double d ; if( sp <= 0 ) return ; d = stack[ sp-1 ] ; i = d ; if( ((double) i) == d ) printf("%c%d\n", TAB, i ) ; else printf("%c%f\n", TAB, d ) ; } /* print - show all stack entries */ print() { int i, s ; double d ; for( s=sp-1 ; s >= 0 ; s-- ) { d = stack[ s ] ; i = d ; if( ((double) i) == d ) printf("%c%d\n", TAB, i ) ; else printf("%c%f\n", TAB, d ) ; } } /* getop - get next operator, operand */ getop( s, limit ) char s[] ; int limit ; { int i, c, oldc ; i = 0 ; do c = agetc(stdin) ; while( c == BLANK || c == TAB || c == NL ) ; i = 0 ; if( c != '.' && c != '-' && c != '+' && (c < '0' || c > '9') ) return c ; if( c == '+' || c == '-' ) { oldc = c ; c = agetc(stdin) ; if( c != '.' && (c < '0' || c > '9') ) { ungetc( c, stdin ) ; return oldc ; } else s[i++] = oldc ; } s[i++] = c ; for( ; (c = agetc(stdin)) >= '0' && c <= '9' ; i++ ) if( i < limit ) s[i] = c ; if( c == '.' ) { if( i < limit ) s[i] = c ; for( i++ ; (c = agetc(stdin)) >= '0' && c <= '9' ; i++ ) if( i < limit ) s[i] = c ; } if( i < limit ) { ungetc( c, stdin ) ; s[i] = EOS ; return NUMBER ; } else { while( c != NL && c != EOF ) c = agetc(stdin) ; s[limit-1] = EOS ; return TOOBIG ; } } /* end getop */