URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
[/] [System09/] [trunk/] [Tools/] [as09/] [eval.c] - Rev 129
Go to most recent revision | Compare with Previous | Blame | View Log
/* * 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 *pointer; struct link *pnt,*bpnt; 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; pointer = lookup(hold); if (pointer != NULL) { if (Pass == 2) { pnt = pointer->L_list; bpnt = NULL; while (pnt != NULL) { bpnt = pnt; pnt = pnt->next; } pnt = (struct link *) alloc(sizeof(struct link)); if (bpnt == NULL) pointer->L_list = pnt; else bpnt->next = pnt; pnt->L_num = Line_num; pnt->next = NULL; } val = Last_sym; } else{ if(Pass==1){ /* forward ref here */ fwdmark(); if( !Force_byte ) Force_word++; val = 0; } else /* added ver TER_2.0 2 Jul 89 */ error("Symbol undefined Pass 2"); } 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); }
Go to most recent revision | Compare with Previous | Blame | View Log