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