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