home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / language / asxsrc / lkeval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-25  |  3.5 KB  |  238 lines

  1. /* lkeval.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "aslink.h"
  14.  
  15. /*
  16.  * Evaluate input term.
  17.  */
  18. int
  19. eval()
  20. {
  21.     register c, n, v;
  22.  
  23.     c = getnb();
  24.     n = 0;
  25.     while ((v = digit(c, radix)) >= 0) {
  26.         n = n*radix + v;
  27.         c = get();
  28.     }
  29.     unget(c);
  30.     return(n);
  31. }
  32.  
  33. /*
  34.  * Expression evaluation.
  35.  * `N' is a firewall priority; all top level calls
  36.  * (from the user) should be made with `n' set to 0.
  37.  */
  38. int
  39. expr (n)
  40. {
  41.     register c, p;
  42.     register v, ve;
  43.  
  44.     v = term();
  45.     while (ctype[c = getnb()] == BINOP) {
  46.         if ((p = oprio(c)) <= n)
  47.             break;
  48.         if ((c == '>' || c == '<') && c != get()) {
  49.             fprintf(stderr, "Invalid expression");
  50.             return(v);
  51.         }
  52.         ve = expr(p);
  53.         if (c == '+') {
  54.             v += ve;
  55.         } else
  56.         if (c == '-') {
  57.             v -= ve;
  58.         } else {
  59.             switch (c) {
  60.  
  61.             case '*':
  62.                 v *= ve;
  63.                 break;
  64.  
  65.             case '/':
  66.                 v /= ve;
  67.                 break;
  68.  
  69.             case '&':
  70.                 v &= ve;
  71.                 break;
  72.  
  73.             case '|':
  74.                 v |= ve;
  75.                 break;
  76.  
  77.             case '%':
  78.                 v %= ve;
  79.                 break;
  80.  
  81.             case '^':
  82.                 v ^= ve;
  83.                 break;
  84.  
  85.             case '<':
  86.                 v <<= ve;
  87.                 break;
  88.  
  89.             case '>':
  90.                 v >>= ve;
  91.                 break;
  92.             }
  93.         }
  94.     }
  95.     unget(c);
  96.     return(v);
  97. }
  98.  
  99. /*
  100.  * Read a term.
  101.  * Handles unary operators, brackets,
  102.  * constants in decimal, octal or hexadecimal
  103.  * and identifiers.
  104.  */
  105. int
  106. term()
  107. {
  108.     register c, n;
  109.     register r, v;
  110.     struct sym *sp;
  111.     char id[NCPS];
  112.  
  113.     c = getnb();
  114.     if (c == '#') { c = getnb(); }
  115.     if (c == '(') {
  116.         v = expr(0);
  117.         if (getnb() != ')')
  118.             fprintf(stderr, "Missing delimiter");
  119.         return(v);
  120.     }
  121.     if (c == '-') {
  122.         return(-expr(100));
  123.     }
  124.     if (c == '~') {
  125.         return(~expr(100));
  126.     }
  127.     if (c == '\'') {
  128.         return(getmap(-1));
  129.     }
  130.     if (c == '\"') {
  131.         if (hilo) {
  132.             return((getmap(-1)&0377)<<8 | (getmap(-1)&0377));
  133.         } else {
  134.             return((getmap(-1)&0377) | (getmap(-1)&0377)<<8);
  135.         }
  136.     }
  137.     if (c == '>' || c == '<') {
  138.         v = expr(100);
  139.         if (c == '>')
  140.             v >>= 8;
  141.         return(v&0377);
  142.     }
  143.     if (ctype[c] == DIGIT) {
  144.         r = 10;
  145.         if (c == '0') {
  146.             c = get();
  147.             switch (c) {
  148.             case 'b':
  149.             case 'B':
  150.                 r = 2;
  151.                 c = get();
  152.                 break;
  153.             case '@':
  154.             case 'o':
  155.             case 'O':
  156.             case 'q':
  157.             case 'Q':
  158.                 r = 8;
  159.                 c = get();
  160.                 break;
  161.             case 'd':
  162.             case 'D':
  163.                 r = 10;
  164.                 c = get();
  165.                 break;
  166.             case 'h':
  167.             case 'H':
  168.             case 'x':
  169.             case 'X':
  170.                 r = 16;
  171.                 c = get();
  172.                 break;
  173.             default:
  174.                 break;
  175.             }
  176.         }
  177.         n = 0;
  178.         while ((v = digit(c, r)) >= 0) {
  179.             n = r*n + v;
  180.             c = get();
  181.         }
  182.         unget(c);
  183.         return(n);
  184.     }
  185.     if (ctype[c] == LETTER) {
  186.         getid(id, c);
  187.         if ((sp = lkpsym(id, 0)) == NULL) {
  188.             fprintf(stderr, "Undefined symbol %8s\n", id);
  189.             return(0);
  190.         } else {
  191.             return(symval(sp));
  192.         }
  193.     }
  194. }
  195.  
  196. /*
  197.  * If `c' is a legal radix `r' digit
  198.  * return its value; otherwise return
  199.  * -1.
  200.  */
  201. int
  202. digit(c, r)
  203. register c, r;
  204. {
  205.     if (r == 16) {
  206.         if (c >= 'A' && c <= 'F')
  207.             return (c - 'A' + 10);
  208.         if (c >= 'a' && c <= 'f')
  209.             return (c - 'a' + 10);
  210.     }
  211.     if (c >= '0' && c <= '9')
  212.         return (c - '0');
  213.     return (-1);
  214. }
  215.  
  216. /*
  217.  * Return the priority of the binary
  218.  * operator `c'.
  219.  */
  220. int
  221. oprio(c)
  222. register c;
  223. {
  224.     if (c == '*' || c == '/' || c == '%')
  225.         return (10);
  226.     if (c == '+' || c == '-')
  227.         return (7);
  228.     if (c == '<' || c == '>')
  229.         return (5);
  230.     if (c == '^')
  231.         return (4);
  232.     if (c == '&')
  233.         return (3);
  234.     if (c == '|')
  235.         return (1);
  236.     return (0);
  237. }
  238.