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