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