home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / misc / smc203.ark / CC22.C < prev    next >
Encoding:
Text File  |  1983-07-28  |  8.9 KB  |  473 lines

  1.  
  2. ifline() {
  3.   while(1) {
  4.     inline();
  5.     if(eof) return;
  6.     if(match("#ifdef")) {
  7.       ++iflevel;
  8.       if(skiplevel) continue;
  9.       blanks();
  10.  
  11. #ifdef HASH
  12.       if(search(lptr, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0)
  13. #else /* HASH */
  14.       if(findmac(lptr)==0)
  15. #endif /* HASH */
  16.  
  17.         skiplevel=iflevel;
  18.       continue;
  19.       }
  20.     if(match("#ifndef")) {
  21.       ++iflevel;
  22.       if(skiplevel) continue;
  23.       blanks();
  24.  
  25. #ifdef HASH
  26.       if(search(lptr, macn, NAMESIZE+2, MACNEND, MACNBR, 0))
  27. #else /* HASH */
  28.       if(findmac(lptr))
  29. #endif /* HASH */
  30.  
  31.         skiplevel=iflevel;
  32.       continue;
  33.       }
  34.     if(match("#else")) {
  35.       if(iflevel) {
  36.         if(skiplevel==iflevel) skiplevel=0;
  37.         else if(skiplevel==0)  skiplevel=iflevel;
  38.         }
  39.       else noiferr();
  40.       continue;
  41.       }
  42.     if(match("#endif")) {
  43.       if(iflevel) {
  44.         if(skiplevel==iflevel) skiplevel=0;
  45.         --iflevel;
  46.         }
  47.       else noiferr();
  48.       continue;
  49.       }
  50.     if(skiplevel) continue;
  51.     if(listfp) {
  52.       if(listfp==output) cout(';', output);
  53.       lout(line, listfp);
  54.       }
  55.     if(ch==0) continue;
  56.     break;
  57.     }
  58.   }
  59.  
  60. keepch(c)  char c; {
  61.   if(pptr<LINEMAX) pline[++pptr]=c;
  62.   }
  63.  
  64. preprocess() {
  65.   int k;
  66.   char c;
  67.   if(ccode) {
  68.     line=mline;
  69.     ifline();
  70.     if(eof) return;
  71.     }
  72.   else {
  73.     line=pline;
  74.     inline();
  75.     return;
  76.     }
  77.   pptr = -1;
  78.   while(ch) {
  79.     if(white()) {
  80.       keepch(' ');
  81.       while(white()) gch();
  82.       }
  83.     else if(ch=='"') {
  84.       keepch(ch);
  85.       gch();
  86.       while((ch!='"')|((*(lptr-1)==92)&(*(lptr-2)!=92))) {
  87.         if(ch==0) {
  88.           error("no quote");
  89.           break;
  90.           }
  91.         keepch(gch());
  92.         }
  93.       gch();
  94.       keepch('"');
  95.       }
  96.     else if(ch==39) {
  97.       keepch(39);
  98.       gch();
  99.       while((ch!=39)|((*(lptr-1)==92)&(*(lptr-2)!=92))) {
  100.         if(ch==0) {
  101.           error("no apostrophe");
  102.           break;
  103.           }
  104.         keepch(gch());
  105.         }
  106.       gch();
  107.       keepch(39);
  108.       }
  109.     else if((ch=='/')&(nch=='*')) {
  110.       bump(2);
  111.       while(((ch=='*')&(nch=='/'))==0) {
  112.         if(ch) bump(1);
  113.         else {
  114.           ifline();
  115.           if(eof) break;
  116.           }
  117.         }
  118.       bump(2);
  119.       }
  120.     else if(an(ch)) {
  121.       k=0;
  122.       while(an(ch)) {
  123.         if(k<NAMEMAX) msname[k++]=ch;
  124.         gch();
  125.         }
  126.       msname[k]=0;
  127.  
  128. #ifdef HASH
  129.       if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)) {
  130.         k=getint(cptr+NAMESIZE, 2);
  131.         while(c=macq[k++]) keepch(c);
  132.         }
  133. #else /* HASH */
  134.       if(k=findmac(msname)) while(c=macq[k++]) keepch(c);
  135. #endif /* HASH */
  136.  
  137.       else {
  138.         k=0;
  139.         while(c=msname[k++]) keepch(c);
  140.         }
  141.       }
  142.     else keepch(gch());
  143.     }
  144.   if(pptr>=LINEMAX) error("line too long");
  145.   keepch(0);
  146.   line=pline;
  147.   bump(0);
  148.   }
  149.  
  150. noiferr() {
  151.   error("no matching #if...");
  152.   errflag=0;
  153.   }
  154.  
  155. addmac() {
  156.   int k;
  157.   if(symname(msname, NO)==0) {
  158.     illname();
  159.     kill();
  160.     return;
  161.     }
  162.   k=0;
  163.  
  164. #ifdef HASH
  165.   if(search(msname, macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) {
  166.     if(cptr2=cptr) while(*cptr2++ = msname[k++]);
  167.     else {
  168.       error("macro name table full");
  169.       return;
  170.       }
  171.     }
  172.   putint(macptr, cptr+NAMESIZE, 2);
  173. #else /* HASH */
  174.   while(putmac(msname[k++]));
  175. #endif /* HASH */
  176.  
  177.   while(white()) gch();
  178.   while(putmac(gch()));
  179.   if(macptr>=MACMAX) {
  180.     error("macro string queue full"); abort(ERRCODE);
  181.     }
  182.   }
  183.  
  184. putmac(c)  char c; {
  185.   macq[macptr]=c;
  186.   if(macptr<MACMAX) ++macptr;
  187.   return c;
  188.   }
  189.  
  190. #ifdef HASH
  191. /*
  192. ** search for symbol match
  193. ** on return cptr points to slot found or empty slot
  194. */
  195. search(sname, buf, len, end, max, off)
  196.   char *sname, *buf, *end;  int len, max, off; {
  197.   cptr=cptr2=buf+((hash(sname)%(max-1))*len);
  198.   while(*cptr != 0) {
  199.     if(astreq(sname, cptr+off, NAMEMAX)) return 1;
  200.     if((cptr=cptr+len) >= end) cptr=buf;
  201.     if(cptr == cptr2) return (cptr=0);
  202.     }
  203.   return 0;
  204.   }
  205.  
  206. hash(sname) char *sname; {
  207.   int i, c;
  208.   i=0;
  209.   while(c = *sname++) i=(i<<1)+c;
  210.   return i;
  211.   }
  212.  
  213. #else /* HASH */
  214. findmac(sname)  char *sname; {
  215.   mack=0;
  216.   while(mack<macptr) {
  217.     if(astreq(sname,macq+mack,NAMEMAX)) {
  218.       while(macq[mack++]);
  219.       return mack;
  220.       }
  221.     while(macq[mack++]);
  222.     while(macq[mack++]);
  223.     }
  224.   return 0;
  225.   }
  226. #endif /* HASH */
  227.  
  228. setstage(before, start) int *before, *start; {
  229.   if((*before=stagenext)==0) stagenext=stage;
  230.   *start=stagenext;
  231.   }
  232.  
  233. clearstage(before, start) char *before, *start; {
  234.   *stagenext=0;
  235.   if(stagenext=before) return;
  236.   if(start) {
  237.  
  238. #ifdef OPTIMIZE
  239.     peephole(start);
  240. #else /* OPTIMIZE */
  241.     sout(start, output);
  242. #endif /* OPTIMIZE */
  243.  
  244.     }
  245.   }
  246.  
  247. outdec(number)  int number; {
  248.   int k,zs;
  249.   char c;
  250.   zs = 0;
  251.   k=10000;
  252.   if (number<0) {
  253.     number=(-number);
  254.     outbyte('-');
  255.     }
  256.   while (k>=1) {
  257.     c=number/k + '0';
  258.     if ((c!='0')|(k==1)|(zs)) {
  259.       zs=1;
  260.       outbyte(c);
  261.       }
  262.     number=number%k;
  263.     k=k/10;
  264.     }
  265.   }
  266.  
  267. ol(ptr)  char ptr[];  {
  268.   ot(ptr);
  269.   nl();
  270.   }
  271.  
  272. ot(ptr) char ptr[]; {
  273.  
  274. #ifdef TAB
  275.   tab();
  276. #else /* TAB */
  277.   outbyte(' ');
  278. #endif /* TAB */
  279.  
  280.   outstr(ptr);
  281.   }
  282.  
  283. outstr(ptr) char ptr[]; {
  284.  
  285. #ifdef POLL
  286.   CCPOLL(1); /* allow program interruption */
  287. #endif /* POLL */
  288.  
  289.   /* must work with symbol table names terminated by length */
  290.   while(*ptr >= ' ') outbyte(*ptr++);
  291.   }
  292.  
  293. outbyte(c) char c; {
  294.   if(stagenext) {
  295.     if(stagenext==stagelast) {
  296.       error("staging buffer overflow");
  297.       return 0;
  298.       }
  299.     else *stagenext++ = c;
  300.     }
  301.   else cout(c,output);
  302.   return c;
  303.   }
  304.  
  305. cout(c, fd) char c; int fd; {
  306.  
  307. #ifdef C80
  308.   if(putc(c, fd)==EOF) xout();
  309. #else /* C80 */
  310.   if(fputc(c, fd)==EOF) xout();
  311. #endif /* C80 */
  312.  
  313.   }
  314.  
  315. sout(string, fd) char *string; int fd; {
  316.   if(fputs(string, fd)==EOF) xout();
  317.   }
  318.  
  319. lout(line, fd) char *line; int fd; {
  320.   sout(line, fd);
  321.   cout('\n', fd);
  322.   }
  323.  
  324. xout() {
  325.   fputs("output error\n", stderr);
  326.   abort(ERRCODE);
  327.   }
  328.  
  329. #ifdef C80
  330. abort(err) int err; {
  331.   exit();  /* exit to CP/M */
  332.   }
  333. #endif /* C80 */
  334.  
  335. #ifdef C80
  336. fputs(string, fd) char *string; int fd; {
  337.   char c;
  338.   while ((c = *string++) != NULL) {
  339.     if (putc(c, fd) == EOF) return EOF;
  340.     }
  341.   return 0;
  342.   }
  343. #endif /* C80 */
  344.  
  345. nl() {
  346.   outbyte('\n');
  347.   }
  348.  
  349. tab() {
  350.   outbyte(TAB);
  351.   }
  352.  
  353. col() {
  354.  
  355. #ifdef COL
  356.   outbyte(':');
  357. #else /* COL */
  358.   outbyte(' ');
  359. #endif /* COL */
  360.  
  361.   }
  362.  
  363. error(msg) char msg[]; {
  364.   if(errflag) return; else errflag=1;
  365.   lout(line, stderr);
  366.   errout(msg, stderr);
  367.  
  368. #ifdef C80
  369.   if(alarm) putc(7, stderr);
  370. #else /* C80 */
  371.   if(alarm) fputc(7, stderr);
  372. #endif /* C80 */
  373.  
  374.   /*
  375.   ** while reading from stderr is not strictly legal,
  376.   ** stderr will always be assigned to the user's terminal
  377.   ** (CON: on CP/M systems [should be /dev/tty on Unix]).
  378.   */
  379.   if(pause) while(getc(stderr)!='\n');
  380.   if(listfp>0) errout(msg, listfp);
  381.   }
  382.  
  383. errout(msg, fp) char msg[]; int fp; {
  384.   int k; k=line+2;
  385.   while(k++ <= lptr) cout(' ', fp);
  386.   lout("/\\", fp);
  387.   sout("**** ", fp); lout(msg, fp);
  388.   }
  389.  
  390. streq(str1,str2)  char str1[],str2[]; {
  391.   /* check for string equality over whole string */
  392.   int k;
  393.   k=0;
  394.   while (str2[k]) {
  395.     if ((str1[k])!=(str2[k])) return 0;
  396.     ++k;
  397.     }
  398.   return k;
  399.  }
  400.  
  401. astreq(str1,str2,len)  char str1[],str2[];int len; {
  402.   /* check for string equality over first 'len' characters */
  403.   int k;
  404.   k=0;
  405.   while (k<len) {
  406.     if ((str1[k])!=(str2[k]))break;
  407.     /*
  408.     ** must detect end of symbol table names terminated by
  409.     ** symbol length in binary
  410.     */
  411.     if(str1[k] < ' ') break;
  412.     if(str2[k] < ' ') break;
  413.     ++k;
  414.     }
  415.   if (an(str1[k]))return 0;
  416.   if (an(str2[k]))return 0;
  417.   return k;
  418.  }
  419.  
  420. match(lit)  char *lit; {
  421.   int k;
  422.   blanks();
  423.   if (k=streq(lptr,lit)) {
  424.     bump(k);
  425.     return 1;
  426.     }
  427.   return 0;
  428.   }
  429.  
  430. amatch(lit,len)  char *lit;int len; {
  431.   int k;
  432.   blanks();
  433.   if (k=astreq(lptr,lit,len)) {
  434.     bump(k);
  435.     while(an(ch)) inbyte();
  436.     return 1;
  437.     }
  438.   return 0;
  439.  }
  440.  
  441. nextop(list) char *list; {
  442.   char op[4];
  443.   opindex=0;
  444.   blanks();
  445.   while(1) {
  446.     opsize=0;
  447.     while(*list > ' ') op[opsize++] = *list++;
  448.     op[opsize]=0;
  449.     if(opsize=streq(lptr, op))
  450.       if((*(lptr+opsize) != '=')&
  451.          (*(lptr+opsize) != *(lptr+opsize-1)))
  452.          return 1;
  453.     if(*list) {
  454.       ++list;
  455.       ++opindex;
  456.       }
  457.     else return 0;
  458.     }
  459.   }
  460.  
  461. blanks() {
  462.   while(1) {
  463.     while(ch) {
  464.       if(white()) gch();
  465.       else return;
  466.       }
  467.     if(line==mline) return;
  468.     preprocess();
  469.     if(eof)break;
  470.     }
  471.   }
  472. 
  473. σσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσσ