1 /* 2 * Copyright (c) 1982 Regents of the University of California 3 */ 4 #ifndef lint 5 static char sccsid[] = "@(#)asscan1.c 4.5 06/30/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: printf("length %d ", ((u_short *)yylval)[-1]); 165 printf("value\"%*s\"", 166 ((u_short *)yylval)[-1], 167 (char *)yylval); 168 break; 169 } /*end of the debug switch*/ 170 printf("\n"); 171 } 172 #endif DEBUG 173 174 } else { /* start a new buffer */ 175 if (useVM){ 176 if (passno == 2){ 177 tok_temp = emptybuf->tok_next; 178 emptybuf->tok_next = tok_free; 179 tok_free = emptybuf; 180 emptybuf = tok_temp; 181 } else { 182 emptybuf = emptybuf->tok_next; 183 } 184 bufno += 1; 185 if (emptybuf == 0){ 186 struct tokbufdesc *newdallop; 187 int i; 188 if (passno == 2) 189 goto badread; 190 emptybuf = newdallop = (struct tokbufdesc *) 191 Calloc(TOKDALLOP, sizeof (struct tokbufdesc)); 192 for (i=0; i < TOKDALLOP; i++){ 193 buftail->tok_next = newdallop; 194 buftail = newdallop; 195 newdallop += 1; 196 } 197 buftail->tok_next = 0; 198 } /*end of need to get more buffers*/ 199 (bytetoktype *)bufptr = &(emptybuf->toks[0]); 200 if (passno == 1) 201 scan_dot_s(emptybuf); 202 } else { /*don't use VM*/ 203 bufno ^= 1; 204 emptybuf = &tokbuf[bufno]; 205 ((bytetoktype *)bufptr) = &(emptybuf->toks[0]); 206 if (passno == 1){ 207 /* 208 * First check if there are things to write 209 * out at all 210 */ 211 if (emptybuf->tok_count >= 0){ 212 if (writeTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){ 213 yyerror("Unexpected end of file writing the interpass tmp file"); 214 exit(2); 215 } 216 } 217 scan_dot_s(emptybuf); 218 } else { /*pass 2*/ 219 if (readTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){ 220 badread: 221 yyerror("Unexpected end of file while reading the interpass tmp file"); 222 exit(1); 223 } 224 } 225 } /*end of using a real live file*/ 226 (char *)tokub = (char *)bufptr + emptybuf->tok_count; 227 #ifdef DEBUG 228 firsttoken = bufptr; 229 if (debug) 230 printf("created buffernumber %d with %d tokens\n", 231 bufno, emptybuf->tok_count); 232 #endif DEBUG 233 goto top; 234 } /*end of reading/creating a new buffer*/ 235 tokptr = bufptr; /*copy back the global value*/ 236 return(val); 237 } /*end of yylex*/ 238 239 240 buildskip(from, to) 241 register ptrall from, to; 242 { 243 int diff; 244 register struct tokbufdesc *middlebuf; 245 /* 246 * check if from and to are in the same buffer 247 * from and to DIFFER BY AT MOST 1 buffer and to is 248 * always ahead of from, with to being in the buffer emptybuf 249 * points to. 250 * The hard part here is accounting for the case where the 251 * skip is to cross a buffer boundary; we must construct 252 * two skips. 253 * 254 * Figure out where the buffer boundary between from and to is 255 * It's easy in VM, as buffers increase to high memory, but 256 * w/o VM, we alternate between two buffers, and want 257 * to look at the exact middle of the contiguous buffer region. 258 */ 259 middlebuf = useVM ? emptybuf : &tokbuf[1]; 260 if ( ( (bytetoktype *)from > (bytetoktype *)middlebuf) 261 ^ ( (bytetoktype *)to > (bytetoktype *)middlebuf) 262 ){ /*split across a buffer boundary*/ 263 ptoken(from, SKIP); 264 /* 265 * Set the skip so it lands someplace beyond 266 * the end of this buffer. 267 * When we pull this skip out in the second pass, 268 * we will temporarily move the current pointer 269 * out beyond the end of the buffer, but immediately 270 * do a compare and fail the compare, and then reset 271 * all the pointers correctly to point into the next buffer. 272 */ 273 bskiplg(from, TOKBUFLG + 1); 274 /* 275 * Now, force from to be in the same buffer as to 276 */ 277 (bytetoktype *)from = (bytetoktype *)&(emptybuf->toks[0]); 278 } 279 /* 280 * Now, to and from are in the same buffer 281 */ 282 if (from > to) 283 yyerror("Internal error: bad skip construction"); 284 else { 285 if ( (diff = (bytetoktype *)to - (bytetoktype *)from) >= 286 (sizeof(bytetoktype) + sizeof(lgtype) + 1)) { 287 ptoken(from, SKIP); 288 bskipfromto(from, to); 289 } else { 290 for ( ; diff > 0; --diff) 291 ptoken(from, VOID); 292 } 293 } 294 } 295 296 movestr(to, from, lg) 297 char *to; /* 4(ap) */ 298 char *from; /* 8(ap) */ 299 int lg; /* 12(ap) */ 300 { 301 if (lg <= 0) 302 return; 303 ; 304 asm("movc3 12(ap),*8(ap),*4(ap)"); 305 ; 306 } 307 308 new_dot_s(namep) 309 char *namep; 310 { 311 newfflag = 1; 312 newfname = namep; 313 dotsname = namep; 314 lineno = 1; 315 scanlineno = 1; 316 } 317 318 min(a, b) 319 { 320 return(a < b ? a : b); 321 } 322