home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 5
/
DATAFILE_PDCD5.iso
/
utilities
/
m
/
motorola
/
!AsRef
/
Sources
/
c
/
eval
< prev
next >
Wrap
Text File
|
1993-07-18
|
4KB
|
205 lines
#include <stdio.h>
#include "mselect.h" /*external selection of microprocessor symbol table*/
#include "proto.h"
#include "as.h"
#include "structs.h"
#include "extvars.h"
/*
* 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;
*
*/
int
eval(void)
{
int left, right; /* left and right terms set
* 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?
*/
int
is_op(char c)
{
if (any(c, "+-*/&%|^"))
return (YES);
return (NO);
}
/*
* get_term --- evaluate a single item in an expression
*/
int
get_term(void)
{
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);
}