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