jac@yoko.rutgers.edu (Jonathan A. Chandross) (12/02/90)
Submitted-by: NONE
Posting-number: Volume 1, Source:11
Archive-name: util/calculator/dc
Architecture: ANY_2
Version-number: 1.00
Enclosed is a simple desk calculator in C.
Enjoy.
=dc.c
-/*
- * dc.c
- *
- * Desk calculator. Supports +,-,* and / on integer and floating point.
- *
- * Usage:
- * dc
- *
- * Commands:
- * d duplicate top of stack (TOS)
- * p print TOS
- * f print all stack entries
- * c clear stack
- * q quit
- * * replace TOS, NOS with NOS * TOS
- * / replace TOS, NOS with NOS / TOS
- * + replace TOS, NOS with NOS * TOS
- * - replace TOS, NOS with NOS - TOS
- * <number> push <number> onto stack, where number is:
- * [+|-] digit+
- * [+|-] [digit+] . digit+
- *
- * Adapted from C Reference Manual
- *
- * Notes: must be linked to flt.lib
- *
- * Contributed Anonymously. Written: November 1983
- *
- * Version 1.00
- *
- */
-
-#include "stdio.h" /* contains extra defines for EOF, etc */
-
-#define BLANK ' '
-#define TAB '\t'
-#define NL '\n'
-#define EOS '\0'
-
-#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 */
-
-
+ END OF ARCHIVE