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