xref: /csrg-svn/usr.bin/pascal/src/fdec.c (revision 3222)
1752Speter /* Copyright (c) 1979 Regents of the University of California */
2752Speter 
3*3222Smckusic static char sccsid[] = "@(#)fdec.c 1.17 03/11/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) {
60752Speter 			fp->ext_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;
86752Speter 
87752Speter 	cbn++;
88752Speter 	if (cbn >= DSPLYSZ) {
89752Speter 		error("Too many levels of function/procedure nesting");
90752Speter 		pexit(ERRS);
91752Speter 	}
92*3222Smckusic 	sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1;
93752Speter 	gotos[cbn] = NIL;
94752Speter 	errcnt[cbn] = syneflg;
95834Speter 	parts[ cbn ] = NIL;
96752Speter 	dfiles[ cbn ] = FALSE;
97752Speter 	if (fp == NIL)
98752Speter 		return (NIL);
99752Speter 	/*
100752Speter 	 * Save the virtual name
101752Speter 	 * list stack pointer so
102752Speter 	 * the space can be freed
103752Speter 	 * later (funcend).
104752Speter 	 */
105752Speter 	fp->ptr[2] = nlp;
106752Speter 	if (fp->class != PROG) {
107752Speter 		for (q = fp->chain; q != NIL; q = q->chain) {
108752Speter 			enter(q);
109752Speter 		}
110752Speter 	}
111752Speter 	if (fp->class == FUNC) {
112752Speter 		/*
113752Speter 		 * For functions, enter the fvar
114752Speter 		 */
115752Speter 		enter(fp->ptr[NL_FVAR]);
116752Speter #		ifdef PC
117752Speter 		    q = fp -> ptr[ NL_FVAR ];
118*3222Smckusic 		    sizes[cbn].curtmps.om_off -= lwidth( q -> type );
119*3222Smckusic 		    sizes[cbn].om_max = sizes[cbn].curtmps.om_off;
120752Speter #		endif PC
121752Speter 	}
122752Speter #	ifdef PTREE
123752Speter 		/*
124752Speter 		 *	pick up the pointer to porf declaration
125752Speter 		 */
126752Speter 	    PorFHeader[ ++nesting ] = fp -> inTree;
127752Speter #	endif PTREE
128752Speter 	return (fp);
129752Speter }
130752Speter 
131752Speter /*
132752Speter  * Segend is called to check for
133752Speter  * unresolved variables, funcs and
134752Speter  * procs, and deliver unresolved and
135752Speter  * baduse error diagnostics at the
136752Speter  * end of a routine segment (a separately
137752Speter  * compiled segment that is not the
138752Speter  * main program) for PC. This
139752Speter  * routine should only be called
140752Speter  * by PC (not standard).
141752Speter  */
142752Speter  segend()
143752Speter  {
144752Speter 	register struct nl *p;
145752Speter 	register int i,b;
146752Speter 	char *cp;
147752Speter 
148752Speter #ifdef PC
149752Speter 	if (opt('s')) {
150752Speter 		standard();
151752Speter 		error("Separately compiled routine segments are not standard.");
152752Speter 	} else {
153752Speter 		b = cbn;
154752Speter 		for (i=0; i<077; i++) {
155752Speter 			for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
156752Speter 			switch (p->class) {
157752Speter 				case BADUSE:
158752Speter 					cp = 's';
159752Speter 					if (p->chain->ud_next == NIL)
160752Speter 						cp++;
161752Speter 					eholdnl();
162752Speter 					if (p->value[NL_KINDS] & ISUNDEF)
163752Speter 						nerror("%s undefined on line%s", p->symbol, cp);
164752Speter 					else
165752Speter 						nerror("%s improperly used on line%s", p->symbol, cp);
166752Speter 					pnumcnt = 10;
167752Speter 					pnums(p->chain);
168752Speter 					pchr('\n');
169752Speter 					break;
170752Speter 
171752Speter 				case FUNC:
172752Speter 				case PROC:
173752Speter 					if ((p->nl_flags & NFORWD) && ((p->ext_flags & NEXTERN) == 0))
174752Speter 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
175752Speter 					break;
176752Speter 
177752Speter 				case FVAR:
178752Speter 					if (((p->nl_flags & NMOD) == 0) && ((p->chain->ext_flags & NEXTERN) == 0))
179752Speter 						nerror("No assignment to the function variable");
180752Speter 					break;
181752Speter 			    }
182752Speter 			   }
183752Speter 			   disptab[i] = p;
184752Speter 		    }
185752Speter 	}
186752Speter #endif PC
187752Speter #ifdef OBJ
188752Speter 	error("Missing program statement and program body");
189752Speter #endif OBJ
190752Speter 
191752Speter }
192752Speter 
193752Speter 
194752Speter /*
195752Speter  * Level1 does level one processing for
196752Speter  * separately compiled routine segments
197752Speter  */
198752Speter level1()
199752Speter {
200752Speter 
201752Speter #	ifdef OBJ
202752Speter 	    error("Missing program statement");
203752Speter #	endif OBJ
204752Speter #	ifdef PC
205752Speter 	    if (opt('s')) {
206752Speter 		    standard();
207752Speter 		    error("Missing program statement");
208752Speter 	    }
209752Speter #	endif PC
210752Speter 
211752Speter 	cbn++;
212*3222Smckusic 	sizes[cbn].om_max = sizes[cbn].curtmps.om_off = -DPOFF1;
213834Speter 	gotos[cbn] = NIL;
214834Speter 	errcnt[cbn] = syneflg;
215834Speter 	parts[ cbn ] = NIL;
216834Speter 	dfiles[ cbn ] = FALSE;
2173073Smckusic 	progseen = TRUE;
218752Speter }
219752Speter 
220752Speter 
221752Speter 
222752Speter pnums(p)
223752Speter 	struct udinfo *p;
224752Speter {
225752Speter 
226752Speter 	if (p->ud_next != NIL)
227752Speter 		pnums(p->ud_next);
228752Speter 	if (pnumcnt == 0) {
229752Speter 		printf("\n\t");
230752Speter 		pnumcnt = 20;
231752Speter 	}
232752Speter 	pnumcnt--;
233752Speter 	printf(" %d", p->ud_line);
234752Speter }
235752Speter 
236752Speter nerror(a1, a2, a3)
237752Speter {
238752Speter 
239752Speter 	if (Fp != NIL) {
240752Speter 		yySsync();
241752Speter #ifndef PI1
242752Speter 		if (opt('l'))
243752Speter 			yyoutline();
244752Speter #endif
245752Speter 		yysetfile(filename);
246752Speter 		printf("In %s %s:\n", classes[Fp->class], Fp->symbol);
247752Speter 		Fp = NIL;
248752Speter 		elineoff();
249752Speter 	}
250752Speter 	error(a1, a2, a3);
251752Speter }
252