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