home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 148_01 / a99eval.c < prev    next >
Text File  |  1987-09-28  |  8KB  |  217 lines

  1. /*
  2.     TMS9900/99105  Cross-Assembler  v. 1.0
  3.  
  4.     January, 1985
  5.  
  6.     Original 6800 version Copyright (c) 1980 William C. Colley, III.
  7.     Modified for the TMS9900/99105  Series by Alexander Cameron.
  8.  
  9. File:    a99eval.c
  10.  
  11. Routines to crunch on source text chunks and give back
  12. evaluated expressions, opcode parameters, etc.
  13. */
  14.  
  15. /*  Get Globals:  */
  16.  
  17. #include "a99.gbl"
  18.  
  19. /*
  20. Function to evaluate the next expression on the present source line.
  21. Function returns the value of the expression.  In addition, a global
  22. flag, evalerr, is set to TRUE if an error occurred anywhere in the
  23. evaluation process.  The precidence parameter, prec, is for the benefit
  24. of the recursion.  In the first call to the routine, use START.
  25. */
  26.  
  27. eval(prec)
  28. char prec;
  29. {
  30.     unsigned valu1, valu2;
  31.     while (TRUE)
  32.     {
  33.         switch (getitem(&valu1,SMALST))
  34.         {
  35.  
  36.             case COMMA:      if (prec != START) backitem(0,COMMA);
  37.                           goto enderr;
  38.  
  39.             case END_LIN: backitem(0,END_LIN);
  40.             enderr:       evalerr = TRUE;
  41.                           markerr('E');
  42.                           return 0;
  43.  
  44.             case OPERATR: if (valu1 == NOT) valu1 = ~eval(UOP2);
  45.                           else if (valu1 == '-') valu1 = -eval(UOP1);
  46.                           else if (valu1 == '+') valu1 = eval(UOP1);
  47.                           else if (valu1 == '(') valu1 = eval(LPREN);
  48.                           else if (valu1 == HIGH) valu1 = eval(UOP3) >> 8;
  49.                           else if (valu1 == LOW) valu1 = eval(UOP3) & 0xff;
  50.                           else if (valu1 == '$') valu1 = pc;
  51.                           else
  52.                           {
  53.                               evalerr = TRUE;
  54.                               markerr('E');
  55.                               break;
  56.                           }
  57.  
  58.             case VALUE:   while (TRUE)
  59.                           {
  60.                               switch (getitem(&valu2,SMALST))
  61.                               {
  62.                 /*  eval shall now return the delimeter */
  63.                 /*  it makes life so much easier for me */
  64.  
  65.                 case COMMA:    /* if (prec != START) */
  66.                         backitem(0,COMMA);
  67.                         goto endeval;
  68.  
  69.                                   case END_LIN: backitem(0,END_LIN);
  70.                                   endeval:      if (prec == LPREN)
  71.                                                 {
  72.                                                     evalerr = TRUE;
  73.                                                     markerr('(');
  74.                                                 }
  75.                                                 return (evalerr) ? 0 : valu1;
  76.  
  77.                                   case VALUE:   evalerr = TRUE;
  78.                                                 markerr('E');
  79.                                                 break;
  80.  
  81.                                   case OPERATR:    quitflag=FALSE;
  82.                         if (valu2 == '+' && addrmode == INDIRECT)
  83.                             {addrmode=AUTOINC;
  84.                              return valu1;
  85.                             }
  86.                         if (valu2 == ')' && addrmode == INDEXED) return valu1;
  87.          
  88.                         if (valu2 == '(' && addrmode == SYMBOLIC)
  89.                             {
  90.                              addrmode=INDEXED;
  91.                              quitflag=TRUE;
  92.                              return valu1;
  93.                             }
  94.                         if (valu2 == '(' || valu2 == NOT || valu2 == HIGH || valu2 == LOW)
  95.                                                 {
  96.                                                     evalerr = TRUE;
  97.                                                     markerr('E');
  98.                                                     break;
  99.                                                 }
  100.                                                 if (prec <= getprec(valu2))
  101.                                                 {
  102.                                                     backitem(valu2,OPERATR);
  103.                                                     return valu1;
  104.                                                 }
  105.                                                 switch (valu2)
  106.                                                 {
  107.                                                     case '+':   valu1 += eval(ADDIT); break;
  108.  
  109.                                                     case '-':   valu1 -= eval(ADDIT); break;
  110.  
  111.                                                     case '*':   valu1 *= eval(MULT); break;
  112.  
  113.                                                     case '/':   valu1 /= eval(MULT); break;
  114.                             case MOD:    valu1 %=eval(MULT);break;
  115.                             case AND:    valu1 &= eval(LOG1);break;
  116.                             case OR:    valu1 |= eval(LOG2);break;
  117.                             case XOR:    valu1 ^= eval(LOG2);break;
  118.                             case '>':   valu1 = (valu1 > eval(RELAT)) ? 0xffff : 0; break;
  119.  
  120.                                                     case GRTEQ: valu1 = (valu1 >= eval(RELAT)) ? 0xffff : 0; break;
  121.  
  122.                                                     case '=':   valu1 = (valu1 == eval(RELAT)) ? 0xffff : 0; break;
  123.  
  124.                                                     case NOTEQ: valu1 = (valu1 != eval(RELAT)) ? 0xffff : 0; break;
  125.  
  126.                                                     case '<':   valu1 = (valu1 < eval(RELAT)) ? 0xffff : 0; break;
  127.  
  128.                                                     case LESEQ: valu1 = (valu1 <= eval(RELAT)) ? 0xffff : 0; break;
  129.  
  130.                                                     case SHL:   if ((valu2 = eval(MULT)) > 15)
  131.                                                                 {
  132.                                                                     evalerr = TRUE;
  133.                                                                     markerr('E');
  134.                                                                     break;
  135.                                                                 }
  136.                                                                 valu1 = valu1 << valu2;
  137.                                                                 break;
  138.  
  139.                                                     case SHR:   if ((valu2 = eval(MULT)) > 15)
  140.                                                                 {
  141.                                                                     evalerr = TRUE;
  142.                                                                     markerr('E');
  143.                                                                     break;
  144.                                                                 }
  145.                                                                 valu1 = valu1 >> valu2;
  146.                                                                 break;
  147.  
  148.                                                     case ')':   if (prec == LPREN) return valu1;
  149.                                                                 else
  150.                                                                 {
  151.                                                                     evalerr = TRUE;
  152.                                                                     markerr('(');
  153.                                                                     break;
  154.                                                                 }
  155.                                                 }
  156.                                           if(quitflag) return valu1;
  157.                 }
  158.                           }
  159.         }
  160.     }
  161. }
  162.  
  163. /*
  164. Function to get the precedence of a binary operator.
  165. Function returns the precedence value.
  166. */
  167.  
  168. getprec(operator)
  169. char operator;
  170. {
  171.     switch (operator)
  172.     {
  173.         case '*':
  174.         case '/':
  175.         case MOD:
  176.         case SHL:
  177.         case SHR:    return MULT;
  178.  
  179.         case '+':
  180.         case '-':    return ADDIT;
  181.  
  182.         case '>':
  183.         case '=':
  184.         case '<':
  185.         case GRTEQ:
  186.         case NOTEQ:
  187.         case LESEQ:    return RELAT;
  188.  
  189.         case AND:    return LOG1;
  190.  
  191.         case OR:
  192.         case XOR:    return LOG2;
  193.  
  194.         case HIGH:
  195.         case LOW:    return UOP3;
  196.  
  197.         case ')':    return RPREN;
  198.     }
  199. }
  200.  
  201. /*
  202. Function to mark up an error in the line if one isn't
  203. already marked up.  The error code letter comes in
  204. through letter.
  205. */
  206.  
  207. markerr(letter)
  208. char letter;
  209. {
  210.     if (errcode == ' ')
  211.     {
  212.         errcode = letter;
  213.         errcount++;
  214.     }
  215. }
  216.  
  217.