15798Srrh /* 25798Srrh * Copyright (c) 1982 Regents of the University of California 35798Srrh */ 45798Srrh #ifndef lint 5*13467Srrh static char sccsid[] = "@(#)asscan2.c 4.9 06/30/83"; 65798Srrh #endif not lint 75798Srrh 85798Srrh #include "asscanl.h" 9*13467Srrh 105798Srrh static inttoktype oval = NL; 115798Srrh 12*13467Srrh char inbufunget[8]; 13*13467Srrh char inbuffer[ASINBUFSIZ]; 14*13467Srrh char *Ginbufptr = inbuffer; 15*13467Srrh int Ginbufcnt = 0; 16*13467Srrh 17*13467Srrh fillinbuffer() 18*13467Srrh { 19*13467Srrh int nread; 20*13467Srrh static int hadeof; 21*13467Srrh int goal; 22*13467Srrh int got; 23*13467Srrh 24*13467Srrh nread = 0; 25*13467Srrh if (hadeof == 0){ 26*13467Srrh goal = sizeof(inbuffer); 27*13467Srrh do { 28*13467Srrh got = read(stdin->_file, inbuffer + nread, goal); 29*13467Srrh if (got == 0) 30*13467Srrh hadeof = 1; 31*13467Srrh if (got <= 0) 32*13467Srrh break; 33*13467Srrh nread += got; 34*13467Srrh goal -= got; 35*13467Srrh } while (goal); 36*13467Srrh } 375798Srrh /* 38*13467Srrh * getchar assumes that Ginbufcnt and Ginbufptr 39*13467Srrh * are adjusted as if one character has been removed 40*13467Srrh * from the input. 415798Srrh */ 42*13467Srrh if (nread == 0){ 43*13467Srrh inbuffer[0] = EOFCHAR; 44*13467Srrh nread = 1; 45*13467Srrh } 46*13467Srrh Ginbufcnt = nread - 1; 47*13467Srrh Ginbufptr = inbuffer + 1; 48*13467Srrh } 495798Srrh 5013462Srrh #ifndef FLEXNAMES 5113462Srrh char strtext[NCPString + 1]; 5213462Srrh #else FLEXNAMES 5313462Srrh # if NCPName < NCPString 5413462Srrh char strtext[NCPString + 1]; 5513462Srrh # else 5613462Srrh #define strtext yytext 5713462Srrh # endif 5813462Srrh #endif FLEXNAMES 5913462Srrh 605798Srrh scan_dot_s(bufferbox) 615798Srrh struct tokbufdesc *bufferbox; 625798Srrh { 63*13467Srrh reg char *inbufptr; 64*13467Srrh reg int inbufcnt; 655798Srrh reg int ryylval; /* local copy of lexical value */ 665798Srrh extern int yylval; /* global copy of lexical value */ 675798Srrh reg int val; /* the value returned */ 685798Srrh int i; /* simple counter */ 695798Srrh reg char *rcp; 70*13467Srrh int ch; /* treated as a character */ 715798Srrh int ch1; /* shadow value */ 725798Srrh struct symtab *op; 73*13467Srrh ptrall lgbackpatch; /* where to stuff a string length */ 745798Srrh reg ptrall bufptr; /* where to stuff tokens */ 755798Srrh ptrall bufub; /* where not to stuff tokens */ 7613448Srrh reg int maxstrlg; /* how long a string can be */ 775798Srrh long intval; /* value of int */ 785798Srrh int linescrossed; /* when doing strings and comments */ 795798Srrh struct Opcode opstruct; 805798Srrh 815798Srrh (bytetoktype *)bufptr = (bytetoktype *) & (bufferbox->toks[0]); 825798Srrh (bytetoktype *)bufub = &(bufferbox->toks[AVAILTOKS]); 835798Srrh 84*13467Srrh MEMTOREGBUF; 855798Srrh if (newfflag){ 8613448Srrh newfflag = 0; 8713448Srrh ryylval = (int)savestr(newfname, strlen(newfname) + 1); 8813448Srrh 895798Srrh ptoken(bufptr, IFILE); 905798Srrh ptoken(bufptr, STRING); 9113448Srrh pptr(bufptr, ryylval); 925798Srrh 935798Srrh ptoken(bufptr, ILINENO); 945798Srrh ptoken(bufptr, INT); 955798Srrh pint(bufptr, 1); 965798Srrh } 975798Srrh 985798Srrh while (bufptr < bufub){ 995798Srrh loop: 100*13467Srrh switch(ryylval = (type+1)[ch = getchar()]) { 1015798Srrh case SCANEOF: 102*13467Srrh endoffile: ; 1035798Srrh inbufptr = 0; 104*13467Srrh ptoken(bufptr, PARSEEOF); 105*13467Srrh goto done; 1065798Srrh 1075798Srrh case DIV: /*process C style comments*/ 1085798Srrh if ( (ch = getchar()) == '*') { /*comment prelude*/ 1095798Srrh int incomment; 1105798Srrh linescrossed = 0; 1115798Srrh incomment = 1; 1125798Srrh ch = getchar(); /*skip over the * */ 1135798Srrh while(incomment){ 1145798Srrh switch(ch){ 1155798Srrh case '*': 1165798Srrh ch = getchar(); 1175798Srrh incomment = (ch != '/'); 1185798Srrh break; 1195798Srrh case '\n': 1205798Srrh scanlineno++; 1215798Srrh linescrossed++; 1225798Srrh ch = getchar(); 1235798Srrh break; 1245798Srrh case EOFCHAR: 1255798Srrh goto endoffile; 1265798Srrh default: 1275798Srrh ch = getchar(); 1285798Srrh break; 1295798Srrh } 1305798Srrh } 1315798Srrh val = ILINESKIP; 1325798Srrh ryylval = linescrossed; 1335798Srrh goto ret; 1345798Srrh } else { /*just an ordinary DIV*/ 1355798Srrh ungetc(ch); 1365798Srrh val = ryylval = DIV; 1375798Srrh goto ret; 1385798Srrh } 1395798Srrh case SH: 1405798Srrh if (oval == NL){ 1415798Srrh /* 1425798Srrh * Attempt to recognize a C preprocessor 1435798Srrh * style comment '^#[ \t]*[0-9]*[ \t]*".*" 1445798Srrh */ 1455798Srrh ch = getchar(); /*bump the #*/ 1465798Srrh while (INCHARSET(ch, SPACE)) 1475798Srrh ch = getchar();/*bump white */ 1485798Srrh if (INCHARSET(ch, DIGIT)){ 1495798Srrh intval = 0; 1505798Srrh while(INCHARSET(ch, DIGIT)){ 1515798Srrh intval = intval*10 + ch - '0'; 1525798Srrh ch = getchar(); 1535798Srrh } 1545798Srrh while (INCHARSET(ch, SPACE)) 1555798Srrh ch = getchar(); 1565798Srrh if (ch == '"'){ 1575798Srrh ptoken(bufptr, ILINENO); 1585798Srrh ptoken(bufptr, INT); 1595798Srrh pint(bufptr, intval - 1); 1605798Srrh ptoken(bufptr, IFILE); 1615798Srrh /* 1625798Srrh * The '"' has already been 1635798Srrh * munched 1645798Srrh * 1655798Srrh * eatstr will not eat 1665798Srrh * the trailing \n, so 1675798Srrh * it is given to the parser 1685798Srrh * and counted. 1695798Srrh */ 1705798Srrh goto eatstr; 1715798Srrh } 1725798Srrh } 1735798Srrh } 1745798Srrh /* 1755798Srrh * Well, its just an ordinary decadent comment 1765798Srrh */ 1775798Srrh while ((ch != '\n') && (ch != EOFCHAR)) 1785798Srrh ch = getchar(); 1795798Srrh if (ch == EOFCHAR) 1805798Srrh goto endoffile; 1815798Srrh val = ryylval = oval = NL; 1825798Srrh scanlineno++; 1835798Srrh goto ret; 1845798Srrh 1855798Srrh case NL: 1865798Srrh scanlineno++; 1875798Srrh val = ryylval; 1885798Srrh goto ret; 1895798Srrh 1905798Srrh case SP: 1915798Srrh oval = SP; /*invalidate ^# meta comments*/ 1925798Srrh goto loop; 1935798Srrh 1945798Srrh case REGOP: /* % , could be used as modulo, or register*/ 1955798Srrh ch = getchar(); 1965798Srrh if (INCHARSET(ch, DIGIT)){ 1975798Srrh ryylval = ch-'0'; 1985798Srrh if (ch=='1') { 1995798Srrh if (INCHARSET( (ch = getchar()), REGDIGIT)) 2005798Srrh ryylval = 10+ch-'0'; 2015798Srrh else 2025798Srrh ungetc(ch); 2035798Srrh } 2045798Srrh /* 2055798Srrh * God only knows what the original author 2065798Srrh * wanted this undocumented feature to 2075798Srrh * do. 2085798Srrh * %5++ is really r7 2095798Srrh */ 2105798Srrh while(INCHARSET( (ch = getchar()), SIGN)) { 2115798Srrh if (ch=='+') 2125798Srrh ryylval++; 2135798Srrh else 2145798Srrh ryylval--; 2155798Srrh } 2165798Srrh ungetc(ch); 2175798Srrh val = REG; 2185798Srrh } else { 2195798Srrh ungetc(ch); 2205798Srrh val = REGOP; 2215798Srrh } 2225798Srrh goto ret; 2235798Srrh 2245798Srrh case ALPH: 2255798Srrh ch1 = ch; 2265798Srrh if (INCHARSET(ch, SZSPECBEGIN)){ 2275798Srrh if( (ch = getchar()) == '`' || ch == '^'){ 2285798Srrh ch1 |= 0100; /*convert to lower*/ 2295798Srrh switch(ch1){ 2305798Srrh case 'b': ryylval = 1; break; 2315798Srrh case 'w': ryylval = 2; break; 2325798Srrh case 'l': ryylval = 4; break; 2335798Srrh default: ryylval = d124; break; 2345798Srrh } 2355798Srrh val = SIZESPEC; 2365798Srrh goto ret; 2375798Srrh } else { 2385798Srrh ungetc(ch); 2395798Srrh ch = ch1; /*restore first character*/ 2405798Srrh } 2415798Srrh } 2425798Srrh rcp = yytext; 2435798Srrh do { 24413462Srrh if (rcp < &yytext[NCPName]) 2455798Srrh *rcp++ = ch; 2465798Srrh } while (INCHARSET ( (ch = getchar()), ALPHA | DIGIT)); 2475798Srrh *rcp = '\0'; 2485798Srrh while (INCHARSET(ch, SPACE)) 2495798Srrh ch = getchar(); 2505798Srrh ungetc(ch); 2515798Srrh 2525798Srrh switch((op = *lookup(1))->s_tag){ 2535798Srrh case 0: 2545798Srrh case LABELID: 2555798Srrh /* 2565798Srrh * Its a name... (Labels are subsets ofname) 2575798Srrh */ 2585798Srrh ryylval = (int)op; 2595798Srrh val = NAME; 2605798Srrh break; 2615798Srrh case INST0: 2625798Srrh case INSTn: 2635798Srrh case IJXXX: 2645798Srrh opstruct.Op_popcode = ( (struct instab *)op)->i_popcode; 2655798Srrh opstruct.Op_eopcode = ( (struct instab *)op)->i_eopcode; 2665798Srrh val = op->s_tag; 2675798Srrh break; 2685798Srrh default: 2695798Srrh ryylval = ( (struct instab *)op)->i_popcode; 2705798Srrh val = op->s_tag; 2715798Srrh break; 2725798Srrh } 2735798Srrh goto ret; 2745798Srrh 2755798Srrh case DIG: 2765798Srrh /* 277*13467Srrh * restore local inbufptr and inbufcnt 2785798Srrh */ 279*13467Srrh REGTOMEMBUF; 280*13467Srrh val = number(ch); 281*13467Srrh MEMTOREGBUF; 2825798Srrh /* 2835798Srrh * yylval or yybignum has been stuffed as a side 2845798Srrh * effect to number(); get the global yylval 2855798Srrh * into our fast local copy in case it was an INT. 2865798Srrh */ 2875798Srrh ryylval = yylval; 2885798Srrh goto ret; 2895798Srrh 2905798Srrh case LSH: 2915798Srrh case RSH: 2925798Srrh /* 2935798Srrh * We allow the C style operators 2945798Srrh * << and >>, as well as < and > 2955798Srrh */ 2965798Srrh if ( (ch1 = getchar()) != ch) 2975798Srrh ungetc(ch1); 2985798Srrh val = ryylval; 2995798Srrh goto ret; 3005798Srrh 3015798Srrh case MINUS: 3025798Srrh if ( (ch = getchar()) =='(') 3035798Srrh ryylval=val=MP; 3045798Srrh else { 3055798Srrh ungetc(ch); 3065798Srrh val=MINUS; 3075798Srrh } 3085798Srrh goto ret; 3095798Srrh 3105798Srrh case SQ: 3115798Srrh if ((ryylval = getchar()) == '\n') 3125798Srrh scanlineno++; /*not entirely correct*/ 3135798Srrh val = INT; 3145798Srrh goto ret; 3155798Srrh 3165798Srrh case DQ: 3175798Srrh eatstr: 3185798Srrh linescrossed = 0; 31913462Srrh for(rcp = strtext, maxstrlg = NCPString; maxstrlg > 0; --maxstrlg){ 32013448Srrh switch(ch = getchar()){ 32113448Srrh case '"': 32213448Srrh goto tailDQ; 32313448Srrh default: 32413448Srrh stuff: 32513448Srrh pchar(rcp, ch); 32613448Srrh break; 32713448Srrh case '\n': 32813448Srrh yywarning("New line in a string constant"); 3295798Srrh scanlineno++; 3305798Srrh linescrossed++; 3315798Srrh ch = getchar(); 33213448Srrh switch(ch){ 33313448Srrh case EOFCHAR: 33413448Srrh pchar(rcp, '\n'); 3355798Srrh ungetc(EOFCHAR); 33613448Srrh goto tailDQ; 33713448Srrh default: 3385798Srrh ungetc(ch); 3395798Srrh ch = '\n'; 3405798Srrh goto stuff; 3415798Srrh } 34213448Srrh break; 34313448Srrh 34413448Srrh case '\\': 3455798Srrh ch = getchar(); /*skip the '\\'*/ 3465798Srrh if ( INCHARSET(ch, BSESCAPE)){ 3475798Srrh switch (ch){ 3485798Srrh case 'b': ch = '\b'; goto stuff; 3495798Srrh case 'f': ch = '\f'; goto stuff; 3505798Srrh case 'n': ch = '\n'; goto stuff; 3515798Srrh case 'r': ch = '\r'; goto stuff; 3525798Srrh case 't': ch = '\t'; goto stuff; 3535798Srrh } 3545798Srrh } 35513448Srrh if ( !(INCHARSET(ch, OCTDIGIT)) ) 35613448Srrh goto stuff; 3575798Srrh i = 0; 3585798Srrh intval = 0; 3595798Srrh while ( (i < 3) && (INCHARSET(ch, OCTDIGIT))){ 36013448Srrh i++; 36113448Srrh intval <<= 3; 36213448Srrh intval += ch - '0'; 3635798Srrh ch = getchar(); 3645798Srrh } 3655798Srrh ungetc(ch); 3666558Srrh ch = (char)intval; 3675798Srrh goto stuff; 36813448Srrh } 3695798Srrh } 37013448Srrh tailDQ: ; 3715798Srrh /* 37213448Srrh * account for any lines that were crossed 3735798Srrh */ 3745798Srrh if (linescrossed){ 37513448Srrh ptoken(bufptr, ILINESKIP); 37613448Srrh pint(bufptr, linescrossed); 37713448Srrh } 37813448Srrh /* 37913462Srrh * put the string in strtext into the string pool 38013448Srrh * 38113448Srrh * The value in ryylval points to the string; 38213448Srrh * the previous 2 bytes is the length of the string 38313448Srrh * 38413448Srrh * Cheat: append a trailing null to the string 38513448Srrh * and then adjust the string length to ignore 38613448Srrh * the trailing null. If any STRING client requires 38713448Srrh * the trailing null, the client can just change STRLEN 38813448Srrh */ 38913448Srrh val = STRING; 39013448Srrh *rcp++ = 0; 39113462Srrh ryylval = (int)savestr(strtext, rcp - strtext); 39213448Srrh STRLEN(((char *)ryylval)) -= 1; 39313448Srrh goto ret; 3945798Srrh 3955798Srrh case BADCHAR: 3965798Srrh linescrossed = lineno; 3975798Srrh lineno = scanlineno; 3985798Srrh yyerror("Illegal character mapped: %d, char read:(octal) %o", 3995798Srrh ryylval, ch); 4005798Srrh lineno = linescrossed; 4015798Srrh val = BADCHAR; 4025798Srrh goto ret; 4035798Srrh 4045798Srrh default: 4055798Srrh val = ryylval; 4065798Srrh goto ret; 4075798Srrh } /*end of the switch*/ 4085798Srrh /* 4095798Srrh * here with one token, so stuff it 4105798Srrh */ 4115798Srrh ret: 4125798Srrh oval = val; 4135798Srrh ptoken(bufptr, val); 4145798Srrh switch(val){ 4155798Srrh case ILINESKIP: 4165798Srrh pint(bufptr, ryylval); 4175798Srrh break; 4185798Srrh case SIZESPEC: 4195798Srrh pchar(bufptr, ryylval); 4205798Srrh break; 4215798Srrh case BFINT: plong(bufptr, ryylval); 4225798Srrh break; 4235798Srrh case INT: plong(bufptr, ryylval); 4245798Srrh break; 4255798Srrh case BIGNUM: pnumber(bufptr, yybignum); 4265798Srrh break; 42713448Srrh case STRING: pptr(bufptr, (int)(char *)ryylval); 42813448Srrh break; 4295798Srrh case NAME: pptr(bufptr, (int)(struct symtab *)ryylval); 4305798Srrh break; 4315798Srrh case REG: pchar(bufptr, ryylval); 4325798Srrh break; 4335798Srrh case INST0: 4345798Srrh case INSTn: 4355798Srrh popcode(bufptr, opstruct); 4365798Srrh break; 4375798Srrh case IJXXX: 4385798Srrh popcode(bufptr, opstruct); 4395798Srrh pptr(bufptr, (int)(struct symtab *)symalloc()); 4405798Srrh break; 4415798Srrh case ISTAB: 4425798Srrh case ISTABSTR: 4435798Srrh case ISTABNONE: 4445798Srrh case ISTABDOT: 4455798Srrh case IALIGN: 4465798Srrh pptr(bufptr, (int)(struct symtab *)symalloc()); 4475798Srrh break; 4485798Srrh /* 4495798Srrh * default: 4505798Srrh */ 4515798Srrh } 4525798Srrh builtval: ; 4535798Srrh } /*end of the while to stuff the buffer*/ 4545798Srrh done: 4555798Srrh bufferbox->tok_count = (bytetoktype *)bufptr - &(bufferbox->toks[0]); 4565798Srrh /* 4575798Srrh * This is a real kludge: 4585798Srrh * 4595798Srrh * We put the last token in the buffer to be a MINUS 4605798Srrh * symbol. This last token will never be picked up 4615798Srrh * in the normal way, but can be looked at during 4625798Srrh * a peekahead look that the short circuit expression 4635798Srrh * evaluator uses to see if an expression is complicated. 4645798Srrh * 4655798Srrh * Consider the following situation: 4665798Srrh * 4675798Srrh * .word 45 + 47 4685798Srrh * buffer 1 | buffer 0 4695798Srrh * the peekahead would want to look across the buffer, 4705798Srrh * but will look in the buffer end zone, see the minus, and 4715798Srrh * fail. 4725798Srrh */ 4735798Srrh ptoken(bufptr, MINUS); 474*13467Srrh REGTOMEMBUF; 4755798Srrh } 476