/*
|
/*
|
* eval --- evaluate expression
|
* eval --- evaluate expression
|
*
|
*
|
* an expression is constructed like this:
|
* an expression is constructed like this:
|
*
|
*
|
* expr ::= expr + term |
|
* expr ::= expr + term |
|
* expr - term ;
|
* expr - term ;
|
* expr * term ;
|
* expr * term ;
|
* expr / term ;
|
* expr / term ;
|
* expr | term ;
|
* expr | term ;
|
* expr & term ;
|
* expr & term ;
|
* expr % term ;
|
* expr % term ;
|
* expr ^ term ;
|
* expr ^ term ;
|
*
|
*
|
* term ::= symbol |
|
* term ::= symbol |
|
* * |
|
* * |
|
* constant ;
|
* constant ;
|
*
|
*
|
* symbol ::= string of alphanumerics with non-initial digit
|
* symbol ::= string of alphanumerics with non-initial digit
|
*
|
*
|
* constant ::= hex constant |
|
* constant ::= hex constant |
|
* binary constant |
|
* binary constant |
|
* octal constant |
|
* octal constant |
|
* decimal constant |
|
* decimal constant |
|
* ascii constant;
|
* ascii constant;
|
*
|
*
|
* hex constant ::= '$' {hex digits};
|
* hex constant ::= '$' {hex digits};
|
*
|
*
|
* octal constant ::= '@' {octal digits};
|
* octal constant ::= '@' {octal digits};
|
*
|
*
|
* binary constant ::= '%' { 1 | 0 };
|
* binary constant ::= '%' { 1 | 0 };
|
*
|
*
|
* decimal constant ::= {decimal digits};
|
* decimal constant ::= {decimal digits};
|
*
|
*
|
* ascii constant ::= ''' any printing char;
|
* ascii constant ::= ''' any printing char;
|
*
|
*
|
*/
|
*/
|
eval()
|
eval()
|
{
|
{
|
int left,right; /* left and right terms for expression */
|
int left,right; /* left and right terms for expression */
|
char o; /* operator character */
|
char o; /* operator character */
|
|
|
#ifdef DEBUG
|
#ifdef DEBUG
|
printf("Evaluating %s\n",Optr);
|
printf("Evaluating %s\n",Optr);
|
#endif
|
#endif
|
Force_byte = NO;
|
Force_byte = NO;
|
Force_word = NO;
|
Force_word = NO;
|
if(*Optr=='<'){
|
if(*Optr=='<'){
|
Force_byte++;
|
Force_byte++;
|
Optr++;
|
Optr++;
|
}
|
}
|
else if(*Optr=='>'){
|
else if(*Optr=='>'){
|
Force_word++;
|
Force_word++;
|
Optr++;
|
Optr++;
|
}
|
}
|
left = get_term(); /* pickup first part of expression */
|
left = get_term(); /* pickup first part of expression */
|
|
|
while( is_op(*Optr)){
|
while( is_op(*Optr)){
|
o = *Optr++; /* pickup connector and skip */
|
o = *Optr++; /* pickup connector and skip */
|
right = get_term(); /* pickup current rightmost side */
|
right = get_term(); /* pickup current rightmost side */
|
switch(o){
|
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 /= 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;
|
case '^': left = left^right; break;
|
}
|
}
|
}
|
}
|
|
|
Result= left;
|
Result= left;
|
#ifdef DEBUG
|
#ifdef DEBUG
|
printf("Result=%x\n",Result);
|
printf("Result=%x\n",Result);
|
printf("Force_byte=%d Force_word=%d\n",Force_byte,Force_word);
|
printf("Force_byte=%d Force_word=%d\n",Force_byte,Force_word);
|
#endif
|
#endif
|
return(YES);
|
return(YES);
|
}
|
}
|
|
|
/*
|
/*
|
* is_op --- is character an expression operator?
|
* is_op --- is character an expression operator?
|
*/
|
*/
|
is_op(c)
|
is_op(c)
|
char c;
|
char c;
|
{
|
{
|
if( any(c,"+-*/&%|^"))
|
if( any(c,"+-*/&%|^"))
|
return(YES);
|
return(YES);
|
return(NO);
|
return(NO);
|
}
|
}
|
|
|
|
|
/*
|
/*
|
* get_term --- evaluate a single item in an expression
|
* get_term --- evaluate a single item in an expression
|
*/
|
*/
|
get_term()
|
get_term()
|
{
|
{
|
char hold[MAXBUF];
|
char hold[MAXBUF];
|
char *tmp;
|
char *tmp;
|
int val = 0; /* local value being built */
|
int val = 0; /* local value being built */
|
int minus; /* unary minus flag */
|
int minus; /* unary minus flag */
|
struct nlist *lookup(),*pointer;
|
struct nlist *pointer;
|
struct link *pnt,*bpnt;
|
struct link *pnt,*bpnt;
|
|
|
if( *Optr == '-' ){
|
if( *Optr == '-' ){
|
Optr++;
|
Optr++;
|
minus =YES;
|
minus =YES;
|
}
|
}
|
else
|
else
|
minus = NO;
|
minus = NO;
|
|
|
while( *Optr == '#' ) Optr++;
|
while( *Optr == '#' ) Optr++;
|
|
|
/* look at rest of expression */
|
/* look at rest of expression */
|
|
|
if(*Optr=='%'){ /* binary constant */
|
if(*Optr=='%'){ /* binary constant */
|
Optr++;
|
Optr++;
|
while( any(*Optr,"01"))
|
while( any(*Optr,"01"))
|
val = (val * 2) + ( (*Optr++)-'0');
|
val = (val * 2) + ( (*Optr++)-'0');
|
}
|
}
|
else if(*Optr=='@'){ /* octal constant */
|
else if(*Optr=='@'){ /* octal constant */
|
Optr++;
|
Optr++;
|
while( any(*Optr,"01234567"))
|
while( any(*Optr,"01234567"))
|
val = (val * 8) + ((*Optr++)-'0');
|
val = (val * 8) + ((*Optr++)-'0');
|
}
|
}
|
else if(*Optr=='$'){ /* hex constant */
|
else if(*Optr=='$'){ /* hex constant */
|
Optr++;
|
Optr++;
|
while( any(*Optr,"0123456789abcdefABCDEF"))
|
while( any(*Optr,"0123456789abcdefABCDEF"))
|
if( *Optr > '9' )
|
if( *Optr > '9' )
|
val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
|
val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
|
else
|
else
|
val = (val * 16) + ((*Optr++)-'0');
|
val = (val * 16) + ((*Optr++)-'0');
|
}
|
}
|
else if( any(*Optr,"0123456789")){ /* decimal constant */
|
else if( any(*Optr,"0123456789")){ /* decimal constant */
|
while(*Optr >= '0' && *Optr <= '9')
|
while(*Optr >= '0' && *Optr <= '9')
|
val = (val * 10) + ( (*Optr++)-'0');
|
val = (val * 10) + ( (*Optr++)-'0');
|
}
|
}
|
else if(*Optr=='*'){ /* current location counter */
|
else if(*Optr=='*'){ /* current location counter */
|
Optr++;
|
Optr++;
|
val = Old_pc;
|
val = Old_pc;
|
}
|
}
|
else if(*Optr=='\''){ /* character literal */
|
else if(*Optr=='\''){ /* character literal */
|
Optr++;
|
Optr++;
|
if(*Optr == EOS)
|
if(*Optr == EOS)
|
val = 0;
|
val = 0;
|
else
|
else
|
val = *Optr++;
|
val = *Optr++;
|
}
|
}
|
else if( alpha(*Optr) ){ /* a symbol */
|
else if( alpha(*Optr) ){ /* a symbol */
|
tmp = hold; /* collect symbol name */
|
tmp = hold; /* collect symbol name */
|
while(alphan(*Optr))
|
while(alphan(*Optr))
|
*tmp++ = *Optr++;
|
*tmp++ = *Optr++;
|
*tmp = EOS;
|
*tmp = EOS;
|
pointer = lookup(hold);
|
pointer = lookup(hold);
|
if (pointer != NULL)
|
if (pointer != NULL)
|
{
|
{
|
if (Pass == 2)
|
if (Pass == 2)
|
{
|
{
|
pnt = pointer->L_list;
|
pnt = pointer->L_list;
|
bpnt = NULL;
|
bpnt = NULL;
|
while (pnt != NULL)
|
while (pnt != NULL)
|
{
|
{
|
bpnt = pnt;
|
bpnt = pnt;
|
pnt = pnt->next;
|
pnt = pnt->next;
|
}
|
}
|
pnt = (struct link *) alloc(sizeof(struct link));
|
pnt = (struct link *) alloc(sizeof(struct link));
|
if (bpnt == NULL)
|
if (bpnt == NULL)
|
pointer->L_list = pnt;
|
pointer->L_list = pnt;
|
else bpnt->next = pnt;
|
else bpnt->next = pnt;
|
pnt->L_num = Line_num;
|
pnt->L_num = Line_num;
|
pnt->next = NULL;
|
pnt->next = NULL;
|
}
|
}
|
val = Last_sym;
|
val = Last_sym;
|
}
|
}
|
else{
|
else{
|
if(Pass==1){ /* forward ref here */
|
if(Pass==1){ /* forward ref here */
|
fwdmark();
|
fwdmark();
|
if( !Force_byte )
|
if( !Force_byte )
|
Force_word++;
|
Force_word++;
|
val = 0;
|
val = 0;
|
}
|
}
|
else /* added ver TER_2.0 2 Jul 89 */
|
else /* added ver TER_2.0 2 Jul 89 */
|
error("Symbol undefined Pass 2");
|
error("Symbol undefined Pass 2");
|
}
|
}
|
if(Pass==2 && Line_num==F_ref && Cfn==Ffn){
|
if(Pass==2 && Line_num==F_ref && Cfn==Ffn){
|
if( !Force_byte )
|
if( !Force_byte )
|
Force_word++;
|
Force_word++;
|
fwdnext();
|
fwdnext();
|
}
|
}
|
}
|
}
|
else
|
else
|
/* none of the above */
|
/* none of the above */
|
val = 0;
|
val = 0;
|
|
|
if(minus)
|
if(minus)
|
return(-val);
|
return(-val);
|
else
|
else
|
return(val);
|
return(val);
|
}
|
}
|
|
|