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