xref: /original-bsd/old/as.vax/asscan1.c (revision a910c8b7)
1 /*
2  *	Copyright (c) 1982 Regents of the University of California
3  */
4 #ifndef lint
5 static char sccsid[] = "@(#)asscan1.c 4.6 07/06/83";
6 #endif not lint
7 
8 #include "asscanl.h"
9 
10 inittokfile()
11 {
12 	if (passno == 1){
13 		if (useVM){
14 			bufstart = &tokbuf[0];
15 			buftail = &tokbuf[1];
16 			bufstart->tok_next = buftail;
17 			buftail->tok_next = 0;
18 		}
19 		tokbuf[0].tok_count = -1;
20 		tokbuf[1].tok_count = -1;
21 	}
22 	tok_temp = 0;
23 	tok_free = 0;
24 	bufno = 0;
25 	emptybuf = &tokbuf[bufno];
26 	tokptr = 0;
27 	tokub = 0;
28 }
29 
30 closetokfile()
31 {
32 	if (passno == 1){
33 		if (useVM){
34 			emptybuf->toks[emptybuf->tok_count++] = PARSEEOF;
35 		} else {
36 			/*
37 			 *	Clean up the buffers that haven't been
38 			 *	written out yet
39 			 */
40 			if (tokbuf[bufno ^ 1].tok_count >= 0){
41 				if (writeTEST((char *)&tokbuf[bufno ^ 1], sizeof *emptybuf, 1, tokfile)){
42 				  badwrite:
43 					yyerror("Unexpected end of file writing the interpass tmp file");
44 				exit(2);
45 				}
46 			}
47 			/*
48 			 *	Ensure that we will read an End of file,
49 			 *	if there are more than one file names
50 			 *	in the argument list
51 			 */
52 			tokbuf[bufno].toks[tokbuf[bufno].tok_count++] = PARSEEOF;
53 			if (writeTEST((char *)&tokbuf[bufno], sizeof *emptybuf, 1, tokfile))
54 				goto badwrite;
55 		}
56 	}	/*end of being pass 1*/
57 }
58 
59 inttoktype yylex()
60 {
61 	register	ptrall	bufptr;
62 	register	inttoktype		val;
63 	register	struct	exp	*locxp;
64 	/*
65 	 *	No local variables to be allocated; this saves
66 	 *	one piddling instruction..
67 	 */
68 	static	int	Lastjxxx;
69 
70 	bufptr = tokptr;		/*copy in the global value*/
71    top:
72 	if (bufptr < tokub){
73 		gtoken(val, bufptr);
74 		switch(yylval = val){
75 		case	PARSEEOF:
76 				yylval = val = PARSEEOF;
77 				break;
78 		case	BFINT:
79 		case	INT:
80 				if (xp >= &explist[NEXP])
81 				     yyerror("Too many expressions; try simplyfing");
82 				else
83 				    locxp = xp++;
84 				locxp->e_number = Znumber;
85 				locxp->e_number.num_tag = TYPL;
86 				glong(locxp->e_xvalue, bufptr);
87 			  makevalue:
88 				locxp->e_xtype = XABS;
89 				locxp->e_xloc = 0;
90 				locxp->e_xname = NULL;
91 				yylval = (int)locxp;
92 				break;
93 		case	BIGNUM:
94 				if (xp >= &explist[NEXP])
95 				     yyerror("Too many expressions; try simplyfing");
96 				else
97 				    locxp = xp++;
98 				gnumber(locxp->e_number, bufptr);
99 				goto makevalue;
100 		case	NAME:
101 				gptr(yylval, bufptr);
102 				lastnam = (struct symtab *)yylval;
103 				break;
104 		case	SIZESPEC:
105 		case 	REG:
106 				gchar(yylval, bufptr);
107 				break;
108 		case	INSTn:
109 		case	INST0:
110 				gopcode(yyopcode, bufptr);
111 				break;
112 		case	IJXXX:
113 				gopcode(yyopcode, bufptr);
114 				/* We can't cast Lastjxxx into (int *) here.. */
115 				gptr(Lastjxxx, bufptr);
116 				lastjxxx = (struct symtab *)Lastjxxx;
117 				break;
118 		case	ILINESKIP:
119 				gint(yylval, bufptr);
120 				lineno += yylval;
121 				goto top;
122 		case	SKIP:
123 				eatskiplg(bufptr);
124 				goto top;
125 		case	VOID:
126 				goto top;
127 		case 	STRING:
128 		case 	ISTAB:
129 		case	ISTABSTR:
130 		case	ISTABNONE:
131 		case	ISTABDOT:
132 		case	IALIGN:
133 				gptr(yylval, bufptr);
134 				break;
135 		}
136 #ifdef DEBUG
137 		if (toktrace){
138 		char	*tok_to_name();
139 		printf("P: %d T#: %4d, %s ",
140 			passno, bufptr -  firsttoken, tok_to_name(val));
141 		switch(val){
142 		case 	INT:	printf("val %d",
143 					((struct exp *)yylval)->e_xvalue);
144 				break;
145 		case	BFINT:	printf("val %d",
146 					((struct exp *)yylval)->e_xvalue);
147 				break;
148 		case 	BIGNUM: bignumprint(((struct exp*)yylval)->e_number);
149 				break;
150 		case	NAME:	printf("\"%.8s\"",
151 					FETCHNAME((struct symtab *)yylval));
152 				break;
153 		case	REG:	printf(" r%d",
154 					yylval);
155 				break;
156 		case	IJXXX:
157 		case	INST0:
158 		case	INSTn:	if (ITABCHECK(yyopcode))
159 					printf("%.8s",
160 						FETCHNAME(ITABFETCH(yyopcode)));
161 				else
162 					printf("IJXXX or INST0 or INSTn can't get into the itab\n");
163 				break;
164 		case	STRING:
165 			printf("length %d, seekoffset %d, place 0%o ",
166 				((struct strdesc *)yylval)->sd_strlen,
167 				((struct strdesc *)yylval)->sd_stroff,
168 				((struct strdesc *)yylval)->sd_place
169 				);
170 			if (((struct strdesc *)yylval)->sd_place & STR_CORE)
171 				printf("value\"%*s\"",
172 					((struct strdesc *)yylval)->sd_strlen,
173 					((struct strdesc *)yylval)->sd_string);
174 			break;
175 		}  		/*end of the debug switch*/
176 		printf("\n");
177 		}
178 #endif DEBUG
179 
180 	} else {	/* start a new buffer */
181 	    if (useVM){
182 		if (passno == 2){
183 			tok_temp = emptybuf->tok_next;
184 			emptybuf->tok_next = tok_free;
185 			tok_free = emptybuf;
186 			emptybuf = tok_temp;
187 		} else {
188 			emptybuf = emptybuf->tok_next;
189 		}
190 		bufno += 1;
191 		if (emptybuf == 0){
192 			struct	tokbufdesc *newdallop;
193 			int	i;
194 			if (passno == 2)
195 				goto badread;
196 			emptybuf = newdallop = (struct tokbufdesc *)
197 			  Calloc(TOKDALLOP, sizeof (struct tokbufdesc));
198 			for (i=0; i < TOKDALLOP; i++){
199 				buftail->tok_next = newdallop;
200 				buftail = newdallop;
201 				newdallop += 1;
202 			}
203 			buftail->tok_next = 0;
204 		}	/*end of need to get more buffers*/
205 		(bytetoktype *)bufptr = &(emptybuf->toks[0]);
206 		if (passno == 1)
207 			scan_dot_s(emptybuf);
208 	    } else {	/*don't use VM*/
209 		bufno ^= 1;
210 		emptybuf = &tokbuf[bufno];
211 		((bytetoktype *)bufptr) = &(emptybuf->toks[0]);
212 		if (passno == 1){
213 			/*
214 			 *	First check if there are things to write
215 			 *	out at all
216 			 */
217 			if (emptybuf->tok_count >= 0){
218 			    if (writeTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){
219 				yyerror("Unexpected end of file writing the interpass tmp file");
220 				exit(2);
221 			    }
222 			}
223 			scan_dot_s(emptybuf);
224 		} else {	/*pass 2*/
225 		    if (readTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){
226 			 badread:
227 			     yyerror("Unexpected end of file while reading the interpass tmp file");
228 			     exit(1);
229 		    }
230 		}
231 	    }	/*end of using a real live file*/
232 	    (char *)tokub = (char *)bufptr + emptybuf->tok_count;
233 #ifdef DEBUG
234 	    firsttoken = bufptr;
235 	    if (debug)
236 		printf("created buffernumber %d with %d tokens\n",
237 			bufno, emptybuf->tok_count);
238 #endif DEBUG
239 	    goto top;
240 	}	/*end of reading/creating a new buffer*/
241 	tokptr = bufptr;		/*copy back the global value*/
242 	return(val);
243 }	/*end of yylex*/
244 
245 
246 buildskip(from, to)
247 	register	ptrall	from, to;
248 {
249 	int	diff;
250 	register	struct	tokbufdesc *middlebuf;
251 	/*
252 	 *	check if from and to are in the same buffer
253 	 *	from and to DIFFER BY AT MOST 1 buffer and to is
254 	 *	always ahead of from, with to being in the buffer emptybuf
255 	 *	points to.
256 	 *	The hard part here is accounting for the case where the
257 	 *	skip is to cross a buffer boundary; we must construct
258 	 *	two skips.
259 	 *
260 	 *	Figure out where the buffer boundary between from and to is
261 	 *	It's easy in VM, as buffers increase to high memory, but
262 	 *	w/o VM, we alternate between two buffers, and want
263 	 *	to look at the exact middle of the contiguous buffer region.
264 	 */
265 	middlebuf = useVM ? emptybuf : &tokbuf[1];
266 	if (  ( (bytetoktype *)from > (bytetoktype *)middlebuf)
267 	    ^ ( (bytetoktype *)to > (bytetoktype *)middlebuf)
268 	   ){	/*split across a buffer boundary*/
269 		ptoken(from, SKIP);
270 		/*
271 		 *	Set the skip so it lands someplace beyond
272 		 *	the end of this buffer.
273 		 *	When we pull this skip out in the second pass,
274 		 *	we will temporarily move the current pointer
275 		 *	out beyond the end of the buffer, but immediately
276 		 *	do a compare and fail the compare, and then reset
277 		 *	all the pointers correctly to point into the next buffer.
278 		 */
279 		bskiplg(from,  TOKBUFLG + 1);
280 		/*
281 		 *	Now, force from to be in the same buffer as to
282 		 */
283 		(bytetoktype *)from = (bytetoktype *)&(emptybuf->toks[0]);
284 	}
285 	/*
286 	 *	Now, to and from are in the same buffer
287 	 */
288 	if (from > to)
289 		yyerror("Internal error: bad skip construction");
290 	else {
291 		if ( (diff = (bytetoktype *)to - (bytetoktype *)from) >=
292 			(sizeof(bytetoktype) + sizeof(lgtype) + 1)) {
293 				ptoken(from, SKIP);
294 				bskipfromto(from, to);
295 		} else {
296 			for ( ; diff > 0; --diff)
297 				ptoken(from, VOID);
298 		}
299 	}
300 }
301 
302 movestr(to, from, lg)
303 	char	*to;	/* 4(ap) */
304 	char	*from;	/* 8(ap) */
305 	int	lg;	/* 12(ap) */
306 {
307 	if (lg <= 0)
308 		return;
309 	;
310 	asm("movc3	12(ap),*8(ap),*4(ap)");
311 	;
312 }
313 
314 new_dot_s(namep)
315 	char	*namep;
316 {
317 	newfflag = 1;
318 	newfname = namep;
319 	dotsname = namep;
320 	lineno = 1;
321 	scanlineno = 1;
322 }
323 
324 min(a, b)
325 {
326 	return(a < b ? a : b);
327 }
328