home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / SMALL_C / CC13.C < prev    next >
Text File  |  1987-10-04  |  7KB  |  316 lines

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