home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 221_01 / cc21.c < prev    next >
Text File  |  1979-12-31  |  13KB  |  504 lines

  1. /* >>>>>> start of cc2 <<<<<<<< */
  2. /*     */
  3. /* Get required array size  */
  4. /*     */
  5. /* invoked when declared variable is followed by "[" */
  6. /* this routine makes subscript the absolute */
  7. /* size of the array. */
  8. needsub()
  9.  {
  10.  int num[1];
  11.  if(match("]"))return (0); /* null size */
  12.  if (number(num)==0) /* go after a number */
  13.   {errrpt("must be constant"); /* it isn't */
  14.   num[0]=1;  /* so force one */
  15.   }
  16.  if (num[0]<0)
  17.   {errrpt("negative size illegal");
  18.   num[0]=(-num[0]);
  19.   }
  20.  needbrack("]");  /* force single dimension */
  21.  return (num[0]);  /* and return size */
  22.  }
  23. /*     */
  24. /* Begin a function  */
  25. /*     */
  26. /* Called from "parse" this routine tries to make a function */
  27. /* out of what follows. */
  28. newfunc(class) int class; {
  29. /* next lines added by dieter flunkert 23 jan 1986 */
  30.  int argtop;  /* top of argument stack */
  31.  char n[namesize],*ptr;
  32. #ifdef STGOTO
  33.   nogo=noloc=0;
  34. #endif
  35. #ifdef PHASE2
  36.   if(monitor) {cout('\n',stderr);sout(line,stderr);}
  37. #endif
  38.  if (symname(n)==0)
  39.   {errrpt("illegal function or declaration");
  40.   kill(); /* invalidate line */
  41.   return;
  42.   }
  43.  if(ptr=findglb(n)) /* already in symbol table ? */
  44.   {if(ptr[ident]!=function)multidef(n);
  45.    /* already variable by that name */
  46.   else if(ptr[offset]==function)multidef(n);
  47.    /* already function by that name */
  48.   else ptr[offset]=function;
  49.    /* otherwise we have what was earlier*/
  50.    /*  assumed to be a function */
  51.   }
  52.  /* if not in table, define as a function now */
  53.  else addglb(n,function,cint,function);
  54.  /* we had better see open paren for args... */
  55.  if(match("(")==0)errrpt("missing open paren");
  56. /* next lines added by dieter flunkert 23 jan 1986 */
  57.  if(first_func) {
  58.    defname(n);  /* define name of asm module */
  59.    first_func = 0;
  60.  }
  61.  entry(n, class);
  62.  if(DEFDEBUG) debug(n);
  63.      /* ** Clear local stack pointer rev. 1P */
  64.  locptr = startloc; /* ** 2 lines inserted  rev. 1P */
  65.  argstk=0;  /* init arg count */
  66.  while(match(")")==0) /* then count args */
  67.   /* any legal name bumps arg count */
  68.   {if(symname(n)) /* **+ Modification  rev. 1P */
  69.    { if (findloc(n)) multidef(n);
  70.    else { addloc(n, 0, 0, argstk);
  71.     argstk = argstk + 2;
  72.    }
  73.   }  /* **- End of modification rev. 1P */
  74.   else{errrpt("illegal argument name");junk();}
  75.   blanks();
  76.   /* if not closing paren, should be comma */
  77.   if(streq(line+lptr,")")==0)
  78.    {if(match(",")==0)
  79.    errrpt("expected comma");
  80.    }
  81.   if(endst())break;
  82.   }
  83. /* ** Next line deleted      rev. 1P */
  84. /* ** locptr=startloc; ** */ /* "clear" local symbol table*/
  85.  stkp=0;   /* preset stack ptr */
  86. /* next line added by dieter flunkert 23 jan 1986 */
  87.  argtop=argstk; /* save top of argument stack */
  88.  while(argstk)
  89.   /* now let user declare what types of things */
  90.   /* those arguments were */
  91.   {if(amatch("char",4)){getarg(argtop,cchar);ns();}
  92.   else if(amatch("int",3)){getarg(argtop,cint);ns();}
  93.   else{errrpt("wrong number args");break;}
  94.   }
  95.  if(statement()!=streturn) /* do a statement, but if */
  96.     /* it's a return, skip */
  97.     /* cleaning up the stack */
  98.   {modstk(0);
  99.   ret();
  100.   }
  101.  stkp=0;   /* reset stack ptr again */
  102.  locptr=startloc; /* deallocate all locals */
  103.  if(litptr) {     /* dump literal pool */
  104.    printlabel(litlab);
  105.    dumplits(1);
  106.    litlab=getlabel();
  107.    }
  108.  }
  109.  
  110. /*     */
  111. /* Declare argument types  */
  112. /*     */
  113. /* called from "newfunc" this routine adds an entry in the */
  114. /* local symbol table for each named argument */
  115. /* ** Function completely rewritten rev. 1P */
  116. /* modified by dieter flunkert 23 jan 1986 */
  117. /* argtop is not allowed to change value. This was the case
  118.  if a function had a declaration like:
  119.    int i; char c; */
  120. getarg(argtop,t)  /* t = cchar or cint */
  121.  int argtop,t;
  122.  {
  123.  int j, legalname, address;
  124.  char n[namesize], c, *argptr;
  125. /* next line deleted by dieter flunkert 23 jan 1986  */
  126. /* argtop = argstk; */
  127.  while(1)
  128.   {if(argstk==0)return; /* no more args */
  129.   if(match("*"))j=pointer;
  130.    else j=variable;
  131.   if((legalname = symname(n)) == 0) illname();
  132.   if(match("[")) /* pointer ? */
  133.   /* it is a pointer, so skip all */
  134.   /* stuff between "[]" */
  135.    {while(inbyte()!=']')
  136.     if(endst())break;
  137.    j=pointer;
  138.    /* add entry as pointer */
  139.    }
  140.   if (legalname) {
  141.    if (argptr = findloc(n)) {
  142.    /*  Add in details of the type and address of */
  143.    /* the name  */
  144.    argptr[ident] = j;
  145.    argptr[type] = t;
  146.    address = argtop - (argptr[offset] + (argptr[offset+1]<<8));
  147.    putint(address, argptr+offset, offsize);
  148.    }
  149.   else errrpt("Expected argument name");
  150.   }
  151.   argstk=argstk-2; /* cnt down */
  152.   if (endst()) return;
  153.   if (match(",") == 0) errrpt("expected comma");
  154.   }
  155.  }
  156. /* ** End of modifications rev. 1P */
  157.  
  158. /*
  159. ** statement parser
  160. **
  161. ** called whenever syntax requires a statement
  162. **  this routine performs that statement
  163. **  and returns a number telling which one
  164. */
  165. statement() {
  166. int class;
  167.  
  168.   if ((ch==0) && (eof)) return;
  169.   if(amatch("static",6)) {
  170.    class=statik;
  171.    if(++stdecl == 1)  /* there are static variables */
  172.        jump(stlab=getlabel()); /* skip static declarations */
  173.   }
  174.   else class=stkloc;
  175.   if(amatch("char",4))  {declloc(cchar,class);ns();}
  176.   else if(amatch("int",3))   {declloc(cint,class);ns();}
  177.   else {
  178.     if(stdecl > 0) {
  179.       postlabel(stlab);
  180.       stdecl = 0;
  181.     }
  182.     if(declared >= 0) {
  183. #ifdef STGOTO
  184.       if(ncmp > 1) nogo=declared; /* disable goto if any */
  185. #endif
  186.       stkp=modstk(stkp - declared);
  187.       declared = -1;
  188.       }
  189.     if(match("{"))               compound();
  190.     else if(amatch("if",2))      {doif();lastst=stif;}
  191.     else if(amatch("while",5))   {dowhile();lastst=stwhile;}
  192. #ifdef STDO
  193.     else if(amatch("do",2))      {dodo();lastst=STDO;}
  194. #endif
  195. #ifdef STFOR
  196.     else if(amatch("for",3))     {dofor();lastst=STFOR;}
  197. #endif
  198. #ifdef STSWITCH
  199.     else if(amatch("switch",6))  {doswitch();lastst=STSWITCH;}
  200.     else if(amatch("case",4))    {docase();lastst=STCASE;}
  201.     else if(amatch("default",7)) {dodefault();lastst=STDEF;}
  202. #endif
  203. #ifdef STGOTO
  204.     else if(amatch("goto", 4))   {dogoto(); lastst=STGOTO;}
  205.     else if(dolabel())           lastst=STLABEL;
  206. #endif
  207.     else if(amatch("return",6))  {doreturn();ns();lastst=streturn;}
  208.     else if(amatch("break",5))   {dobreak();ns();lastst=stbreak;}
  209.     else if(amatch("continue",8)){docont();ns();lastst=stcont;}
  210.     else if(match(";"))          ;
  211.     else if(match("#asm"))       {doasm();lastst=stasm;}
  212.     else                         {doexpression();ns();lastst=stexp;}
  213.     }
  214.   return lastst;
  215.   }
  216.  
  217. #ifdef STDO
  218. dodo() {
  219.   int wq[4], top;
  220.   addwhile(wq);
  221.   postlabel(top=getlabel());
  222.   statement();
  223.   needbrack("while");
  224.   postlabel(wq[wqloop]);
  225.   test(wq[wqlab],YES);
  226.   jump(top);
  227.   postlabel(wq[wqlab]);
  228.   delwhile();
  229.   ns();
  230.   }
  231. #endif
  232.  
  233. #ifdef STFOR
  234. dofor() {
  235.   int wq[4], lab1, lab2;
  236.   addwhile(wq);
  237.   lab1=getlabel();
  238.   lab2=getlabel();
  239.   needbrack("(");
  240.   if(match(";")==0) {
  241.     doexpression();            /* expr 1 */
  242.     ns();
  243.     }
  244.   postlabel(lab1);
  245.   if(match(";")==0) {
  246.     test(wq[wqlab],NO); /* expr 2 */
  247.     ns();
  248.     }
  249.   jump(lab2);
  250.   postlabel(wq[wqloop]);
  251.   if(match(")")==0) {
  252.     doexpression();            /* expr 3 */
  253.     needbrack(")");
  254.     }
  255.   jump(lab1);
  256.   postlabel(lab2);
  257.   statement();
  258.   jump(wq[wqloop]);
  259.   postlabel(wq[wqlab]);
  260.   delwhile();
  261.   }
  262. #endif
  263.  
  264. #ifdef STSWITCH
  265. doswitch() {
  266.   int wq[4], endlab, swact, swdef, *swnex, *swptr;
  267.   swact=swactive;
  268.   swdef=swdefault;
  269.   swnex=swptr=swnext;
  270.   addwhile(wq);
  271.   needbrack("(");
  272.   doexpression();      /* evaluate switch expression */
  273.   needbrack(")");
  274.   swdefault=0;
  275.   swactive=1;
  276.   jump(endlab=getlabel());
  277.   statement();   /* cases, etc. */
  278.   jump(wq[wqlab]);
  279.   postlabel(endlab);
  280.   sw();          /* match cases */
  281.   while(swptr < swnext) {
  282.     defstorage(cint>>2);
  283.     printlabel(*swptr++);  /* case label */
  284.     outbyte(',');
  285.     outdec(*swptr++);      /* case value */
  286.     nl();
  287.     }
  288.   defstorage(cint>>2);
  289.   outdec(0);
  290.   nl();
  291.   if(swdefault) jump(swdefault);
  292.   postlabel(wq[wqlab]);
  293.   delwhile();
  294.   swnext=swnex;
  295.   swdefault=swdef;
  296.   swactive=swact;
  297.   }
  298.  
  299. docase() {
  300.   if(swactive==0) errrpt("not in switch");
  301.   if(swnext > swend) {
  302.     errrpt("too many cases");
  303.     return;
  304.     }
  305.   postlabel(*swnext++ = getlabel());
  306.   constexpr(swnext++);
  307.   needbrack(":");
  308.   }
  309.  
  310. dodefault() {
  311.   if(swactive) {
  312.     if(swdefault) errrpt("multiple defaults");
  313.     }
  314.   else errrpt("not in switch");
  315.   needbrack(":");
  316.   postlabel(swdefault=getlabel());
  317.   }
  318. #endif
  319.  
  320. #ifdef STGOTO
  321. dogoto() {
  322.   char ssname[namesize];
  323.   if(nogo > 0) errrpt("not allowed with block-locals");
  324.   else noloc = 1;
  325.   if(symname(ssname)) jump(addlabel(ssname));
  326.   else errrpt("bad label");
  327.   ns();
  328.   }
  329.  
  330. dolabel() {
  331.   int i;
  332.   char ssname[namesize];
  333.   char *savelptr;
  334.   blanks();
  335.   savelptr=lptr;
  336.   if(symname(ssname)) {
  337.     if(gch()==':') {
  338.       postlabel(addlabel(ssname));
  339.       return 1;
  340.       }
  341.     else {
  342.      i=savelptr-lptr+1;
  343.      while(--i) inchar();
  344.      }
  345.     }
  346.   return 0;
  347.   }
  348.  
  349. addlabel(ssname) char *ssname; {
  350.   if(cptr=findloc(ssname)) {
  351.     if(cptr[ident]!=LABEL) errrpt("not a label");
  352.     }
  353.   else cptr=addloc(ssname, LABEL, LABEL, getlabel(), LABEL);
  354.   return (getint(cptr+offset, offsize));
  355.   }
  356. #endif
  357.  
  358.  
  359. /*     */
  360. /* Semicolon enforcer  */
  361. /*     */
  362. /* called whenever syntax requires a semicolon */
  363. ns() {if(match(";")==0)errrpt("missing semicolon");}
  364. /*     */
  365. /* Compound statement  */
  366. /*     */
  367. /* allow any number of statements to fall between "{}" */
  368. compound()
  369.  {
  370.  int savcsp;
  371.  char *savloc, *savstat;
  372.  
  373.  savcsp=stkp;
  374.  startcomp=savloc=locptr;
  375.  savstat=statptr;
  376.  declared = stdecl = statlab = 0;
  377.  ++ncmp;  /* new level open */
  378.  while (match("}")==0)
  379.   if(eof) {
  380.     errrpt("no final }");
  381.     break;
  382.   }
  383.   else statement(); /* do one */
  384.  --ncmp;  /* close current level */
  385.  if(lastst != streturn)
  386.    modstk(savcsp);  /* delete local variable space */
  387.  stkp=savcsp;
  388. #ifdef STGOTO
  389.   cptr=savloc;            /* retain labels */
  390.   while(cptr < locptr) {
  391.     cptr2=nextsym(cptr);
  392.     if(cptr[ident] == LABEL) {
  393.       while(cptr < cptr2) *savloc++ = *cptr++;
  394.       }
  395.     else cptr=cptr2;
  396.     }
  397. #endif
  398.  declared = -1;
  399.   locptr=savloc;
  400.   statptr=savstat;
  401.  }
  402. /*     */
  403. /*  "if" statement  */
  404. /*     */
  405. doif()
  406.  {
  407.  int flev,fsp,flab1,flab2;
  408.  flev=locptr; /* record current local level */
  409.  fsp=stkp;  /* record current stk ptr */
  410.  flab1=getlabel(); /* get label for false branch */
  411.  test(flab1,YES); /* get expression, and branch false */
  412.  statement(); /* if true, do a statement */
  413.  stkp=modstk(fsp); /* then clean up the stack */
  414.  locptr=flev; /* and deallocate any locals */
  415.  if (amatch("else",4)==0) /* if...else ? */
  416.   /* simple "if"...print false label */
  417.   {postlabel(flab1);
  418.   return;  /* and exit */
  419.   }
  420.  /* an "if...else" statement. */
  421.  flab2=getlabel();
  422. #ifdef STGOTO
  423.  if((lastst != streturn)&&(lastst != STGOTO) jump(flab2);
  424. #else
  425.  if(lastst != streturn) jump(flab2); /* jump around false code */
  426. #endif
  427.  postlabel(flab1); /* print false label */
  428.  statement();  /* and do "else" clause */
  429.  stkp=modstk(fsp);  /* then clean up stk ptr */
  430.  locptr=flev;  /* and deallocate locals */
  431.  postlabel(flab2); /* print true label */
  432.  }
  433. /*     */
  434. /* "while" statement  */
  435. /*     */
  436. dowhile()
  437.  {
  438.  int lwq[4];  /* allocate local queue */
  439.  addwhile(lwq);  /* add entry to queue */
  440.     /* (for "break" statement) */
  441.  postlabel(lwq[wqloop]); /* loop label */
  442.  test(lwq[wqlab],YES); /* see if true */
  443.  statement();  /* if so, do a statement */
  444.  jump(lwq[wqloop]); /* loop to label */
  445.  postlabel(lwq[wqlab]); /* exit label */
  446.  delwhile();  /* delete queue entry */
  447.  }
  448. /*     */
  449. /* "return" statement  */
  450. /*     */
  451. doreturn()
  452.  {
  453.  /* if not end of statement, get an expression */
  454.  if(endst()==0)doexpression();
  455.  modstk(0); /* clean up stk */
  456.  ret();  /* and exit function */
  457.  }
  458. /*     */
  459. /* "break" statement  */
  460. /*     */
  461. dobreak()
  462.  {
  463.  int *ptr;
  464.  /* see if any "whiles" are open */
  465.  if ((ptr=readwhile())==0) return; /* no */
  466.  modstk((ptr[wqsp])); /* else clean up stk ptr */
  467.  jump(ptr[wqlab]); /* jump to exit label */
  468.  }
  469. /*     */
  470. /* "continue" statement  */
  471. /*     */
  472. docont()
  473.  {
  474.  int *ptr;
  475.  /* see if any "whiles" are open */
  476.  if ((ptr=readwhile())==0) return; /* no */
  477.  modstk((ptr[wqsp])); /* else clean up stk ptr */
  478.  jump(ptr[wqloop]); /* jump to loop label */
  479.  }
  480. /*     */
  481. /* "asm" pseudo-statement  */
  482. /*     */
  483. /* enters mode where assembly language statement are */
  484. /* passed intact through parser */
  485. doasm()
  486.  {
  487.  cmode=0;  /* mark mode as "asm" */
  488.  while (1)
  489.   {inline(); /* get and print lines */
  490.   if(eof) break;
  491.   if (match("#endasm")){
  492.    if (ctext){
  493.     comment();
  494.     outstr(line);
  495.    }
  496.    break; /* until... */
  497.   }
  498.   outstr(line);
  499.   nl();
  500.   }
  501.  kill();  /* invalidate line */
  502.  cmode=1;  /* then back to parse level */
  503. }
  504.