xref: /csrg-svn/usr.bin/pascal/src/fdec.c (revision 11334)
1752Speter /* Copyright (c) 1979 Regents of the University of California */
2752Speter 
3*11334Speter static char sccsid[] = "@(#)fdec.c 1.23 02/28/83";
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"
11*11334Speter #include "tmps.h"
12752Speter 
13752Speter /*
14752Speter  * this array keeps the pxp counters associated with
15752Speter  * functions and procedures, so that they can be output
16752Speter  * when their bodies are encountered
17752Speter  */
18752Speter int	bodycnts[ DSPLYSZ ];
19752Speter 
20752Speter #ifdef PC
21752Speter #   include "pc.h"
22752Speter #   include "pcops.h"
23752Speter #endif PC
24752Speter 
25752Speter #ifdef OBJ
26752Speter int	cntpatch;
27752Speter int	nfppatch;
28752Speter #endif OBJ
29752Speter 
30752Speter funcfwd(fp)
31752Speter 	struct nl *fp;
32752Speter {
33752Speter 
34752Speter 	    /*
35752Speter 	     *	save the counter for this function
36752Speter 	     */
37752Speter 	if ( monflg ) {
38752Speter 	    fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
39752Speter 	}
40752Speter 	return (fp);
41752Speter }
42752Speter 
43752Speter /*
44752Speter  * Funcext marks the procedure or
45752Speter  * function external in the symbol
46752Speter  * table. Funcext should only be
47752Speter  * called if PC, and is an error
48752Speter  * otherwise.
49752Speter  */
50752Speter 
51752Speter funcext(fp)
52752Speter 	struct nl *fp;
53752Speter {
54752Speter 
557715Smckusick #ifdef OBJ
567715Smckusick 	error("Procedures or functions cannot be declared external.");
577715Smckusick #endif OBJ
587715Smckusick 
59752Speter #ifdef PC
607715Smckusick 	    /*
617715Smckusick 	     *	save the counter for this function
627715Smckusick 	     */
637715Smckusick 	if ( monflg ) {
647715Smckusick 	    fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
657715Smckusick 	}
66752Speter  	if (opt('s')) {
67752Speter 		standard();
68752Speter 		error("External procedures and functions are not standard");
69752Speter 	} else {
70752Speter 		if (cbn == 1) {
713825Speter 			fp->extra_flags |= NEXTERN;
72825Speter 			stabefunc( fp -> symbol , fp -> class , line );
73752Speter 		}
74752Speter 		else
75752Speter 			error("External procedures and functions can only be declared at the outermost level.");
76752Speter 	}
77752Speter #endif PC
78752Speter 
79752Speter 	return(fp);
80752Speter }
81752Speter 
82752Speter /*
83752Speter  * Funcbody is called
84752Speter  * when the actual (resolved)
85752Speter  * declaration of a procedure is
86752Speter  * encountered. It puts the names
87752Speter  * of the (function) and parameters
88752Speter  * into the symbol table.
89752Speter  */
90752Speter funcbody(fp)
91752Speter 	struct nl *fp;
92752Speter {
93752Speter 	register struct nl *q, *p;
94752Speter 
95752Speter 	cbn++;
96752Speter 	if (cbn >= DSPLYSZ) {
97752Speter 		error("Too many levels of function/procedure nesting");
98752Speter 		pexit(ERRS);
99752Speter 	}
100*11334Speter 	tmpinit(cbn);
101752Speter 	gotos[cbn] = NIL;
102752Speter 	errcnt[cbn] = syneflg;
103834Speter 	parts[ cbn ] = NIL;
104752Speter 	dfiles[ cbn ] = FALSE;
105752Speter 	if (fp == NIL)
106752Speter 		return (NIL);
107752Speter 	/*
108752Speter 	 * Save the virtual name
109752Speter 	 * list stack pointer so
110752Speter 	 * the space can be freed
111752Speter 	 * later (funcend).
112752Speter 	 */
113752Speter 	fp->ptr[2] = nlp;
114752Speter 	if (fp->class != PROG) {
115752Speter 		for (q = fp->chain; q != NIL; q = q->chain) {
116752Speter 			enter(q);
1173825Speter #			ifdef PC
1183825Speter 			    q -> extra_flags |= NPARAM;
1193825Speter #			endif PC
120752Speter 		}
121752Speter 	}
122752Speter 	if (fp->class == FUNC) {
123752Speter 		/*
124752Speter 		 * For functions, enter the fvar
125752Speter 		 */
126752Speter 		enter(fp->ptr[NL_FVAR]);
127752Speter #		ifdef PC
128752Speter 		    q = fp -> ptr[ NL_FVAR ];
1293825Speter 		    if (q -> type != NIL ) {
130*11334Speter 			sizes[cbn].curtmps.om_off = q -> value[NL_OFFS];
131*11334Speter 			sizes[cbn].om_max = q -> value[NL_OFFS];
1323825Speter 		    }
133752Speter #		endif PC
134752Speter 	}
135752Speter #	ifdef PTREE
136752Speter 		/*
137752Speter 		 *	pick up the pointer to porf declaration
138752Speter 		 */
139752Speter 	    PorFHeader[ ++nesting ] = fp -> inTree;
140752Speter #	endif PTREE
141752Speter 	return (fp);
142752Speter }
143752Speter 
144752Speter /*
145752Speter  * Segend is called to check for
146752Speter  * unresolved variables, funcs and
147752Speter  * procs, and deliver unresolved and
148752Speter  * baduse error diagnostics at the
149752Speter  * end of a routine segment (a separately
150752Speter  * compiled segment that is not the
151752Speter  * main program) for PC. This
152752Speter  * routine should only be called
153752Speter  * by PC (not standard).
154752Speter  */
155752Speter  segend()
156752Speter  {
157752Speter 	register struct nl *p;
158752Speter 	register int i,b;
159752Speter 	char *cp;
160752Speter 
161752Speter #ifdef PC
1627719Smckusick 	if ( monflg ) {
1637719Smckusick 	    error("Only the module containing the \"program\" statement");
1647719Smckusick 	    cerror("can be profiled with ``pxp''.\n");
1657719Smckusick 	}
166752Speter 	if (opt('s')) {
167752Speter 		standard();
168752Speter 		error("Separately compiled routine segments are not standard.");
169752Speter 	} else {
170752Speter 		b = cbn;
171752Speter 		for (i=0; i<077; i++) {
172752Speter 			for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
173752Speter 			switch (p->class) {
174752Speter 				case BADUSE:
175752Speter 					cp = 's';
176752Speter 					if (p->chain->ud_next == NIL)
177752Speter 						cp++;
178752Speter 					eholdnl();
179752Speter 					if (p->value[NL_KINDS] & ISUNDEF)
180752Speter 						nerror("%s undefined on line%s", p->symbol, cp);
181752Speter 					else
182752Speter 						nerror("%s improperly used on line%s", p->symbol, cp);
183752Speter 					pnumcnt = 10;
184752Speter 					pnums(p->chain);
185752Speter 					pchr('\n');
186752Speter 					break;
187752Speter 
188752Speter 				case FUNC:
189752Speter 				case PROC:
1903825Speter 					if ((p->nl_flags & NFORWD) &&
1913825Speter 					    ((p->extra_flags & NEXTERN) == 0))
192752Speter 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
193752Speter 					break;
194752Speter 
195752Speter 				case FVAR:
1963825Speter 					if (((p->nl_flags & NMOD) == 0) &&
1973825Speter 					    ((p->chain->extra_flags & NEXTERN) == 0))
198752Speter 						nerror("No assignment to the function variable");
199752Speter 					break;
200752Speter 			    }
201752Speter 			   }
202752Speter 			   disptab[i] = p;
203752Speter 		    }
204752Speter 	}
205752Speter #endif PC
206752Speter #ifdef OBJ
207752Speter 	error("Missing program statement and program body");
208752Speter #endif OBJ
209752Speter 
210752Speter }
211752Speter 
212752Speter 
213752Speter /*
214752Speter  * Level1 does level one processing for
215752Speter  * separately compiled routine segments
216752Speter  */
217752Speter level1()
218752Speter {
219752Speter 
220752Speter #	ifdef OBJ
221752Speter 	    error("Missing program statement");
222752Speter #	endif OBJ
223752Speter #	ifdef PC
224752Speter 	    if (opt('s')) {
225752Speter 		    standard();
226752Speter 		    error("Missing program statement");
227752Speter 	    }
228752Speter #	endif PC
229752Speter 
230752Speter 	cbn++;
231*11334Speter 	tmpinit(cbn);
232834Speter 	gotos[cbn] = NIL;
233834Speter 	errcnt[cbn] = syneflg;
234834Speter 	parts[ cbn ] = NIL;
235834Speter 	dfiles[ cbn ] = FALSE;
2363073Smckusic 	progseen = TRUE;
237752Speter }
238752Speter 
239752Speter 
240752Speter 
241752Speter pnums(p)
242752Speter 	struct udinfo *p;
243752Speter {
244752Speter 
245752Speter 	if (p->ud_next != NIL)
246752Speter 		pnums(p->ud_next);
247752Speter 	if (pnumcnt == 0) {
248752Speter 		printf("\n\t");
249752Speter 		pnumcnt = 20;
250752Speter 	}
251752Speter 	pnumcnt--;
252752Speter 	printf(" %d", p->ud_line);
253752Speter }
254752Speter 
255752Speter nerror(a1, a2, a3)
256752Speter {
257752Speter 
258752Speter 	if (Fp != NIL) {
259752Speter 		yySsync();
260752Speter #ifndef PI1
261752Speter 		if (opt('l'))
262752Speter 			yyoutline();
263752Speter #endif
264752Speter 		yysetfile(filename);
265752Speter 		printf("In %s %s:\n", classes[Fp->class], Fp->symbol);
266752Speter 		Fp = NIL;
267752Speter 		elineoff();
268752Speter 	}
269752Speter 	error(a1, a2, a3);
270752Speter }
271