home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 204_01 / getsym.c < prev    next >
Text File  |  1979-12-31  |  18KB  |  555 lines

  1. #include        <stdio.h>
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7. /*
  8.  *    68000 C compiler
  9.  *
  10.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  11.  *  all commercial rights reserved.
  12.  *
  13.  *    This compiler is intended as an instructive tool for personal use. Any
  14.  *    use for profit without the written consent of the author is prohibited.
  15.  *
  16.  *    This compiler may be distributed freely for non-commercial use as long
  17.  *    as this notice stays intact. Please forward any enhancements or questions
  18.  *    to:
  19.  *
  20.  *        Matthew Brandt
  21.  *        Box 920337
  22.  *        Norcross, Ga 30092
  23.  */
  24.  
  25. static int      errno[80];
  26. static int      numerrs;
  27. static char     inline[132];
  28. int             total_errors = 0;
  29. char            *lptr;          /* shared with preproc */
  30. FILE            *inclfile[10];  /* shared with preproc */
  31. int             inclline[10];   /* shared with preproc */
  32. int             incldepth;      /* shared with preproc */
  33. char            *linstack[20];  /* stack for substitutions */
  34. char            chstack[20];    /* place to save lastch */
  35. int             lstackptr = 0;  /* substitution stack pointer */
  36.  
  37. int     isalnum(c)
  38. char    c;
  39. {       return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
  40.                 (c >= '0' && c <= '9');
  41. }
  42.  
  43. int     isidch(c)
  44. char    c;
  45. {       return isalnum(c) || c == '_' || c == '$';
  46. }
  47.  
  48. int     isspace(c)
  49. char    c;
  50. {       return c == ' ' || c == '\t' || c == '\n';
  51. }
  52.  
  53. int     isdigit(c)
  54. char    c;
  55. {       return (c >= '0' && c <= '9');
  56. }
  57.  
  58. initsym()
  59. {       lptr = inline;
  60.         inline[0] = 0;
  61.         numerrs = 0;
  62.         total_errors = 0;
  63.         lineno = 0;
  64. }
  65.  
  66. int     getline(listflag)
  67. int     listflag;
  68. {       int     rv;
  69.         if( lineno > 0 && listflag) {
  70.                 fprintf(list,"%6d\t%s",lineno,inline);
  71.                 while(numerrs--)
  72.                         fprintf(list," *** error %d\n",errno[numerrs]);
  73.                 numerrs = 0;
  74.                 }
  75.         ++lineno;
  76.         rv = (fgets(inline,131,input) == NULL);
  77.         if( rv && incldepth > 0 ) {
  78.                 fclose(input);
  79.                 input = inclfile[--incldepth];
  80.                 lineno = inclline[incldepth];
  81.                 return getline(0);
  82.                 }
  83.         if( rv )
  84.                 return 1;
  85.         lptr = inline;
  86.         if(inline[0] == '#')
  87.                 return preprocess();
  88.         return 0;
  89. }
  90.  
  91. /*
  92.  *      getch - basic get character routine.
  93.  */
  94. int     getch()
  95. {       while( (lastch = *lptr++) == '\0') {
  96.                 if( lstackptr > 0 ) {
  97.                         lptr = linstack[--lstackptr];
  98.                         lastch = chstack[lstackptr];
  99.                         return lastch;
  100.                         }
  101.                 if(getline(incldepth == 0))
  102.                         return lastch = -1;
  103.                 }
  104.         return lastch;
  105. }
  106.  
  107. /*
  108.  *      error - print error information
  109.  */
  110. error(n)
  111. int     n;
  112. {       errno[numerrs++] = n;
  113.         ++total_errors;
  114. }
  115.  
  116. /*
  117.  *      getid - get an identifier.
  118.  *
  119.  *      identifiers are any isidch conglomerate
  120.  *      that doesn't start with a numeric character.
  121.  *      this set INCLUDES keywords.
  122.  */
  123. int     getid()
  124. {       register int    i;
  125.         i = 0;
  126.         while(isidch(lastch)) {
  127.                 if(i < 19)
  128.                         lastid[i++] = lastch;
  129.                 getch();
  130.                 }
  131.         lastid[i] = '\0';
  132.         lastst = id;
  133. }
  134.  
  135. /*
  136.  *      getsch - get a character in a quoted string.
  137.  *
  138.  *      this routine handles all of the escape mechanisms
  139.  *      for characters in strings and character constants.
  140.  */
  141. int     getsch()        /* return an in-quote character */
  142. {       register int    i, j;
  143.         if(lastch == '\n')
  144.                 return -1;
  145.         if(lastch != '\\') {
  146.                 i = lastch;
  147.                 getch();
  148.                 return i;
  149.                 }
  150.         getch();        /* get an escaped character */
  151.         if(isdigit(lastch)) {
  152.                 i = 0;
  153.                 for(i = 0;j < 3;++j) {
  154.                         if(lastch <= '7' && lastch >= '0')
  155.                                 i = (i << 3) + lastch - '0';
  156.                         else
  157.                                 break;
  158.                         getch();
  159.                         }
  160.                 return i;
  161.                 }
  162.         i = lastch;
  163.         getch();
  164.         switch(i) {
  165.                 case '\n':
  166.                         getch();
  167.                         return getsch();
  168.                 case 'b':
  169.                         return '\b';
  170.                 case 'f':
  171.                         return '\f';
  172.                 case 'n':
  173.                         return '\n';
  174.                 case 'r':
  175.                         return '\r';
  176.                 case 't':
  177.                         return '\t';
  178.                 default:
  179.                         return i;
  180.                 }
  181. }
  182.  
  183. int     radix36(c)
  184. char    c;
  185. {       if(isdigit(c))
  186.                 return c - '0';
  187.         if(c >= 'a' && c <= 'z')
  188.                 return c - 'a' + 10;
  189.         if(c >= 'A' && c <= 'Z')
  190.                 return c - 'A' + 10;
  191.         return -1;
  192. }
  193.  
  194. /*
  195.  *      getbase - get an integer in any base.
  196.  */
  197. getbase(b)
  198. {       register int    i, j;
  199.         i = 0;
  200.         while(isalnum(lastch)) {
  201.                 if((j = radix36(lastch)) < b) {
  202.                         i = i * b + j;
  203.                         getch();
  204.                         }
  205.                 else break;
  206.                 }
  207.         ival = i;
  208.         lastst = iconst;
  209. }
  210.  
  211. /*
  212.  *      getfrac - get fraction part of a floating number.
  213.  */
  214. getfrac()
  215. {       double  frmul;
  216.         frmul = 0.1;
  217.         while(isdigit(lastch)) {
  218.                 rval += frmul * (lastch - '0');
  219.                 getch();
  220.                 frmul *= 0.1;
  221.                 }
  222. }
  223.  
  224. /*
  225.  *      getexp - get exponent part of floating number.
  226.  *
  227.  *      this algorithm is primative but usefull.  Floating
  228.  *      exponents are limited to +/-255 but most hardware
  229.  *      won't support more anyway.
  230.  */
  231. getexp()
  232. {       double  expo, exmul;
  233.         expo = 1.0;
  234.         if(lastst != rconst)
  235.                 rval = ival;
  236.         if(lastch = '-') {
  237.                 exmul = 0.1;
  238.                 getch();
  239.                 }
  240.         else
  241.                 exmul = 10.0;
  242.         getbase(10);
  243.         if(ival > 255)
  244.                 error(ERR_FPCON);
  245.         else
  246.                 while(ival--)
  247.                         expo *= exmul;
  248.         rval *= expo;
  249. }
  250.  
  251. /*
  252.  *      getnum - get a number from input.
  253.  *
  254.  *      getnum handles all of the numeric input. it accepts
  255.  *      decimal, octal, hexidecimal, and floating point numbers.
  256.  */
  257. getnum()
  258. {       register int    i, j, k;
  259.         i = 0;
  260.         if(lastch == '0') {
  261.                 getch();
  262.                 if(lastch == 'x' || lastch == 'X') {
  263.                         getch();
  264.                         getbase(16);
  265.                         }
  266.                 else getbase(8);
  267.                 }
  268.         else    {
  269.                 getbase(10);
  270.                 if(lastch == '.') {
  271.                         getch();
  272.                         rval = ival;    /* float the integer part */
  273.                         getfrac();      /* add the fractional part */
  274.                         lastst = rconst;
  275.                         }
  276.                 if(lastch == 'e' || lastch == 'E') {
  277.                         getch();
  278.                         getexp();       /* get the exponent */
  279.                         }
  280.                 }
  281. }
  282.  
  283. /*
  284.  *      getsym - get next symbol from input stream.
  285.  *
  286.  *      getsym is the basic lexical analyzer.  It builds
  287.  *      basic tokens out of the characters on the input
  288.  *      stream and sets the following global variables:
  289.  *
  290.  *      lastch:         A look behind buffer.
  291.  *      lastst:         type of last symbol read.
  292.  *      laststr:        last string constant read.
  293.  *      lastid:         last identifier read.
  294.  *      ival:           last integer constant read.
  295.  *      rval:           last real constant read.
  296.  *
  297.  *      getsym should be called for all your input needs...
  298.  */
  299. int     getsym()
  300. {       register int    i, j, k;
  301.         SYM             *sp;
  302. restart:        /* we come back here after comments */
  303.         while(isspace(lastch))
  304.                 getch();
  305.         if( lastch == -1)
  306.                 lastst = eof;
  307.         else if(isdigit(lastch))
  308.                 getnum();
  309.         else if(isidch(lastch)) {
  310.                 getid();
  311.                 if( (sp = search(lastid,defsyms.head)) != 0 ) {
  312.                         linstack[lstackptr] = lptr;
  313.                         chstack[lstackptr++] = lastch;
  314.                         lptr = sp->value.s;
  315.                         getch();
  316.                         goto restart;
  317.                         }
  318.                 }
  319.         else switch(lastch) {
  320.                 case '+':
  321.                         getch();
  322.                         if(lastch == '+') {
  323.                                 getch();
  324.                                 lastst = autoinc;
  325.                                 }
  326.                         else if(lastch == '=') {
  327.                                 getch();
  328.                                 lastst = asplus;
  329.                                 }
  330.                         else lastst = plus;
  331.                         break;
  332.                 case '-':
  333.                         getch();
  334.                         if(lastch == '-') {
  335.                                 getch();
  336.                                 lastst = autodec;
  337.                                 }
  338.                         else if(lastch == '=') {
  339.                                 getch();
  340.                                 lastst = asminus;
  341.                                 }
  342.                         else if(lastch == '>') {
  343.                                 getch();
  344.                                 lastst = pointsto;
  345.                                 }
  346.                         else lastst = minus;
  347.                         break;
  348.                 case '*':
  349.                         getch();
  350.                         if(lastch == '=') {
  351.                                 getch();
  352.                                 lastst = astimes;
  353.                                 }
  354.                         else lastst = star;
  355.                         break;
  356.                 case '/':
  357.                         getch();
  358.                         if(lastch == '=') {
  359.                                 getch();
  360.                                 lastst = asdivide;
  361.                                 }
  362.                         else if(lastch == '*') {
  363.                                 getch();
  364.                                 for(;;) {
  365.                                         if(lastch == '*') {
  366.                                                 getch();
  367.                                                 if(lastch == '/') {
  368.                                                         getch();
  369.                                                         goto restart;
  370.                                                         }
  371.                                                 }
  372.                                         else
  373.                                                 getch();
  374.                                         }
  375.                                 }
  376.                         else lastst = divide;
  377.                         break;
  378.                 case '^':
  379.                         getch();
  380.                         lastst = uparrow;
  381.                         break;
  382.                 case ';':
  383.                         getch();
  384.                         lastst = semicolon;
  385.                         break;
  386.                 case ':':
  387.                         getch();
  388.                         lastst = colon;
  389.                         break;
  390.                 case '=':
  391.                         getch();
  392.                         if(lastch == '=') {
  393.                                 getch();
  394.                                 lastst = eq;
  395.                                 }
  396.                         else lastst = assign;
  397.                         break;
  398.                 case '>':
  399.                         getch();
  400.                         if(lastch == '=') {
  401.                                 getch();
  402.                                 lastst = geq;
  403.                                 }
  404.                         else if(lastch == '>') {
  405.                                 getch();
  406.                                 if(lastch == '=') {
  407.                                         getch();
  408.                                         lastst = asrshift;
  409.                                         }
  410.                                 else lastst = rshift;
  411.                                 }
  412.                         else lastst = gt;
  413.                         break;
  414.                 case '<':
  415.                         getch();
  416.                         if(lastch == '=') {
  417.                                 getch();
  418.                                 lastst = leq;
  419.                                 }
  420.                         else if(lastch == '<') {
  421.                                 getch();
  422.                                 if(lastch == '=') {
  423.                                         getch();
  424.                                         lastst = aslshift;
  425.                                         }
  426.                                 else lastst = lshift;
  427.                                 }
  428.                         else lastst = lt;
  429.                         break;
  430.                 case '\'':
  431.                         getch();
  432.                         ival = getsch();        /* get a string char */
  433.                         if(lastch != '\'')
  434.                                 error(ERR_SYNTAX);
  435.                         else
  436.                                 getch();
  437.                         lastst = iconst;
  438.                         break;
  439.                 case '\"':
  440.                         getch();
  441.                         for(i = 0;i < MAX_STRLEN;++i) {
  442.                                 if(lastch == '\"')
  443.                                         break;
  444.                                 if((j = getsch()) == -1)
  445.                                         break;
  446.                                 else
  447.                                         laststr[i] = j;
  448.                                 }
  449.                         laststr[i] = 0;
  450.                         lastst = sconst;
  451.                         if(lastch != '\"')
  452.                                 error(ERR_SYNTAX);
  453.                         else
  454.                                 getch();
  455.                         break;
  456.                 case '!':
  457.                         getch();
  458.                         if(lastch == '=') {
  459.                                 getch();
  460.                                 lastst = neq;
  461.                                 }
  462.                         else lastst = not;
  463.                         break;
  464.                 case '%':
  465.                         getch();
  466.                         if(lastch == '=') {
  467.                                 getch();
  468.                                 lastst = asmodop;
  469.                                 }
  470.                         else lastst = modop;
  471.                         break;
  472.                 case '~':
  473.                         getch();
  474.                         lastst = compl;
  475.                         break;
  476.                 case '.':
  477.                         getch();
  478.                         lastst = dot;
  479.                         break;
  480.                 case ',':
  481.                         getch();
  482.                         lastst = comma;
  483.                         break;
  484.                 case '&':
  485.                         getch();
  486.                         if( lastch == '&') {
  487.                                 lastst = land;
  488.                                 getch();
  489.                                 }
  490.                         else if( lastch == '=') {
  491.                                 lastst = asand;
  492.                                 getch();
  493.                                 }
  494.                         else
  495.                                 lastst = and;
  496.                         break;
  497.                 case '|':
  498.                         getch();
  499.                         if(lastch == '|') {
  500.                                 lastst = lor;
  501.                                 getch();
  502.                                 }
  503.                         else if( lastch == '=') {
  504.                                 lastst = asor;
  505.                                 getch();
  506.                                 }
  507.                         else
  508.                                 lastst = or;
  509.                         break;
  510.                 case '(':
  511.                         getch();
  512.                         lastst = openpa;
  513.                         break;
  514.                 case ')':
  515.                         getch();
  516.                         lastst = closepa;
  517.                         break;
  518.                 case '[':
  519.                         getch();
  520.                         lastst = openbr;
  521.                         break;
  522.                 case ']':
  523.                         getch();
  524.                         lastst = closebr;
  525.                         break;
  526.                 case '{':
  527.                         getch();
  528.                         lastst = begin;
  529.                         break;
  530.                 case '}':
  531.                         getch();
  532.                         lastst = end;
  533.                         break;
  534.                 case '?':
  535.                         getch();
  536.                         lastst = hook;
  537.                         break;
  538.                 default:
  539.                         getch();
  540.                         error(ERR_ILLCHAR);
  541.                         goto restart;   /* get a real token */
  542.                 }
  543.         if(lastst == id)
  544.                 searchkw();
  545. }
  546.  
  547. needpunc(p)
  548. enum e_sym      p;
  549. {       if( lastst == p)
  550.                 getsym();
  551.         else
  552.                 error(ERR_PUNCT);
  553. }
  554.  
  555.