Apple Aztec C source - dc.c
Dave Newkirk
dcn at ihuxl.UUCP
Fri Nov 18 00:40:38 AEST 1983
/* 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 */
More information about the Comp.sources.unix
mailing list