xref: /csrg-svn/usr.bin/pascal/src/fdec.c (revision 14729)
1752Speter /* Copyright (c) 1979 Regents of the University of California */
2752Speter 
3*14729Sthien #ifndef lint
4*14729Sthien static char sccsid[] = "@(#)fdec.c 1.24 08/19/83";
5*14729Sthien #endif
6752Speter 
7752Speter #include "whoami.h"
8752Speter #include "0.h"
9752Speter #include "tree.h"
10752Speter #include "opcode.h"
11752Speter #include "objfmt.h"
12752Speter #include "align.h"
1311334Speter #include "tmps.h"
14752Speter 
15752Speter /*
16752Speter  * this array keeps the pxp counters associated with
17752Speter  * functions and procedures, so that they can be output
18752Speter  * when their bodies are encountered
19752Speter  */
20752Speter int	bodycnts[ DSPLYSZ ];
21752Speter 
22752Speter #ifdef PC
23752Speter #   include "pc.h"
24752Speter #   include "pcops.h"
25752Speter #endif PC
26752Speter 
27752Speter #ifdef OBJ
28752Speter int	cntpatch;
29752Speter int	nfppatch;
30752Speter #endif OBJ
31752Speter 
32752Speter funcfwd(fp)
33752Speter 	struct nl *fp;
34752Speter {
35752Speter 
36752Speter 	    /*
37752Speter 	     *	save the counter for this function
38752Speter 	     */
39752Speter 	if ( monflg ) {
40752Speter 	    fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
41752Speter 	}
42752Speter }
43752Speter 
44752Speter /*
45752Speter  * Funcext marks the procedure or
46752Speter  * function external in the symbol
47752Speter  * table. Funcext should only be
48752Speter  * called if PC, and is an error
49752Speter  * otherwise.
50752Speter  */
51752Speter 
52*14729Sthien struct nl *
53752Speter funcext(fp)
54752Speter 	struct nl *fp;
55752Speter {
56752Speter 
577715Smckusick #ifdef OBJ
587715Smckusick 	error("Procedures or functions cannot be declared external.");
597715Smckusick #endif OBJ
607715Smckusick 
61752Speter #ifdef PC
627715Smckusick 	    /*
637715Smckusick 	     *	save the counter for this function
647715Smckusick 	     */
657715Smckusick 	if ( monflg ) {
667715Smckusick 	    fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
677715Smckusick 	}
68752Speter  	if (opt('s')) {
69752Speter 		standard();
70752Speter 		error("External procedures and functions are not standard");
71752Speter 	} else {
72752Speter 		if (cbn == 1) {
733825Speter 			fp->extra_flags |= NEXTERN;
74825Speter 			stabefunc( fp -> symbol , fp -> class , line );
75752Speter 		}
76752Speter 		else
77752Speter 			error("External procedures and functions can only be declared at the outermost level.");
78752Speter 	}
79752Speter #endif PC
80752Speter 
81752Speter 	return(fp);
82752Speter }
83752Speter 
84752Speter /*
85752Speter  * Funcbody is called
86752Speter  * when the actual (resolved)
87752Speter  * declaration of a procedure is
88752Speter  * encountered. It puts the names
89752Speter  * of the (function) and parameters
90752Speter  * into the symbol table.
91752Speter  */
92*14729Sthien struct nl *
93752Speter funcbody(fp)
94752Speter 	struct nl *fp;
95752Speter {
96*14729Sthien 	register struct nl *q;
97752Speter 
98752Speter 	cbn++;
99752Speter 	if (cbn >= DSPLYSZ) {
100752Speter 		error("Too many levels of function/procedure nesting");
101752Speter 		pexit(ERRS);
102752Speter 	}
10311334Speter 	tmpinit(cbn);
104752Speter 	gotos[cbn] = NIL;
105752Speter 	errcnt[cbn] = syneflg;
106834Speter 	parts[ cbn ] = NIL;
107752Speter 	dfiles[ cbn ] = FALSE;
108752Speter 	if (fp == NIL)
109752Speter 		return (NIL);
110752Speter 	/*
111752Speter 	 * Save the virtual name
112752Speter 	 * list stack pointer so
113752Speter 	 * the space can be freed
114752Speter 	 * later (funcend).
115752Speter 	 */
116752Speter 	fp->ptr[2] = nlp;
117752Speter 	if (fp->class != PROG) {
118752Speter 		for (q = fp->chain; q != NIL; q = q->chain) {
119*14729Sthien 			(void) enter(q);
1203825Speter #			ifdef PC
1213825Speter 			    q -> extra_flags |= NPARAM;
1223825Speter #			endif PC
123752Speter 		}
124752Speter 	}
125752Speter 	if (fp->class == FUNC) {
126752Speter 		/*
127752Speter 		 * For functions, enter the fvar
128752Speter 		 */
129*14729Sthien 		(void) enter(fp->ptr[NL_FVAR]);
130752Speter #		ifdef PC
131752Speter 		    q = fp -> ptr[ NL_FVAR ];
1323825Speter 		    if (q -> type != NIL ) {
13311334Speter 			sizes[cbn].curtmps.om_off = q -> value[NL_OFFS];
13411334Speter 			sizes[cbn].om_max = q -> value[NL_OFFS];
1353825Speter 		    }
136752Speter #		endif PC
137752Speter 	}
138752Speter #	ifdef PTREE
139752Speter 		/*
140752Speter 		 *	pick up the pointer to porf declaration
141752Speter 		 */
142752Speter 	    PorFHeader[ ++nesting ] = fp -> inTree;
143752Speter #	endif PTREE
144752Speter 	return (fp);
145752Speter }
146752Speter 
147752Speter /*
148752Speter  * Segend is called to check for
149752Speter  * unresolved variables, funcs and
150752Speter  * procs, and deliver unresolved and
151752Speter  * baduse error diagnostics at the
152752Speter  * end of a routine segment (a separately
153752Speter  * compiled segment that is not the
154752Speter  * main program) for PC. This
155752Speter  * routine should only be called
156752Speter  * by PC (not standard).
157752Speter  */
158752Speter  segend()
159752Speter  {
160*14729Sthien #ifdef PC
161752Speter 	register struct nl *p;
162752Speter 	register int i,b;
163752Speter 	char *cp;
164752Speter 
1657719Smckusick 	if ( monflg ) {
1667719Smckusick 	    error("Only the module containing the \"program\" statement");
1677719Smckusick 	    cerror("can be profiled with ``pxp''.\n");
1687719Smckusick 	}
169752Speter 	if (opt('s')) {
170752Speter 		standard();
171752Speter 		error("Separately compiled routine segments are not standard.");
172752Speter 	} else {
173752Speter 		b = cbn;
174752Speter 		for (i=0; i<077; i++) {
175752Speter 			for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
176752Speter 			switch (p->class) {
177752Speter 				case BADUSE:
178*14729Sthien 					cp = "s";
179*14729Sthien 					if (((struct udinfo *) (p->chain))->ud_next == NIL)
180752Speter 						cp++;
181752Speter 					eholdnl();
182752Speter 					if (p->value[NL_KINDS] & ISUNDEF)
183752Speter 						nerror("%s undefined on line%s", p->symbol, cp);
184752Speter 					else
185752Speter 						nerror("%s improperly used on line%s", p->symbol, cp);
186752Speter 					pnumcnt = 10;
187*14729Sthien 					pnums((struct udinfo *) (p->chain));
188752Speter 					pchr('\n');
189752Speter 					break;
190752Speter 
191752Speter 				case FUNC:
192752Speter 				case PROC:
1933825Speter 					if ((p->nl_flags & NFORWD) &&
1943825Speter 					    ((p->extra_flags & NEXTERN) == 0))
195752Speter 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
196752Speter 					break;
197752Speter 
198752Speter 				case FVAR:
1993825Speter 					if (((p->nl_flags & NMOD) == 0) &&
2003825Speter 					    ((p->chain->extra_flags & NEXTERN) == 0))
201752Speter 						nerror("No assignment to the function variable");
202752Speter 					break;
203752Speter 			    }
204752Speter 			   }
205752Speter 			   disptab[i] = p;
206752Speter 		    }
207752Speter 	}
208752Speter #endif PC
209752Speter #ifdef OBJ
210752Speter 	error("Missing program statement and program body");
211752Speter #endif OBJ
212752Speter 
213752Speter }
214752Speter 
215752Speter 
216752Speter /*
217752Speter  * Level1 does level one processing for
218752Speter  * separately compiled routine segments
219752Speter  */
220752Speter level1()
221752Speter {
222752Speter 
223752Speter #	ifdef OBJ
224752Speter 	    error("Missing program statement");
225752Speter #	endif OBJ
226752Speter #	ifdef PC
227752Speter 	    if (opt('s')) {
228752Speter 		    standard();
229752Speter 		    error("Missing program statement");
230752Speter 	    }
231752Speter #	endif PC
232752Speter 
233752Speter 	cbn++;
23411334Speter 	tmpinit(cbn);
235834Speter 	gotos[cbn] = NIL;
236834Speter 	errcnt[cbn] = syneflg;
237834Speter 	parts[ cbn ] = NIL;
238834Speter 	dfiles[ cbn ] = FALSE;
2393073Smckusic 	progseen = TRUE;
240752Speter }
241752Speter 
242752Speter 
243752Speter 
244752Speter pnums(p)
245752Speter 	struct udinfo *p;
246752Speter {
247752Speter 
248752Speter 	if (p->ud_next != NIL)
249752Speter 		pnums(p->ud_next);
250752Speter 	if (pnumcnt == 0) {
251752Speter 		printf("\n\t");
252752Speter 		pnumcnt = 20;
253752Speter 	}
254752Speter 	pnumcnt--;
255752Speter 	printf(" %d", p->ud_line);
256752Speter }
257752Speter 
258*14729Sthien /*VARARGS*/
259752Speter nerror(a1, a2, a3)
260*14729Sthien     char *a1,*a2,*a3;
261752Speter {
262752Speter 
263752Speter 	if (Fp != NIL) {
264752Speter 		yySsync();
265752Speter #ifndef PI1
266752Speter 		if (opt('l'))
267752Speter 			yyoutline();
268752Speter #endif
269752Speter 		yysetfile(filename);
270752Speter 		printf("In %s %s:\n", classes[Fp->class], Fp->symbol);
271752Speter 		Fp = NIL;
272752Speter 		elineoff();
273752Speter 	}
274752Speter 	error(a1, a2, a3);
275752Speter }
276