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