local/toolchest/ksh/shlib/arith.c
/*   
 *   ARITH (PREC)
 *
 *        int PREC;
 *
 *   Evaluate the expression given in the global pointer strg
 *   as an arithmetic expression, to PREC digits.  The form
 *   of strg is as is given for the LET builtin.
 */
ARITH (PREC)
int PREC.

Evaluate the expression given in the global pointer strg
as an arithmetic expression, to PREC digits.  The form
of strg is as is given for the LET builtin.
ARITH ( PREC ) int PREC . Evaluate the expression given in the global pointer strg as an arithmetic expression to PREC digits . The form of strg is as is given for the LET builtin .
static long int arith(prec)
{
	register int c;
#ifdef pdp11
	long r;
	long rr;
#else
	register long r;
	register long rr;
#endif
	int base;
	char *ostr;
	char dot = 0;
	while((c=getchr()),isspace(c));
	if(c==0)
		goto done;
	ostr = (strg-1);
	r = 0;
	if(c == '-')
		r = -arith(8);
	else if(c == '!')
		r = !arith(7);
	else if(isalpha(c))
	{
		int oldc;
		char *varname,*sp;
		varname = ostr;
		for(;isalnum(c);c=getchr());
		if(c == '[')
		{
			seekto(bracket_match(ungetc()));
			c = getchr();
			if(c == 0)
				aerror(varname,subscript);
			c = getchr();
		}
		sp = (strg-1);
		*sp = 0;
		for(oldc = c;isspace(c);c = getchr());
		if(c == '='&& peekc() != '=')
			asslong(lookup(varname),r=arith(2));
		else
		{
			char *str;
			register struct Namnod *np = lookup(varname);
			register union Namval *up;
			ungetc();
                	if (attest (np, INT_GER))
			{
#ifdef NAME_SCOPE
				if (attest (np,C_WRITE))
					np = copy_nod(np,1);
#endif
				up= &np->value.namval;
				if(attest(np,IN_DIR))
					up = up->up;
				if(attest (np, (BLT_NOD)))
					r = (long)((*up->fp->f_vp)());
				else if(up->lp==NULL)
					r = 0;
				else
	                        	r = *up->lp;
			}
		 else
			{
				if((str=valup(np))==0 || *str==0)
					aerror(varname,badnum);
				r = aeval(str);
			}
		}
		*sp = oldc;
	}
	else
	{
		base = 10;
		ungetc();
		lastbase = base;
	}
	while((c=getchr()) && c != ']')
	{
		switch(c)
		{
			case ')':
				if(prec)
					goto done;
				else
					aerror(ostr,synmsg);
			case '(':
				r = arith(1);
				if((c=getchr()) != ')')
					aerror(ostr,synmsg);
				break;
			case '=':	case '!':
				if(prec > 3)
					goto done;
				if(getchr() != '=')
					aerror(ostr,synmsg);
				rr = arith(4);
				if(c == '=')
					r = r == rr;
				else
					r = r != rr;
				break;
			case	'<':	case	'>':
				if(prec > 4)
					goto done;
				if(peekc() == '=')
				{
					getchr();
					rr = arith(5);
					if(c == '<')
						r = r <= rr;
					else
						r = r >= rr;
					break;
				}
				rr = arith(5);
				if(c == '<')
					r = r < rr;
				else
					r = r > rr;
				break;
			case '+':	case '-':
				if(prec > 5)
					goto done;
				rr = arith(6);
				if(c == '+')
					r +=  rr;
				else
					r -= rr;
				break;
			case '*':	case '/':	case '%':
				if(prec > 6)
					goto done;
				rr = arith(7);
				if (c == '*')
					r *= rr;
				else if(rr == 0)
					aerror(ostr,divzero);
				else if (c == '/')
					r /= rr;
				else
					r %= rr;
				break;
			case ' ':	case '\n':	case '\t':
				break;
			case '#':
				lastbase = base = r;
				r = 0;
				break;
			case '.':
				if(dot++==0)
					continue;
			default:
			{
				register int d;
				for(d=0; hdigits[d] && c != hdigits[d];d++);
				d >>= 1;
				if( d < base )
				{
					if(dot==0)
						r = base*r + d;
				}
				else
					aerror(ostr,badnum);
			}
		}
	}
done:
	ungetc();
	return(r);
}
static long int arith ( prec ) { register int c ; #ifdef pdp11 long r ; long rr ; #else register long r ; register long rr ; #endif int base ; char * ostr ; char dot = 0 ; while ( ( c = getchr ( ) ) , isspace ( c ) ) ; if ( c == 0 ) goto done ; ostr = ( strg - 1 ) ; r = 0 ; if ( c == ' ' ) r = - arith ( 8 ) ; else if ( c == ' ' ) r = ! arith ( 7 ) ; else if ( isalpha ( c ) ) { int oldc ; char * varname , * sp ; varname = ostr ; for ( ; isalnum ( c ) ; c = getchr ( ) ) ; if ( c == ' ' ) { seekto ( bracket_match ( ungetc ( ) ) ) ; c = getchr ( ) ; if ( c == 0 ) aerror ( varname , subscript ) ; c = getchr ( ) ; } sp = ( strg - 1 ) ; * sp = 0 ; for ( oldc = c ; isspace ( c ) ; c = getchr ( ) ) ; if ( c == ' ' && peekc ( ) != ' ' ) asslong ( lookup ( varname ) , r = arith ( 2 ) ) ; else { char * str ; register struct Namnod * np = lookup ( varname ) ; register union Namval * up ; ungetc ( ) ; if ( attest ( np , INT_GER ) ) { #ifdef NAME_SCOPE if ( attest ( np , C_WRITE ) ) np = copy_nod ( np , 1 ) ; #endif up = & np -> value . namval ; if ( attest ( np , IN_DIR ) ) up = up -> up ; if ( attest ( np , ( BLT_NOD ) ) ) r = ( long ) ( ( * up -> fp -> f_vp ) ( ) ) ; else if ( up -> lp == NULL ) r = 0 ; else r = * up -> lp ; } else { if ( ( str = valup ( np ) ) == 0 || * str == 0 ) aerror ( varname , badnum ) ; r = aeval ( str ) ; } } * sp = oldc ; } else { base = 10 ; ungetc ( ) ; lastbase = base ; } while ( ( c = getchr ( ) ) && c != ' ' ) { switch ( c ) { case ' ' : if ( prec ) goto done ; else aerror ( ostr , synmsg ) ; case ' ' : r = arith ( 1 ) ; if ( ( c = getchr ( ) ) != ' ' ) aerror ( ostr , synmsg ) ; break ; case ' ' : case ' ' : if ( prec > 3 ) goto done ; if ( getchr ( ) != ' ' ) aerror ( ostr , synmsg ) ; rr = arith ( 4 ) ; if ( c == ' ' ) r = r == rr ; else r = r != rr ; break ; case ' ' : case ' ' : if ( prec > 4 ) goto done ; if ( peekc ( ) == ' ' ) { getchr ( ) ; rr = arith ( 5 ) ; if ( c == ' ' ) r = r <= rr ; else r = r >= rr ; break ; } rr = arith ( 5 ) ; if ( c == ' ' ) r = r < rr ; else r = r > rr ; break ; case ' ' : case ' ' : if ( prec > 5 ) goto done ; rr = arith ( 6 ) ; if ( c == ' ' ) r += rr ; else r -= rr ; break ; case ' ' : case ' ' : case ' ' : if ( prec > 6 ) goto done ; rr = arith ( 7 ) ; if ( c == ' ' ) r *= rr ; else if ( rr == 0 ) aerror ( ostr , divzero ) ; else if ( c == ' ' ) r /= rr ; else r %= rr ; break ; case ' ' : case ' \n ' : case ' \t ' : break ; case ' ' : lastbase = base = r ; r = 0 ; break ; case ' ' : if ( dot ++ == 0 ) continue ; default : { register int d ; for ( d = 0 ; hdigits [ d ] && c != hdigits [ d ] ; d ++ ) ; d >>= 1 ; if ( d < base ) { if ( dot == 0 ) r = base * r + d ; } else aerror ( ostr , badnum ) ; } } } done : ungetc ( ) ; return ( r ) ; }
ARITH (PREC)
        int PREC;
ARITH ( PREC ) int PREC ;
/* ignore whitespace */ /* null terminate variable name */ /* skip over whitespace */