home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 163_01 / cc12.c < prev    next >
Text File  |  1990-12-28  |  10KB  |  338 lines

  1. /*
  2. ** open an include file
  3. */
  4. doinclude() {
  5.   if(monitor) lout(line, stderr);
  6.   blanks();         /* skip over to name                            */
  7.   if(match("<")) ;  /* ignore <> */
  8.   else match("\42"); /* ignore "" */
  9.   if((input2=fopen(lptr,"r"))==NULL) {
  10.     input2=EOF;
  11.     error("open failure on include file");
  12.     }
  13.   kill();           /* clear rest of line                           */
  14.       /* so next read will come from                                */
  15.       /* new file (if open)                                         */
  16.   }
  17.  
  18. /*
  19. **  test for global declarations
  20. */
  21. dodeclare(class) int class; {
  22.   if(amatch("char",4)) {
  23.     declglb(CCHAR,class);
  24.     return 1;
  25.     }
  26.   else if((amatch("int",3))|(class==EXTERNAL)|(class==STATIC)) {
  27.     declglb(CINT, class);
  28.     return 1;
  29.     }
  30.   return 0;
  31.   }
  32.  
  33. /*
  34. ** declare a static variable
  35. */
  36. declglb(type, class) int type, class; {
  37. int k, j, dim2, ndim;
  38. char *ste; /* symbol table entry */
  39.   dim2 = 1;
  40.   ndim = 0;
  41.   while(1) {
  42.     if(match(";")) return;
  43.     if(match("*")) {
  44.       j=POINTER;
  45.       k=0;
  46.       }
  47.     else {
  48.       j=VARIABLE;
  49.       k=1;
  50.       }
  51.     if(symname(ssname, YES)==0) illname();
  52.     blanks();
  53.     if(streq(lptr, "(")) {
  54.       if(j==POINTER) error("pointer functions not allowed");
  55.       if(type==CCHAR) error("character functions not allowed");
  56.       if((class==STATIC)|(class==PUBLIC)) {
  57.         newfunc(class);
  58.         return;
  59.         }
  60.       else {
  61.         j=FUNCTION;
  62.         if(match("()") == 0) error("missing closing paren");
  63.         }
  64.       }
  65.     if(findglb(ssname)) multidef(ssname);
  66.     if(j!=FUNCTION) {
  67.       if(match("[")) {
  68.         k=needsub();  /* get size                                     */
  69.     j=ARRAY;      /* !0=array                                     */
  70.     ndim = 1;
  71.     if(match("[")) {
  72.       dim2 = needsub();
  73.       ndim = 2;
  74.       if(dim2 == 0) {
  75.          error("need array size");
  76.          k = dim2 = 1;
  77.       } /* if dim2 */
  78.     } /* if match */
  79.       } /* if match */
  80.     } /* if j!= */
  81.     if(class!=EXTERNAL) j=initials(type>>2, j, k, class, dim2);
  82.     ste = addsym(ssname, j, type, k, &glbptr, class, dim2, ndim);
  83.     if(ste) ste[STATUS] |= DECLARED;
  84.     if(match(",")==0) {ns(); return;}  /* more? */
  85.     }
  86.   }
  87.  
  88. /*
  89. ** declare local variables
  90. */
  91. declloc(typ) int typ; {
  92.   int k, j, dim2, ndim;
  93. #ifdef STGOTO
  94.   if(noloc) error("not allowed with goto");
  95. #endif
  96.   if(declared < 0)  error("must declare first in block");
  97.   while(1) {
  98.     while(1) {
  99.       if(endst()) return;
  100.       if(match("*")) j=POINTER;
  101.       else j=VARIABLE;
  102.       if(symname(ssname, YES)==0) illname();
  103.       /* no multidef check, block-locals are together               */
  104.       k=BPW;
  105.       if (match("[")) {
  106.     ndim = 1;
  107.         k=needsub();
  108.         if(k) {
  109.           j=ARRAY;
  110.       if(typ == CINT) k = k << LBPW;
  111.       if(match("[")) {
  112.           dim2 = needsub();
  113.           k = k * dim2;
  114.           ndim = 2;
  115.       }
  116.     }
  117.         else {
  118.           j = POINTER;
  119.           k = BPW;
  120.       if(match("[")) {
  121.           dim2 = needsub();
  122.           while(inbyte() != ']') if(endst()) break;
  123.           ndim = 2;
  124.        }
  125.       }
  126.         }
  127.       else if(match("()")) j=FUNCTION;
  128.       else if((typ==CCHAR)&(j==VARIABLE)) k=SBPC;
  129.       declared = declared + k;
  130.       addsym(ssname, j, typ, csp - declared, &locptr, AUTOMATIC, dim2, ndim);
  131.       break;
  132.       }
  133.     if (match(",")==0) return;
  134.     }
  135.   }
  136.  
  137. /*
  138. ** inialize global objects
  139. */
  140. initials(size, ident, dim, class, dim2) int size, ident, dim, class, dim2; {
  141.   int savedim, savectxt, dimsz, sflag, otemp;
  142.   savectxt = ctext;
  143.   sflag = -1;
  144.   ctext = 0; /* turn off interleaved source - problem with multi-line dcls */
  145.   litptr=0;
  146.   if(dim==0) dim = -1;
  147.   dimsz = dim * dim2;
  148.   savedim=dim;
  149.   if(class==PUBLIC) entry();
  150.   startglob();
  151.   if(match("=")) {
  152.     if(match("{")) {
  153.       while(dimsz) {
  154.     otemp = dimsz;
  155.     init(size, ident, &dimsz);
  156.     if(match(",")==0) break;
  157.     if(otemp != dimsz) sflag = 1;
  158.         }
  159.       needtoken("}");
  160.       }
  161.     else {
  162.       otemp = dimsz;
  163.       init(size, ident, &dimsz);
  164.       if (otemp != dimsz) sflag = 1;
  165.       }
  166.     }
  167.   if((savedim == -1) & (sflag == -1)) {
  168.     stowlit(0, size=BPW);
  169.     ident=POINTER;
  170.     }
  171.   dumplits(size);
  172.   dumpzero(size, dimsz);
  173.   ctext = savectxt; /* restore source code interleave mode */
  174.   return ident;
  175.   }
  176.  
  177. /*
  178. ** evaluate one initializer
  179. */
  180. init(size, ident, dim) int size, ident, *dim; {
  181.   int value;
  182.   if(qstr(&value)) {
  183.     if((ident==VARIABLE)|(size!=1))
  184.       error("must assign to char pointer or array");
  185.     *dim = *dim- (litptr-value);
  186.     if(ident==POINTER) point();
  187.     }
  188.   else if(constexpr(&value)) {
  189.     if(ident==POINTER) error("cannot assign to pointer");
  190.     stowlit(value, size);
  191.     *dim = *dim-1;
  192.     }
  193.   }
  194.  
  195. /*
  196. ** get required array size
  197. */
  198. needsub() {
  199.   int val;
  200.   if (match("]")) return 0;  /* null size                           */
  201.   if (constexpr(&val) == 0) val = 1;
  202.   if (val<0) {
  203.     error("negative size illegal");
  204.     val = -val;
  205.     }
  206.   needtoken("]");            /* force single dimension             */
  207.   return val;                /* and return size                    */
  208.   }
  209.  
  210. /*
  211. ** begin a function
  212. **
  213. ** called from "parse" and tries to make a function
  214. ** out of the following text
  215. **
  216. ** Patched per P. L. Woods (DDJ #52)
  217. */
  218. newfunc(class) int class; {
  219.   char *ptr, *source, *dest, funname[NAMESIZE];
  220. #ifdef STGOTO
  221.   nogo  =              /* enable goto statements */
  222.   noloc = 0;           /* enable block-local declarations */
  223. #endif
  224.   lastst=              /* no statement yet */
  225.   litptr=0;            /* clear lit pool */
  226.   litlab=getlabel();   /* label next literal pool */
  227.   locptr=STARTLOC;     /* clear local variables */
  228.   if(monitor) lout(line,stderr);
  229.   if(class==PUBLIC) {  /* skip symname if STATIC -- already done */
  230.     if(symname(ssname, YES)==0) {
  231.       error("illegal function or declaration");
  232.       kill();          /* invalidate line */
  233.       return;
  234.       }
  235.     }
  236.   if(match("(")==0) error("no open paren");
  237.   if(ptr=findglb(ssname)) {        /* already in symbol table ?    */
  238.     if(ptr[IDENT]!=FUNCTION)       multidef(ssname);
  239.     else if(ptr[STATUS] & DECLARED) multidef(ssname);
  240.     else ptr[STATUS] |= DECLARED;
  241.     /* earlier assumed to be a function */
  242.     }
  243.   else {
  244.     ptr = addsym(ssname, FUNCTION, CINT, FUNCTION, &glbptr, STATIC, 0, 0);
  245.     if(ptr) ptr[STATUS] |= DECLARED;
  246.     }
  247.   if(class==PUBLIC) entry(); /* gen the PUBLIC declaration */
  248.   source=ssname;
  249.   dest=funname;
  250.   while(*dest++=*source++); /* save function name (for ENDP) */
  251.   startfun(funname); /* gen PROC and BP manipulation */
  252.   locptr=STARTLOC;
  253.   argstk=0;         /* init arg count                              */
  254.   while(match(")")==0) {  /* then count args
  255.     /* any legal name bumps arg count                              */
  256.     if(symname(ssname, YES)) {
  257.       if(findloc(ssname)) multidef(ssname);
  258.       else {
  259.         ++argstk;
  260.     ptr = addsym(ssname, 0, 0, argstk, &locptr, AUTOMATIC, 0, 0);
  261.         if(ptr) ptr[STATUS] |= DECLARED;
  262.         }
  263.       }
  264.     else {error("illegal argument name"); junk();}
  265.     blanks();
  266.     /* if not closing paren, should be comma                       */
  267.     if(streq(lptr,")")==0) {
  268.       if(match(",")==0) error("no comma");
  269.       }
  270.     if(endst()) break;
  271.     }
  272.   csp=0;            /* preset stack pointer                        */
  273.   argtop=argstk;
  274.   while(argstk) {
  275.     /* now let user declare what types of things                   */
  276.     /*              those arguments were                           */
  277.     if(amatch("char",4))     {doargs(CCHAR);ns();}
  278.     else if(amatch("int",3)) {doargs(CINT);ns();}
  279.     else {error("argument(s) not declared"); break;}
  280.     }
  281.   if(statement()!=STRETURN) ret();
  282.   endfun(funname); /* gen the ENDP */
  283.   if(litptr) {
  284.     startlit(); /* set to DATASEG */
  285.     printlabel(litlab);
  286.     dumplits(1);   /* dump literals                                */
  287.     }
  288.   }
  289.  
  290. /*
  291. ** declare argument types
  292. **
  293. ** called from "newfunc" this routine adds an entry in the
  294. ** local symbol table for each named argument
  295. **
  296. ** rewritten per P. L. Woods (DDJ #52)
  297. */
  298. doargs(t) int t; {
  299.   int j, legalname, dim2, ndim;
  300.   char c, *argptr;
  301.   while(1) {
  302.     if(argstk==0) return;      /* no arguments                     */
  303.     if(match("*")) j=POINTER; else j=VARIABLE;
  304.     if((legalname=symname(ssname, YES))==0) illname();
  305.     if(match("[")) {   /* is it a pointer ?                        */
  306.       ndim = 1;
  307.       /* yes, so skip stuff between "[...]"                        */
  308.       while(inbyte()!=']') if(endst()) break;
  309.                else if(streq(lptr,"[")) break; /* check this logic */
  310.       j=POINTER;      /* add entry as pointer                      */
  311.       if(match("[")) {
  312.     dim2 = needsub();
  313.     ndim = 2;
  314.       }
  315.     }
  316.     if(legalname) {
  317.       if(argptr=findloc(ssname)) {
  318.         if(argptr[TYPE]==NULL) {
  319.           /* add details of type and address                       */
  320.           argptr[IDENT]=j;
  321.           argptr[TYPE]=t;
  322.           putint((((argtop-getint(argptr+OFFSET, OFFSIZE))*BPW)+STKFRSZ),
  323.           argptr+OFFSET, OFFSIZE);
  324.       argptr[NDIM] = ndim;
  325.       putint(dim2, argptr + CDIM, 2);
  326.           }
  327.         else error("duplicate argument declaration");
  328.         }
  329.       else error("not an argument");
  330.       }
  331.     --argstk; /* count down */
  332.     if(endst())return;
  333.     if(match(",")==0) error(" no comma");
  334.     }
  335.   }
  336.  
  337.  
  338.