home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / cpm / utils / s / smc21src.lzh / CC13.C < prev    next >
Encoding:
Text File  |  1992-12-08  |  7.6 KB  |  341 lines

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