Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/c068/lex.lis
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

843 lines
28 KiB
Plaintext

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 }