home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / misc / smc203.ark / CC13.C < prev    next >
Encoding:
Text File  |  1983-07-28  |  7.5 KB  |  321 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.       if(ncmp > 1) nogo=declared; /* disable goto if any */
  18. #endif /* STGOTO */
  19.  
  20.       csp=modstk(csp - declared, NO);
  21.       declared = -1;
  22.       }
  23.     if(match("{"))               compound();
  24.     else if(amatch("if",2))      {doif();lastst=STIF;}
  25.     else if(amatch("while",5))   {dowhile();lastst=STWHILE;}
  26.  
  27. #ifdef STDO
  28.     else if(amatch("do",2))      {dodo();lastst=STDO;}
  29. #endif /* STDO */
  30.  
  31. #ifdef STFOR
  32.     else if(amatch("for",3))     {dofor();lastst=STFOR;}
  33. #endif /* STFOR */
  34.  
  35. #ifdef STSWITCH
  36.     else if(amatch("switch",6))  {doswitch();lastst=STSWITCH;}
  37.     else if(amatch("case",4))    {docase();lastst=STCASE;}
  38.     else if(amatch("default",7)) {dodefault();lastst=STDEF;}
  39. #endif /* STSWITCH */
  40.  
  41. #ifdef STGOTO
  42.     else if(amatch("goto", 4))   {dogoto(); lastst=STGOTO;}
  43.     else if(dolabel())           ;
  44. #endif /* STGOTO */
  45.  
  46.     else if(amatch("return",6))  {doreturn();ns();lastst=STRETURN;}
  47.     else if(amatch("break",5))   {dobreak();ns();lastst=STBREAK;}
  48.     else if(amatch("continue",8)){docont();ns();lastst=STCONT;}
  49.     else if(match(";"))          errflag=0;
  50.     else if(match("#asm"))       {doasm();lastst=STASM;}
  51.     else                         {doexpr();ns();lastst=STEXPR;}
  52.     }
  53.   return lastst;
  54.   }
  55.  
  56. /*
  57. ** semicolon enforcer
  58. **
  59. ** called whenever syntax requires a semicolon
  60. */
  61. ns()  {
  62.   if(match(";")==0) error("no semicolon");
  63.   else errflag=0;
  64.   }
  65.  
  66. compound()  {
  67.   int savcsp;
  68.   char *savloc;
  69.   savcsp=csp;
  70.   savloc=locptr;
  71.   declared=0;    /* may now declare local variables */
  72.   ++ncmp;        /* new level open */
  73.   while (match("}")==0)
  74.     if(eof) {
  75.       error("no final }");
  76.       break;
  77.       }
  78.     else statement();     /* do one */
  79.   --ncmp;                 /* close current level */
  80.   csp=modstk(savcsp, NO); /* delete local variable space */
  81.  
  82. #ifdef STGOTO
  83.   cptr=savloc;            /* retain labels */
  84.   while(cptr < locptr) {
  85.     cptr2=nextsym(cptr);
  86.     if(cptr[IDENT] == LABEL) {
  87.       while(cptr < cptr2) *savloc++ = *cptr++;
  88.       }
  89.     else cptr=cptr2;
  90.     }
  91. #endif /* STGOTO */
  92.  
  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.  
  109. #ifdef STGOTO
  110.   if((lastst != STRETURN)&(lastst != STGOTO)) jump(flab2);
  111. #else /* STGOTO */
  112.   if(lastst != STRETURN) jump(flab2);
  113. #endif /* STGOTO */
  114.  
  115.   postlabel(flab1); /* print false label */
  116.   statement();      /* and do "else" clause */
  117.   postlabel(flab2); /* print true label */
  118.   }
  119.  
  120. doexpr() {
  121.   int const, val;
  122.   char *before, *start;
  123.   while(1) {
  124.     setstage(&before, &start);
  125.     expression(&const, &val);
  126.     clearstage(before, start);
  127.     if(ch != ',') break;
  128.     bump(1);
  129.     }
  130.   }
  131.  
  132. dowhile()  {
  133.   /*
  134.   ** patched per DDJ
  135.   */
  136.   int wq[4];              /* allocate local queue */
  137.   addwhile(wq);           /* add entry to queue for "break" */
  138.   postlabel(wq[WQLOOP]);  /* loop label */
  139.   test(wq[WQEXIT], YES);  /* see if true */
  140.   statement();            /* if so, do a statement */
  141.   jump(wq[WQLOOP]);       /* loop to label */
  142.   postlabel(wq[WQEXIT]);  /* exit label */
  143.   delwhile();             /* delete queue entry */
  144.   }
  145.  
  146. #ifdef STDO
  147. dodo() {
  148.   int wq[4], top;
  149.   addwhile(wq);
  150.   postlabel(top=getlabel());
  151.   statement();
  152.   needtoken("while");
  153.   postlabel(wq[WQLOOP]);
  154.   test(wq[WQEXIT], YES);
  155.   jump(top);
  156.   postlabel(wq[WQEXIT]);
  157.   delwhile();
  158.   ns();
  159.   }
  160. #endif /* STDO */
  161.  
  162. #ifdef STFOR
  163. dofor() {
  164.   int wq[4], lab1, lab2;
  165.   addwhile(wq);
  166.   lab1=getlabel();
  167.   lab2=getlabel();
  168.   needtoken("(");
  169.   if(match(";")==0) {
  170.     doexpr();            /* expr 1 */
  171.     ns();
  172.     }
  173.   postlabel(lab1);
  174.   if(match(";")==0) {
  175.     test(wq[WQEXIT], NO); /* expr 2 */
  176.     ns();
  177.     }
  178.   jump(lab2);
  179.   postlabel(wq[WQLOOP]);
  180.   if(match(")")==0) {
  181.     doexpr();            /* expr 3 */
  182.     needtoken(")");
  183.     }
  184.   jump(lab1);
  185.   postlabel(lab2);
  186.   statement();
  187.   jump(wq[WQLOOP]);
  188.   postlabel(wq[WQEXIT]);
  189.   delwhile();
  190.   }
  191. #endif /* STFOR */
  192.  
  193. #ifdef STSWITCH
  194. doswitch() {
  195.   int wq[4], endlab, swact, swdef, *swnex, *swptr;
  196.   swact=swactive;
  197.   swdef=swdefault;
  198.   swnex=swptr=swnext;
  199.   addwhile(wq);
  200.   *(wqptr + WQLOOP - WQSIZ) = 0;
  201.   needtoken("(");
  202.   doexpr();      /* evaluate switch expression */
  203.   needtoken(")");
  204.   swdefault=0;
  205.   swactive=1;
  206.   jump(endlab=getlabel());
  207.   statement();   /* cases, etc. */
  208.   jump(wq[WQEXIT]);
  209.   postlabel(endlab);
  210.   sw();          /* match cases */
  211.   while(swptr < swnext) {
  212.     defstorage(CINT>>2);
  213.     printlabel(*swptr++);  /* case label */
  214.     outbyte(',');
  215.     outdec(*swptr++);      /* case value */
  216.     nl();
  217.     }
  218.   defstorage(CINT>>2);
  219.   outdec(0);
  220.   nl();
  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 /* STSWITCH */
  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);
  278.   return (getint(cptr+OFFSET, OFFSIZE));
  279.   }
  280. #endif /* STGOTO */
  281.  
  282. doreturn()  {
  283.   if(endst()==0) {
  284.     doexpr();
  285.     modstk(0, YES);
  286.     }
  287.   else modstk(0, NO);
  288.   zzret();
  289.   }
  290.  
  291. dobreak()  {
  292.   int *ptr;
  293.   if ((ptr=readwhile(wqptr))==0) return; /* no loops open */
  294.   modstk((ptr[WQSP]), NO);          /* clean up stk ptr */
  295.   jump(ptr[WQEXIT]);                /* jump to exit label */
  296.   }
  297.  
  298. docont()  {
  299.   int *ptr;
  300.   ptr = wqptr;
  301.   while (1) {
  302.     if ((ptr=readwhile(ptr))==0) return; /* no loops open */
  303.     if (ptr[WQLOOP]) break;
  304.     }
  305.   modstk((ptr[WQSP]), NO);          /* clean up stk ptr */
  306.   jump(ptr[WQLOOP]);                /* jump to loop label */
  307.   }
  308.  
  309. doasm()  {
  310.   ccode=0;                /* mark mode as "asm" */
  311.   while (1) {
  312.     inline();
  313.     if (match("#endasm")) break;
  314.     if(eof)break;
  315.     lout(line, output);
  316.     }
  317.   kill();
  318.   ccode=1;
  319.   }
  320. 
  321. σσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσ