1752Speter /* Copyright (c) 1979 Regents of the University of California */ 2752Speter 3*3825Speter static char sccsid[] = "@(#)fdec.c 1.20 06/01/81"; 4752Speter 5752Speter #include "whoami.h" 6752Speter #include "0.h" 7752Speter #include "tree.h" 8752Speter #include "opcode.h" 9752Speter #include "objfmt.h" 10752Speter #include "align.h" 11752Speter 12752Speter /* 13752Speter * this array keeps the pxp counters associated with 14752Speter * functions and procedures, so that they can be output 15752Speter * when their bodies are encountered 16752Speter */ 17752Speter int bodycnts[ DSPLYSZ ]; 18752Speter 19752Speter #ifdef PC 20752Speter # include "pc.h" 21752Speter # include "pcops.h" 22752Speter #endif PC 23752Speter 24752Speter #ifdef OBJ 25752Speter int cntpatch; 26752Speter int nfppatch; 27752Speter #endif OBJ 28752Speter 29752Speter funcfwd(fp) 30752Speter struct nl *fp; 31752Speter { 32752Speter 33752Speter /* 34752Speter * save the counter for this function 35752Speter */ 36752Speter if ( monflg ) { 37752Speter fp -> value[ NL_CNTR ] = bodycnts[ cbn ]; 38752Speter } 39752Speter return (fp); 40752Speter } 41752Speter 42752Speter /* 43752Speter * Funcext marks the procedure or 44752Speter * function external in the symbol 45752Speter * table. Funcext should only be 46752Speter * called if PC, and is an error 47752Speter * otherwise. 48752Speter */ 49752Speter 50752Speter funcext(fp) 51752Speter struct nl *fp; 52752Speter { 53752Speter 54752Speter #ifdef PC 55752Speter if (opt('s')) { 56752Speter standard(); 57752Speter error("External procedures and functions are not standard"); 58752Speter } else { 59752Speter if (cbn == 1) { 60*3825Speter fp->extra_flags |= NEXTERN; 61825Speter stabefunc( fp -> symbol , fp -> class , line ); 62752Speter } 63752Speter else 64752Speter error("External procedures and functions can only be declared at the outermost level."); 65752Speter } 66752Speter #endif PC 67752Speter #ifdef OBJ 68752Speter error("Procedures or functions cannot be declared external."); 69752Speter #endif OBJ 70752Speter 71752Speter return(fp); 72752Speter } 73752Speter 74752Speter /* 75752Speter * Funcbody is called 76752Speter * when the actual (resolved) 77752Speter * declaration of a procedure is 78752Speter * encountered. It puts the names 79752Speter * of the (function) and parameters 80752Speter * into the symbol table. 81752Speter */ 82752Speter funcbody(fp) 83752Speter struct nl *fp; 84752Speter { 85752Speter register struct nl *q, *p; 86*3825Speter struct nl *functemp; 87752Speter 88752Speter cbn++; 89752Speter if (cbn >= DSPLYSZ) { 90752Speter error("Too many levels of function/procedure nesting"); 91752Speter pexit(ERRS); 92752Speter } 933222Smckusic sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1; 943276Smckusic sizes[cbn].reg_max = -1; 953276Smckusic sizes[cbn].curtmps.reg_off = 0; 96752Speter gotos[cbn] = NIL; 97752Speter errcnt[cbn] = syneflg; 98834Speter parts[ cbn ] = NIL; 99752Speter dfiles[ cbn ] = FALSE; 100752Speter if (fp == NIL) 101752Speter return (NIL); 102752Speter /* 103752Speter * Save the virtual name 104752Speter * list stack pointer so 105752Speter * the space can be freed 106752Speter * later (funcend). 107752Speter */ 108752Speter fp->ptr[2] = nlp; 109752Speter if (fp->class != PROG) { 110752Speter for (q = fp->chain; q != NIL; q = q->chain) { 111752Speter enter(q); 112*3825Speter # ifdef PC 113*3825Speter q -> extra_flags |= NPARAM; 114*3825Speter # endif PC 115752Speter } 116752Speter } 117752Speter if (fp->class == FUNC) { 118752Speter /* 119752Speter * For functions, enter the fvar 120752Speter */ 121752Speter enter(fp->ptr[NL_FVAR]); 122752Speter # ifdef PC 123752Speter q = fp -> ptr[ NL_FVAR ]; 124*3825Speter if (q -> type != NIL ) { 125*3825Speter functemp = tmpalloc( 126*3825Speter leven( 127*3825Speter roundup( 128*3825Speter (int)lwidth(q -> type), 129*3825Speter (long)align(q -> type))), 130*3825Speter q -> type, NOREG); 131*3825Speter if ( q -> ptr[NL_OFFS] != functemp->value[NL_OFFS] ) 1323276Smckusic panic("func var"); 133*3825Speter } 134*3825Speter q -> extra_flags |= functemp -> extra_flags; 135752Speter # endif PC 136752Speter } 137752Speter # ifdef PTREE 138752Speter /* 139752Speter * pick up the pointer to porf declaration 140752Speter */ 141752Speter PorFHeader[ ++nesting ] = fp -> inTree; 142752Speter # endif PTREE 143752Speter return (fp); 144752Speter } 145752Speter 146752Speter /* 147752Speter * Segend is called to check for 148752Speter * unresolved variables, funcs and 149752Speter * procs, and deliver unresolved and 150752Speter * baduse error diagnostics at the 151752Speter * end of a routine segment (a separately 152752Speter * compiled segment that is not the 153752Speter * main program) for PC. This 154752Speter * routine should only be called 155752Speter * by PC (not standard). 156752Speter */ 157752Speter segend() 158752Speter { 159752Speter register struct nl *p; 160752Speter register int i,b; 161752Speter char *cp; 162752Speter 163752Speter #ifdef PC 164752Speter if (opt('s')) { 165752Speter standard(); 166752Speter error("Separately compiled routine segments are not standard."); 167752Speter } else { 168752Speter b = cbn; 169752Speter for (i=0; i<077; i++) { 170752Speter for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) { 171752Speter switch (p->class) { 172752Speter case BADUSE: 173752Speter cp = 's'; 174752Speter if (p->chain->ud_next == NIL) 175752Speter cp++; 176752Speter eholdnl(); 177752Speter if (p->value[NL_KINDS] & ISUNDEF) 178752Speter nerror("%s undefined on line%s", p->symbol, cp); 179752Speter else 180752Speter nerror("%s improperly used on line%s", p->symbol, cp); 181752Speter pnumcnt = 10; 182752Speter pnums(p->chain); 183752Speter pchr('\n'); 184752Speter break; 185752Speter 186752Speter case FUNC: 187752Speter case PROC: 188*3825Speter if ((p->nl_flags & NFORWD) && 189*3825Speter ((p->extra_flags & NEXTERN) == 0)) 190752Speter nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 191752Speter break; 192752Speter 193752Speter case FVAR: 194*3825Speter if (((p->nl_flags & NMOD) == 0) && 195*3825Speter ((p->chain->extra_flags & NEXTERN) == 0)) 196752Speter nerror("No assignment to the function variable"); 197752Speter break; 198752Speter } 199752Speter } 200752Speter disptab[i] = p; 201752Speter } 202752Speter } 203752Speter #endif PC 204752Speter #ifdef OBJ 205752Speter error("Missing program statement and program body"); 206752Speter #endif OBJ 207752Speter 208752Speter } 209752Speter 210752Speter 211752Speter /* 212752Speter * Level1 does level one processing for 213752Speter * separately compiled routine segments 214752Speter */ 215752Speter level1() 216752Speter { 217752Speter 218752Speter # ifdef OBJ 219752Speter error("Missing program statement"); 220752Speter # endif OBJ 221752Speter # ifdef PC 222752Speter if (opt('s')) { 223752Speter standard(); 224752Speter error("Missing program statement"); 225752Speter } 226752Speter # endif PC 227752Speter 228752Speter cbn++; 2293222Smckusic sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1; 230834Speter gotos[cbn] = NIL; 231834Speter errcnt[cbn] = syneflg; 232834Speter parts[ cbn ] = NIL; 233834Speter dfiles[ cbn ] = FALSE; 2343073Smckusic progseen = TRUE; 235752Speter } 236752Speter 237752Speter 238752Speter 239752Speter pnums(p) 240752Speter struct udinfo *p; 241752Speter { 242752Speter 243752Speter if (p->ud_next != NIL) 244752Speter pnums(p->ud_next); 245752Speter if (pnumcnt == 0) { 246752Speter printf("\n\t"); 247752Speter pnumcnt = 20; 248752Speter } 249752Speter pnumcnt--; 250752Speter printf(" %d", p->ud_line); 251752Speter } 252752Speter 253752Speter nerror(a1, a2, a3) 254752Speter { 255752Speter 256752Speter if (Fp != NIL) { 257752Speter yySsync(); 258752Speter #ifndef PI1 259752Speter if (opt('l')) 260752Speter yyoutline(); 261752Speter #endif 262752Speter yysetfile(filename); 263752Speter printf("In %s %s:\n", classes[Fp->class], Fp->symbol); 264752Speter Fp = NIL; 265752Speter elineoff(); 266752Speter } 267752Speter error(a1, a2, a3); 268752Speter } 269