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[] = "@(#)asscan4.c	5.1 (Berkeley) 4/30/85";
   9: #endif not lint
  10: 
  11: #include "asscanl.h"
  12: 
  13: #define reg register
  14: #define NUMSIZE 128 /* how many characters long a number can be */
  15: #define FLTCHAR(x)  (INCHARSET((x),(DIGIT|SIGN|FLOATEXP|POINT)))
  16: 
  17: static char numbuf[NUMSIZE];
  18: 
  19: #define BACK(backval)   intval = backval; goto stuffback;
  20: 
  21: int number(ch)
  22:     reg int ch;
  23: {
  24:         int radix;
  25:         int digit;      /* part of number being constructed */
  26:     reg int intval;     /* number being constructed */
  27:     reg char    *cp;
  28:     reg char    *inbufptr;
  29:     reg int inbufcnt;
  30:         char    ch1;
  31:         Bignum  floatnumber();
  32:         Ovf overflow;   /* overflow flag */
  33:         int maxstrlg;
  34: 
  35:     MEMTOREGBUF;
  36:     cp = numbuf;
  37:     radix = 10;
  38: 
  39:     switch(ch){
  40:     case '0':
  41:         switch(ch = getchar()){
  42:         case 'b':
  43:             yylval = -1;
  44:             BACK(BFINT);
  45:         case 'f':
  46:             /*
  47: 			 * Check if it is a local label by peeking ahead
  48: 			 */
  49:             ch1 = getchar();
  50:             ungetc(ch1);
  51:             if (!FLTCHAR(ch1)){
  52:                 yylval = 1;
  53:                 BACK(BFINT);
  54:             }
  55:             /*FALLTHROUGH*/
  56:         case 'F': ch = 'f'; goto floatnum;
  57:         case 'd':
  58:         case 'D': ch = 'd'; goto floatnum;
  59:         case 'h':
  60:         case 'H': ch = 'h'; goto floatnum;
  61:         case 'g':
  62:         case 'G': ch = 'g'; goto floatnum;
  63: 
  64:         case 'x':
  65:         case 'X':
  66:             ch = '0';
  67:             radix = 16;
  68:             break;
  69:         case '0':
  70:         case '1': case '2': case '3': case '4':
  71:         case '5': case '6': case '7': case '8':
  72:         case '9':
  73:             radix = 8;
  74:             break;
  75:         default:    /* single 0 */
  76:             ungetc(ch);
  77:             intval = 0;
  78:             goto smallnum;
  79:         }
  80:         break;
  81: 
  82:     case '1': case '2': case '3': case '4':
  83:     case '5': case '6': case '7': case '8':
  84:     case '9':
  85:         switch(ch1 = getchar()){
  86:         case 'f':
  87:             yylval = ((ch - '0') + 1);
  88:             BACK(BFINT);
  89:         case 'b':
  90:             yylval = -((ch - '0') + 1);
  91:             BACK(BFINT);
  92:         default:
  93:             ungetc(ch1);    /* put back non zero */
  94:         }
  95:         radix = 10;
  96:         break;
  97:     }
  98:     intval = 0;
  99:     /*
 100: 	 *	There is a character in ch that must be used to
 101: 	 *	cons up the number; we can't ungetc it
 102: 	 */
 103:     do{
 104:         digit = ch - '0';
 105:         switch(radix){
 106:         case 8:
 107:             intval <<= 3;
 108:             break;
 109:         case 10:
 110:             intval *= 10;
 111:             break;
 112:         case 16:
 113:             intval <<= 4;
 114:             if (INCHARSET(ch, HEXLDIGIT)){
 115:                 digit = (ch - 'a') + 10;
 116:                 break;
 117:             }
 118:             if (INCHARSET(ch, HEXUDIGIT)){
 119:                 digit = (ch - 'A') + 10;
 120:                 break;
 121:             }
 122:         }
 123:         *cp++ = ch;
 124:         /*
 125: 		 *	Build a negative number, then negate it
 126: 		 */
 127:         intval -= digit;
 128: 
 129:         ch = getchar();
 130:         if(!INCHARSET(ch, DIGIT)){
 131:             if (radix != 16)
 132:                 break;
 133:             if(!INCHARSET(ch, (HEXLDIGIT|HEXUDIGIT)))
 134:                 break;
 135:         }
 136:     } while (1);
 137:     ungetc(ch);
 138:     *cp = 0;
 139:     maxstrlg = cp - numbuf;
 140:     /*
 141: 	 *	See if the number is too large for our previous calculation
 142: 	 */
 143:     switch(radix){
 144:     case 16:
 145:         if (maxstrlg > 8)
 146:             goto bignum;
 147:         break;
 148:     case 10:
 149:         if (maxstrlg >= 10)
 150:             goto bignum;
 151:         break;
 152:     case 8:
 153:         if (maxstrlg > 11)
 154:             goto bignum;
 155:         if (maxstrlg == 11 && numbuf[0] > 3)
 156:             goto bignum;
 157:         break;
 158:     }
 159:     /*
 160: 	 *	Negate the number
 161: 	 */
 162:   smallnum: ;
 163:     yylval = -intval;
 164:     BACK(INT);
 165:   bignum: ;
 166:     yybignum = as_atoi(numbuf, radix, &overflow);
 167:     BACK(BIGNUM);
 168:   floatnum: ;
 169:     REGTOMEMBUF;
 170:     yybignum = floatnumber(ch);
 171:     return(BIGNUM);
 172:  stuffback: ;
 173:     REGTOMEMBUF;
 174:     return(intval);
 175: }
 176: 
 177: #define TOOLONG \
 178:     if (cp == &numbuf[NUMSIZE]){ \
 179:         if (passno == 2) \
 180:             yywarning(toolong); \
 181:             goto process; \
 182:     }
 183: #define scanit(sign) \
 184:     REGTOMEMBUF; \
 185:     error |= scanint(sign, &cp); \
 186:     MEMTOREGBUF; \
 187:     ch = getchar(); \
 188:     TOOLONG;
 189: 
 190: Bignum floatnumber(fltradix)
 191:     int fltradix;
 192: {
 193:         char    *cp;
 194:         int ch;
 195:         char    *toolong = "Floating number too long.";
 196:         char    *prologue =
 197:             "Floating 0%c conflicts with exponent %c; choose %c";
 198:         /*
 199: 		 *	This is not implemented yet:
 200: 		 *	overflow is set on floating overflow.
 201: 		 */
 202:         Ovf overflow;
 203:         int error;
 204:         int fractOK;
 205:     reg char    *inbufptr;
 206:     reg int inbufcnt;
 207: 
 208:     MEMTOREGBUF;
 209:     cp = numbuf;
 210:     error = 0;
 211:     fractOK = 0;
 212: 
 213:     scanit(1);
 214:     if(INCHARSET(ch, POINT)){
 215:         fractOK++;
 216:         *cp++ = '.';
 217:         scanit(0);
 218:     }
 219:     if(INCHARSET(ch, FLOATEXP)){
 220:         fractOK++;
 221:         if(ch != fltradix){
 222:             if (passno == 2)
 223:                 yywarning(prologue, fltradix, ch, fltradix);
 224:         }
 225:         switch(fltradix){
 226:         case 'd':
 227:         case 'f':
 228:             *cp++ = 'e';        /* will be read by atof() */
 229:             break;
 230:         default:
 231:             *cp++ = fltradix;   /* will be read by bigatof() */
 232:             break;
 233:         }
 234:         scanit(1);
 235:     }
 236:     if (error || fractOK == 0){
 237:         yyerror("Badly formatted floating point number.");
 238:     }
 239:     ungetc(ch);
 240:     *cp++ = 0;
 241: 
 242:   process: ;
 243:     switch(fltradix){
 244:     case 'f':   fltradix = TYPF;    break;
 245:     case 'd':   fltradix = TYPD;    break;
 246:     case 'g':   fltradix = TYPG;    nGHnumbers++; break;
 247:     case 'h':   fltradix = TYPH;    nGHnumbers++; break;
 248:     }
 249:     REGTOMEMBUF;
 250:     /*
 251: 	 *	The overflow value is lost in the call to as_atof
 252: 	 */
 253:     return(as_atof(numbuf, fltradix, &overflow));
 254: }
 255: /*
 256:  *	Scan an optionally signed integer, putting back the lookahead
 257:  *	character when finished scanning.
 258:  */
 259: int scanint(signOK, dstcpp)
 260:     int signOK;
 261:     char    **dstcpp;
 262: {
 263:         int ch;
 264:         int back = 0;
 265:     reg char    *inbufptr;
 266:     reg int inbufcnt;
 267: 
 268:     MEMTOREGBUF;
 269:     ch = getchar();
 270:     while (INCHARSET(ch, SIGN)){
 271:         if (signOK && !back)
 272:             *((*dstcpp)++) = ch;
 273:         else
 274:             back = 1;
 275:         ch = getchar();
 276:     }
 277:     while (INCHARSET(ch, DIGIT)){
 278:         *((*dstcpp)++) = ch;
 279:         ch = getchar();
 280:     }
 281:     ungetc(ch);
 282:     REGTOMEMBUF;
 283:     return(back);
 284: }

Defined functions

floatnumber defined in line 190; used 2 times
number defined in line 21; used 1 times
scanint defined in line 259; used 1 times

Defined variables

numbuf defined in line 17; used 7 times
sccsid defined in line 8; never used

Defined macros

BACK defined in line 19; used 6 times
FLTCHAR defined in line 15; used 1 times
  • in line 51
NUMSIZE defined in line 14; used 2 times
TOOLONG defined in line 177; used 1 times
reg defined in line 13; used 9 times
scanit defined in line 183; used 3 times
Last modified: 1985-04-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1150
Valid CSS Valid XHTML 1.0 Strict