home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
AS11.ZIP
/
EVAL.C
< prev
next >
Wrap
Text File
|
1986-11-01
|
4KB
|
178 lines
/*
* eval --- evaluate expression
*
* an expression is constructed like this:
*
* expr ::= expr + term |
* expr - term ;
* expr * term ;
* expr / term ;
* expr | term ;
* expr & term ;
* expr % term ;
* expr ^ term ;
*
* term ::= symbol |
* * |
* constant ;
*
* symbol ::= string of alphanumerics with non-initial digit
*
* constant ::= hex constant |
* binary constant |
* octal constant |
* decimal constant |
* ascii constant;
*
* hex constant ::= '$' {hex digits};
*
* octal constant ::= '@' {octal digits};
*
* binary constant ::= '%' { 1 | 0 };
*
* decimal constant ::= {decimal digits};
*
* ascii constant ::= ''' any printing char;
*
*/
eval()
{
int left,right; /* left and right terms for expression */
char o; /* operator character */
#ifdef DEBUG
printf("Evaluating %s\n",Optr);
#endif
Force_byte = NO;
Force_word = NO;
if(*Optr=='<'){
Force_byte++;
Optr++;
}
else if(*Optr=='>'){
Force_word++;
Optr++;
}
left = get_term(); /* pickup first part of expression */
while( is_op(*Optr)){
o = *Optr++; /* pickup connector and skip */
right = get_term(); /* pickup current rightmost side */
switch(o){
case '+': left += right; break;
case '-': left -= right; break;
case '*': left *= right; break;
case '/': left /= right; break;
case '|': left |= right; break;
case '&': left &= right; break;
case '%': left %= right; break;
case '^': left = left^right; break;
}
}
Result= left;
#ifdef DEBUG
printf("Result=%x\n",Result);
printf("Force_byte=%d Force_word=%d\n",Force_byte,Force_word);
#endif
return(YES);
}
/*
* is_op --- is character an expression operator?
*/
is_op(c)
char c;
{
if( any(c,"+-*/&%|^"))
return(YES);
return(NO);
}
/*
* get_term --- evaluate a single item in an expression
*/
get_term()
{
char hold[MAXBUF];
char *tmp;
int val = 0; /* local value being built */
int minus; /* unary minus flag */
struct nlist *lookup();
if( *Optr == '-' ){
Optr++;
minus =YES;
}
else
minus = NO;
while( *Optr == '#' ) Optr++;
/* look at rest of expression */
if(*Optr=='%'){ /* binary constant */
Optr++;
while( any(*Optr,"01"))
val = (val * 2) + ( (*Optr++)-'0');
}
else if(*Optr=='@'){ /* octal constant */
Optr++;
while( any(*Optr,"01234567"))
val = (val * 8) + ((*Optr++)-'0');
}
else if(*Optr=='$'){ /* hex constant */
Optr++;
while( any(*Optr,"0123456789abcdefABCDEF"))
if( *Optr > '9' )
val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
else
val = (val * 16) + ((*Optr++)-'0');
}
else if( any(*Optr,"0123456789")){ /* decimal constant */
while(*Optr >= '0' && *Optr <= '9')
val = (val * 10) + ( (*Optr++)-'0');
}
else if(*Optr=='*'){ /* current location counter */
Optr++;
val = Old_pc;
}
else if(*Optr=='\''){ /* character literal */
Optr++;
if(*Optr == EOS)
val = 0;
else
val = *Optr++;
}
else if( alpha(*Optr) ){ /* a symbol */
tmp = hold; /* collect symbol name */
while(alphan(*Optr))
*tmp++ = *Optr++;
*tmp = EOS;
if(lookup(hold) != NULL)
val = Last_sym;
else{
if(Pass==1){ /* forward ref here */
fwdmark();
if( !Force_byte )
Force_word++;
val = 0;
}
}
if(Pass==2 && Line_num==F_ref && Cfn==Ffn){
if( !Force_byte )
Force_word++;
fwdnext();
}
}
else
/* none of the above */
val = 0;
if(minus)
return(-val);
else
return(val);
}