date and time created 83/08/11 20:49:40 by sam
[unix-history] / usr / src / old / as.vax / asscan4.c
CommitLineData
ad576865
RH
1/*
2 * Copyright (c) 1982 Regents of the University of California
3 */
4#ifndef lint
12044a7d 5static char sccsid[] = "@(#)asscan4.c 4.4 %G%";
ad576865
RH
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
14static char numbuf[NUMSIZE];
15
12044a7d
RH
16#define BACK(backval) intval = backval; goto stuffback;
17
18int number(ch)
ad576865 19 reg int ch;
ad576865
RH
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;
12044a7d 26 reg int inbufcnt;
ad576865
RH
27 char ch1;
28 Bignum floatnumber();
29 Ovf overflow; /* overflow flag */
30 int maxstrlg;
31
12044a7d 32 MEMTOREGBUF;
ad576865
RH
33 cp = numbuf;
34 radix = 10;
35
36 switch(ch){
37 case '0':
38 switch(ch = getchar()){
39 case 'b':
40 yylval = -1;
12044a7d 41 BACK(BFINT);
ad576865
RH
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;
12044a7d 50 BACK(BFINT);
ad576865
RH
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);
12044a7d 85 BACK(BFINT);
ad576865
RH
86 case 'b':
87 yylval = -((ch - '0') + 1);
12044a7d 88 BACK(BFINT);
ad576865
RH
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;
12044a7d 161 BACK(INT);
ad576865
RH
162 bignum: ;
163 yybignum = as_atoi(numbuf, radix, &overflow);
12044a7d 164 BACK(BIGNUM);
ad576865 165 floatnum: ;
12044a7d
RH
166 REGTOMEMBUF;
167 yybignum = floatnumber(ch);
ad576865 168 return(BIGNUM);
12044a7d
RH
169 stuffback: ;
170 REGTOMEMBUF;
171 return(intval);
ad576865
RH
172}
173
12044a7d
RH
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;
ad576865 186
12044a7d 187Bignum floatnumber(fltradix)
ad576865 188 int fltradix;
ad576865
RH
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;
12044a7d 203 reg int inbufcnt;
ad576865 204
12044a7d 205 MEMTOREGBUF;
ad576865
RH
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 }
12044a7d 246 REGTOMEMBUF;
ad576865
RH
247 /*
248 * The overflow value is lost in the call to as_atof
249 */
ad576865
RH
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 */
12044a7d 256int scanint(signOK, dstcpp)
ad576865
RH
257 int signOK;
258 char **dstcpp;
ad576865 259{
12044a7d
RH
260 int ch;
261 int back = 0;
262 reg char *inbufptr;
263 reg int inbufcnt;
ad576865 264
12044a7d 265 MEMTOREGBUF;
ad576865
RH
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);
12044a7d 279 REGTOMEMBUF;
ad576865
RH
280 return(back);
281}