1File: LEX.C Page 1 1 /* 2 Copyright 1982 3 Alcyon Corporation 4 8716 Production Ave. 5 San Diego, Ca. 92121 6 */ 7 8 #include "parser.h" 9 #define SOI '\01' 10 #define STEL HSIZE/2 11 12 /* 13 * the following are the cases within gettok, all other cases are 14 * single character unambiguous tokens. Note that we need to take 15 * special care not to interfere with the single character unambiguous 16 * operators, this is why there is a gap between WHITSP and EXCLAM. 17 */ 18 #define BADC 0 /*bad character*/ 19 #define WHITSP 101 /*white space*/ 20 #define EXCLAM 102 /*exlamation point*/ 21 #define DQUOTE 103 /*double quote*/ 22 #define PERCNT 104 /*percent sign*/ 23 #define AMPER 105 /*ampersand*/ 24 #define SQUOTE 106 /*single quote*/ 25 #define STAR 107 /*asterisk or mult sign*/ 26 #define PLUS 108 /*plus sign*/ 27 #define MINUS 109 /*minus sign*/ 28 #define SLASH 110 /*divide sign*/ 29 #define DIGIT 111 /*0..9*/ 30 #define LCAROT 112 /*less than sign*/ 31 #define EQUAL 113 /*equals sign*/ 32 #define RCAROT 114 /*greater than*/ 33 #define ALPHA 115 /*a..z,A..Z and underbar*/ 34 #define CAROT 116 /*^*/ 35 #define BAR 117 /*vertical bar*/ 36 37 char ctype[] { 38 BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC, 39 BADC, WHITSP, WHITSP, WHITSP, WHITSP, WHITSP, BADC, BADC, 40 BADC, BADC, BADC, BADC, WHITSP, BADC, BADC, BADC, 41 BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC, 42 WHITSP, EXCLAM, DQUOTE, BADC, BADC, PERCNT, AMPER, SQUOTE, 43 LPAREN, RPAREN, STAR, PLUS, COMMA, MINUS, PERIOD, SLASH, 44 DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, 45 DIGIT, DIGIT, COLON, SEMI, LCAROT, EQUAL, RCAROT, QMARK, 46 BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, 47 ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, 48 ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, 49 ALPHA, ALPHA, ALPHA, LBRACK, BADC, RBRACK, CAROT, ALPHA, 50 BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, 51 ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, 52 ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, 53 ALPHA, ALPHA, ALPHA, LCURBR, BAR, RCURBR, COMPL, BADC 54 }; 55 56 /*key word table*/ 57 struct resword { 58 char *r_name; 59 int r_value; 1File: LEX.C Page 2 60 } reswords[] { 61 "auto", R_AUTO, 62 "break", R_BREAK, 63 "case", R_CASE, 64 "char", R_CHAR, 65 "continue", R_CONTINUE, 66 "do", R_DO, 67 "default", R_DEFAULT, 68 "double", R_DOUBLE, 69 "goto", R_GOTO, 70 "else", R_ELSE, 71 "extern", R_EXTERNAL, 72 "float", R_FLOAT, 73 "for", R_FOR, 74 "if", R_IF, 75 "int", R_INT, 76 "long", R_LONG, 77 "register", R_REGISTER, 78 "return", R_RETURN, 79 "short", R_SHORT, 80 "sizeof", R_SIZEOF, 81 "static", R_STATIC, 82 "struct", R_STRUCT, 83 "switch", R_SWITCH, 84 "typedef", R_TYPEDEF, 85 "union", R_UNION, 86 "unsigned", R_UNSIGNED, 87 "while", R_WHILE, 88 0, 89 }; 90 91 #define SELFMOD 0200 92 #define ASMASK 0177 93 94 /* 95 * this table is used to check for an operator after an equals sign. 96 * note that =-, =* and =& may all have an ambiguous meaning if not 97 * followed by a space, this is checked for in gettok. 98 */ 99 char asmap[] { 100 EQUALS, /*==*/ 101 EQADD, /*=+*/ 102 EQSUB|SELFMOD, /*=-*/ 103 EQMULT|SELFMOD, /*=**/ 104 EQDIV, /*=/*/ 105 EQOR, /*=|*/ 106 EQAND|SELFMOD, /*=&*/ 107 EQXOR, /*=^*/ 108 EQMOD, /*=%*/ 109 }; 110 111 char escmap[] "\b\n\r\t"; 112 int pbchar; /*pushed back character*/ 113 struct symbol *symtab[HSIZE]; /*hash table*/ 114 struct symbol *symbols; /*pointer to next avail symbol buf*/ 115 int nsyms; /*number of symbol bufs in memory*/ 116 117 /* 118 * getdec - get a decimal number 1File: LEX.C Page 3 119 * Uses Horner's method to get decimal number. Note that 120 * multiplication by 10 is cleverly programmed as two shifts and two 121 * adds. This is because long multiplies are painful on both the 122 * PDP-11 and 68000. 123 */ 124 long getdec() /* returns number*/ 125 { 126 register long value; 127 register char c; 128 129 for( value = 0; (c=ngetch()) >= '0' && c <= '9'; ) { 130 value =<< 1; /*value = value*2*/ 131 value =+ value << 2; /*value*2 + value*8 = value*10*/ 132 value =+ (c-'0'); 133 } 134 putback(c); 135 return(value); 136 } 137 138 #define BIAS 127L 139 #define EXPSIZ 4 140 #define FRACSIZ 20 141 142 long toieee(); 143 long toffp(); 144 float power10(); 145 146 /* 147 * getfp - get a floating point constant 148 * we've already gotten the significant digits, now build a 149 * floating point number with possible decimal digits and an 150 * exponent, yields an ieee formated floating point number, 151 * unless the fflag is on, then a ffp constant is generated. 152 */ 153 long 154 getfp(significant) 155 long significant; 156 { 157 register char c; 158 register long places; /* decimal places */ 159 int esign; 160 float exp, fraction, fp; 161 162 places = 0L; esign = 0; fraction = significant; exp = 0.0; 163 if ((c = ngetch()) == '.') /* get decimal places */ 164 for( ; (c=ngetch()) >= '0' && c <= '9';) { 165 fraction = fraction * 10.0; 166 fraction = fraction + (c - '0'); 167 places++; 168 } 169 170 if (c=='e' || c=='E') { /* exponent exists */ 171 esign = (peekis('-')) ? 1 : (peekis('+')) ? 0 : 0; 172 for( ; (c=ngetch()) >= '0' && c <= '9'; ) { 173 exp = exp * 10.0; 174 exp = exp + (c - '0'); 175 } 176 } 177 1File: LEX.C Page 4 178 putback(c); 179 if (esign) 180 exp = -exp; 181 places = exp - places; 182 fp = fraction * power10(places); 183 if (fflag) 184 return( toffp(fp) ); 185 else 186 return ( toieee(fp) ); 187 } 188 189 float 190 power10(pwr) /* used by getfp, 10^pwr */ 191 long pwr; 192 { 193 float f; 194 195 if (pwr < 0L) /* negative power */ 196 for (f = 1.0; pwr < 0L; pwr++) 197 f = f / 10.0; 198 else /* positive power */ 199 for (f = 1.0; pwr > 0L; pwr--) 200 f = f * 10.0; 201 return(f); 202 } 203 204 long 205 toffp(f) /* converts current machine float to ffp rep */ 206 float f; 207 { 208 register long exp; 209 register int sign, count; 210 long l; 211 212 if (f == 0.0) 213 return(0L); 214 if (f < 0.0) { 215 sign = 1; 216 f = -f; 217 } 218 else 219 sign = 0; 220 exp = 0L; 221 for( ; f >= 1.0; f = f / 2.0) 222 exp++; 223 for( ; f < 0.5; f = f * 2.0) 224 exp--; 225 f = f * 16777216.0; /* 2 ^ 24 */ 226 l = f; 227 l =<< 8; 228 if (sign) 229 l =| 0x80; 230 exp =+ 0x40; 231 l =| (exp & 0x7f); 232 return(l); 233 } 234 235 long 236 toieee(f) /* converts current machine float to ieee rep */ 1File: LEX.C Page 5 237 float f; 238 { 239 register long exp; 240 register int sign, count; 241 long l; 242 243 if (f == 0.0) 244 return(0L); 245 if (f < 0.0) { 246 sign = 1; 247 f = -f; 248 } 249 else 250 sign = 0; 251 exp = 0L; 252 for( ; f >= 2.0; f = f / 2.0) 253 exp++; 254 for( ; f < 1.0; f = f * 2.0) 255 exp--; 256 f = f - 1.0; 257 f = f * 8388608.0; /* 2 ^ 23 */ 258 l = f; 259 if (sign) 260 l =| 0x80000000; 261 exp = (exp + BIAS)<<23; 262 l =| (exp & 0x7f800000); 263 return(l); 264 } 265 266 #define toupper(c) ((c) & ~32) 267 /* gethex - get an hexidecimal number*/ 268 /* Uses Horner's method to get hexidecimal number*/ 269 long gethex() /* returns number*/ 270 { 271 register long value; 272 register char c, ch; 273 274 value = 0; 275 while( 1 ) { 276 if( (c=ngetch()) >= '0' && c <= '9' ) 277 c =- '0'; 278 else if((ch=toupper(c)) >= 'A' && ch <= 'F' ) /* [vlh] */ 279 c = ch - ('A'-10); 280 else 281 break; 282 value = (value<<4) + c; 283 } 284 putback(c); 285 return(value); 286 } 287 288 /* getoct - get an octal number*/ 289 /* Uses Horner's method to get octal number*/ 290 long getoct(flag) /* returns number*/ 291 int flag; /* string flag 1=>in string, else 0*/ 292 { 293 register long value; 294 register char c; 295 register int count; 1File: LEX.C Page 6 296 297 count = 0; 298 for( value = 0; (c=ngetch()) >= '0' && c <= '7'; ) { 299 if( flag && ++count > 3 ) 300 break; 301 value = (value<<3) + (c-'0'); 302 } 303 putback(c); 304 return(value); 305 } 306 307 /* 308 * gettok - get next token from input 309 * Checks pushed-packed token buffer, supresses / * * / comments, 310 * folds multiple character special symbols into single word token. 311 */ 312 gettok() /* returns token type*/ 313 { 314 register int c, nextc, i; 315 register char *p; 316 register long value; 317 char sym[SSIZE]; 318 319 if( peektok ) { 320 i = peektok; 321 peektok = 0; 322 return(i); 323 } 324 while( (c=ngetch()) != EOF ) { 325 switch(ctype[c]) { 326 327 case BADC: /*bad character*/ 328 error("invalid character"); 329 break; 330 331 case SEMI: 332 cvalue = 0; /* [vlh] not reserved word... */ 333 default: 334 return( ctype[c] ); 335 336 case WHITSP: /*skip all white space*/ 337 break; 338 339 case EXCLAM: /*!= or !*/ 340 return( peekis('=') ? NEQUALS : NOT ); 341 342 case DQUOTE: /*quoted string*/ 343 getstr(cstr,STRSIZE,'"'); 344 cvalue = nextlabel++; 345 return(STRING); 346 347 case PERCNT: /*%= or %*/ 348 return( peekis('=') ? EQMOD : MOD ); 349 350 case AMPER: /*&=, && or &*/ 351 return( peekis('=') ? EQAND : peekis('&') ? LAND : AND ); 352 353 case SQUOTE: /*character constant*/ 354 getstr(cstr,STRSIZE,'\''); 1File: LEX.C Page 7 355 if( cstrsize > CHRSPWORD+1 ) { 356 error("character constant too long"); 357 cstrsize = CHRSPWORD + 1; 358 } 359 cvalue = 0; 360 for( p = cstr; --cstrsize > 0; ) { 361 cvalue =<< BITSPCHAR; 362 cvalue =| (*p++ & 0377); 363 } 364 return(CINT); 365 366 case STAR: /**= or **/ 367 return( peekis('=') ? EQMULT : MULT ); 368 369 case PLUS: /*+=, ++ or +*/ 370 return( peekis('=') ? EQADD : peekis('+') ? PREINC : ADD ); 371 372 case MINUS: /*-=, --, -> or -*/ 373 return( peekis('=') ? EQSUB : peekis('-') ? PREDEC : 374 peekis('>') ? APTR : SUB ); 375 376 case SLASH: /*/ *..* /, //..., /= or /*/ 377 if( peekis('*') ) { 378 while( (c=ngetch()) != EOF ) 379 if( c == '*' && peekis('/') ) 380 break; 381 if( c == EOF ) { 382 error("no */ before EOF"); 383 return(EOF); 384 } 385 continue; 386 } 387 if( peekis('/') ) { 388 while( (c=ngetch()) != EOF && c != EOLC ) 389 ; 390 continue; 391 } 392 return( peekis('=') ? EQDIV : DIV ); 393 394 case DIGIT: /*number constant (long or reg)*/ 395 i = 0; /*flags if long constant*/ 396 if( c != '0' ) { 397 putback(c); 398 dofp: 399 value = getdec(); 400 if ((c=ngetch())=='.' || c=='e' || c=='E') { /*[vlh] 3.4 */ 401 putback(c); 402 clvalue = getfp(value); 403 return(CFLOAT); 404 } 405 putback(c); 406 if( value > 32767 || value < -32768 ) 407 i++; 408 } 409 else if( peekis('x') || peekis('X') ) { 410 value = gethex(); 411 if( value < 0 || value >= 0x10000L ) 412 i++; 413 } 1File: LEX.C Page 8 414 else { 415 if (peekis('.')) { 416 putback('.'); 417 goto dofp; 418 } 419 value = getoct(0); 420 if( value < 0 || value >= 0x10000L ) 421 i++; 422 } 423 if( peekis('l') || peekis('L') || i ) { 424 clvalue = value; 425 return(CLONG); 426 } 427 cvalue = value; 428 return(CINT); 429 430 case LCAROT: /*<=, <<, <<= or <*/ 431 return( peekis('=') ? LESSEQ : peekis('<') ? 432 (peekis('=') ? EQLSH : LSH) : LESS ); 433 434 case EQUAL: /*==, =<<, =>>, =+, ..., =*/ 435 if( peekis('<') ) { 436 if( peekis('<') ) 437 return(EQLSH); 438 } 439 else if( peekis('>') ) { 440 if( peekis('>') ) 441 return(EQRSH); 442 } 443 else if( (i=index("=+-*/|&^%",(c=ngetch()))) >= 0 ) { 444 i = asmap[i]; 445 if( i & SELFMOD ) { 446 if( (nextc=ngetch()) != ' ' ) 447 if (!wflag) /*[vlh] old fashion initialization*/ 448 error("=%c assumed",c); 449 putback(nextc); 450 } 451 return( i & ASMASK ); 452 } 453 else 454 putback(c); 455 return(ASSIGN); 456 457 case RCAROT: /*>=, >>, >>= or >*/ 458 return( peekis('=') ? GREATEQ : peekis('>') ? 459 (peekis('=') ? EQRSH : RSH) : GREAT ); 460 461 case ALPHA: /*[A-Za-z][A-Za-z0-9]**/ 462 p = &sym[0]; 463 i = SSIZE; 464 for(; ctype[c] == ALPHA || ctype[c] == DIGIT; c=ngetch(),i-- ) 465 if( i > 0 ) 466 *p++ = c; 467 if( i > 0 ) 468 *p = '\0'; 469 putback(c); 470 csp = lookup(sym); 471 if( csp->s_attrib & SRESWORD ) { 472 cvalue = csp->s_offset; 1File: LEX.C Page 9 473 return(RESWORD); 474 } 475 smember = 0; 476 return(SYMBOL); 477 478 case CAROT: /*^= or ^*/ 479 return( peekis('=') ? EQXOR : XOR ); 480 481 case BAR: /*|=, || or |*/ 482 return( peekis('=') ? EQOR : peekis('|') ? LOR : OR ); 483 484 } 485 } 486 return(EOF); 487 } 488 489 /* 490 * peekis - peeks at next character for specific character 491 * Gets next (possibly pushed back) character, if it matches 492 * the given character 1 is returned, otherwise the character 493 * is put back. 494 */ 495 peekis(tc) /* returns 1 if match, 0 otherwise*/ 496 int tc; /* test character*/ 497 { 498 register int c; 499 500 if( (c=ngetch()) == tc ) 501 return(1); 502 putback(c); 503 return(0); 504 } 505 506 /* ngetch - get a possibly pushed back character*/ 507 /* Checks pbchar variable, returns it if non-zero, handles counting*/ 508 /* of new lines and whether you are in an include or not.*/ 509 ngetch() /* returns character read or EOF*/ 510 { 511 register int c; 512 register char *ifile; 513 514 if( pbchar ) { 515 c = pbchar; 516 pbchar = 0; 517 } 518 else if( (c=getc(&ibuf)) == EOLC ) { 519 if( inclflag ) 520 inclflag = 0; 521 else 522 lineno++; 523 } 524 else if( c == SOI) { /*[vlh]add incl filename & line # */ 525 inclflag++; 526 ifile = &inclfile; 527 while ((c=getc(&ibuf)) != SOI) 528 *ifile++ = c&0377; 529 *ifile = 0; 530 inclline = getdec() & 077777; 531 c = ' '; 1File: LEX.C Page 10 532 } 533 else if( c < 0 ) 534 c = EOF; 535 return(c); 536 } 537 538 /* 539 * peekc - peek at the next non-whitespace character after token 540 * This allows for the problem of having to look at two tokens 541 * at once. The second token is always a semi-colon or colon, 542 * so we only look at the single character, rather than going 543 * thru gettok. 544 */ 545 peekc(tc) /* returns 1 if match, 0 otherwise*/ 546 int tc; /* character to look for*/ 547 { 548 register int c; 549 550 while( ctype[(c=ngetch())] == WHITSP) ; 551 if( c == tc ) 552 return(1); 553 putback(c); 554 return(0); 555 } 556 557 /* putback - puts back a single character*/ 558 /* Checks pbchar for error condition.*/ 559 putback(c) /* returns - none*/ 560 int c; 561 { 562 if( pbchar ) 563 error("too many chars pushed back"); 564 else 565 pbchar = c; 566 } 567 568 /* getstr - get a quoted (single or double) character string*/ 569 /* Gets specified number of characters, handling escapes.*/ 570 getstr(str,nchars,endc) /* returns - none*/ 571 char *str; /* pointer to string buffer*/ 572 int nchars; /* max number of characters*/ 573 char endc; /* ending string character*/ 574 { 575 register char *p; 576 register int i; 577 register int c; 578 register int j; 579 580 cstrsize = 1; 581 p = str; 582 for( i = nchars; (c=ngetch()) != endc; i-- ) { 583 if( c == EOF || c == EOLC ) { 584 error("string cannot cross line"); 585 break; 586 } 587 if( c == '\\' ) { 588 if( (c=ngetch()) >= '0' && c <= '7' ) { 589 putback(c); 590 if( (c=getoct(1)) < 0 || c > 255 ) { 1File: LEX.C Page 11 591 error("bad character constant"); 592 continue; 593 } 594 } 595 else if( (j=index("bnrt",c)) >= 0 ) 596 c = escmap[j]; 597 else if( c == EOLC ) /*escape followed by nl->ignore*/ 598 continue; 599 } 600 if( i > 0 ) { /*room left in string?*/ 601 cstrsize++; 602 *p++ = c; 603 } 604 else if( !i ) /*only say error once...*/ 605 error("string too long"); 606 } 607 if( i <= 0 ) /*string overflow?*/ 608 p--; 609 *p = '\0'; 610 } 611 612 /* syminit - initialize the symbol table, install reswords*/ 613 /* Goes thru the resword table and installs them into the symbol*/ 614 /* table.*/ 615 syminit() /* returns - none*/ 616 { 617 register struct resword *rp; 618 619 for( rp = &reswords[0]; rp->r_name != 0; rp++ ) 620 install(rp->r_name,SRESWORD|SDEFINED,rp->r_value); 621 } 622 623 /* install - install a symbol in the symbol table*/ 624 /* Allocates a symbol entry, copies info into it and links it*/ 625 /* into the hash table chain.*/ 626 char *install(sym,attrib,offset) /* returns pointer to symbol struct*/ 627 char *sym; /* symbol to install*/ 628 int attrib; /* attribues of symbol*/ 629 int offset; /* symbol offset (resword value)*/ 630 { 631 register struct symbol *sp; 632 register int i; 633 634 while( !(sp=symbols) ) { 635 if( !(sp=sbrk(SYMSIZE)) ) 636 ferror("symbol table overflow"); 637 for( i = SYMSIZE/(sizeof *symbols); --i >= 0; ) { 638 sp->s_next = symbols; 639 symbols = sp++; 640 } 641 } 642 symbols = sp->s_next; 643 sp->s_attrib = attrib; 644 sp->s_sc = 0; sp->s_type = 0; sp->s_dp = 0; sp->s_ssp = 0; 645 sp->s_offset = offset; 646 sp->s_struc = (instruct) ? strucptr[smember+instruct] : 0; 647 symcopy(sym,sp->s_symbol); /*copy symbol to symbol struct*/ 648 i = symhash(sym,instruct|smember); /*link into chain list*/ 649 sp->s_next = symtab[i]; 1File: LEX.C Page 12 650 symtab[i] = sp; 651 return(sp); 652 } 653 654 /* lookup - looks up a symbol in symbol table*/ 655 /* Hashes symbol, then goes thru chain, if not found, then*/ 656 /* installs the symbol.*/ 657 char *lookup(sym) /* returns pointer to symbol buffer*/ 658 char *sym; /* pointer to symbol*/ 659 { 660 register struct symbol *sp, *hold; 661 register char *p; 662 int exact; /* same name, diff type or offset */ 663 664 p = sym; 665 for( sp = symtab[symhash(p,0)]; sp != 0; sp = sp->s_next ) 666 if((sp->s_attrib&(SRESWORD|STYPEDEF)) && symequal(p,sp->s_symbol)) 667 return(sp); 668 if (!(smember|instruct)) { /*[vlh]*/ 669 for( sp=symtab[symhash(p,0)]; sp!=0; sp=sp->s_next ) 670 if( symequal(p,sp->s_symbol) ) return(sp); 671 } 672 else { /* doing a declaration or an expression */ 673 hold = 0; exact = 0; 674 for( sp=symtab[symhash(p,instruct|smember)]; sp!=0; sp=sp->s_next ) 675 if( symequal(p,sp->s_symbol) ) 676 if (symsame(sp,hold,&exact)) return(sp); 677 else if (!hold && !exact) hold = sp; 678 if (hold && !exact) return(hold); 679 } 680 return(install(p,0,0)); 681 } 682 683 /* freesyms - frees all local symbols at end of function declaration*/ 684 /* Searches thru symbol table, deleting all symbols marked as locals*/ 685 freesyms() /* returns - none*/ 686 { 687 register int i, tinfo; 688 register struct symbol *sp, *tp, *nextp, **htp; 689 690 for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ ) 691 for( tp = 0, sp = *htp; sp != 0; sp = nextp ) { 692 nextp = sp->s_next; 693 if( !(sp->s_attrib&SDEFINED) ) { 694 error("undefined label: %.8s",sp->s_symbol); 695 sp->s_attrib =| SDEFINED; 696 } 697 if( sp->s_attrib & (SGLOBAL|SRESWORD) ) 698 tp = sp; 699 else { 700 if( tp ) 701 tp->s_next = sp->s_next; 702 else 703 *htp = sp->s_next; 704 sp->s_next = symbols; 705 symbols = sp; 706 } 707 } 708 } 1File: LEX.C Page 13 709 710 /* chksyms - checks symbol table for undefined symbols, etc.*/ 711 /* Goes thru the symbol table checking for undeclared forward*/ 712 /* referenced structures, and outputs local symbols for debugger.*/ 713 chksyms() /* returns - none*/ 714 { 715 register struct symbol **htp, *sp; 716 register int i, sc; 717 718 for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ ) 719 for( sp = *htp; sp != 0; sp = sp->s_next ) { 720 sc = sp->s_sc; 721 if(sc!=0 && sp->s_ssp>=0 && (btype(sp->s_type))==FRSTRUCT) { 722 sp->s_ssp = frstab[sp->s_ssp]->s_ssp; /* 3.4 ssp>0 */ 723 sp->s_type = (sp->s_type&~TYPE) | STRUCT; 724 } 725 if( sc == PDECLIST ) { 726 error("not in parameter list: %.8s",sp->s_symbol); 727 sp->s_sc = AUTO; 728 } 729 if( infunc ) 730 outlocal(sp->s_type,sp->s_sc,sp->s_symbol,sp->s_offset); 731 } 732 } 733 734 /* symhash - compute hash value for symbol*/ 735 /* Sums the symbols characters and takes that modulus the hash table*/ 736 /* size.*/ 737 symhash(sym,stel) /* returns hash value for symbol*/ 738 char *sym; /* pointer to symbol*/ 739 int stel; /* structure element flag*/ 740 { 741 register char *p; 742 register int hashval, i; 743 744 hashval = (stel ? STEL : 0 ); 745 for( p = sym, i = SSIZE; *p != '\0' && i > 0; i-- ) 746 hashval =+ *p++; 747 return( hashval % HSIZE ); 748 } 749 750 /* symequal - check for symbol equality*/ 751 /* Does comparison between two symbols.*/ 752 symequal(sym1,sym2) /* returns 1 if equal, 0 otherwise*/ 753 char *sym1; /* pointer to first symbol*/ 754 char *sym2; /* pointer to second symbol*/ 755 { 756 register char *p, *q; 757 register int i; 758 759 for( p = sym1, q = sym2, i = SSIZE; *p == *q++; ) 760 if( *p++ == '\0' || --i == 0 ) 761 return(1); 762 return(0); 763 } 764 765 /* symsame - symbol member same as declared */ 766 symsame(sp,hold,exact) /* [vlh] */ 767 struct symbol *sp, *hold; 1File: LEX.C Page 14 768 int *exact; 769 { 770 if (strucptr[smember+instruct]) 771 if (strucptr[smember+instruct]==sp->s_struc) return(1); 772 if (hold) 773 if (sp->s_type != hold->s_type || sp->s_offset != hold->s_offset) 774 *exact = 1; 775 return(0); 776 } 777 778 /* symcopy - symbol copy*/ 779 /* Copies one symbol to another.*/ 780 symcopy(sym1,sym2) /* returns - none*/ 781 char *sym1; /* pointer to symbol to copy*/ 782 char *sym2; /* pointer to area to copy to*/ 783 { 784 register char *p, *q; 785 register int i; 786 787 for( p = sym1, q = sym2, i = SSIZE; --i >= 0; ) 788 *q++ = ( *p ? *p++ : '\0'); 789 } 790 791 /* index - find the index of a character in a string*/ 792 /* This is identical to Software Tools index.*/ 793 index(str,chr) /* returns index of c in str or -1*/ 794 char *str; /* pointer to string to search*/ 795 char chr; /* character to search for*/ 796 { 797 register char *s; 798 register int i; 799 800 for( s = str, i = 0; *s != '\0'; i++ ) 801 if( *s++ == chr ) 802 return(i); 803 return(-1); 804 } 805 806 /* next - if next token matches given token, skip and return success*/ 807 /* This allows for clean parsing of declarations.*/ 808 next(tok) /* returns 1 if matched, 0 otherwise*/ 809 int tok; 810 { 811 register int token; 812 813 if( (token=gettok()) == tok ) 814 return(1); 815 peektok = token; 816 return(0); 817 } 818 819 /* pbtok - put back the given token*/ 820 /* This merely sets the peektok variable*/ 821 pbtok(tok) /* returns - none*/ 822 int tok; 823 { 824 if( peektok ) 825 error("too many tokens pushed back"); 826 peektok = tok; 1File: LEX.C Page 15 827 }