date and time created 88/07/22 16:08:01 by bostic
[unix-history] / usr / src / old / as.vax / asscan2.c
CommitLineData
3bd55f52 1/*
bcf1365c
DF
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.
3bd55f52 5 */
bcf1365c 6
3bd55f52 7#ifndef lint
bcf1365c 8static char sccsid[] = "@(#)asscan2.c 5.1 (Berkeley) %G%";
3bd55f52
RH
9#endif not lint
10
11#include "asscanl.h"
12044a7d 12
3bd55f52 13static inttoktype oval = NL;
c86c4907 14#define ASINBUFSIZ 4096
12044a7d
RH
15char inbufunget[8];
16char inbuffer[ASINBUFSIZ];
17char *Ginbufptr = inbuffer;
18int Ginbufcnt = 0;
55520623 19int scannerhadeof;
12044a7d
RH
20
21fillinbuffer()
22{
23 int nread;
12044a7d
RH
24 int goal;
25 int got;
26
27 nread = 0;
55520623 28 if (scannerhadeof == 0){
12044a7d
RH
29 goal = sizeof(inbuffer);
30 do {
31 got = read(stdin->_file, inbuffer + nread, goal);
32 if (got == 0)
55520623 33 scannerhadeof = 1;
12044a7d
RH
34 if (got <= 0)
35 break;
36 nread += got;
37 goal -= got;
38 } while (goal);
55520623
RH
39 } else {
40 scannerhadeof = 0;
12044a7d 41 }
3bd55f52 42 /*
12044a7d
RH
43 * getchar assumes that Ginbufcnt and Ginbufptr
44 * are adjusted as if one character has been removed
45 * from the input.
3bd55f52 46 */
12044a7d
RH
47 if (nread == 0){
48 inbuffer[0] = EOFCHAR;
49 nread = 1;
50 }
51 Ginbufcnt = nread - 1;
52 Ginbufptr = inbuffer + 1;
53}
3bd55f52 54
3bd55f52
RH
55scan_dot_s(bufferbox)
56 struct tokbufdesc *bufferbox;
57{
12044a7d
RH
58 reg char *inbufptr;
59 reg int inbufcnt;
3bd55f52
RH
60 reg int ryylval; /* local copy of lexical value */
61 extern int yylval; /* global copy of lexical value */
62 reg int val; /* the value returned */
63 int i; /* simple counter */
64 reg char *rcp;
12044a7d 65 int ch; /* treated as a character */
3bd55f52 66 int ch1; /* shadow value */
3bd55f52 67 struct symtab *op;
3bd55f52 68 ptrall lgbackpatch; /* where to stuff a string length */
12044a7d 69 reg ptrall bufptr; /* where to stuff tokens */
3bd55f52 70 ptrall bufub; /* where not to stuff tokens */
3bd55f52
RH
71 long intval; /* value of int */
72 int linescrossed; /* when doing strings and comments */
73 struct Opcode opstruct;
ffe89e04 74 reg int strlg; /* the length of a string */
3bd55f52
RH
75
76 (bytetoktype *)bufptr = (bytetoktype *) & (bufferbox->toks[0]);
77 (bytetoktype *)bufub = &(bufferbox->toks[AVAILTOKS]);
78
12044a7d 79 MEMTOREGBUF;
3bd55f52 80 if (newfflag){
ad67d5e5 81 newfflag = 0;
ffe89e04 82 ryylval = (int)savestr(newfname, strlen(newfname)+1, STR_BOTH);
ad67d5e5 83
3bd55f52
RH
84 ptoken(bufptr, IFILE);
85 ptoken(bufptr, STRING);
ad67d5e5 86 pptr(bufptr, ryylval);
3bd55f52
RH
87
88 ptoken(bufptr, ILINENO);
89 ptoken(bufptr, INT);
90 pint(bufptr, 1);
3bd55f52
RH
91 }
92
93 while (bufptr < bufub){
94 loop:
12044a7d 95 switch(ryylval = (type+1)[ch = getchar()]) {
3bd55f52 96 case SCANEOF:
12044a7d 97 endoffile: ;
3bd55f52 98 inbufptr = 0;
12044a7d
RH
99 ptoken(bufptr, PARSEEOF);
100 goto done;
3bd55f52
RH
101
102 case DIV: /*process C style comments*/
103 if ( (ch = getchar()) == '*') { /*comment prelude*/
104 int incomment;
105 linescrossed = 0;
106 incomment = 1;
107 ch = getchar(); /*skip over the * */
108 while(incomment){
109 switch(ch){
110 case '*':
111 ch = getchar();
112 incomment = (ch != '/');
113 break;
114 case '\n':
115 scanlineno++;
116 linescrossed++;
117 ch = getchar();
118 break;
119 case EOFCHAR:
120 goto endoffile;
3bd55f52
RH
121 default:
122 ch = getchar();
123 break;
124 }
125 }
126 val = ILINESKIP;
127 ryylval = linescrossed;
128 goto ret;
129 } else { /*just an ordinary DIV*/
130 ungetc(ch);
131 val = ryylval = DIV;
132 goto ret;
133 }
134 case SH:
135 if (oval == NL){
136 /*
137 * Attempt to recognize a C preprocessor
138 * style comment '^#[ \t]*[0-9]*[ \t]*".*"
139 */
140 ch = getchar(); /*bump the #*/
141 while (INCHARSET(ch, SPACE))
142 ch = getchar();/*bump white */
143 if (INCHARSET(ch, DIGIT)){
144 intval = 0;
145 while(INCHARSET(ch, DIGIT)){
146 intval = intval*10 + ch - '0';
147 ch = getchar();
148 }
149 while (INCHARSET(ch, SPACE))
150 ch = getchar();
151 if (ch == '"'){
152 ptoken(bufptr, ILINENO);
153 ptoken(bufptr, INT);
154 pint(bufptr, intval - 1);
155 ptoken(bufptr, IFILE);
156 /*
157 * The '"' has already been
158 * munched
159 *
160 * eatstr will not eat
161 * the trailing \n, so
162 * it is given to the parser
163 * and counted.
164 */
165 goto eatstr;
166 }
167 }
168 }
169 /*
170 * Well, its just an ordinary decadent comment
171 */
172 while ((ch != '\n') && (ch != EOFCHAR))
173 ch = getchar();
174 if (ch == EOFCHAR)
175 goto endoffile;
176 val = ryylval = oval = NL;
177 scanlineno++;
178 goto ret;
179
180 case NL:
181 scanlineno++;
182 val = ryylval;
183 goto ret;
184
185 case SP:
186 oval = SP; /*invalidate ^# meta comments*/
187 goto loop;
188
189 case REGOP: /* % , could be used as modulo, or register*/
190 ch = getchar();
191 if (INCHARSET(ch, DIGIT)){
192 ryylval = ch-'0';
193 if (ch=='1') {
194 if (INCHARSET( (ch = getchar()), REGDIGIT))
195 ryylval = 10+ch-'0';
196 else
197 ungetc(ch);
198 }
199 /*
200 * God only knows what the original author
201 * wanted this undocumented feature to
202 * do.
203 * %5++ is really r7
204 */
205 while(INCHARSET( (ch = getchar()), SIGN)) {
206 if (ch=='+')
207 ryylval++;
208 else
209 ryylval--;
210 }
211 ungetc(ch);
212 val = REG;
213 } else {
214 ungetc(ch);
215 val = REGOP;
216 }
217 goto ret;
218
219 case ALPH:
220 ch1 = ch;
221 if (INCHARSET(ch, SZSPECBEGIN)){
222 if( (ch = getchar()) == '`' || ch == '^'){
223 ch1 |= 0100; /*convert to lower*/
224 switch(ch1){
225 case 'b': ryylval = 1; break;
226 case 'w': ryylval = 2; break;
227 case 'l': ryylval = 4; break;
228 default: ryylval = d124; break;
229 }
230 val = SIZESPEC;
231 goto ret;
232 } else {
233 ungetc(ch);
234 ch = ch1; /*restore first character*/
235 }
236 }
237 rcp = yytext;
238 do {
abcba8d5 239 if (rcp < &yytext[NCPName])
3bd55f52
RH
240 *rcp++ = ch;
241 } while (INCHARSET ( (ch = getchar()), ALPHA | DIGIT));
242 *rcp = '\0';
243 while (INCHARSET(ch, SPACE))
244 ch = getchar();
245 ungetc(ch);
246
247 switch((op = *lookup(1))->s_tag){
248 case 0:
249 case LABELID:
250 /*
ec43bca4 251 * Its a name... (Labels are subsets of name)
3bd55f52
RH
252 */
253 ryylval = (int)op;
254 val = NAME;
255 break;
256 case INST0:
257 case INSTn:
258 case IJXXX:
259 opstruct.Op_popcode = ( (struct instab *)op)->i_popcode;
260 opstruct.Op_eopcode = ( (struct instab *)op)->i_eopcode;
261 val = op->s_tag;
262 break;
263 default:
264 ryylval = ( (struct instab *)op)->i_popcode;
265 val = op->s_tag;
266 break;
267 }
268 goto ret;
269
270 case DIG:
271 /*
12044a7d 272 * restore local inbufptr and inbufcnt
3bd55f52 273 */
12044a7d
RH
274 REGTOMEMBUF;
275 val = number(ch);
276 MEMTOREGBUF;
3bd55f52
RH
277 /*
278 * yylval or yybignum has been stuffed as a side
279 * effect to number(); get the global yylval
280 * into our fast local copy in case it was an INT.
281 */
282 ryylval = yylval;
3bd55f52
RH
283 goto ret;
284
285 case LSH:
286 case RSH:
287 /*
288 * We allow the C style operators
289 * << and >>, as well as < and >
290 */
291 if ( (ch1 = getchar()) != ch)
292 ungetc(ch1);
293 val = ryylval;
294 goto ret;
295
296 case MINUS:
297 if ( (ch = getchar()) =='(')
298 ryylval=val=MP;
299 else {
300 ungetc(ch);
301 val=MINUS;
302 }
303 goto ret;
304
305 case SQ:
306 if ((ryylval = getchar()) == '\n')
307 scanlineno++; /*not entirely correct*/
308 val = INT;
309 goto ret;
310
311 case DQ:
312 eatstr:
313 linescrossed = 0;
ffe89e04 314 for (strlg = 0; /*VOID*/; strlg++){
ad67d5e5
RH
315 switch(ch = getchar()){
316 case '"':
317 goto tailDQ;
318 default:
319 stuff:
ec43bca4 320 putc(ch, strfile);
ad67d5e5
RH
321 break;
322 case '\n':
323 yywarning("New line in a string constant");
3bd55f52
RH
324 scanlineno++;
325 linescrossed++;
326 ch = getchar();
ad67d5e5 327 switch(ch){
ad67d5e5 328 case EOFCHAR:
ec43bca4 329 putc('\n', strfile);
3bd55f52 330 ungetc(EOFCHAR);
ad67d5e5
RH
331 goto tailDQ;
332 default:
3bd55f52
RH
333 ungetc(ch);
334 ch = '\n';
335 goto stuff;
336 }
ad67d5e5
RH
337 break;
338
339 case '\\':
3bd55f52
RH
340 ch = getchar(); /*skip the '\\'*/
341 if ( INCHARSET(ch, BSESCAPE)){
342 switch (ch){
343 case 'b': ch = '\b'; goto stuff;
344 case 'f': ch = '\f'; goto stuff;
345 case 'n': ch = '\n'; goto stuff;
346 case 'r': ch = '\r'; goto stuff;
347 case 't': ch = '\t'; goto stuff;
348 }
349 }
ad67d5e5
RH
350 if ( !(INCHARSET(ch, OCTDIGIT)) )
351 goto stuff;
3bd55f52
RH
352 i = 0;
353 intval = 0;
354 while ( (i < 3) && (INCHARSET(ch, OCTDIGIT))){
ad67d5e5
RH
355 i++;
356 intval <<= 3;
357 intval += ch - '0';
3bd55f52
RH
358 ch = getchar();
359 }
360 ungetc(ch);
8a7e35d9 361 ch = (char)intval;
3bd55f52 362 goto stuff;
ad67d5e5 363 }
3bd55f52 364 }
ad67d5e5 365 tailDQ: ;
3bd55f52 366 /*
ad67d5e5 367 * account for any lines that were crossed
3bd55f52 368 */
3bd55f52 369 if (linescrossed){
ad67d5e5
RH
370 ptoken(bufptr, ILINESKIP);
371 pint(bufptr, linescrossed);
372 }
373 /*
ad67d5e5
RH
374 * Cheat: append a trailing null to the string
375 * and then adjust the string length to ignore
376 * the trailing null. If any STRING client requires
377 * the trailing null, the client can just change STRLEN
378 */
ec43bca4 379 putc(0, strfile);
ffe89e04
RH
380 ryylval = (int)savestr((char *)0, strlg + 1, STR_FILE);
381 val = STRING;
ec43bca4 382 ((struct strdesc *)ryylval)->sd_strlen -= 1;
ad67d5e5 383 goto ret;
3bd55f52
RH
384
385 case BADCHAR:
386 linescrossed = lineno;
387 lineno = scanlineno;
388 yyerror("Illegal character mapped: %d, char read:(octal) %o",
389 ryylval, ch);
390 lineno = linescrossed;
391 val = BADCHAR;
392 goto ret;
393
394 default:
395 val = ryylval;
396 goto ret;
397 } /*end of the switch*/
398 /*
399 * here with one token, so stuff it
400 */
401 ret:
402 oval = val;
403 ptoken(bufptr, val);
404 switch(val){
405 case ILINESKIP:
406 pint(bufptr, ryylval);
407 break;
408 case SIZESPEC:
409 pchar(bufptr, ryylval);
410 break;
411 case BFINT: plong(bufptr, ryylval);
412 break;
413 case INT: plong(bufptr, ryylval);
414 break;
415 case BIGNUM: pnumber(bufptr, yybignum);
416 break;
ad67d5e5
RH
417 case STRING: pptr(bufptr, (int)(char *)ryylval);
418 break;
3bd55f52
RH
419 case NAME: pptr(bufptr, (int)(struct symtab *)ryylval);
420 break;
421 case REG: pchar(bufptr, ryylval);
422 break;
423 case INST0:
424 case INSTn:
425 popcode(bufptr, opstruct);
426 break;
427 case IJXXX:
428 popcode(bufptr, opstruct);
429 pptr(bufptr, (int)(struct symtab *)symalloc());
430 break;
431 case ISTAB:
432 case ISTABSTR:
433 case ISTABNONE:
434 case ISTABDOT:
435 case IALIGN:
436 pptr(bufptr, (int)(struct symtab *)symalloc());
437 break;
438 /*
439 * default:
440 */
441 }
442 builtval: ;
443 } /*end of the while to stuff the buffer*/
444 done:
445 bufferbox->tok_count = (bytetoktype *)bufptr - &(bufferbox->toks[0]);
3bd55f52
RH
446 /*
447 * This is a real kludge:
448 *
449 * We put the last token in the buffer to be a MINUS
450 * symbol. This last token will never be picked up
451 * in the normal way, but can be looked at during
452 * a peekahead look that the short circuit expression
453 * evaluator uses to see if an expression is complicated.
454 *
455 * Consider the following situation:
456 *
457 * .word 45 + 47
458 * buffer 1 | buffer 0
459 * the peekahead would want to look across the buffer,
460 * but will look in the buffer end zone, see the minus, and
461 * fail.
462 */
463 ptoken(bufptr, MINUS);
12044a7d 464 REGTOMEMBUF;
3bd55f52 465}