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