home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / motasm / src_c_eval < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-04  |  6.3 KB  |  205 lines

  1. #include <stdio.h>
  2.  
  3. #include "mselect.h"    /*external selection of microprocessor symbol table*/
  4. #include "proto.h"
  5. #include "as.h"
  6. #include "structs.h"
  7. #include "extvars.h"
  8.  
  9.  
  10. /*
  11.  * eval --- evaluate expression
  12.  * 
  13.  * an expression is constructed like this:
  14.  * 
  15.  * expr ::=  expr + term | expr - term ; expr * term ; expr / term ; expr | term
  16.  * ; expr & term ; expr % term ; expr ^ term ;
  17.  * 
  18.  * term ::=  symbol | * | constant ;
  19.  * 
  20.  * symbol ::=  string of alphanumerics with non-initial digit
  21.  * 
  22.  * constant ::= hex constant | binary constant | octal constant | decimal
  23.  * constant | ascii constant;
  24.  * 
  25.  * hex constant ::= '$' {hex digits};
  26.  * 
  27.  * octal constant ::= '@' {octal digits};
  28.  * 
  29.  * binary constant ::= '%' { 1 | 0 };
  30.  * 
  31.  * decimal constant ::= {decimal digits};
  32.  * 
  33.  * ascii constant ::= ''' any printing char;
  34.  * 
  35.  */
  36. int
  37. eval(void)
  38. {
  39.         int             left, right;    /* left and right terms set
  40.                                          * expression */
  41.         char            o;      /* operator character */
  42.  
  43. #ifdef DEBUG
  44.         printf("Evaluating %s\n", Optr);
  45. #endif
  46.         Force_byte = NO;
  47.         Force_word = NO;
  48.         if (*Optr == '<') {
  49.                 Force_byte++;
  50.                 Optr++;
  51.         } else if (*Optr == '>') {
  52.                 Force_word++;
  53.                 Optr++;
  54.         }
  55.         left = get_term();      /* pickup first part of expression */
  56.  
  57.         while (is_op(*Optr)) {
  58.                 o = *Optr++;    /* pickup connector and skip */
  59.                 right = get_term();     /* pickup current rightmost side */
  60.                 switch (o) {
  61.                 case '+':
  62.                         left += right;
  63.                         break;
  64.                 case '-':
  65.                         left -= right;
  66.                         break;
  67.                 case '*':
  68.                         left *= right;
  69.                         break;
  70.                 case '/':
  71.                         left /= right;
  72.                         break;
  73.                 case '|':
  74.                         left |= right;
  75.                         break;
  76.                 case '&':
  77.                         left &= right;
  78.                         break;
  79.                 case '%':
  80.                         left %= right;
  81.                         break;
  82.                 case '^':
  83.                         left = left ^ right;
  84.                         break;
  85.                 }
  86.         }
  87.  
  88.         Result = left;
  89. #ifdef DEBUG
  90.         printf("Result=%x\n", Result);
  91.         printf("Force_byte=%d  Force_word=%d\n", Force_byte, Force_word);
  92. #endif
  93.         return (YES);
  94. }
  95.  
  96. /*
  97.  * is_op --- is character an expression operator?
  98.  */
  99. int
  100. is_op(char c)
  101. {
  102.         if (any(c, "+-*/&%|^"))
  103.                 return (YES);
  104.         return (NO);
  105. }
  106.  
  107.  
  108. /*
  109.  * get_term --- evaluate a single item in an expression
  110.  */
  111. int
  112. get_term(void)
  113. {
  114.         char            hold[MAXBUF];
  115.         char           *tmp;
  116.         int             val = 0;/* local value being built */
  117.         int             minus;  /* unary minus flag */
  118.         struct nlist   *pointer;
  119.         struct link    *pnt, *bpnt;
  120.  
  121.         if (*Optr == '-') {
  122.                 Optr++;
  123.                 minus = YES;
  124.         } else
  125.                 minus = NO;
  126.  
  127.         while (*Optr == '#')
  128.                 Optr++;
  129.  
  130.         /* look at rest of expression */
  131.  
  132.         if (*Optr == '%') {     /* binary constant */
  133.                 Optr++;
  134.                 while (any(*Optr, "01"))
  135.                         val = (val * 2) + ((*Optr++) - '0');
  136.         } else if (*Optr == '@') {      /* octal constant */
  137.                 Optr++;
  138.                 while (any(*Optr, "01234567"))
  139.                         val = (val * 8) + ((*Optr++) - '0');
  140.         } else if (*Optr == '$') {      /* hex constant */
  141.                 Optr++;
  142.                 while (any(*Optr, "0123456789abcdefABCDEF"))
  143.                         if (*Optr > '9')
  144.                                 val = (val * 16) + 10 + (mapdn(*Optr++) - 'a');
  145.                         else
  146.                                 val = (val * 16) + ((*Optr++) - '0');
  147.         } else if (any(*Optr, "0123456789")) {  /* decimal constant */
  148.                 while (*Optr >= '0' && *Optr <= '9')
  149.                         val = (val * 10) + ((*Optr++) - '0');
  150.         } else if (*Optr == '*') {      /* current location counter */
  151.                 Optr++;
  152.                 val = Old_pc;
  153.         } else if (*Optr == '\'') {     /* character literal */
  154.                 Optr++;
  155.                 if (*Optr == EOS)
  156.                         val = 0;
  157.                 else
  158.                         val = *Optr++;
  159.         } else if (alpha(*Optr)) {      /* a symbol */
  160.                 tmp = hold;     /* collect symbol name */
  161.                 while (alphan(*Optr))
  162.                         *tmp++ = *Optr++;
  163.                 *tmp = EOS;
  164.                 pointer = lookup(hold);
  165.                 if (pointer != NULL) {
  166.                         if (Pass == 2) {
  167.                                 pnt = pointer->L_list;
  168.                                 bpnt = NULL;
  169.                                 while (pnt != NULL) {
  170.                                         bpnt = pnt;
  171.                                         pnt = pnt->next;
  172.                                 }
  173.                                 pnt = (struct link *) alloc(sizeof(struct link));
  174.                                 if (bpnt == NULL)
  175.                                         pointer->L_list = pnt;
  176.                                 else
  177.                                         bpnt->next = pnt;
  178.                                 pnt->L_num = Line_num;
  179.                                 pnt->next = NULL;
  180.                         }
  181.                         val = Last_sym;
  182.                 } else {
  183.                         if (Pass == 1) {        /* forward ref here */
  184.                                 fwdmark();
  185.                                 if (!Force_byte)
  186.                                         Force_word++;
  187.                                 val = 0;
  188.                         } else  /* added ver TER_2.0  2 Jul 89 */
  189.                                 error("Symbol undefined Pass 2");
  190.                 }
  191.                 if (Pass == 2 && Line_num == F_ref && Cfn == Ffn) {
  192.                         if (!Force_byte)
  193.                                 Force_word++;
  194.                         fwdnext();
  195.                 }
  196.         } else
  197.                 /* none of the above */
  198.                 val = 0;
  199.  
  200.         if (minus)
  201.                 return (-val);
  202.         else
  203.                 return (val);
  204. }
  205.