xref: /csrg-svn/old/as.vax/asscan1.c (revision 19828)
15797Srrh /*
2*19828Sdist  * Copyright (c) 1982 Regents of the University of California.
3*19828Sdist  * All rights reserved.  The Berkeley software License Agreement
4*19828Sdist  * specifies the terms and conditions for redistribution.
55797Srrh  */
6*19828Sdist 
75797Srrh #ifndef lint
8*19828Sdist static char sccsid[] = "@(#)asscan1.c	5.1 (Berkeley) 04/30/85";
95797Srrh #endif not lint
105797Srrh 
115797Srrh #include "asscanl.h"
125797Srrh 
inittokfile()1313515Srrh inittokfile()
145797Srrh {
155797Srrh 	if (passno == 1){
165797Srrh 		if (useVM){
175797Srrh 			bufstart = &tokbuf[0];
185797Srrh 			buftail = &tokbuf[1];
195797Srrh 			bufstart->tok_next = buftail;
205797Srrh 			buftail->tok_next = 0;
215797Srrh 		}
225797Srrh 		tokbuf[0].tok_count = -1;
235797Srrh 		tokbuf[1].tok_count = -1;
245797Srrh 	}
255797Srrh 	tok_temp = 0;
265797Srrh 	tok_free = 0;
275797Srrh 	bufno = 0;
285797Srrh 	emptybuf = &tokbuf[bufno];
295797Srrh 	tokptr = 0;
305797Srrh 	tokub = 0;
315797Srrh }
325797Srrh 
closetokfile()3313515Srrh closetokfile()
345797Srrh {
355797Srrh 	if (passno == 1){
365797Srrh 		if (useVM){
375797Srrh 			emptybuf->toks[emptybuf->tok_count++] = PARSEEOF;
385797Srrh 		} else {
395797Srrh 			/*
405797Srrh 			 *	Clean up the buffers that haven't been
415797Srrh 			 *	written out yet
425797Srrh 			 */
435797Srrh 			if (tokbuf[bufno ^ 1].tok_count >= 0){
4413515Srrh 				if (writeTEST((char *)&tokbuf[bufno ^ 1], sizeof *emptybuf, 1, tokfile)){
455797Srrh 				  badwrite:
465797Srrh 					yyerror("Unexpected end of file writing the interpass tmp file");
475797Srrh 				exit(2);
485797Srrh 				}
495797Srrh 			}
505797Srrh 			/*
515797Srrh 			 *	Ensure that we will read an End of file,
525797Srrh 			 *	if there are more than one file names
535797Srrh 			 *	in the argument list
545797Srrh 			 */
555797Srrh 			tokbuf[bufno].toks[tokbuf[bufno].tok_count++] = PARSEEOF;
5613515Srrh 			if (writeTEST((char *)&tokbuf[bufno], sizeof *emptybuf, 1, tokfile))
575797Srrh 				goto badwrite;
585797Srrh 		}
595797Srrh 	}	/*end of being pass 1*/
605797Srrh }
615797Srrh 
yylex()625797Srrh inttoktype yylex()
635797Srrh {
645797Srrh 	register	ptrall	bufptr;
655797Srrh 	register	inttoktype		val;
665797Srrh 	register	struct	exp	*locxp;
675797Srrh 	/*
685797Srrh 	 *	No local variables to be allocated; this saves
695797Srrh 	 *	one piddling instruction..
705797Srrh 	 */
715797Srrh 	static	int	Lastjxxx;
725797Srrh 
735797Srrh 	bufptr = tokptr;		/*copy in the global value*/
745797Srrh    top:
755797Srrh 	if (bufptr < tokub){
765797Srrh 		gtoken(val, bufptr);
775797Srrh 		switch(yylval = val){
785797Srrh 		case	PARSEEOF:
795797Srrh 				yylval = val = PARSEEOF;
805797Srrh 				break;
815797Srrh 		case	BFINT:
825797Srrh 		case	INT:
835797Srrh 				if (xp >= &explist[NEXP])
845797Srrh 				     yyerror("Too many expressions; try simplyfing");
855797Srrh 				else
865797Srrh 				    locxp = xp++;
875797Srrh 				locxp->e_number = Znumber;
885797Srrh 				locxp->e_number.num_tag = TYPL;
895797Srrh 				glong(locxp->e_xvalue, bufptr);
905797Srrh 			  makevalue:
915797Srrh 				locxp->e_xtype = XABS;
925797Srrh 				locxp->e_xloc = 0;
935797Srrh 				locxp->e_xname = NULL;
945797Srrh 				yylval = (int)locxp;
955797Srrh 				break;
965797Srrh 		case	BIGNUM:
975797Srrh 				if (xp >= &explist[NEXP])
985797Srrh 				     yyerror("Too many expressions; try simplyfing");
995797Srrh 				else
1005797Srrh 				    locxp = xp++;
1015797Srrh 				gnumber(locxp->e_number, bufptr);
1025797Srrh 				goto makevalue;
1035797Srrh 		case	NAME:
1045797Srrh 				gptr(yylval, bufptr);
1055797Srrh 				lastnam = (struct symtab *)yylval;
1065797Srrh 				break;
1075797Srrh 		case	SIZESPEC:
1085797Srrh 		case 	REG:
1095797Srrh 				gchar(yylval, bufptr);
1105797Srrh 				break;
1115797Srrh 		case	INSTn:
1125797Srrh 		case	INST0:
1135797Srrh 				gopcode(yyopcode, bufptr);
1145797Srrh 				break;
1155797Srrh 		case	IJXXX:
1165797Srrh 				gopcode(yyopcode, bufptr);
1175797Srrh 				/* We can't cast Lastjxxx into (int *) here.. */
1185797Srrh 				gptr(Lastjxxx, bufptr);
1195797Srrh 				lastjxxx = (struct symtab *)Lastjxxx;
1205797Srrh 				break;
1215797Srrh 		case	ILINESKIP:
1225797Srrh 				gint(yylval, bufptr);
1235797Srrh 				lineno += yylval;
1245797Srrh 				goto top;
1255797Srrh 		case	SKIP:
1265797Srrh 				eatskiplg(bufptr);
1275797Srrh 				goto top;
1285797Srrh 		case	VOID:
1295797Srrh 				goto top;
1305797Srrh 		case 	STRING:
1315797Srrh 		case 	ISTAB:
1325797Srrh 		case	ISTABSTR:
1335797Srrh 		case	ISTABNONE:
1345797Srrh 		case	ISTABDOT:
1355797Srrh 		case	IALIGN:
1365797Srrh 				gptr(yylval, bufptr);
1375797Srrh 				break;
1385797Srrh 		}
1395797Srrh #ifdef DEBUG
1405797Srrh 		if (toktrace){
1415797Srrh 		char	*tok_to_name();
1425797Srrh 		printf("P: %d T#: %4d, %s ",
1435797Srrh 			passno, bufptr -  firsttoken, tok_to_name(val));
1445797Srrh 		switch(val){
1455797Srrh 		case 	INT:	printf("val %d",
1465797Srrh 					((struct exp *)yylval)->e_xvalue);
1475797Srrh 				break;
1485797Srrh 		case	BFINT:	printf("val %d",
1495797Srrh 					((struct exp *)yylval)->e_xvalue);
1505797Srrh 				break;
1515797Srrh 		case 	BIGNUM: bignumprint(((struct exp*)yylval)->e_number);
1525797Srrh 				break;
1535797Srrh 		case	NAME:	printf("\"%.8s\"",
15413515Srrh 					FETCHNAME((struct symtab *)yylval));
1555797Srrh 				break;
1565797Srrh 		case	REG:	printf(" r%d",
1575797Srrh 					yylval);
1585797Srrh 				break;
1595797Srrh 		case	IJXXX:
1605797Srrh 		case	INST0:
1615797Srrh 		case	INSTn:	if (ITABCHECK(yyopcode))
16213515Srrh 					printf("%.8s",
16313515Srrh 						FETCHNAME(ITABFETCH(yyopcode)));
1645797Srrh 				else
1655797Srrh 					printf("IJXXX or INST0 or INSTn can't get into the itab\n");
1665797Srrh 				break;
16713807Srrh 		case	STRING:
16813807Srrh 			printf("length %d, seekoffset %d, place 0%o ",
16913807Srrh 				((struct strdesc *)yylval)->sd_strlen,
17013807Srrh 				((struct strdesc *)yylval)->sd_stroff,
17113807Srrh 				((struct strdesc *)yylval)->sd_place
17213807Srrh 				);
17313807Srrh 			if (((struct strdesc *)yylval)->sd_place & STR_CORE)
17413448Srrh 				printf("value\"%*s\"",
17513807Srrh 					((struct strdesc *)yylval)->sd_strlen,
17613807Srrh 					((struct strdesc *)yylval)->sd_string);
17713807Srrh 			break;
1785797Srrh 		}  		/*end of the debug switch*/
1795797Srrh 		printf("\n");
1805797Srrh 		}
1815797Srrh #endif DEBUG
1825797Srrh 
1835797Srrh 	} else {	/* start a new buffer */
1845797Srrh 	    if (useVM){
1855797Srrh 		if (passno == 2){
1865797Srrh 			tok_temp = emptybuf->tok_next;
1875797Srrh 			emptybuf->tok_next = tok_free;
1885797Srrh 			tok_free = emptybuf;
1895797Srrh 			emptybuf = tok_temp;
1905797Srrh 		} else {
1915797Srrh 			emptybuf = emptybuf->tok_next;
1925797Srrh 		}
1935797Srrh 		bufno += 1;
1945797Srrh 		if (emptybuf == 0){
1955797Srrh 			struct	tokbufdesc *newdallop;
1965797Srrh 			int	i;
1975797Srrh 			if (passno == 2)
1985797Srrh 				goto badread;
1995797Srrh 			emptybuf = newdallop = (struct tokbufdesc *)
2005797Srrh 			  Calloc(TOKDALLOP, sizeof (struct tokbufdesc));
2015797Srrh 			for (i=0; i < TOKDALLOP; i++){
2025797Srrh 				buftail->tok_next = newdallop;
2035797Srrh 				buftail = newdallop;
2045797Srrh 				newdallop += 1;
2055797Srrh 			}
2065797Srrh 			buftail->tok_next = 0;
2075797Srrh 		}	/*end of need to get more buffers*/
2085797Srrh 		(bytetoktype *)bufptr = &(emptybuf->toks[0]);
2095797Srrh 		if (passno == 1)
2105797Srrh 			scan_dot_s(emptybuf);
2115797Srrh 	    } else {	/*don't use VM*/
2125797Srrh 		bufno ^= 1;
2135797Srrh 		emptybuf = &tokbuf[bufno];
2145797Srrh 		((bytetoktype *)bufptr) = &(emptybuf->toks[0]);
2155797Srrh 		if (passno == 1){
2165797Srrh 			/*
2175797Srrh 			 *	First check if there are things to write
2185797Srrh 			 *	out at all
2195797Srrh 			 */
2205797Srrh 			if (emptybuf->tok_count >= 0){
22113515Srrh 			    if (writeTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){
2225797Srrh 				yyerror("Unexpected end of file writing the interpass tmp file");
2235797Srrh 				exit(2);
2245797Srrh 			    }
2255797Srrh 			}
2265797Srrh 			scan_dot_s(emptybuf);
2275797Srrh 		} else {	/*pass 2*/
22813515Srrh 		    if (readTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){
2295797Srrh 			 badread:
2305797Srrh 			     yyerror("Unexpected end of file while reading the interpass tmp file");
2315797Srrh 			     exit(1);
2325797Srrh 		    }
2335797Srrh 		}
2345797Srrh 	    }	/*end of using a real live file*/
2355797Srrh 	    (char *)tokub = (char *)bufptr + emptybuf->tok_count;
2365797Srrh #ifdef DEBUG
2375797Srrh 	    firsttoken = bufptr;
2385797Srrh 	    if (debug)
2395797Srrh 		printf("created buffernumber %d with %d tokens\n",
2405797Srrh 			bufno, emptybuf->tok_count);
2415797Srrh #endif DEBUG
2425797Srrh 	    goto top;
2435797Srrh 	}	/*end of reading/creating a new buffer*/
2445797Srrh 	tokptr = bufptr;		/*copy back the global value*/
2455797Srrh 	return(val);
2465797Srrh }	/*end of yylex*/
2475797Srrh 
2485797Srrh 
buildskip(from,to)2495797Srrh buildskip(from, to)
2505797Srrh 	register	ptrall	from, to;
2515797Srrh {
2525797Srrh 	int	diff;
2535797Srrh 	register	struct	tokbufdesc *middlebuf;
2545797Srrh 	/*
2555797Srrh 	 *	check if from and to are in the same buffer
2565797Srrh 	 *	from and to DIFFER BY AT MOST 1 buffer and to is
2575797Srrh 	 *	always ahead of from, with to being in the buffer emptybuf
2585797Srrh 	 *	points to.
2595797Srrh 	 *	The hard part here is accounting for the case where the
2605797Srrh 	 *	skip is to cross a buffer boundary; we must construct
2615797Srrh 	 *	two skips.
2625797Srrh 	 *
2635797Srrh 	 *	Figure out where the buffer boundary between from and to is
2645797Srrh 	 *	It's easy in VM, as buffers increase to high memory, but
2655797Srrh 	 *	w/o VM, we alternate between two buffers, and want
2665797Srrh 	 *	to look at the exact middle of the contiguous buffer region.
2675797Srrh 	 */
2685797Srrh 	middlebuf = useVM ? emptybuf : &tokbuf[1];
2695797Srrh 	if (  ( (bytetoktype *)from > (bytetoktype *)middlebuf)
2705797Srrh 	    ^ ( (bytetoktype *)to > (bytetoktype *)middlebuf)
2715797Srrh 	   ){	/*split across a buffer boundary*/
2725797Srrh 		ptoken(from, SKIP);
2735797Srrh 		/*
2745797Srrh 		 *	Set the skip so it lands someplace beyond
2755797Srrh 		 *	the end of this buffer.
2765797Srrh 		 *	When we pull this skip out in the second pass,
2775797Srrh 		 *	we will temporarily move the current pointer
2785797Srrh 		 *	out beyond the end of the buffer, but immediately
2795797Srrh 		 *	do a compare and fail the compare, and then reset
2805797Srrh 		 *	all the pointers correctly to point into the next buffer.
2815797Srrh 		 */
2825797Srrh 		bskiplg(from,  TOKBUFLG + 1);
2835797Srrh 		/*
2845797Srrh 		 *	Now, force from to be in the same buffer as to
2855797Srrh 		 */
2865797Srrh 		(bytetoktype *)from = (bytetoktype *)&(emptybuf->toks[0]);
2875797Srrh 	}
2885797Srrh 	/*
2895797Srrh 	 *	Now, to and from are in the same buffer
2905797Srrh 	 */
2915797Srrh 	if (from > to)
2925797Srrh 		yyerror("Internal error: bad skip construction");
2935797Srrh 	else {
2945797Srrh 		if ( (diff = (bytetoktype *)to - (bytetoktype *)from) >=
2955797Srrh 			(sizeof(bytetoktype) + sizeof(lgtype) + 1)) {
2965797Srrh 				ptoken(from, SKIP);
2975797Srrh 				bskipfromto(from, to);
2985797Srrh 		} else {
2995797Srrh 			for ( ; diff > 0; --diff)
3005797Srrh 				ptoken(from, VOID);
3015797Srrh 		}
3025797Srrh 	}
3035797Srrh }
3045797Srrh 
movestr(to,from,lg)3055797Srrh movestr(to, from, lg)
30613448Srrh 	char	*to;	/* 4(ap) */
30713448Srrh 	char	*from;	/* 8(ap) */
30813448Srrh 	int	lg;	/* 12(ap) */
3095797Srrh {
31013448Srrh 	if (lg <= 0)
31113448Srrh 		return;
31213448Srrh 	;
31313448Srrh 	asm("movc3	12(ap),*8(ap),*4(ap)");
31413448Srrh 	;
3155797Srrh }
3165797Srrh 
new_dot_s(namep)3175797Srrh new_dot_s(namep)
3185797Srrh 	char	*namep;
3195797Srrh {
3205797Srrh 	newfflag = 1;
3215797Srrh 	newfname = namep;
3225797Srrh 	dotsname = namep;
3235797Srrh 	lineno = 1;
3245797Srrh 	scanlineno = 1;
3255797Srrh }
32613448Srrh 
min(a,b)32713448Srrh min(a, b)
32813448Srrh {
32913448Srrh 	return(a < b ? a : b);
33013448Srrh }
331