home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / emulator / unix / z80pack / z80asm / z80anum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-09  |  7.2 KB  |  318 lines

  1. /*
  2.  *      Z80 - Assembler
  3.  *      Copyright (C) 1987-1992 by Udo Munk
  4.  *
  5.  *    History:
  6.  *    17-SEP-1987 Development under Digital Research CP/M 2.2
  7.  *      28-JUN-1988 Switched to Unix System V.3
  8.  */
  9.  
  10. /*
  11.  *      Dieses Modul enthaelt die numerischen
  12.  *      Rechen- und Umwandlungsfunktionen.
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <ctype.h>
  17. #include "z80a.h"
  18. #include "z80aglb.h"
  19.  
  20. #ifndef isxdigit
  21. #define isxdigit(c) (isdigit(c) || (c>='a' && c<='f') || (c>='A' && c<='F'))
  22. #endif
  23.  
  24. /*
  25.  *      Definition Operatoren-Symbole fuer den Expression-Parser
  26.  */
  27. #define OPEDEC          1       /* Dezimalzahl */
  28. #define OPEHEX          2       /* Hexzahl */
  29. #define OPEOCT          3       /* Octalzahl */
  30. #define OPEBIN          4       /* Binaerzahl */
  31. #define OPESUB          5       /* arithmetisches - */
  32. #define OPEADD          6       /* arithmetisches + */
  33. #define OPEMUL          7       /* arithmetisches * */
  34. #define OPEDIV          8       /* arithmetisches / */
  35. #define OPEMOD          9       /* arithmetisches Modulo */
  36. #define OPESHL          10      /* logisches shift left */
  37. #define OPESHR          11      /* logisches shift right */
  38. #define OPELOR          12      /* logisches OR */
  39. #define OPELAN          13      /* logisches AND */
  40. #define OPEXOR          14      /* logisches XOR */
  41. #define OPECOM          15      /* logisches Komplement */
  42. #define OPESYM          99      /* Symbol */
  43.  
  44. /*
  45.  *      Rekursiver Expression-Parser
  46.  *
  47.  *    Input:    Pointer auf den restlichen Argument-String
  48.  *
  49.  *      Output: berechneter Wert
  50.  */
  51. eval(s)
  52. register char *s;
  53. {
  54.     register char *p;
  55.     register int val;
  56.     char word[MAXLINE];
  57.     struct sym *sp, *get_sym();
  58.  
  59.     val = 0;
  60.     while (*s) {
  61.         p = word;
  62.         if (*s == '(') {
  63.             s++;
  64.             while (*s != ')') {
  65.                 if (*s == '\0') {
  66.                     asmerr(E_MISPAR);
  67.                     goto eval_break;
  68.                 }
  69.                 *p++ = *s++;
  70.             }
  71.             *p = '\0';
  72.             s++;
  73.             val = eval(word);
  74.             continue;
  75.         }
  76.         if (*s == STRSEP) {
  77.             s++;
  78.             while (*s != STRSEP) {
  79.                 if (*s == '\n' || *s == '\0') {
  80.                     asmerr(E_MISHYP);
  81.                     goto hyp_error;
  82.                 }
  83.                 *p++ = *s++;
  84.             }
  85.             s++;
  86. hyp_error:
  87.             *p = '\0';
  88.             val = strval(word);
  89.             continue;
  90.         }
  91.         if (isari(*s))
  92.             *p++ = *s++;
  93.         else
  94.             while (!isspace(*s) && !isari(*s) && (*s != '\0'))
  95.                 *p++ = *s++;
  96.         *p = '\0';
  97.         switch (get_type(word)) {
  98.         case OPESYM:                    /* Symbol */
  99.             if (strcmp(word, "$") == 0) {
  100.                 val = pc;
  101.                 break;
  102.             }
  103.             if (strlen(word) > SYMSIZE)
  104.                 word[SYMSIZE] = '\0';
  105.             if ((sp = get_sym(word)) != NULL)
  106.                 val = sp->sym_wert;
  107.             else
  108.                 asmerr(E_UNDSYM);
  109.             break;
  110.         case OPEDEC:                    /* Dezimalzahl */
  111.             val = atoi(word);
  112.             break;
  113.         case OPEHEX:                    /* Hexzahl */
  114.             val = axtoi(word);
  115.             break;
  116.         case OPEBIN:                    /* Binaerzahl */
  117.             val = abtoi(word);
  118.             break;
  119.         case OPEOCT:                    /* Oktalzahl */
  120.             val = aotoi(word);
  121.             break;
  122.         case OPESUB:                    /* arithmetisches - */
  123.             val -= eval(s);
  124.             goto eval_break;
  125.         case OPEADD:                    /* arithmetisches + */
  126.             val += eval(s);
  127.             goto eval_break;
  128.         case OPEMUL:                    /* arithmetisches * */
  129.             val *= eval(s);
  130.             goto eval_break;
  131.         case OPEDIV:                    /* arithmetisches / */
  132.             val /= eval(s);
  133.             goto eval_break;
  134.         case OPEMOD:                    /* arithmetisches Modulo */
  135.             val %= eval(s);
  136.             goto eval_break;
  137.         case OPESHL:                    /* logisches shift left */
  138.             val <<= eval(s);
  139.             goto eval_break;
  140.         case OPESHR:                    /* logisches shift right */
  141.             val >>= eval(s);
  142.             goto eval_break;
  143.         case OPELOR:                    /* logisches OR */
  144.             val |= eval(s);
  145.             goto eval_break;
  146.         case OPELAN:                    /* logisches AND */
  147.             val &= eval(s);
  148.             goto eval_break;
  149.         case OPEXOR:                    /* logisches XOR */
  150.             val ^= eval(s);
  151.             goto eval_break;
  152.         case OPECOM:                    /* logisches Komplement */
  153.             val = ~(eval(s));
  154.             goto eval_break;
  155.         }
  156.     }
  157.     eval_break:
  158.     return(val);
  159. }
  160.  
  161. /*
  162.  *      Operanden Typ-Bestimmung
  163.  *
  164.  *      Input:  Pointer auf zu bestimmenden String
  165.  *
  166.  *      Output: Operanden Typ
  167.  */
  168. get_type(s)
  169. char *s;
  170. {
  171.     if (isdigit(*s)) {              /* numerischer Operand */
  172.         if (isdigit(*(s + strlen(s) - 1)))      /* Dezimalzahl */
  173.             return(OPEDEC);
  174.         else if (*(s + strlen(s) - 1) == 'H')   /* Hexzahl */
  175.             return(OPEHEX);
  176.         else if (*(s + strlen(s) - 1) == 'B')   /* Binaerzahl */
  177.             return(OPEBIN);
  178.         else if (*(s + strlen(s) - 1) == 'O')   /* Oktalzahl */
  179.             return(OPEOCT);
  180.     } else if (*s == '-')           /* arithmetischer Operand - */
  181.         return(OPESUB);
  182.     else if (*s == '+')             /* arithmetischer Operand + */
  183.         return(OPEADD);
  184.     else if (*s == '*')             /* arithmetischer Operand * */
  185.         return(OPEMUL);
  186.     else if (*s == '/')             /* arithmetischer Operand / */
  187.         return(OPEDIV);
  188.     else if (*s == '%')             /* arithmetisches Modulo */
  189.         return(OPEMOD);
  190.     else if (*s == '<')             /* logisches shift left */
  191.         return(OPESHL);
  192.     else if (*s == '>')             /* logisches shift rigth */
  193.         return(OPESHR);
  194.     else if (*s == '|')             /* logisches OR */
  195.         return(OPELOR);
  196.     else if (*s == '&')             /* logisches AND */
  197.         return(OPELAN);
  198.     else if (*s == '^')             /* logisches XOR */
  199.         return(OPEXOR);
  200.     else if (*s == '~')             /* logisches Komplement */
  201.         return(OPECOM);
  202.     return(OPESYM);                 /* Operand ist ein Symbol */
  203. }
  204.  
  205. /*
  206.  *      Die Funktion prueft einen Character auf die arithmetischen
  207.  *      Operatoren +, -, *, /, %, <, >, |, &, ~ und ^.
  208.  */
  209. isari(c)
  210. register int c;
  211. {
  212.     return((c) == '+' || (c) == '-' || (c) == '*' ||
  213.            (c) == '/' || (c) == '%' || (c) == '<' ||
  214.            (c) == '>' || (c) == '|' || (c) == '&' ||
  215.            (c) == '~' || (c) == '^');
  216. }
  217.  
  218. /*
  219.  *      Umwandlung eines ASCII-Strings mit einer Hexzahl in
  220.  *      einen Integer.
  221.  *      Format: nnnnH oder 0nnnnH wenn 1.Ziffer > 9
  222.  */
  223. axtoi(str)
  224. register char *str;
  225. {
  226.     register int num;
  227.  
  228.     num = 0;
  229.     while (isxdigit(*str)) {
  230.         num *= 16;
  231.         num += *str - ((*str <= '9') ? '0' : '7');
  232.         str++;
  233.     }
  234.     return(num);
  235. }
  236.  
  237. /*
  238.  *      Umwandlung eines ASCII-Strings mit einer Oktalzahl in
  239.  *      einen Integer.
  240.  *      Format: nnnnO
  241.  */
  242. aotoi(str)
  243. register char *str;
  244. {
  245.     register int num;
  246.  
  247.     num = 0;
  248.     while ('0' <= *str && *str <= '7') {
  249.         num *= 8;
  250.         num += (*str++) - '0';
  251.     }
  252.     return(num);
  253. }
  254.  
  255. /*
  256.  *      Umwandlung eines ASCII-Strings mit einer Binaerzahl in
  257.  *      einen Integer.
  258.  *      Format: nnnnnnnnnnnnnnnnB
  259.  */
  260. abtoi(str)
  261. register char *str;
  262. {
  263.     register int num;
  264.  
  265.     num = 0;
  266.     while ('0' <= *str && *str <= '1') {
  267.         num *= 2;
  268.         num += (*str++) - '0';
  269.     }
  270.     return(num);
  271. }
  272.  
  273. /*
  274.  *      Umwandlung eines ASCII-Strings in einen Integer.
  275.  */
  276. strval(str)
  277. register char *str;
  278. {
  279.     register int num;
  280.  
  281.     num = 0;
  282.     while (*str) {
  283.         num <<= 8;
  284.         num += (int) *str++;
  285.     }
  286.     return(num);
  287. }
  288.  
  289. /*
  290.  *      Die Funktion prueft einen Wert auf -256 < Wert < 256
  291.  *      Output: Wert wenn im Bereich, sonst 0 und Fehlermeldung
  292.  */
  293. chk_v1(i)
  294. register int i;
  295. {
  296.     if (i >= -255 && i <= 255)
  297.         return(i);
  298.     else {
  299.         asmerr(E_VALOUT);
  300.         return(0);
  301.     }
  302. }
  303.  
  304. /*
  305.  *      Die Funktion prueft einen Wert auf -128 < Wert < 128
  306.  *      Output: Wert wenn im Bereich, sonst 0 und Fehlermeldung
  307.  */
  308. chk_v2(i)
  309. register int i;
  310. {
  311.     if (i >= -127 && i <= 127)
  312.         return(i);
  313.     else {
  314.         asmerr(E_VALOUT);
  315.         return(0);
  316.     }
  317. }
  318.