home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / icon / dos / src / icont / llex.c < prev    next >
C/C++ Source or Header  |  1992-02-10  |  8KB  |  374 lines

  1. /*
  2.  * llex.c -- lexical analysis routines.
  3.  */
  4.  
  5. #ifdef CRAY
  6. #include <stdlib.h>
  7. #endif                    /* CRAY */
  8.  
  9. #include "link.h"
  10. #include "tproto.h"
  11. #include "opcode.h"
  12.  
  13. int nlflag = 0;        /* newline last seen */
  14.  
  15. #if MACINTOSH
  16. #if MPW
  17. #include <CursorCtl.h>
  18. #define CURSORINTERVAL 100
  19. #endif                    /* MPW */
  20. #endif                    /* MACINTOSH */
  21.  
  22. #if !EBCDIC
  23. #define tonum(c)    (isdigit(c) ? (c - '0') : ((c & 037) + 9))
  24. #endif                    /* !EBCDIC */
  25.  
  26. #if !EBCDIC
  27. /*
  28.  * getopc - get an opcode from infile, return the opcode number (via
  29.  *  binary search of opcode table), and point id at the name of the opcode.
  30.  */
  31. int getopc(id)
  32. char **id;
  33.    {
  34.    register char *s;
  35.    register struct opentry *p;
  36.    register int test;
  37.    int low, high, cmp;
  38.  
  39.    s = getstr();
  40.    if (s == NULL)
  41.       return EOF;
  42.    low = 0;
  43.    high = NOPCODES;
  44.    do {
  45.       test = (low + high) / 2;
  46.       p = &optable[test];
  47.       if ((cmp = strcmp(p->op_name, s)) < 0)
  48.          low = test + 1;
  49.       else if (cmp > 0)
  50.          high = test;
  51.       else {
  52.          *id = p->op_name;
  53.          return (p->op_code);
  54.          }
  55.       } while (low < high);
  56.    *id = s;
  57.    return 0;
  58.    }
  59. #else                    /* !EBCDIC */
  60. /*
  61.  * getopc - get an opcode from infile, return the opcode number (via
  62.  * sequential search of opcode table) and point id at the name of the opcode.
  63.  */
  64.  
  65. int getopc(id)
  66. char **id;
  67.    {
  68.    register char *s;
  69.    register struct opentry *p;
  70.    register int test;
  71.  
  72.    s = getstr();
  73.    if (s == NULL)
  74.       return EOF;
  75.    for(test=0;test < NOPCODES; test++) {
  76.        p = &optable[test];
  77.        if( strcmp(p->op_name, s) == 0) {
  78.            *id = p->op_name;
  79.            return (p->op_code);
  80.        }
  81.    }
  82.    *id = s;
  83.    return 0;
  84.    }
  85. #endif                    /* !EBCDIC */
  86.  
  87. /*
  88.  * getid - get an identifier from infile, put it in the identifier
  89.  *  table, and return a pointer to it.
  90.  */
  91. char *getid()
  92.    {
  93.    register char *s;
  94.  
  95.    s = getstr();
  96.    if (s == NULL)
  97.       return NULL;
  98.    return putident((int)strlen(s)+1);
  99.    }
  100.  
  101. /*
  102.  * getstr - get an identifier from infile and return a pointer to it.
  103.  */
  104. char *getstr()
  105.    {
  106.    register int c;
  107.    register char *p;
  108.  
  109. #if MACINTOSH
  110. #if MPW
  111.    {
  112.    static short cursorcount = CURSORINTERVAL;
  113.    if (--cursorcount == 0) {
  114.       RotateCursor(-32);
  115.       cursorcount = CURSORINTERVAL;
  116.       }
  117.    }
  118. #endif                    /* MPW */
  119. #endif                    /* MACINTOSH */
  120.  
  121.    p = lsfree;
  122.    while ((c = getc(infile)) == ' ' || c == '\t') ;
  123.    if (c == EOF)
  124.       return NULL;
  125.  
  126. #if MSDOS && INTEL_386
  127.    /*
  128.     * Code Builder lets carriage returns through sometimes.
  129.     */
  130.    while (c != ' ' && c != '\t' && c != '\n' && c != '\r' && c != ',' &&
  131.       c != EOF) {
  132. #else                    /* MSDOS && INTEL_386 */
  133.    while (c != ' ' && c != '\t' && c != '\n' && c != ',' && c != EOF) {
  134. #endif                    /* MSDOS && INTEL_386 */
  135.  
  136.       if (p >= lsend)
  137.          quit("out of string space");
  138.       *p++ = c;
  139.       c = getc(infile);
  140.       }
  141.    *p = 0;
  142.    nlflag = (c == '\n');
  143.    return lsfree;
  144.    }
  145.  
  146. /*
  147.  * getrest - get the rest of the line from infile, put it in the identifier
  148.  *  table, and return a pointer to it.
  149.  */
  150. char *getrest()
  151.    {
  152.    register int c;
  153.    register char *p;
  154.  
  155.    p = lsfree;
  156.  
  157. #if MSDOS && INTEL_386
  158.    /*
  159.     * Code Builder lets carriage returns through on occasion
  160.     */
  161.    while ((c = getc(infile)) != '\n' && c != '\r' && c != EOF) {
  162. #else                    /* MSDOS && INTEL_386 */
  163.    while ((c = getc(infile)) != '\n' && c != EOF) {
  164. #endif                    /* MSDOS && INTEL_386 */
  165.  
  166.       if (p >= lsend)
  167.          quit("out of string space");
  168.       *p++ = c;
  169.       }
  170.    *p = 0;
  171.    nlflag = (c == '\n');
  172.    return putident((int)strlen(lsfree)+1);
  173.    }
  174.  
  175. /*
  176.  * getdec - get a decimal integer from infile, and return it.
  177.  */
  178. int getdec()
  179.    {
  180.    register int c, n;
  181.    int sign = 1, rv;
  182.  
  183.    n = 0;
  184.    while ((c = getc(infile)) == ' ' || c == '\t') ;
  185.    if (c == EOF)
  186.       return 0;
  187.    if (c == '-') {
  188.       sign = -1;
  189.       c = getc(infile);
  190.       }
  191.    while (c >= '0' && c <= '9') {
  192.       n = n * 10 + (c - '0');
  193.       c = getc(infile);
  194.       }
  195.    nlflag = (c == '\n');
  196.    rv = n * sign;
  197.    return rv;                    /* some compilers ... */
  198.    }
  199.  
  200. /*
  201.  * getoct - get an octal number from infile, and return it.
  202.  */
  203. int getoct()
  204.    {
  205.    register int c, n;
  206.  
  207.    n = 0;
  208.    while ((c = getc(infile)) == ' ' || c == '\t') ;
  209.    if (c == EOF)
  210.       return 0;
  211.    while (c >= '0' && c <= '7') {
  212.       n = (n << 3) | (c - '0');
  213.       c = getc(infile);
  214.       }
  215.    nlflag = (c == '\n');
  216.    return n;
  217.    }
  218.  
  219. /*
  220.  *  Get integer, but if it's too large for a long, put the string via cp
  221.  *   and return -1.
  222.  */
  223. long getint(j,cp)
  224.    int j;
  225.    char **cp;
  226.    {
  227.    register int c;
  228.    int over = 0;
  229.    register char *p;
  230.    double result = 0;
  231.    long lresult = 0;
  232.    double radix;
  233.  
  234.    if (lsfree + j > lsend)
  235.       quit("out of string space");
  236.    p = lsfree;
  237.    
  238.    while ((c = getc(infile)) >= '0' && c <= '9') {
  239.       *p++ = c;
  240.       result = result * 10 + (c - '0');
  241.       lresult = lresult * 10 + (c - '0');
  242.       if (result <= MinLong || result >= MaxLong) {
  243.          over = 1;            /* flag overflow */
  244.          result = 0;            /* reset to avoid fp exception */
  245.          }
  246.       }
  247.    if (c == 'r' || c == 'R') {
  248.       *p++ = c;
  249.       radix = result;
  250.       lresult = 0;
  251.       result = 0;
  252.       while (c = getc(infile)) {
  253.          *p++ = c;
  254.          if (isdigit(c) || isalpha(c))
  255.             c = tonum(c);
  256.          else
  257.             break;
  258.          result = result * radix + c;
  259.          lresult = lresult * radix + c;
  260.          if (result <= MinLong || result >= MaxLong) {
  261.             over = 1;            /* flag overflow */
  262.             result = 0;            /* reset to avoid fp exception */
  263.             }
  264.          }
  265.       }
  266.    nlflag = (c == '\n');
  267.    if (!over)
  268.       return lresult;            /* integer is small enough */
  269.    else {                /* integer is too large */
  270.       *p++ = 0;
  271.       *cp = putident((int)(p - lsfree));/* convert integer to string */
  272.       return -1;            /* indicate integer is too big */
  273.       }
  274.    }
  275.  
  276. /*
  277.  * getreal - get an Icon real number from infile, and return it.
  278.  */
  279. double getreal()
  280.    {
  281.    double n;
  282.    register int c, d, e;
  283.    int esign;
  284.    register char *s, *ep;
  285.    char cbuf[128];
  286.  
  287.    s = cbuf;
  288.    d = 0;
  289.    while ((c = getc(infile)) == '0')
  290.       ;
  291.    while (c >= '0' && c <= '9') {
  292.       *s++ = c;
  293.       d++;
  294.       c = getc(infile);
  295.       }
  296.    if (c == '.') {
  297.       if (s == cbuf)
  298.          *s++ = '0';
  299.       *s++ = c;
  300.       while ((c = getc(infile)) >= '0' && c <= '9')
  301.          *s++ = c;
  302.       }
  303.    ep = s;
  304.    if (c == 'e' || c == 'E') {
  305.       *s++ = c;
  306.       if ((c = getc(infile)) == '+' || c == '-') {
  307.          esign = (c == '-');
  308.          *s++ = c;
  309.          c = getc(infile);
  310.          }
  311.       e = 0;
  312.       while (c >= '0' && c <= '9') {
  313.          e = e * 10 + c - '0';
  314.          *s++ = c;
  315.          c = getc(infile);
  316.          }
  317.       if (esign) e = -e;
  318.       e += d - 1;
  319.       if (abs(e) >= LogHuge)
  320.          *ep = '\0';
  321.       }
  322.    *s = '\0';
  323.    n = atof(cbuf);
  324.    nlflag = (c == '\n');
  325.    return n;
  326.    }
  327.  
  328. /*
  329.  * getlab - get a label ("L" followed by a number) from infile,
  330.  *  and return the number.
  331.  */
  332.  
  333. int getlab()
  334.    {
  335.    register int c;
  336.  
  337.    while ((c = getc(infile)) != 'L' && c != EOF && c != '\n') ;
  338.    if (c == 'L')
  339.       return getdec();
  340.    nlflag = (c == '\n');
  341.    return 0;
  342.    }
  343.  
  344. /*
  345.  * getstrlit - get a string literal from infile, as a string
  346.  *  of octal bytes, and return it.
  347.  */
  348. char *getstrlit(l)
  349. register int l;
  350.    {
  351.    register char *p;
  352.  
  353.    if (lsfree + l > lsend)
  354.       quit("out of string space");
  355.    p = lsfree;
  356.    while (!nlflag && l--)
  357.       *p++ = getoct();
  358.    *p++ = 0;
  359.    return putident((int)(p-lsfree));
  360.    }
  361.  
  362. /*
  363.  * newline - skip to next line.
  364.  */
  365. novalue newline()
  366.    {
  367.    register int c;
  368.  
  369.    if (!nlflag) {
  370.       while ((c = getc(infile)) != '\n' && c != EOF) ;
  371.       }
  372.    nlflag = 0;
  373.    }
  374.