xref: /csrg-svn/usr.bin/pascal/src/fdec.c (revision 7719)
1752Speter /* Copyright (c) 1979 Regents of the University of California */
2752Speter 
3*7719Smckusick static char sccsid[] = "@(#)fdec.c 1.22 08/12/82";
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 
547715Smckusick #ifdef OBJ
557715Smckusick 	error("Procedures or functions cannot be declared external.");
567715Smckusick #endif OBJ
577715Smckusick 
58752Speter #ifdef PC
597715Smckusick 	    /*
607715Smckusick 	     *	save the counter for this function
617715Smckusick 	     */
627715Smckusick 	if ( monflg ) {
637715Smckusick 	    fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
647715Smckusick 	}
65752Speter  	if (opt('s')) {
66752Speter 		standard();
67752Speter 		error("External procedures and functions are not standard");
68752Speter 	} else {
69752Speter 		if (cbn == 1) {
703825Speter 			fp->extra_flags |= NEXTERN;
71825Speter 			stabefunc( fp -> symbol , fp -> class , line );
72752Speter 		}
73752Speter 		else
74752Speter 			error("External procedures and functions can only be declared at the outermost level.");
75752Speter 	}
76752Speter #endif PC
77752Speter 
78752Speter 	return(fp);
79752Speter }
80752Speter 
81752Speter /*
82752Speter  * Funcbody is called
83752Speter  * when the actual (resolved)
84752Speter  * declaration of a procedure is
85752Speter  * encountered. It puts the names
86752Speter  * of the (function) and parameters
87752Speter  * into the symbol table.
88752Speter  */
89752Speter funcbody(fp)
90752Speter 	struct nl *fp;
91752Speter {
92752Speter 	register struct nl *q, *p;
933825Speter 	struct nl	*functemp;
94752Speter 
95752Speter 	cbn++;
96752Speter 	if (cbn >= DSPLYSZ) {
97752Speter 		error("Too many levels of function/procedure nesting");
98752Speter 		pexit(ERRS);
99752Speter 	}
1003222Smckusic 	sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1;
1013276Smckusic 	sizes[cbn].reg_max = -1;
1023276Smckusic 	sizes[cbn].curtmps.reg_off = 0;
103752Speter 	gotos[cbn] = NIL;
104752Speter 	errcnt[cbn] = syneflg;
105834Speter 	parts[ cbn ] = NIL;
106752Speter 	dfiles[ cbn ] = FALSE;
107752Speter 	if (fp == NIL)
108752Speter 		return (NIL);
109752Speter 	/*
110752Speter 	 * Save the virtual name
111752Speter 	 * list stack pointer so
112752Speter 	 * the space can be freed
113752Speter 	 * later (funcend).
114752Speter 	 */
115752Speter 	fp->ptr[2] = nlp;
116752Speter 	if (fp->class != PROG) {
117752Speter 		for (q = fp->chain; q != NIL; q = q->chain) {
118752Speter 			enter(q);
1193825Speter #			ifdef PC
1203825Speter 			    q -> extra_flags |= NPARAM;
1213825Speter #			endif PC
122752Speter 		}
123752Speter 	}
124752Speter 	if (fp->class == FUNC) {
125752Speter 		/*
126752Speter 		 * For functions, enter the fvar
127752Speter 		 */
128752Speter 		enter(fp->ptr[NL_FVAR]);
129752Speter #		ifdef PC
130752Speter 		    q = fp -> ptr[ NL_FVAR ];
1313825Speter 		    if (q -> type != NIL ) {
1323825Speter 			functemp = tmpalloc(
1333825Speter 					leven(
1343825Speter 					    roundup(
1353825Speter 						(int)lwidth(q -> type),
1363825Speter 						(long)align(q -> type))),
1373825Speter 					q -> type, NOREG);
1383825Speter 			if ( q -> ptr[NL_OFFS] != functemp->value[NL_OFFS] )
1393276Smckusic 			    panic("func var");
1403825Speter 		    }
1413825Speter 		    q -> extra_flags |= functemp -> extra_flags;
142752Speter #		endif PC
143752Speter 	}
144752Speter #	ifdef PTREE
145752Speter 		/*
146752Speter 		 *	pick up the pointer to porf declaration
147752Speter 		 */
148752Speter 	    PorFHeader[ ++nesting ] = fp -> inTree;
149752Speter #	endif PTREE
150752Speter 	return (fp);
151752Speter }
152752Speter 
153752Speter /*
154752Speter  * Segend is called to check for
155752Speter  * unresolved variables, funcs and
156752Speter  * procs, and deliver unresolved and
157752Speter  * baduse error diagnostics at the
158752Speter  * end of a routine segment (a separately
159752Speter  * compiled segment that is not the
160752Speter  * main program) for PC. This
161752Speter  * routine should only be called
162752Speter  * by PC (not standard).
163752Speter  */
164752Speter  segend()
165752Speter  {
166752Speter 	register struct nl *p;
167752Speter 	register int i,b;
168752Speter 	char *cp;
169752Speter 
170752Speter #ifdef PC
171*7719Smckusick 	if ( monflg ) {
172*7719Smckusick 	    error("Only the module containing the \"program\" statement");
173*7719Smckusick 	    cerror("can be profiled with ``pxp''.\n");
174*7719Smckusick 	}
175752Speter 	if (opt('s')) {
176752Speter 		standard();
177752Speter 		error("Separately compiled routine segments are not standard.");
178752Speter 	} else {
179752Speter 		b = cbn;
180752Speter 		for (i=0; i<077; i++) {
181752Speter 			for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
182752Speter 			switch (p->class) {
183752Speter 				case BADUSE:
184752Speter 					cp = 's';
185752Speter 					if (p->chain->ud_next == NIL)
186752Speter 						cp++;
187752Speter 					eholdnl();
188752Speter 					if (p->value[NL_KINDS] & ISUNDEF)
189752Speter 						nerror("%s undefined on line%s", p->symbol, cp);
190752Speter 					else
191752Speter 						nerror("%s improperly used on line%s", p->symbol, cp);
192752Speter 					pnumcnt = 10;
193752Speter 					pnums(p->chain);
194752Speter 					pchr('\n');
195752Speter 					break;
196752Speter 
197752Speter 				case FUNC:
198752Speter 				case PROC:
1993825Speter 					if ((p->nl_flags & NFORWD) &&
2003825Speter 					    ((p->extra_flags & NEXTERN) == 0))
201752Speter 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
202752Speter 					break;
203752Speter 
204752Speter 				case FVAR:
2053825Speter 					if (((p->nl_flags & NMOD) == 0) &&
2063825Speter 					    ((p->chain->extra_flags & NEXTERN) == 0))
207752Speter 						nerror("No assignment to the function variable");
208752Speter 					break;
209752Speter 			    }
210752Speter 			   }
211752Speter 			   disptab[i] = p;
212752Speter 		    }
213752Speter 	}
214752Speter #endif PC
215752Speter #ifdef OBJ
216752Speter 	error("Missing program statement and program body");
217752Speter #endif OBJ
218752Speter 
219752Speter }
220752Speter 
221752Speter 
222752Speter /*
223752Speter  * Level1 does level one processing for
224752Speter  * separately compiled routine segments
225752Speter  */
226752Speter level1()
227752Speter {
228752Speter 
229752Speter #	ifdef OBJ
230752Speter 	    error("Missing program statement");
231752Speter #	endif OBJ
232752Speter #	ifdef PC
233752Speter 	    if (opt('s')) {
234752Speter 		    standard();
235752Speter 		    error("Missing program statement");
236752Speter 	    }
237752Speter #	endif PC
238752Speter 
239752Speter 	cbn++;
2403222Smckusic 	sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1;
241834Speter 	gotos[cbn] = NIL;
242834Speter 	errcnt[cbn] = syneflg;
243834Speter 	parts[ cbn ] = NIL;
244834Speter 	dfiles[ cbn ] = FALSE;
2453073Smckusic 	progseen = TRUE;
246752Speter }
247752Speter 
248752Speter 
249752Speter 
250752Speter pnums(p)
251752Speter 	struct udinfo *p;
252752Speter {
253752Speter 
254752Speter 	if (p->ud_next != NIL)
255752Speter 		pnums(p->ud_next);
256752Speter 	if (pnumcnt == 0) {
257752Speter 		printf("\n\t");
258752Speter 		pnumcnt = 20;
259752Speter 	}
260752Speter 	pnumcnt--;
261752Speter 	printf(" %d", p->ud_line);
262752Speter }
263752Speter 
264752Speter nerror(a1, a2, a3)
265752Speter {
266752Speter 
267752Speter 	if (Fp != NIL) {
268752Speter 		yySsync();
269752Speter #ifndef PI1
270752Speter 		if (opt('l'))
271752Speter 			yyoutline();
272752Speter #endif
273752Speter 		yysetfile(filename);
274752Speter 		printf("In %s %s:\n", classes[Fp->class], Fp->symbol);
275752Speter 		Fp = NIL;
276752Speter 		elineoff();
277752Speter 	}
278752Speter 	error(a1, a2, a3);
279752Speter }
280