xref: /csrg-svn/usr.bin/pascal/src/fdec.c (revision 3073)
1752Speter /* Copyright (c) 1979 Regents of the University of California */
2752Speter 
3*3073Smckusic static	char sccsid[] = "@(#)fdec.c 1.13 1/24/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 /*
30752Speter  * Funchdr inserts
31752Speter  * declaration of a the
32752Speter  * prog/proc/func into the
33752Speter  * namelist. It also handles
34752Speter  * the arguments and puts out
35752Speter  * a transfer which defines
36752Speter  * the entry point of a procedure.
37752Speter  */
38752Speter 
39752Speter struct nl *
40752Speter funchdr(r)
41752Speter 	int *r;
42752Speter {
43752Speter 	register struct nl *p;
44752Speter 	register *il, **rl;
45752Speter 	int *rll;
46752Speter 	struct nl *cp, *dp, *sp;
47*3073Smckusic 	int w, s, o, *pp;
48752Speter 
49752Speter 	if (inpflist(r[2])) {
50752Speter 		opush('l');
51752Speter 		yyretrieve();	/* kludge */
52752Speter 	}
53752Speter 	pfcnt++;
54834Speter 	parts[ cbn ] |= RPRT;
55752Speter 	line = r[1];
56752Speter 	if (r[3] == NIL && (p=lookup1(r[2])) != NIL && bn == cbn) {
57752Speter 		/*
58752Speter 		 * Symbol already defined
59752Speter 		 * in this block. it is either
60752Speter 		 * a redeclared symbol (error)
61752Speter 		 * a forward declaration,
62752Speter 		 * or an external declaration.
63752Speter 		 */
64752Speter 		if ((p->class == FUNC || p->class == PROC) && (p->nl_flags & NFORWD) != 0) {
65752Speter 			/*
66752Speter 			 * Grammar doesnt forbid
67752Speter 			 * types on a resolution
68752Speter 			 * of a forward function
69752Speter 			 * declaration.
70752Speter 			 */
71752Speter 			if (p->class == FUNC && r[4])
72752Speter 				error("Function type should be given only in forward declaration");
73752Speter 			/*
74752Speter 			 * get another counter for the actual
75752Speter 			 */
76752Speter 			if ( monflg ) {
77752Speter 			    bodycnts[ cbn ] = getcnt();
78752Speter 			}
79752Speter #			ifdef PC
80752Speter 			    enclosing[ cbn ] = p -> symbol;
81752Speter #			endif PC
82752Speter #			ifdef PTREE
83752Speter 				/*
84752Speter 				 *	mark this proc/func as forward
85752Speter 				 *	in the pTree.
86752Speter 				 */
87752Speter 			    pDEF( p -> inTree ).PorFForward = TRUE;
88752Speter #			endif PTREE
89752Speter 			return (p);
90752Speter 		}
91752Speter 	}
92752Speter 
93752Speter 	/* if a routine segment is being compiled,
94752Speter 	 * do level one processing.
95752Speter 	 */
96752Speter 
97752Speter 	 if ((r[0] != T_PROG) && (!progseen))
98752Speter 		level1();
99752Speter 
100752Speter 
101752Speter 	/*
102752Speter 	 * Declare the prog/proc/func
103752Speter 	 */
104752Speter 	switch (r[0]) {
105752Speter 	    case T_PROG:
106*3073Smckusic 		    progseen = TRUE;
107752Speter 		    if (opt('z'))
108*3073Smckusic 			    monflg = TRUE;
109752Speter 		    program = p = defnl(r[2], PROG, 0, 0);
110752Speter 		    p->value[3] = r[1];
111752Speter 		    break;
112752Speter 	    case T_PDEC:
113752Speter 		    if (r[4] != NIL)
114752Speter 			    error("Procedures do not have types, only functions do");
115752Speter 		    p = enter(defnl(r[2], PROC, 0, 0));
116752Speter 		    p->nl_flags |= NMOD;
117752Speter #		    ifdef PC
118752Speter 			enclosing[ cbn ] = r[2];
119752Speter #		    endif PC
120752Speter 		    break;
121752Speter 	    case T_FDEC:
122752Speter 		    il = r[4];
123752Speter 		    if (il == NIL)
124752Speter 			    error("Function type must be specified");
125752Speter 		    else if (il[0] != T_TYID) {
126752Speter 			    il = NIL;
127752Speter 			    error("Function type can be specified only by using a type identifier");
128752Speter 		    } else
129752Speter 			    il = gtype(il);
130752Speter 		    p = enter(defnl(r[2], FUNC, il, NIL));
131752Speter 		    p->nl_flags |= NMOD;
132752Speter 		    /*
133752Speter 		     * An arbitrary restriction
134752Speter 		     */
135752Speter 		    switch (o = classify(p->type)) {
136752Speter 			    case TFILE:
137752Speter 			    case TARY:
138752Speter 			    case TREC:
139752Speter 			    case TSET:
140752Speter 			    case TSTR:
1411626Speter 				    warning();
1421196Speter 				    if (opt('s')) {
143752Speter 					    standard();
1441196Speter 				    }
1451626Speter 				    error("Functions should not return %ss", clnames[o]);
146752Speter 		    }
147752Speter #		    ifdef PC
148752Speter 			enclosing[ cbn ] = r[2];
149752Speter #		    endif PC
150752Speter 		    break;
151752Speter 	    default:
152752Speter 		    panic("funchdr");
153752Speter 	}
154752Speter 	if (r[0] != T_PROG) {
155752Speter 		/*
156752Speter 		 * Mark this proc/func as
157752Speter 		 * being forward declared
158752Speter 		 */
159752Speter 		p->nl_flags |= NFORWD;
160752Speter 		/*
161752Speter 		 * Enter the parameters
162752Speter 		 * in the next block for
163752Speter 		 * the time being
164752Speter 		 */
165752Speter 		if (++cbn >= DSPLYSZ) {
166752Speter 			error("Procedure/function nesting too deep");
167752Speter 			pexit(ERRS);
168752Speter 		}
169752Speter 		/*
170752Speter 		 * For functions, the function variable
171752Speter 		 */
172752Speter 		if (p->class == FUNC) {
173752Speter #			ifdef OBJ
174752Speter 			    cp = defnl(r[2], FVAR, p->type, 0);
175752Speter #			endif OBJ
176752Speter #			ifdef PC
177752Speter 				/*
178752Speter 				 * fvars used to be allocated and deallocated
179752Speter 				 * by the caller right before the arguments.
180752Speter 				 * the offset of the fvar was kept in
181752Speter 				 * value[NL_OFFS] of function (very wierd,
182752Speter 				 * but see asgnop).
183752Speter 				 * now, they are locals to the function
184752Speter 				 * with the offset kept in the fvar.
185752Speter 				 */
186752Speter 
187*3073Smckusic 			    cp = defnl(r[2], FVAR, p->type,
188*3073Smckusic 				    -(roundup((int)(DPOFF1+lwidth(p->type)),
189*3073Smckusic 					(long)align(p->type))));
190752Speter #			endif PC
191752Speter 			cp->chain = p;
192752Speter 			p->ptr[NL_FVAR] = cp;
193752Speter 		}
194752Speter 		/*
195752Speter 		 * Enter the parameters
196752Speter 		 * and compute total size
197752Speter 		 */
198752Speter 		cp = sp = p;
199752Speter 
200752Speter #		ifdef OBJ
201752Speter 		    o = 0;
202752Speter #		endif OBJ
203752Speter #		ifdef PC
204752Speter 			/*
205752Speter 			 * parameters used to be allocated backwards,
206752Speter 			 * then fixed.  for pc, they are allocated correctly.
207752Speter 			 * also, they are aligned.
208752Speter 			 */
209752Speter 		o = DPOFF2;
210752Speter #		endif PC
211752Speter 		for (rl = r[3]; rl != NIL; rl = rl[2]) {
212752Speter 			p = NIL;
213752Speter 			if (rl[1] == NIL)
214752Speter 				continue;
215752Speter 			/*
216752Speter 			 * Parametric procedures
217752Speter 			 * don't have types !?!
218752Speter 			 */
219752Speter 			if (rl[1][0] != T_PPROC) {
220752Speter 				rll = rl[1][2];
221752Speter 				if (rll[0] != T_TYID) {
222752Speter 					error("Types for arguments can be specified only by using type identifiers");
223752Speter 					p = NIL;
224752Speter 				} else
225752Speter 					p = gtype(rll);
226752Speter 			}
227752Speter 			for (il = rl[1][1]; il != NIL; il = il[2]) {
228752Speter 				switch (rl[1][0]) {
229752Speter 				    default:
230752Speter 					    panic("funchdr2");
231752Speter 				    case T_PVAL:
232752Speter 					    if (p != NIL) {
233752Speter 						    if (p->class == FILET)
234752Speter 							    error("Files cannot be passed by value");
235752Speter 						    else if (p->nl_flags & NFILES)
236752Speter 							    error("Files cannot be a component of %ss passed by value",
237752Speter 								    nameof(p));
238752Speter 					    }
239752Speter #					    ifdef OBJ
240*3073Smckusic 						w = width(p);
241*3073Smckusic 						o -= even(w);
242*3073Smckusic #						ifdef DEC11
243*3073Smckusic 						    dp = defnl(il[1], VAR, p, o);
244*3073Smckusic #						else
245*3073Smckusic 						    dp = defnl(il[1], VAR, p,
246*3073Smckusic 							(w < 2) ? o + 1 : o);
247*3073Smckusic #						endif DEC11
248752Speter #					    endif OBJ
249752Speter #					    ifdef PC
250752Speter 						dp = defnl( il[1] , VAR , p
251*3073Smckusic 							, o = roundup( o , (long)A_STACK ) );
252752Speter 						o += width( p );
253752Speter #					    endif PC
254752Speter 					    dp->nl_flags |= NMOD;
255752Speter 					    break;
256752Speter 				    case T_PVAR:
257752Speter #					    ifdef OBJ
258752Speter 						dp = defnl(il[1], REF, p, o -= sizeof ( int * ) );
259752Speter #					    endif OBJ
260752Speter #					    ifdef PC
261752Speter 						dp = defnl( il[1] , REF , p
262*3073Smckusic 							, o = roundup( o , (long)A_STACK ) );
263752Speter 						o += sizeof(char *);
264752Speter #					    endif PC
265752Speter 					    break;
266752Speter 				    case T_PFUNC:
2671196Speter #					    ifdef OBJ
2681196Speter 						dp = defnl(il[1], FFUNC, p, o -= sizeof ( int * ) );
2691196Speter #					    endif OBJ
2701196Speter #					    ifdef PC
2711196Speter 						dp = defnl( il[1] , FFUNC , p
272*3073Smckusic 							, o = roundup( o , (long)A_STACK ) );
2731196Speter 						o += sizeof(char *);
2741196Speter #					    endif PC
2751196Speter 					    dp -> nl_flags |= NMOD;
2761196Speter 					    break;
277752Speter 				    case T_PPROC:
2781196Speter #					    ifdef OBJ
2791196Speter 						dp = defnl(il[1], FPROC, p, o -= sizeof ( int * ) );
2801196Speter #					    endif OBJ
2811196Speter #					    ifdef PC
2821196Speter 						dp = defnl( il[1] , FPROC , p
283*3073Smckusic 							, o = roundup( o , (long)A_STACK ) );
2841196Speter 						o += sizeof(char *);
2851196Speter #					    endif PC
2861196Speter 					    dp -> nl_flags |= NMOD;
2871196Speter 					    break;
288752Speter 				    }
289752Speter 				if (dp != NIL) {
290752Speter 					cp->chain = dp;
291752Speter 					cp = dp;
292752Speter 				}
293752Speter 			}
294752Speter 		}
295752Speter 		cbn--;
296752Speter 		p = sp;
297752Speter #		ifdef OBJ
298752Speter 		    p->value[NL_OFFS] = -o+DPOFF2;
299752Speter 			/*
300752Speter 			 * Correct the naivete (naievity)
301752Speter 			 * of our above code to
302752Speter 			 * calculate offsets
303752Speter 			 */
304752Speter 		    for (il = p->chain; il != NIL; il = il->chain)
305752Speter 			    il->value[NL_OFFS] += p->value[NL_OFFS];
306752Speter #		endif OBJ
307752Speter #		ifdef PC
308*3073Smckusic 		    p -> value[ NL_OFFS ] = roundup( o , (long)A_STACK );
309752Speter #		endif PC
310752Speter 	} else {
311752Speter 		/*
312752Speter 		 * The wonderful
313752Speter 		 * program statement!
314752Speter 		 */
315752Speter #		ifdef OBJ
316752Speter 		    if (monflg) {
317752Speter 			    put(1, O_PXPBUF);
318*3073Smckusic 			    cntpatch = put(2, O_CASE4, (long)0);
319*3073Smckusic 			    nfppatch = put(2, O_CASE4, (long)0);
320752Speter 		    }
321752Speter #		endif OBJ
322752Speter 		cp = p;
323752Speter 		for (rl = r[3]; rl; rl = rl[2]) {
324752Speter 			if (rl[1] == NIL)
325752Speter 				continue;
326752Speter 			dp = defnl(rl[1], VAR, 0, 0);
327752Speter 			cp->chain = dp;
328752Speter 			cp = dp;
329752Speter 		}
330752Speter 	}
331752Speter 	/*
332752Speter 	 * Define a branch at
333752Speter 	 * the "entry point" of
334752Speter 	 * the prog/proc/func.
335752Speter 	 */
336752Speter 	p->entloc = getlab();
337752Speter 	if (monflg) {
338752Speter 		bodycnts[ cbn ] = getcnt();
339752Speter 		p->value[ NL_CNTR ] = 0;
340752Speter 	}
341752Speter #	ifdef OBJ
342*3073Smckusic 	    put(2, O_TRA4, (long)p->entloc);
343752Speter #	endif OBJ
344752Speter #	ifdef PTREE
345752Speter 	    {
346752Speter 		pPointer	PF = tCopy( r );
347752Speter 
348752Speter 		pSeize( PorFHeader[ nesting ] );
349752Speter 		if ( r[0] != T_PROG ) {
350752Speter 			pPointer	*PFs;
351752Speter 
352752Speter 			PFs = &( pDEF( PorFHeader[ nesting ] ).PorFPFs );
353752Speter 			*PFs = ListAppend( *PFs , PF );
354752Speter 		} else {
355752Speter 			pDEF( PorFHeader[ nesting ] ).GlobProg = PF;
356752Speter 		}
357752Speter 		pRelease( PorFHeader[ nesting ] );
358752Speter 	    }
359752Speter #	endif PTREE
360752Speter 	return (p);
361752Speter }
362752Speter 
363752Speter funcfwd(fp)
364752Speter 	struct nl *fp;
365752Speter {
366752Speter 
367752Speter 	    /*
368752Speter 	     *	save the counter for this function
369752Speter 	     */
370752Speter 	if ( monflg ) {
371752Speter 	    fp -> value[ NL_CNTR ] = bodycnts[ cbn ];
372752Speter 	}
373752Speter 	return (fp);
374752Speter }
375752Speter 
376752Speter /*
377752Speter  * Funcext marks the procedure or
378752Speter  * function external in the symbol
379752Speter  * table. Funcext should only be
380752Speter  * called if PC, and is an error
381752Speter  * otherwise.
382752Speter  */
383752Speter 
384752Speter funcext(fp)
385752Speter 	struct nl *fp;
386752Speter {
387752Speter 
388752Speter #ifdef PC
389752Speter  	if (opt('s')) {
390752Speter 		standard();
391752Speter 		error("External procedures and functions are not standard");
392752Speter 	} else {
393752Speter 		if (cbn == 1) {
394752Speter 			fp->ext_flags |= NEXTERN;
395825Speter 			stabefunc( fp -> symbol , fp -> class , line );
396752Speter 		}
397752Speter 		else
398752Speter 			error("External procedures and functions can only be declared at the outermost level.");
399752Speter 	}
400752Speter #endif PC
401752Speter #ifdef OBJ
402752Speter 	error("Procedures or functions cannot be declared external.");
403752Speter #endif OBJ
404752Speter 
405752Speter 	return(fp);
406752Speter }
407752Speter 
408752Speter /*
409752Speter  * Funcbody is called
410752Speter  * when the actual (resolved)
411752Speter  * declaration of a procedure is
412752Speter  * encountered. It puts the names
413752Speter  * of the (function) and parameters
414752Speter  * into the symbol table.
415752Speter  */
416752Speter funcbody(fp)
417752Speter 	struct nl *fp;
418752Speter {
419752Speter 	register struct nl *q, *p;
420752Speter 
421752Speter 	cbn++;
422752Speter 	if (cbn >= DSPLYSZ) {
423752Speter 		error("Too many levels of function/procedure nesting");
424752Speter 		pexit(ERRS);
425752Speter 	}
426752Speter 	sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1;
427752Speter 	gotos[cbn] = NIL;
428752Speter 	errcnt[cbn] = syneflg;
429834Speter 	parts[ cbn ] = NIL;
430752Speter 	dfiles[ cbn ] = FALSE;
431752Speter 	if (fp == NIL)
432752Speter 		return (NIL);
433752Speter 	/*
434752Speter 	 * Save the virtual name
435752Speter 	 * list stack pointer so
436752Speter 	 * the space can be freed
437752Speter 	 * later (funcend).
438752Speter 	 */
439752Speter 	fp->ptr[2] = nlp;
440752Speter 	if (fp->class != PROG) {
441752Speter 		for (q = fp->chain; q != NIL; q = q->chain) {
442752Speter 			enter(q);
443752Speter 		}
444752Speter 	}
445752Speter 	if (fp->class == FUNC) {
446752Speter 		/*
447752Speter 		 * For functions, enter the fvar
448752Speter 		 */
449752Speter 		enter(fp->ptr[NL_FVAR]);
450752Speter #		ifdef PC
451752Speter 		    q = fp -> ptr[ NL_FVAR ];
452752Speter 		    sizes[cbn].om_off -= lwidth( q -> type );
453752Speter 		    sizes[cbn].om_max = sizes[cbn].om_off;
454752Speter #		endif PC
455752Speter 	}
456752Speter #	ifdef PTREE
457752Speter 		/*
458752Speter 		 *	pick up the pointer to porf declaration
459752Speter 		 */
460752Speter 	    PorFHeader[ ++nesting ] = fp -> inTree;
461752Speter #	endif PTREE
462752Speter 	return (fp);
463752Speter }
464752Speter 
465752Speter struct	nl *Fp;
466752Speter int	pnumcnt;
467752Speter /*
468752Speter  * Funcend is called to
469752Speter  * finish a block by generating
470752Speter  * the code for the statements.
471752Speter  * It then looks for unresolved declarations
472752Speter  * of labels, procedures and functions,
473752Speter  * and cleans up the name list.
474752Speter  * For the program, it checks the
475752Speter  * semantics of the program
476752Speter  * statement (yuchh).
477752Speter  */
478752Speter funcend(fp, bundle, endline)
479752Speter 	struct nl *fp;
480752Speter 	int *bundle;
481752Speter 	int endline;
482752Speter {
483752Speter 	register struct nl *p;
484752Speter 	register int i, b;
485*3073Smckusic 	int var, inp, out, *blk;
486*3073Smckusic 	bool chkref;
487752Speter 	struct nl *iop;
488752Speter 	char *cp;
489752Speter 	extern int cntstat;
490752Speter #	ifdef PC
491752Speter 	    int	toplabel = getlab();
492752Speter 	    int	botlabel = getlab();
493752Speter #	endif PC
494752Speter 
495752Speter 	cntstat = 0;
496752Speter /*
497752Speter  *	yyoutline();
498752Speter  */
499752Speter 	if (program != NIL)
500752Speter 		line = program->value[3];
501752Speter 	blk = bundle[2];
502752Speter 	if (fp == NIL) {
503752Speter 		cbn--;
504752Speter #		ifdef PTREE
505752Speter 		    nesting--;
506752Speter #		endif PTREE
507752Speter 		return;
508752Speter 	}
509752Speter #ifdef OBJ
510752Speter 	/*
511752Speter 	 * Patch the branch to the
512752Speter 	 * entry point of the function
513752Speter 	 */
514752Speter 	patch4(fp->entloc);
515752Speter 	/*
516752Speter 	 * Put out the block entrance code and the block name.
5172220Smckusic 	 * HDRSZE is the number of bytes of info in the static
5182220Smckusic 	 * BEG data area exclusive of the proc name. It is
5192220Smckusic 	 * currently defined as:
5202220Smckusic 	/*	struct hdr {
5212220Smckusic 	/*		long framesze;	/* number of bytes of local vars */
5222220Smckusic 	/*		long nargs;	/* number of bytes of arguments */
523*3073Smckusic 	/*		bool tests;	/* TRUE => perform runtime tests */
5242220Smckusic 	/*		short offset;	/* offset of procedure in source file */
5252220Smckusic 	/*		char name[1];	/* name of active procedure */
5262220Smckusic 	/*	};
527752Speter 	 */
528*3073Smckusic #	define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool))
529*3073Smckusic 	var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8)
530*3073Smckusic 		| (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0);
5311196Speter 	    /*
5321196Speter 	     *  output the number of bytes of arguments
5331196Speter 	     *  this is only checked on formal calls.
5341196Speter 	     */
535*3073Smckusic 	put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2));
5362190Smckusic 	    /*
5372190Smckusic 	     *	Output the runtime test mode for the routine
5382190Smckusic 	     */
539*3073Smckusic 	put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE);
5402190Smckusic 	    /*
5412190Smckusic 	     *	Output line number and routine name
5422190Smckusic 	     */
543752Speter 	put(2, O_CASE2, bundle[1]);
544752Speter 	putstr(fp->symbol, 0);
545752Speter #endif OBJ
546752Speter #ifdef PC
547752Speter 	/*
548752Speter 	 * put out the procedure entry code
549752Speter 	 */
550752Speter 	if ( fp -> class == PROG ) {
551752Speter 	    putprintf( "	.text" , 0 );
552752Speter 	    putprintf( "	.align	1" , 0 );
553752Speter 	    putprintf( "	.globl	_main" , 0 );
554752Speter 	    putprintf( "_main:" , 0 );
555752Speter 	    putprintf( "	.word	0" , 0 );
556752Speter 	    putprintf( "	calls	$0,_PCSTART" , 0 );
557752Speter 	    putprintf( "	movl	4(ap),__argc" , 0 );
558752Speter 	    putprintf( "	movl	8(ap),__argv" , 0 );
559752Speter 	    putprintf( "	calls	$0,_program" , 0 );
560752Speter 	    putprintf( "	calls	$0,_PCEXIT" , 0 );
561752Speter 	    ftnno = fp -> entloc;
562752Speter 	    putprintf( "	.text" , 0 );
563752Speter 	    putprintf( "	.align	1" , 0 );
564752Speter 	    putprintf( "	.globl	_program" , 0 );
565752Speter 	    putprintf( "_program:" , 0 );
5662163Speter 	    stabfunc( "program" , fp -> class , bundle[1] , 0 );
567752Speter 	} else {
568752Speter 	    ftnno = fp -> entloc;
569752Speter 	    putprintf( "	.text" , 0 );
570752Speter 	    putprintf( "	.align	1" , 0 );
571752Speter 	    putprintf( "	.globl	" , 1 );
572752Speter 	    for ( i = 1 ; i < cbn ; i++ ) {
573752Speter 		putprintf( EXTFORMAT , 1 , enclosing[ i ] );
574752Speter 	    }
575752Speter 	    putprintf( "" , 0 );
576752Speter 	    for ( i = 1 ; i < cbn ; i++ ) {
577752Speter 		putprintf( EXTFORMAT , 1 , enclosing[ i ] );
578752Speter 	    }
579752Speter 	    putprintf( ":" , 0 );
5802163Speter 	    stabfunc( fp -> symbol , fp -> class , bundle[1] , cbn - 1 );
5812163Speter 	    for ( p = fp -> chain ; p != NIL ; p = p -> chain ) {
5822163Speter 		stabparam( p -> symbol , p2type( p -> type )
5832163Speter 			    , p -> value[ NL_OFFS ] , lwidth( p -> type ) );
5842163Speter 	    }
5852163Speter 	    if ( fp -> class == FUNC ) {
5862163Speter 		    /*
5872163Speter 		     *	stab the function variable
5882163Speter 		     */
5892163Speter 		p = fp -> ptr[ NL_FVAR ];
5902163Speter 		stablvar( p -> symbol , p2type( p -> type ) , cbn
5912163Speter 			, p -> value[ NL_OFFS ] , lwidth( p -> type ) );
5922163Speter 	    }
5932163Speter 		/*
5942163Speter 		 *	stab local variables
5952163Speter 		 *	rummage down hash chain links.
5962163Speter 		 */
5972163Speter 	    for ( i = 0 ; i <= 077 ; i++ ) {
5982163Speter 		for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) {
5992163Speter 		    if ( ( p -> nl_block & 037 ) != cbn ) {
6002163Speter 			break;
6012163Speter 		    }
6022163Speter 		    /*
6032163Speter 		     *	stab local variables
6042163Speter 		     *	that's named variables, but not params
6052163Speter 		     */
6062163Speter 		    if (   ( p -> symbol != NIL )
6072163Speter 			&& ( p -> class == VAR )
6082163Speter 			&& ( p -> value[ NL_OFFS ] < 0 ) ) {
6092163Speter 			stablvar( p -> symbol , p2type( p -> type ) , cbn
6102163Speter 			    , p -> value[ NL_OFFS ] , lwidth( p -> type ) );
6112163Speter 		    }
6122163Speter 		}
6132163Speter 	    }
614752Speter 	}
615752Speter 	stablbrac( cbn );
616752Speter 	    /*
617752Speter 	     *	register save mask
618752Speter 	     */
619752Speter 	if ( opt( 't' ) ) {
620752Speter 	    putprintf( "	.word	0x%x" , 0 , RUNCHECK | RSAVEMASK );
621752Speter 	} else {
622752Speter 	    putprintf( "	.word	0x%x" , 0 , RSAVEMASK );
623752Speter 	}
624752Speter 	putjbr( botlabel );
625752Speter 	putlab( toplabel );
626752Speter 	if ( profflag ) {
627752Speter 		/*
628752Speter 		 *	call mcount for profiling
629752Speter 		 */
630752Speter 	    putprintf( "	moval	1f,r0" , 0 );
631752Speter 	    putprintf( "	jsb	mcount" , 0 );
632752Speter 	    putprintf( "	.data" , 0 );
633752Speter 	    putprintf( "	.align	2" , 0 );
634752Speter 	    putprintf( "1:" , 0 );
635752Speter 	    putprintf( "	.long	0" , 0 );
636752Speter 	    putprintf( "	.text" , 0 );
637752Speter 	}
638752Speter 	    /*
639752Speter 	     *	set up unwind exception vector.
640752Speter 	     */
641752Speter 	putprintf( "	moval	%s,%d(%s)" , 0
642752Speter 		, UNWINDNAME , UNWINDOFFSET , P2FPNAME );
643752Speter 	    /*
644752Speter 	     *	save address of display entry, for unwind.
645752Speter 	     */
646752Speter 	putprintf( "	moval	%s+%d,%d(%s)" , 0
647752Speter 		, DISPLAYNAME , cbn * sizeof(struct dispsave)
648752Speter 		, DPTROFFSET , P2FPNAME );
649752Speter 	    /*
650752Speter 	     *	save old display
651752Speter 	     */
652752Speter 	putprintf( "	movq	%s+%d,%d(%s)" , 0
653752Speter 		, DISPLAYNAME , cbn * sizeof(struct dispsave)
654752Speter 		, DSAVEOFFSET , P2FPNAME );
655752Speter 	    /*
656752Speter 	     *	set up new display by saving AP and FP in appropriate
657752Speter 	     *	slot in display structure.
658752Speter 	     */
659752Speter 	putprintf( "	movq	%s,%s+%d" , 0
660752Speter 		, P2APNAME , DISPLAYNAME , cbn * sizeof(struct dispsave) );
661752Speter 	    /*
662752Speter 	     *	ask second pass to allocate known locals
663752Speter 	     */
664752Speter 	putlbracket( ftnno , -sizes[ cbn ].om_max );
665752Speter 	    /*
666752Speter 	     *	and zero them if checking is on
6672125Smckusic 	     *	by calling blkclr( bytes of locals , starting local address );
668752Speter 	     */
6691196Speter 	if ( opt( 't' ) ) {
6701196Speter 	    if ( ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
6711196Speter 		putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
6722125Smckusic 			, "_blkclr" );
6731196Speter 		putleaf( P2ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
6741196Speter 			, 0 , P2INT , 0 );
6751196Speter 		putLV( 0 , cbn , sizes[ cbn ].om_max , P2CHAR );
6761196Speter 		putop( P2LISTOP , P2INT );
6771196Speter 		putop( P2CALL , P2INT );
6781196Speter 		putdot( filename , line );
6791196Speter 	    }
6801196Speter 		/*
6811196Speter 		 *  check number of longs of arguments
6821196Speter 		 *  this can only be wrong for formal calls.
6831196Speter 		 */
6841196Speter 	    if ( fp -> class != PROG ) {
6851196Speter 		    putleaf( P2ICON , 0 , 0 , ADDTYPE( P2PTR , P2FTN | P2INT ) ,
6861196Speter 			    "_NARGCHK" );
6871196Speter 		    putleaf( P2ICON ,
6881196Speter 			(fp->value[NL_OFFS] - DPOFF2) / sizeof(long) ,
6891196Speter 			0 , P2INT , 0 );
6901196Speter 		    putop( P2CALL , P2INT );
6911196Speter 		    putdot( filename , line );
6921196Speter 	    }
693752Speter 	}
694752Speter #endif PC
695752Speter 	if ( monflg ) {
696752Speter 		if ( fp -> value[ NL_CNTR ] != 0 ) {
697752Speter 			inccnt( fp -> value [ NL_CNTR ] );
698752Speter 		}
699752Speter 		inccnt( bodycnts[ fp -> nl_block & 037 ] );
700752Speter 	}
701752Speter 	if (fp->class == PROG) {
702752Speter 		/*
703752Speter 		 * The glorious buffers option.
704752Speter 		 *          0 = don't buffer output
705752Speter 		 *          1 = line buffer output
706752Speter 		 *          2 = 512 byte buffer output
707752Speter 		 */
708752Speter #		ifdef OBJ
709752Speter 		    if (opt('b') != 1)
710752Speter 			    put(1, O_BUFF | opt('b') << 8);
711752Speter #		endif OBJ
712752Speter #		ifdef PC
713752Speter 		    if ( opt( 'b' ) != 1 ) {
714752Speter 			putleaf( P2ICON , 0 , 0
715752Speter 				, ADDTYPE( P2FTN | P2INT , P2PTR ) , "_BUFF" );
716752Speter 			putleaf( P2ICON , opt( 'b' ) , 0 , P2INT , 0 );
717752Speter 			putop( P2CALL , P2INT );
718752Speter 			putdot( filename , line );
719752Speter 		    }
720752Speter #		endif PC
721752Speter 		out = 0;
722752Speter 		for (p = fp->chain; p != NIL; p = p->chain) {
723752Speter 			if (strcmp(p->symbol, "input") == 0) {
724752Speter 				inp++;
725752Speter 				continue;
726752Speter 			}
727752Speter 			if (strcmp(p->symbol, "output") == 0) {
728752Speter 				out++;
729752Speter 				continue;
730752Speter 			}
731752Speter 			iop = lookup1(p->symbol);
732752Speter 			if (iop == NIL || bn != cbn) {
733752Speter 				error("File %s listed in program statement but not declared", p->symbol);
734752Speter 				continue;
735752Speter 			}
736752Speter 			if (iop->class != VAR) {
737752Speter 				error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
738752Speter 				continue;
739752Speter 			}
740752Speter 			if (iop->type == NIL)
741752Speter 				continue;
742752Speter 			if (iop->type->class != FILET) {
743752Speter 				error("File %s listed in program statement but defined as %s",
744752Speter 					p->symbol, nameof(iop->type));
745752Speter 				continue;
746752Speter 			}
747752Speter #			ifdef OBJ
7482068Smckusic 			    put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
749752Speter 			    i = lenstr(p->symbol,0);
7502068Smckusic 			    put(2, O_CON24, i);
751752Speter 			    put(2, O_LVCON, i);
752752Speter 			    putstr(p->symbol, 0);
753*3073Smckusic 			    put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]);
754752Speter 			    put(1, O_DEFNAME);
755752Speter #			endif OBJ
756752Speter #			ifdef PC
757752Speter 			    putleaf( P2ICON , 0 , 0
758752Speter 				    , ADDTYPE( P2FTN | P2INT , P2PTR )
759752Speter 				    , "_DEFNAME" );
760752Speter 			    putLV( p -> symbol , bn , iop -> value[NL_OFFS]
761752Speter 				    , p2type( iop ) );
762752Speter 			    putCONG( p -> symbol , strlen( p -> symbol )
763752Speter 				    , LREQ );
764752Speter 			    putop( P2LISTOP , P2INT );
765752Speter 			    putleaf( P2ICON , strlen( p -> symbol )
766752Speter 				    , 0 , P2INT , 0 );
767752Speter 			    putop( P2LISTOP , P2INT );
768752Speter 			    putleaf( P2ICON
769752Speter 				, text(iop->type) ? 0 : width(iop->type->type)
770752Speter 				, 0 , P2INT , 0 );
771752Speter 			    putop( P2LISTOP , P2INT );
772752Speter 			    putop( P2CALL , P2INT );
773752Speter 			    putdot( filename , line );
774752Speter #			endif PC
775752Speter 		}
776752Speter 		if (out == 0 && fp->chain != NIL) {
777752Speter 			recovered();
778752Speter 			error("The file output must appear in the program statement file list");
779752Speter 		}
780752Speter 	}
781752Speter 	/*
782752Speter 	 * Process the prog/proc/func body
783752Speter 	 */
784752Speter 	noreach = 0;
785752Speter 	line = bundle[1];
786752Speter 	statlist(blk);
787752Speter #	ifdef PTREE
788752Speter 	    {
789752Speter 		pPointer Body = tCopy( blk );
790752Speter 
791752Speter 		pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
792752Speter 	    }
793752Speter #	endif PTREE
794752Speter #	ifdef OBJ
795752Speter 	    if (cbn== 1 && monflg != 0) {
796*3073Smckusic 		    patchfil(cntpatch - 2, (long)cnts, 2);
797*3073Smckusic 		    patchfil(nfppatch - 2, (long)pfcnt, 2);
798752Speter 	    }
799752Speter #	endif OBJ
800752Speter #	ifdef PC
801752Speter 	    if ( fp -> class == PROG && monflg ) {
802752Speter 		putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
803752Speter 			, "_PMFLUSH" );
804752Speter 		putleaf( P2ICON , cnts , 0 , P2INT , 0 );
805752Speter 		putleaf( P2ICON , pfcnt , 0 , P2INT , 0 );
806752Speter 		putop( P2LISTOP , P2INT );
8072068Smckusic 		putLV( PCPCOUNT , 0 , 0 , P2INT );
8082068Smckusic 		putop( P2LISTOP , P2INT );
809752Speter 		putop( P2CALL , P2INT );
810752Speter 		putdot( filename , line );
811752Speter 	    }
812752Speter #	endif PC
813752Speter 	if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
814752Speter 		recovered();
815752Speter 		error("Input is used but not defined in the program statement");
816752Speter 	}
817752Speter 	/*
818752Speter 	 * Clean up the symbol table displays and check for unresolves
819752Speter 	 */
820752Speter 	line = endline;
821752Speter 	b = cbn;
822752Speter 	Fp = fp;
823752Speter 	chkref = syneflg == errcnt[cbn] && opt('w') == 0;
824752Speter 	for (i = 0; i <= 077; i++) {
825752Speter 		for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
826752Speter 			/*
827752Speter 			 * Check for variables defined
828752Speter 			 * but not referenced
829752Speter 			 */
830752Speter 			if (chkref && p->symbol != NIL)
831752Speter 			switch (p->class) {
832752Speter 				case FIELD:
833752Speter 					/*
834752Speter 					 * If the corresponding record is
835752Speter 					 * unused, we shouldn't complain about
836752Speter 					 * the fields.
837752Speter 					 */
838752Speter 				default:
839752Speter 					if ((p->nl_flags & (NUSED|NMOD)) == 0) {
840752Speter 						warning();
841752Speter 						nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
842752Speter 						break;
843752Speter 					}
844752Speter 					/*
845752Speter 					 * If a var parameter is either
846752Speter 					 * modified or used that is enough.
847752Speter 					 */
848752Speter 					if (p->class == REF)
849752Speter 						continue;
850752Speter #					ifdef OBJ
851752Speter 					    if ((p->nl_flags & NUSED) == 0) {
852752Speter 						warning();
853752Speter 						nerror("%s %s is never used", classes[p->class], p->symbol);
854752Speter 						break;
855752Speter 					    }
856752Speter #					endif OBJ
857752Speter #					ifdef PC
858752Speter 					    if (((p->nl_flags & NUSED) == 0) && ((p->ext_flags & NEXTERN) == 0)) {
859752Speter 						warning();
860752Speter 						nerror("%s %s is never used", classes[p->class], p->symbol);
861752Speter 						break;
862752Speter 					    }
863752Speter #					endif PC
864752Speter 					if ((p->nl_flags & NMOD) == 0) {
865752Speter 						warning();
866752Speter 						nerror("%s %s is used but never set", classes[p->class], p->symbol);
867752Speter 						break;
868752Speter 					}
869752Speter 				case LABEL:
870752Speter 				case FVAR:
871752Speter 				case BADUSE:
872752Speter 					break;
873752Speter 			}
874752Speter 			switch (p->class) {
875752Speter 				case BADUSE:
876752Speter 					cp = "s";
877752Speter 					if (p->chain->ud_next == NIL)
878752Speter 						cp++;
879752Speter 					eholdnl();
880752Speter 					if (p->value[NL_KINDS] & ISUNDEF)
881752Speter 						nerror("%s undefined on line%s", p->symbol, cp);
882752Speter 					else
883752Speter 						nerror("%s improperly used on line%s", p->symbol, cp);
884752Speter 					pnumcnt = 10;
885752Speter 					pnums(p->chain);
886752Speter 					pchr('\n');
887752Speter 					break;
888752Speter 
889752Speter 				case FUNC:
890752Speter 				case PROC:
891752Speter #					ifdef OBJ
892752Speter 					    if ((p->nl_flags & NFORWD))
893752Speter 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
894752Speter #					endif OBJ
895752Speter #					ifdef PC
896752Speter 					    if ((p->nl_flags & NFORWD) && ((p->ext_flags & NEXTERN) == 0))
897752Speter 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
898752Speter #					endif PC
899752Speter 					break;
900752Speter 
901752Speter 				case LABEL:
902752Speter 					if (p->nl_flags & NFORWD)
903752Speter 						nerror("label %s was declared but not defined", p->symbol);
904752Speter 					break;
905752Speter 				case FVAR:
906752Speter 					if ((p->nl_flags & NMOD) == 0)
907752Speter 						nerror("No assignment to the function variable");
908752Speter 					break;
909752Speter 			}
910752Speter 		}
911752Speter 		/*
912752Speter 		 * Pop this symbol
913752Speter 		 * table slot
914752Speter 		 */
915752Speter 		disptab[i] = p;
916752Speter 	}
917752Speter 
918752Speter #	ifdef OBJ
919752Speter 	    put(1, O_END);
920752Speter #	endif OBJ
921752Speter #	ifdef PC
922752Speter 		/*
923752Speter 		 *	if there were file variables declared at this level
924752Speter 		 *	call pclose( &__disply[ cbn ] ) to clean them up.
925752Speter 		 */
926752Speter 	    if ( dfiles[ cbn ] ) {
927752Speter 		putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
928752Speter 			, "_PCLOSE" );
929752Speter 		putRV( DISPLAYNAME , 0 , cbn * sizeof( struct dispsave )
930752Speter 			, P2PTR | P2CHAR );
931752Speter 		putop( P2CALL , P2INT );
932752Speter 		putdot( filename , line );
933752Speter 	    }
934752Speter 		/*
935752Speter 		 *	if this is a function,
936752Speter 		 *	the function variable is the return value.
937752Speter 		 *	if it's a scalar valued function, return scalar,
938752Speter 		 *	else, return a pointer to the structure value.
939752Speter 		 */
940752Speter 	    if ( fp -> class == FUNC ) {
941752Speter 		struct nl	*fvar = fp -> ptr[ NL_FVAR ];
942752Speter 		long		fvartype = p2type( fvar -> type );
9431196Speter 		long		label;
9441196Speter 		char		labelname[ BUFSIZ ];
945752Speter 
946752Speter 		switch ( classify( fvar -> type ) ) {
947752Speter 		    case TBOOL:
948752Speter 		    case TCHAR:
949752Speter 		    case TINT:
950752Speter 		    case TSCAL:
951752Speter 		    case TDOUBLE:
952752Speter 		    case TPTR:
953752Speter 			putRV( fvar -> symbol , ( fvar -> nl_block ) & 037
954752Speter 				, fvar -> value[ NL_OFFS ] , fvartype );
955752Speter 			break;
956752Speter 		    default:
9571196Speter 			label = getlab();
9581196Speter 			sprintf( labelname , PREFIXFORMAT ,
9591196Speter 				LABELPREFIX , label );
9601196Speter 			putprintf( "	.data" , 0 );
9611196Speter 			putprintf( "	.lcomm	%s,%d" , 0 ,
9621196Speter 				    labelname , lwidth( fvar -> type ) );
9631196Speter 			putprintf( "	.text" , 0 );
9641374Speter 			putleaf( P2NAME , 0 , 0 , fvartype , labelname );
965752Speter 			putLV( fvar -> symbol , ( fvar -> nl_block ) & 037
966752Speter 				, fvar -> value[ NL_OFFS ] , fvartype );
9671196Speter 			putstrop( P2STASG , fvartype , lwidth( fvar -> type ) ,
9681196Speter 				align( fvar -> type ) );
9691374Speter 			putdot( filename , line );
9701374Speter 			putleaf( P2ICON , 0 , 0 , fvartype , labelname );
971752Speter 			break;
972752Speter 		}
973752Speter 		putop( P2FORCE , fvartype );
974752Speter 		putdot( filename , line );
975752Speter 	    }
976752Speter 		/*
977752Speter 		 *	restore old display entry from save area
978752Speter 		 */
979752Speter 
980752Speter 	    putprintf( "	movq	%d(%s),%s+%d" , 0
981752Speter 		, DSAVEOFFSET , P2FPNAME
982752Speter 		, DISPLAYNAME , cbn * sizeof(struct dispsave) );
983752Speter 	    stabrbrac( cbn );
984752Speter 	    putprintf( "	ret" , 0 );
985752Speter 		/*
986752Speter 		 *	let the second pass allocate locals
987752Speter 		 */
988752Speter 	    putlab( botlabel );
989752Speter 	    putprintf( "	subl2	$LF%d,sp" , 0 , ftnno );
990752Speter 	    putrbracket( ftnno );
991752Speter 	    putjbr( toplabel );
992752Speter 		/*
993752Speter 		 *	declare pcp counters, if any
994752Speter 		 */
995752Speter 	    if ( monflg && fp -> class == PROG ) {
996752Speter 		putprintf( "	.data" , 0 );
997752Speter 		putprintf( "	.comm	" , 1 );
998752Speter 		putprintf( PCPCOUNT , 1 );
999752Speter 		putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
1000752Speter 		putprintf( "	.text" , 0 );
1001752Speter 	    }
1002752Speter #	endif PC
1003752Speter #ifdef DEBUG
1004752Speter 	dumpnl(fp->ptr[2], fp->symbol);
1005752Speter #endif
1006752Speter 	/*
1007752Speter 	 * Restore the
1008752Speter 	 * (virtual) name list
1009752Speter 	 * position
1010752Speter 	 */
1011752Speter 	nlfree(fp->ptr[2]);
1012752Speter 	/*
1013752Speter 	 * Proc/func has been
1014752Speter 	 * resolved
1015752Speter 	 */
1016752Speter 	fp->nl_flags &= ~NFORWD;
1017752Speter 	/*
1018752Speter 	 * Patch the beg
1019752Speter 	 * of the proc/func to
1020752Speter 	 * the proper variable size
1021752Speter 	 */
1022752Speter 	if (Fp == NIL)
1023752Speter 		elineon();
1024752Speter #	ifdef OBJ
1025*3073Smckusic 	    patchfil(var, (long)(-sizes[cbn].om_max), 2);
1026752Speter #	endif OBJ
1027752Speter 	cbn--;
1028752Speter 	if (inpflist(fp->symbol)) {
1029752Speter 		opop('l');
1030752Speter 	}
1031752Speter }
1032752Speter 
1033752Speter 
1034752Speter /*
1035752Speter  * Segend is called to check for
1036752Speter  * unresolved variables, funcs and
1037752Speter  * procs, and deliver unresolved and
1038752Speter  * baduse error diagnostics at the
1039752Speter  * end of a routine segment (a separately
1040752Speter  * compiled segment that is not the
1041752Speter  * main program) for PC. This
1042752Speter  * routine should only be called
1043752Speter  * by PC (not standard).
1044752Speter  */
1045752Speter  segend()
1046752Speter  {
1047752Speter 	register struct nl *p;
1048752Speter 	register int i,b;
1049752Speter 	char *cp;
1050752Speter 
1051752Speter #ifdef PC
1052752Speter 	if (opt('s')) {
1053752Speter 		standard();
1054752Speter 		error("Separately compiled routine segments are not standard.");
1055752Speter 	} else {
1056752Speter 		b = cbn;
1057752Speter 		for (i=0; i<077; i++) {
1058752Speter 			for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
1059752Speter 			switch (p->class) {
1060752Speter 				case BADUSE:
1061752Speter 					cp = 's';
1062752Speter 					if (p->chain->ud_next == NIL)
1063752Speter 						cp++;
1064752Speter 					eholdnl();
1065752Speter 					if (p->value[NL_KINDS] & ISUNDEF)
1066752Speter 						nerror("%s undefined on line%s", p->symbol, cp);
1067752Speter 					else
1068752Speter 						nerror("%s improperly used on line%s", p->symbol, cp);
1069752Speter 					pnumcnt = 10;
1070752Speter 					pnums(p->chain);
1071752Speter 					pchr('\n');
1072752Speter 					break;
1073752Speter 
1074752Speter 				case FUNC:
1075752Speter 				case PROC:
1076752Speter 					if ((p->nl_flags & NFORWD) && ((p->ext_flags & NEXTERN) == 0))
1077752Speter 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
1078752Speter 					break;
1079752Speter 
1080752Speter 				case FVAR:
1081752Speter 					if (((p->nl_flags & NMOD) == 0) && ((p->chain->ext_flags & NEXTERN) == 0))
1082752Speter 						nerror("No assignment to the function variable");
1083752Speter 					break;
1084752Speter 			    }
1085752Speter 			   }
1086752Speter 			   disptab[i] = p;
1087752Speter 		    }
1088752Speter 	}
1089752Speter #endif PC
1090752Speter #ifdef OBJ
1091752Speter 	error("Missing program statement and program body");
1092752Speter #endif OBJ
1093752Speter 
1094752Speter }
1095752Speter 
1096752Speter 
1097752Speter /*
1098752Speter  * Level1 does level one processing for
1099752Speter  * separately compiled routine segments
1100752Speter  */
1101752Speter level1()
1102752Speter {
1103752Speter 
1104752Speter #	ifdef OBJ
1105752Speter 	    error("Missing program statement");
1106752Speter #	endif OBJ
1107752Speter #	ifdef PC
1108752Speter 	    if (opt('s')) {
1109752Speter 		    standard();
1110752Speter 		    error("Missing program statement");
1111752Speter 	    }
1112752Speter #	endif PC
1113752Speter 
1114752Speter 	cbn++;
1115752Speter 	sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1;
1116834Speter 	gotos[cbn] = NIL;
1117834Speter 	errcnt[cbn] = syneflg;
1118834Speter 	parts[ cbn ] = NIL;
1119834Speter 	dfiles[ cbn ] = FALSE;
1120*3073Smckusic 	progseen = TRUE;
1121752Speter }
1122752Speter 
1123752Speter 
1124752Speter 
1125752Speter pnums(p)
1126752Speter 	struct udinfo *p;
1127752Speter {
1128752Speter 
1129752Speter 	if (p->ud_next != NIL)
1130752Speter 		pnums(p->ud_next);
1131752Speter 	if (pnumcnt == 0) {
1132752Speter 		printf("\n\t");
1133752Speter 		pnumcnt = 20;
1134752Speter 	}
1135752Speter 	pnumcnt--;
1136752Speter 	printf(" %d", p->ud_line);
1137752Speter }
1138752Speter 
1139752Speter nerror(a1, a2, a3)
1140752Speter {
1141752Speter 
1142752Speter 	if (Fp != NIL) {
1143752Speter 		yySsync();
1144752Speter #ifndef PI1
1145752Speter 		if (opt('l'))
1146752Speter 			yyoutline();
1147752Speter #endif
1148752Speter 		yysetfile(filename);
1149752Speter 		printf("In %s %s:\n", classes[Fp->class], Fp->symbol);
1150752Speter 		Fp = NIL;
1151752Speter 		elineoff();
1152752Speter 	}
1153752Speter 	error(a1, a2, a3);
1154752Speter }
1155