xref: /csrg-svn/usr.bin/pascal/src/lab.c (revision 756)
1*756Speter /* Copyright (c) 1979 Regents of the University of California */
2*756Speter 
3*756Speter static	char sccsid[] = "@(#)lab.c 1.1 08/27/80";
4*756Speter 
5*756Speter #include "whoami.h"
6*756Speter #include "0.h"
7*756Speter #include "tree.h"
8*756Speter #include "opcode.h"
9*756Speter #include "objfmt.h"
10*756Speter #ifdef PC
11*756Speter #   include	"pc.h"
12*756Speter #   include	"pcops.h"
13*756Speter #endif PC
14*756Speter 
15*756Speter /*
16*756Speter  * Label enters the definitions
17*756Speter  * of the label declaration part
18*756Speter  * into the namelist.
19*756Speter  */
20*756Speter label(r, l)
21*756Speter 	int *r, l;
22*756Speter {
23*756Speter #ifndef PI0
24*756Speter 	register *ll;
25*756Speter 	register struct nl *p, *lp;
26*756Speter 
27*756Speter 	lp = NIL;
28*756Speter #else
29*756Speter 	send(REVLAB, r);
30*756Speter #endif
31*756Speter 	if ( ! progseen ) {
32*756Speter 	    level1();
33*756Speter 	}
34*756Speter 	line = l;
35*756Speter #ifndef PI1
36*756Speter #ifdef PC
37*756Speter     if (opt('s')) {
38*756Speter 	if (parts & (CPRT|TPRT|VPRT)){
39*756Speter 		standard();
40*756Speter 		error("Label declarations must precede const, type and var declarations");
41*756Speter 	}
42*756Speter 	if (parts & LPRT) {
43*756Speter 		standard();
44*756Speter 		error("All labels must be declared in one label part");
45*756Speter 	}
46*756Speter     }
47*756Speter #endif PC
48*756Speter #ifdef OBJ
49*756Speter 	if (parts & (CPRT|TPRT|VPRT))
50*756Speter 		error("Label declarations must precede const, type and var declarations");
51*756Speter 	if (parts & LPRT)
52*756Speter 		error("All labels must be declared in one label part");
53*756Speter #endif OBJ
54*756Speter 	parts |= LPRT;
55*756Speter #endif
56*756Speter #ifndef PI0
57*756Speter 	for (ll = r; ll != NIL; ll = ll[2]) {
58*756Speter 		l = getlab();
59*756Speter 		p = enter(defnl(ll[1], LABEL, 0, l));
60*756Speter 		/*
61*756Speter 		 * Get the label for the eventual target
62*756Speter 		 */
63*756Speter 		p->value[1] = getlab();
64*756Speter 		p->chain = lp;
65*756Speter 		p->nl_flags |= (NFORWD|NMOD);
66*756Speter 		p->value[NL_GOLEV] = NOTYET;
67*756Speter 		p->entloc = l;
68*756Speter 		lp = p;
69*756Speter #		ifdef OBJ
70*756Speter 		    /*
71*756Speter 		     * This operator is between
72*756Speter 		     * the bodies of two procedures
73*756Speter 		     * and provides a target for
74*756Speter 		     * gotos for this label via TRA.
75*756Speter 		     */
76*756Speter 		    putlab(l);
77*756Speter 		    put2(O_GOTO | cbn<<8+INDX, p->value[1]);
78*756Speter #		endif OBJ
79*756Speter #		ifdef PC
80*756Speter 		    /*
81*756Speter 		     *	labels have to be .globl otherwise /lib/c2 may
82*756Speter 		     *	throw them away if they aren't used in the function
83*756Speter 		     *	which defines them.
84*756Speter 		     */
85*756Speter 		    if (cbn == 1) {
86*756Speter 				/*
87*756Speter 				 *	stab the label for separate compilation.
88*756Speter 				 *	make label number = label name.
89*756Speter 				 */
90*756Speter 			    p -> value[1] = atol( p -> symbol );
91*756Speter 			    stabglab( p -> value[1] );
92*756Speter 			    putprintf( "	.globl	" , 1 );
93*756Speter 			    putprintf( PREFIXFORMAT , 0 , PLABELPREFIX
94*756Speter 					, p -> value[1] );
95*756Speter 		    } else {
96*756Speter 			    putprintf( "	.globl	" , 1 );
97*756Speter 			    putprintf( PREFIXFORMAT , 0 , GLABELPREFIX
98*756Speter 					, p -> value[1] );
99*756Speter 		    }
100*756Speter #		endif PC
101*756Speter 	}
102*756Speter 	gotos[cbn] = lp;
103*756Speter #	ifdef PTREE
104*756Speter 	    {
105*756Speter 		pPointer	Labels = LabelDCopy( r );
106*756Speter 
107*756Speter 		pDEF( PorFHeader[ nesting ] ).PorFLabels = Labels;
108*756Speter 	    }
109*756Speter #	endif PTREE
110*756Speter #endif
111*756Speter }
112*756Speter 
113*756Speter #ifndef PI0
114*756Speter /*
115*756Speter  * Gotoop is called when
116*756Speter  * we get a statement "goto label"
117*756Speter  * and generates the needed tra.
118*756Speter  */
119*756Speter gotoop(s)
120*756Speter 	char *s;
121*756Speter {
122*756Speter 	register struct nl *p;
123*756Speter 
124*756Speter 	gocnt++;
125*756Speter 	p = lookup(s);
126*756Speter 	if (p == NIL)
127*756Speter 		return (NIL);
128*756Speter #	ifdef OBJ
129*756Speter 	    put2(O_TRA4, p->entloc);
130*756Speter #	endif OBJ
131*756Speter #	ifdef PC
132*756Speter 	    if ( cbn != bn ) {
133*756Speter 		    /*
134*756Speter 		     *	call goto to unwind the stack to the destination level
135*756Speter 		     */
136*756Speter 		putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
137*756Speter 			, "_GOTO" );
138*756Speter 		putLV( DISPLAYNAME , 0 , bn * sizeof( struct dispsave )
139*756Speter 			, P2PTR | P2INT );
140*756Speter 		putop( P2CALL , P2INT );
141*756Speter 		putdot( filename , line );
142*756Speter 	    }
143*756Speter 	    if ( bn <= 1 ) {
144*756Speter 		printjbr( PLABELPREFIX , p -> value[1] );
145*756Speter 	    } else {
146*756Speter 		printjbr( GLABELPREFIX , p -> value[1] );
147*756Speter 	    }
148*756Speter #	endif PC
149*756Speter 	if (bn == cbn)
150*756Speter 		if (p->nl_flags & NFORWD) {
151*756Speter 			if (p->value[NL_GOLEV] == NOTYET) {
152*756Speter 				p->value[NL_GOLEV] = level;
153*756Speter 				p->value[NL_GOLINE] = line;
154*756Speter 			}
155*756Speter 		} else
156*756Speter 			if (p->value[NL_GOLEV] == DEAD) {
157*756Speter 				recovered();
158*756Speter 				error("Goto %s is into a structured statement", p->symbol);
159*756Speter 			}
160*756Speter }
161*756Speter 
162*756Speter /*
163*756Speter  * Labeled is called when a label
164*756Speter  * definition is encountered, and
165*756Speter  * marks that it has been found and
166*756Speter  * patches the associated GOTO generated
167*756Speter  * by gotoop.
168*756Speter  */
169*756Speter labeled(s)
170*756Speter 	char *s;
171*756Speter {
172*756Speter 	register struct nl *p;
173*756Speter 
174*756Speter 	p = lookup(s);
175*756Speter 	if (p == NIL)
176*756Speter 		return (NIL);
177*756Speter 	if (bn != cbn) {
178*756Speter 		error("Label %s not defined in correct block", s);
179*756Speter 		return;
180*756Speter 	}
181*756Speter 	if ((p->nl_flags & NFORWD) == 0) {
182*756Speter 		error("Label %s redefined", s);
183*756Speter 		return;
184*756Speter 	}
185*756Speter 	p->nl_flags &= ~NFORWD;
186*756Speter #	ifdef OBJ
187*756Speter 	    patch4(p->entloc);
188*756Speter #	endif OBJ
189*756Speter #	ifdef PC
190*756Speter 	    if ( bn <= 1 ) {
191*756Speter 		putprintf( PREFIXFORMAT , 1 , PLABELPREFIX , p -> value[1] );
192*756Speter 	    } else {
193*756Speter 		putprintf( PREFIXFORMAT , 1 , GLABELPREFIX , p -> value[1] );
194*756Speter 	    }
195*756Speter 	    putprintf( ":" , 0 );
196*756Speter #	endif PC
197*756Speter 	if (p->value[NL_GOLEV] != NOTYET)
198*756Speter 		if (p->value[NL_GOLEV] < level) {
199*756Speter 			recovered();
200*756Speter 			error("Goto %s from line %d is into a structured statement", s, p->value[NL_GOLINE]);
201*756Speter 		}
202*756Speter 	p->value[NL_GOLEV] = level;
203*756Speter }
204*756Speter #endif
205