home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 163_01 / cc13.c < prev    next >
Text File  |  1990-12-28  |  8KB  |  325 lines

  1. /*
  2. ** statement parser
  3. **
  4. ** called whenever syntax requires a statement
  5. **  this routine performs that statement
  6. **  and returns a number telling which one
  7. */
  8. statement() {
  9.   if ((ch==0) & (eof)) return;
  10.   else if(amatch("char",4))  {declloc(CCHAR);ns();}
  11.   else if(amatch("int",3))   {declloc(CINT);ns();}
  12.   else {
  13.     if (declared >= 0) {
  14. #ifdef STGOTO
  15.       if(ncmp > 1) nogo=declared; /* disable goto if any */
  16. #endif
  17.       csp=modstk(csp - declared);
  18.       declared = -1;
  19.       }
  20.     if(match("{"))               compound();
  21.     else if(amatch("if",2))      {doif();lastst=STIF;}
  22.     else if(amatch("while",5))   {dowhile();lastst=STWHILE;}
  23. #ifdef STDO
  24.     else if(amatch("do",2))      {dodo();lastst=STDO;}
  25. #endif
  26. #ifdef STFOR
  27.     else if(amatch("for",3))     {dofor();lastst=STFOR;}
  28. #endif
  29. #ifdef STSWITCH
  30.     else if(amatch("switch",6))  {doswitch();lastst=STSWITCH;}
  31.     else if(amatch("case",4))    {docase();lastst=STCASE;}
  32.     else if(amatch("default",7)) {dodefault();lastst=STDEF;}
  33. #endif
  34. #ifdef STGOTO
  35.     else if(amatch("goto",4))    {dogoto();lastst=STGOTO;}
  36.     else if(dolabel())           ;
  37. #endif
  38.     else if(amatch("return",6))  {doreturn();ns();lastst=STRETURN;}
  39.     else if(amatch("break",5))   {dobreak();ns();lastst=STBREAK;}
  40.     else if(amatch("continue",8)){docont();ns();lastst=STCONT;}
  41.     else if(match(";"))          errflag=0;
  42.     else if(match("#asm"))       {doasm();lastst=STASM;}
  43.     else                         {doexpr();ns();lastst=STEXPR;}
  44.     }
  45.   return lastst;
  46.   }
  47.  
  48. /*
  49. ** semicolon enforcer
  50. **
  51. ** called whenever syntax requires a semicolon
  52. */
  53. ns()  {
  54.   if(match(";")==0) error("no semicolon");
  55.   else errflag=0;
  56.   }
  57.  
  58. compound()  {
  59.   int savcsp;
  60.   char *savloc;
  61.   savcsp=csp;
  62.   savloc=locptr;
  63.   declared=0;    /* may now declare local variables */
  64.   ++ncmp;        /* new level open */
  65.   while (match("}")==0)
  66.     if(eof) {
  67.       error("no final }");
  68.       break;
  69.       }
  70.     else statement();     /* do one */
  71.   --ncmp;                 /* close current level */
  72.   csp=modstk(savcsp);     /* delete local variable space */
  73. #ifdef  STGOTO
  74.   cptr=savloc;            /* retain labels */
  75.   while(cptr < locptr) {
  76.     cptr2=nextsym(cptr);
  77.     if(cptr[IDENT] == LABEL) {
  78.       while(cptr < cptr2) *savloc++ = *cptr++;
  79.       }
  80.     else cptr=cptr2;
  81.     }
  82. #endif
  83.   locptr=savloc;          /* delete local symbols */
  84.   declared = -1;          /* may not declare variables */
  85.   }
  86.  
  87. doif()  {
  88.   int flab1,flab2;
  89.   flab1=getlabel(); /* get label for false branch */
  90.   test(flab1, YES); /* get expression, and branch false */
  91.   statement();      /* if true, do a statement */
  92.   if (amatch("else",4)==0) {      /* if...else ? */
  93.     /* simple "if"...print false label */
  94.     postlabel(flab1);
  95.     return;         /* and exit */
  96.     }
  97.   flab2=getlabel();
  98. #ifdef STGOTO
  99.   if((lastst != STRETURN)&(lastst != STGOTO)) jump(flab2);
  100. #else
  101.   if(lastst != STRETURN) jump(flab2);
  102. #endif
  103.   postlabel(flab1); /* print false label */
  104.   statement();      /* and do "else" clause */
  105.   postlabel(flab2); /* print true label */
  106.   }
  107.  
  108. doexpr() {
  109.   int const, val;
  110.   char *before, *start;
  111.   while(1) {
  112.     setstage(&before, &start);
  113.     expression(&const, &val);
  114.     clearstage(before, start);
  115.     if(ch != ',') break;
  116.     bump(1);
  117.     }
  118.   }
  119.  
  120. /*
  121. ** analyze expression and assure that result is left in primary
  122. ** register by optimizer
  123. */
  124. doexpr2() {
  125.   int const, val;
  126.   char *before, *start;
  127.   while(1) {
  128.     setstage(&before, &start);
  129.     expression(&const, &val);
  130.     comment2(); /* start a comment in the staging buffer */
  131.     outstr("@@"); /* special flag for "don't optimize out load of primary" */
  132.     nl();
  133.     clearstage(before, start);
  134.     if(ch != ',') break;
  135.     bump(1);
  136.     }
  137.   }
  138.  
  139. dowhile()  {
  140.   int wq[4];              /* allocate local queue */
  141.   addwhile(wq);           /* add entry to queue for "break" */
  142.   postlabel(wq[WQLOOP]);  /* loop label */
  143.   test(wq[WQEXIT], YES);  /* see if true */
  144.   statement();            /* if so, do a statement */
  145.   jump(wq[WQLOOP]);       /* loop to label */
  146.   postlabel(wq[WQEXIT]);  /* exit label */
  147.   delwhile();             /* delete queue entry */
  148.   }
  149.  
  150. #ifdef STDO
  151. dodo() {
  152.   int wq[4], top;
  153.   addwhile(wq);
  154.   postlabel(top=getlabel());
  155.   statement();
  156.   needtoken("while");
  157.   postlabel(wq[WQLOOP]);
  158.   test(wq[WQEXIT], YES);
  159.   jump(top);
  160.   postlabel(wq[WQEXIT]);
  161.   delwhile();
  162.   ns();
  163.   }
  164. #endif
  165.  
  166. #ifdef STFOR
  167. dofor() {
  168.   int wq[4], lab1, lab2;
  169.   addwhile(wq);
  170.   lab1=getlabel();
  171.   lab2=getlabel();
  172.   needtoken("(");
  173.   if(match(";")==0) {
  174.     doexpr();           /* expr 1 */
  175.     ns();
  176.     }
  177.   postlabel(lab1);
  178.   if(match(";")==0) {
  179.     test(wq[WQEXIT], NO); /* expr 2 */
  180.     ns();
  181.     }
  182.   jump(lab2);
  183.   postlabel(wq[WQLOOP]);
  184.   if(match(")")==0) {
  185.     doexpr();            /* expr 3 */
  186.     needtoken(")");
  187.     }
  188.   jump(lab1);
  189.   postlabel(lab2);
  190.   statement();
  191.   jump(wq[WQLOOP]);
  192.   postlabel(wq[WQEXIT]);
  193.   delwhile();
  194.   }
  195. #endif
  196.  
  197. #ifdef STSWITCH
  198. /*
  199. ** fixed per J. E. Hendrix letter, DDJ #77
  200. */
  201. doswitch() {
  202.   int wq[4], endlab, swact, swdef, *swnex, *swptr;
  203.   swact=swactive;
  204.   swdef=swdefault;
  205.   swnex=swptr=swnext;
  206.   addwhile(wq);
  207.   *(wqptr+WQLOOP-WQSIZ) = 0;
  208.   needtoken("(");
  209.   doexpr2(); /* evaluate switch expression (and keep result) */
  210.   needtoken(")");
  211.   swdefault=0;
  212.   swactive=1;
  213.   jump(endlab=getlabel());
  214.   statement();   /* cases, etc */
  215.   jump(wq[WQEXIT]);
  216.   postlabel(endlab);
  217.   while(swptr < swnext) {
  218.     sw(swptr[0], swptr[1]);
  219.     swptr += 2;
  220.     }
  221.   if(swdefault) jump(swdefault);
  222.   postlabel(wq[WQEXIT]);
  223.   delwhile();
  224.   swnext=swnex;
  225.   swdefault=swdef;
  226.   swactive=swact;
  227.   }
  228.  
  229. docase() {
  230.   if(swactive==0) error("not in switch");
  231.   if(swnext > swend) {
  232.     error("too many cases");
  233.     return;
  234.     }
  235.   postlabel(*swnext++ = getlabel());
  236.   constexpr(swnext++);
  237.   needtoken(":");
  238.   }
  239.  
  240. dodefault() {
  241.   if(swactive) {
  242.     if(swdefault) error("multiple defaults");
  243.     }
  244.   else error("not in switch");
  245.   needtoken(":");
  246.   postlabel(swdefault=getlabel());
  247.   }
  248. #endif
  249.  
  250. #ifdef STGOTO
  251. dogoto() {
  252.   if(nogo > 0) error("not allowed with block-locals");
  253.   else noloc = 1;
  254.   if(symname(ssname, YES)) jump(addlabel());
  255.   else error("bad label");
  256.   ns();
  257.   }
  258.  
  259. dolabel() {
  260.   char *savelptr;
  261.   blanks();
  262.   savelptr=lptr;
  263.   if(symname(ssname, YES)) {
  264.     if(gch()==':') {
  265.       postlabel(addlabel());
  266.       return 1;
  267.       }
  268.     else bump(savelptr-lptr);
  269.     }
  270.   return 0;
  271.   }
  272.  
  273. addlabel()  {
  274.   if(cptr=findloc(ssname)) {
  275.     if(cptr[IDENT]!=LABEL) error("not a label");
  276.     }
  277.   else cptr=addsym(ssname, LABEL, LABEL, getlabel(), &locptr, LABEL, 0, 0);
  278.   return (getint(cptr+OFFSET, OFFSIZE));
  279.   }
  280. #endif
  281.  
  282. doreturn()  {
  283.   if(endst()==0) doexpr2(); /* evaluate expression (and keep result) */
  284.   modstk(0);
  285.   ret();
  286.   }
  287.  
  288. /*
  289. ** fixed per J. E. Hendrix letter, DDJ #77
  290. */
  291. dobreak()  {
  292.   int *ptr;
  293.   if ((ptr=readwhile(wqptr))==0) return; /* no loops open */
  294.   modstk((ptr[WQSP]));              /* clean up stk ptr */
  295.   jump(ptr[WQEXIT]);                /* jump to exit label */
  296.   }
  297.  
  298. /*
  299. ** fixed per J. E. Hendrix letter, DDJ #77
  300. */
  301. docont()  {
  302.   int *ptr;
  303.   ptr = wqptr;
  304.   while(1) {
  305.     if ((ptr=readwhile(ptr))==0) return; /* no loops open */
  306.     if (ptr[WQLOOP]) break;
  307.     }
  308.   modstk((ptr[WQSP]));              /* clean up stk ptr */
  309.   jump(ptr[WQLOOP]);                /* jump to loop label */
  310.   }
  311.  
  312. doasm()  {
  313.   ccode=0;                /* mark mode as "asm" */
  314.   while (1) {
  315.     inline();
  316.     if (match("#endasm")) break;
  317.     if(eof)break;
  318.     lout(line, output);
  319.     }
  320.   kill();
  321.   ccode=1;
  322.   }
  323.  
  324.  
  325.