Blame


1 17e5fb89 2004-04-21 devnull %{
2 17e5fb89 2004-04-21 devnull #include <u.h>
3 17e5fb89 2004-04-21 devnull #include <libc.h>
4 17e5fb89 2004-04-21 devnull #include <bio.h>
5 17e5fb89 2004-04-21 devnull
6 17e5fb89 2004-04-21 devnull enum
7 17e5fb89 2004-04-21 devnull {
8 17e5fb89 2004-04-21 devnull Ndim = 15, /* number of dimensions */
9 17e5fb89 2004-04-21 devnull Nsym = 40, /* size of a name */
10 17e5fb89 2004-04-21 devnull Nvar = 203, /* hash table size */
11 cbeb0b26 2006-04-01 devnull Maxe = 695 /* log of largest number */
12 17e5fb89 2004-04-21 devnull };
13 17e5fb89 2004-04-21 devnull
14 17e5fb89 2004-04-21 devnull typedef struct Var Var;
15 17e5fb89 2004-04-21 devnull typedef struct Node Node;
16 17e5fb89 2004-04-21 devnull typedef struct Prefix Prefix;
17 17e5fb89 2004-04-21 devnull
18 17e5fb89 2004-04-21 devnull struct Node
19 17e5fb89 2004-04-21 devnull {
20 17e5fb89 2004-04-21 devnull double val;
21 17e5fb89 2004-04-21 devnull schar dim[Ndim];
22 17e5fb89 2004-04-21 devnull };
23 17e5fb89 2004-04-21 devnull struct Var
24 17e5fb89 2004-04-21 devnull {
25 17e5fb89 2004-04-21 devnull Rune name[Nsym];
26 17e5fb89 2004-04-21 devnull Node node;
27 17e5fb89 2004-04-21 devnull Var* link;
28 17e5fb89 2004-04-21 devnull };
29 17e5fb89 2004-04-21 devnull struct Prefix
30 17e5fb89 2004-04-21 devnull {
31 17e5fb89 2004-04-21 devnull double val;
32 17e5fb89 2004-04-21 devnull char* name;
33 17e5fb89 2004-04-21 devnull Rune* pname;
34 17e5fb89 2004-04-21 devnull };
35 17e5fb89 2004-04-21 devnull
36 17e5fb89 2004-04-21 devnull char buf[100];
37 17e5fb89 2004-04-21 devnull int digval;
38 17e5fb89 2004-04-21 devnull Biobuf* fi;
39 17e5fb89 2004-04-21 devnull Biobuf linebuf;
40 17e5fb89 2004-04-21 devnull Var* fund[Ndim];
41 17e5fb89 2004-04-21 devnull Rune line[1000];
42 17e5fb89 2004-04-21 devnull ulong lineno;
43 17e5fb89 2004-04-21 devnull int linep;
44 17e5fb89 2004-04-21 devnull int nerrors;
45 17e5fb89 2004-04-21 devnull Node one;
46 17e5fb89 2004-04-21 devnull int peekrune;
47 17e5fb89 2004-04-21 devnull Node retnode1;
48 17e5fb89 2004-04-21 devnull Node retnode2;
49 17e5fb89 2004-04-21 devnull Node retnode;
50 17e5fb89 2004-04-21 devnull Rune sym[Nsym];
51 17e5fb89 2004-04-21 devnull Var* vars[Nvar];
52 17e5fb89 2004-04-21 devnull int vflag;
53 17e5fb89 2004-04-21 devnull
54 17e5fb89 2004-04-21 devnull #define div unitsdiv
55 17e5fb89 2004-04-21 devnull
56 17e5fb89 2004-04-21 devnull extern void add(Node*, Node*, Node*);
57 17e5fb89 2004-04-21 devnull extern void div(Node*, Node*, Node*);
58 17e5fb89 2004-04-21 devnull extern int specialcase(Node*, Node*, Node*);
59 17e5fb89 2004-04-21 devnull extern double fadd(double, double);
60 17e5fb89 2004-04-21 devnull extern double fdiv(double, double);
61 17e5fb89 2004-04-21 devnull extern double fmul(double, double);
62 17e5fb89 2004-04-21 devnull extern int gdigit(void*);
63 17e5fb89 2004-04-21 devnull extern Var* lookup(int);
64 17e5fb89 2004-04-21 devnull extern void main(int, char*[]);
65 17e5fb89 2004-04-21 devnull extern void mul(Node*, Node*, Node*);
66 17e5fb89 2004-04-21 devnull extern void ofile(void);
67 17e5fb89 2004-04-21 devnull extern double pname(void);
68 17e5fb89 2004-04-21 devnull extern void printdim(char*, int, int);
69 17e5fb89 2004-04-21 devnull extern int ralpha(int);
70 17e5fb89 2004-04-21 devnull extern int readline(void);
71 17e5fb89 2004-04-21 devnull extern void sub(Node*, Node*, Node*);
72 17e5fb89 2004-04-21 devnull extern int Ufmt(Fmt*);
73 17e5fb89 2004-04-21 devnull extern void xpn(Node*, Node*, int);
74 17e5fb89 2004-04-21 devnull extern void yyerror(char*, ...);
75 17e5fb89 2004-04-21 devnull extern int yylex(void);
76 17e5fb89 2004-04-21 devnull extern int yyparse(void);
77 17e5fb89 2004-04-21 devnull
78 17e5fb89 2004-04-21 devnull typedef Node* indnode;
79 17e5fb89 2004-04-21 devnull /* #pragma varargck type "U" indnode */
80 17e5fb89 2004-04-21 devnull
81 17e5fb89 2004-04-21 devnull %}
82 17e5fb89 2004-04-21 devnull %union
83 17e5fb89 2004-04-21 devnull {
84 17e5fb89 2004-04-21 devnull Node node;
85 17e5fb89 2004-04-21 devnull Var* var;
86 17e5fb89 2004-04-21 devnull int numb;
87 17e5fb89 2004-04-21 devnull double val;
88 17e5fb89 2004-04-21 devnull }
89 17e5fb89 2004-04-21 devnull
90 17e5fb89 2004-04-21 devnull %type <node> prog expr expr0 expr1 expr2 expr3 expr4
91 17e5fb89 2004-04-21 devnull
92 17e5fb89 2004-04-21 devnull %token <val> VAL
93 17e5fb89 2004-04-21 devnull %token <var> VAR
94 17e5fb89 2004-04-21 devnull %token <numb> SUP
95 17e5fb89 2004-04-21 devnull %%
96 17e5fb89 2004-04-21 devnull prog:
97 17e5fb89 2004-04-21 devnull ':' VAR expr
98 17e5fb89 2004-04-21 devnull {
99 17e5fb89 2004-04-21 devnull int f;
100 17e5fb89 2004-04-21 devnull
101 17e5fb89 2004-04-21 devnull f = $2->node.dim[0];
102 17e5fb89 2004-04-21 devnull $2->node = $3;
103 17e5fb89 2004-04-21 devnull $2->node.dim[0] = 1;
104 17e5fb89 2004-04-21 devnull if(f)
105 17e5fb89 2004-04-21 devnull yyerror("redefinition of %S", $2->name);
106 17e5fb89 2004-04-21 devnull else
107 17e5fb89 2004-04-21 devnull if(vflag)
108 17e5fb89 2004-04-21 devnull print("%S\t%U\n", $2->name, &$2->node);
109 17e5fb89 2004-04-21 devnull }
110 17e5fb89 2004-04-21 devnull | ':' VAR '#'
111 17e5fb89 2004-04-21 devnull {
112 17e5fb89 2004-04-21 devnull int f, i;
113 17e5fb89 2004-04-21 devnull
114 17e5fb89 2004-04-21 devnull for(i=1; i<Ndim; i++)
115 17e5fb89 2004-04-21 devnull if(fund[i] == 0)
116 17e5fb89 2004-04-21 devnull break;
117 17e5fb89 2004-04-21 devnull if(i >= Ndim) {
118 17e5fb89 2004-04-21 devnull yyerror("too many dimensions");
119 17e5fb89 2004-04-21 devnull i = Ndim-1;
120 17e5fb89 2004-04-21 devnull }
121 17e5fb89 2004-04-21 devnull fund[i] = $2;
122 17e5fb89 2004-04-21 devnull
123 17e5fb89 2004-04-21 devnull f = $2->node.dim[0];
124 17e5fb89 2004-04-21 devnull $2->node = one;
125 17e5fb89 2004-04-21 devnull $2->node.dim[0] = 1;
126 17e5fb89 2004-04-21 devnull $2->node.dim[i] = 1;
127 17e5fb89 2004-04-21 devnull if(f)
128 17e5fb89 2004-04-21 devnull yyerror("redefinition of %S", $2->name);
129 17e5fb89 2004-04-21 devnull else
130 17e5fb89 2004-04-21 devnull if(vflag)
131 17e5fb89 2004-04-21 devnull print("%S\t#\n", $2->name);
132 17e5fb89 2004-04-21 devnull }
133 17e5fb89 2004-04-21 devnull | '?' expr
134 17e5fb89 2004-04-21 devnull {
135 17e5fb89 2004-04-21 devnull retnode1 = $2;
136 17e5fb89 2004-04-21 devnull }
137 17e5fb89 2004-04-21 devnull | '?'
138 17e5fb89 2004-04-21 devnull {
139 17e5fb89 2004-04-21 devnull retnode1 = one;
140 17e5fb89 2004-04-21 devnull }
141 17e5fb89 2004-04-21 devnull
142 17e5fb89 2004-04-21 devnull expr:
143 17e5fb89 2004-04-21 devnull expr4
144 17e5fb89 2004-04-21 devnull | expr '+' expr4
145 17e5fb89 2004-04-21 devnull {
146 17e5fb89 2004-04-21 devnull add(&$$, &$1, &$3);
147 17e5fb89 2004-04-21 devnull }
148 17e5fb89 2004-04-21 devnull | expr '-' expr4
149 17e5fb89 2004-04-21 devnull {
150 17e5fb89 2004-04-21 devnull sub(&$$, &$1, &$3);
151 17e5fb89 2004-04-21 devnull }
152 17e5fb89 2004-04-21 devnull
153 17e5fb89 2004-04-21 devnull expr4:
154 17e5fb89 2004-04-21 devnull expr3
155 17e5fb89 2004-04-21 devnull | expr4 '*' expr3
156 17e5fb89 2004-04-21 devnull {
157 17e5fb89 2004-04-21 devnull mul(&$$, &$1, &$3);
158 17e5fb89 2004-04-21 devnull }
159 17e5fb89 2004-04-21 devnull | expr4 '/' expr3
160 17e5fb89 2004-04-21 devnull {
161 17e5fb89 2004-04-21 devnull div(&$$, &$1, &$3);
162 17e5fb89 2004-04-21 devnull }
163 17e5fb89 2004-04-21 devnull
164 17e5fb89 2004-04-21 devnull expr3:
165 17e5fb89 2004-04-21 devnull expr2
166 17e5fb89 2004-04-21 devnull | expr3 expr2
167 17e5fb89 2004-04-21 devnull {
168 17e5fb89 2004-04-21 devnull mul(&$$, &$1, &$2);
169 17e5fb89 2004-04-21 devnull }
170 17e5fb89 2004-04-21 devnull
171 17e5fb89 2004-04-21 devnull expr2:
172 17e5fb89 2004-04-21 devnull expr1
173 17e5fb89 2004-04-21 devnull | expr2 SUP
174 17e5fb89 2004-04-21 devnull {
175 17e5fb89 2004-04-21 devnull xpn(&$$, &$1, $2);
176 17e5fb89 2004-04-21 devnull }
177 17e5fb89 2004-04-21 devnull | expr2 '^' expr1
178 17e5fb89 2004-04-21 devnull {
179 17e5fb89 2004-04-21 devnull int i;
180 17e5fb89 2004-04-21 devnull
181 17e5fb89 2004-04-21 devnull for(i=1; i<Ndim; i++)
182 17e5fb89 2004-04-21 devnull if($3.dim[i]) {
183 17e5fb89 2004-04-21 devnull yyerror("exponent has units");
184 17e5fb89 2004-04-21 devnull $$ = $1;
185 17e5fb89 2004-04-21 devnull break;
186 17e5fb89 2004-04-21 devnull }
187 17e5fb89 2004-04-21 devnull if(i >= Ndim) {
188 17e5fb89 2004-04-21 devnull i = $3.val;
189 17e5fb89 2004-04-21 devnull if(i != $3.val)
190 17e5fb89 2004-04-21 devnull yyerror("exponent not integral");
191 17e5fb89 2004-04-21 devnull xpn(&$$, &$1, i);
192 17e5fb89 2004-04-21 devnull }
193 17e5fb89 2004-04-21 devnull }
194 17e5fb89 2004-04-21 devnull
195 17e5fb89 2004-04-21 devnull expr1:
196 17e5fb89 2004-04-21 devnull expr0
197 17e5fb89 2004-04-21 devnull | expr1 '|' expr0
198 17e5fb89 2004-04-21 devnull {
199 17e5fb89 2004-04-21 devnull div(&$$, &$1, &$3);
200 17e5fb89 2004-04-21 devnull }
201 17e5fb89 2004-04-21 devnull
202 17e5fb89 2004-04-21 devnull expr0:
203 17e5fb89 2004-04-21 devnull VAR
204 17e5fb89 2004-04-21 devnull {
205 17e5fb89 2004-04-21 devnull if($1->node.dim[0] == 0) {
206 17e5fb89 2004-04-21 devnull yyerror("undefined %S", $1->name);
207 17e5fb89 2004-04-21 devnull $$ = one;
208 17e5fb89 2004-04-21 devnull } else
209 17e5fb89 2004-04-21 devnull $$ = $1->node;
210 17e5fb89 2004-04-21 devnull }
211 17e5fb89 2004-04-21 devnull | VAL
212 17e5fb89 2004-04-21 devnull {
213 17e5fb89 2004-04-21 devnull $$ = one;
214 17e5fb89 2004-04-21 devnull $$.val = $1;
215 17e5fb89 2004-04-21 devnull }
216 17e5fb89 2004-04-21 devnull | '(' expr ')'
217 17e5fb89 2004-04-21 devnull {
218 17e5fb89 2004-04-21 devnull $$ = $2;
219 17e5fb89 2004-04-21 devnull }
220 17e5fb89 2004-04-21 devnull %%
221 17e5fb89 2004-04-21 devnull
222 17e5fb89 2004-04-21 devnull int
223 17e5fb89 2004-04-21 devnull yylex(void)
224 17e5fb89 2004-04-21 devnull {
225 17e5fb89 2004-04-21 devnull int c, i;
226 17e5fb89 2004-04-21 devnull
227 17e5fb89 2004-04-21 devnull c = peekrune;
228 17e5fb89 2004-04-21 devnull peekrune = ' ';
229 17e5fb89 2004-04-21 devnull
230 17e5fb89 2004-04-21 devnull loop:
231 17e5fb89 2004-04-21 devnull if((c >= '0' && c <= '9') || c == '.')
232 17e5fb89 2004-04-21 devnull goto numb;
233 17e5fb89 2004-04-21 devnull if(ralpha(c))
234 17e5fb89 2004-04-21 devnull goto alpha;
235 17e5fb89 2004-04-21 devnull switch(c) {
236 17e5fb89 2004-04-21 devnull case ' ':
237 17e5fb89 2004-04-21 devnull case '\t':
238 17e5fb89 2004-04-21 devnull c = line[linep++];
239 17e5fb89 2004-04-21 devnull goto loop;
240 17e5fb89 2004-04-21 devnull case 0xd7:
241 17e5fb89 2004-04-21 devnull return 0x2a;
242 17e5fb89 2004-04-21 devnull case 0xf7:
243 17e5fb89 2004-04-21 devnull return 0x2f;
244 17e5fb89 2004-04-21 devnull case 0xb9:
245 17e5fb89 2004-04-21 devnull case 0x2071:
246 17e5fb89 2004-04-21 devnull yylval.numb = 1;
247 17e5fb89 2004-04-21 devnull return SUP;
248 17e5fb89 2004-04-21 devnull case 0xb2:
249 17e5fb89 2004-04-21 devnull case 0x2072:
250 17e5fb89 2004-04-21 devnull yylval.numb = 2;
251 17e5fb89 2004-04-21 devnull return SUP;
252 17e5fb89 2004-04-21 devnull case 0xb3:
253 17e5fb89 2004-04-21 devnull case 0x2073:
254 17e5fb89 2004-04-21 devnull yylval.numb = 3;
255 17e5fb89 2004-04-21 devnull return SUP;
256 17e5fb89 2004-04-21 devnull }
257 17e5fb89 2004-04-21 devnull return c;
258 17e5fb89 2004-04-21 devnull
259 17e5fb89 2004-04-21 devnull alpha:
260 17e5fb89 2004-04-21 devnull memset(sym, 0, sizeof(sym));
261 17e5fb89 2004-04-21 devnull for(i=0;; i++) {
262 17e5fb89 2004-04-21 devnull if(i < nelem(sym))
263 17e5fb89 2004-04-21 devnull sym[i] = c;
264 17e5fb89 2004-04-21 devnull c = line[linep++];
265 17e5fb89 2004-04-21 devnull if(!ralpha(c))
266 17e5fb89 2004-04-21 devnull break;
267 17e5fb89 2004-04-21 devnull }
268 17e5fb89 2004-04-21 devnull sym[nelem(sym)-1] = 0;
269 17e5fb89 2004-04-21 devnull peekrune = c;
270 17e5fb89 2004-04-21 devnull yylval.var = lookup(0);
271 17e5fb89 2004-04-21 devnull return VAR;
272 17e5fb89 2004-04-21 devnull
273 17e5fb89 2004-04-21 devnull numb:
274 17e5fb89 2004-04-21 devnull digval = c;
275 17e5fb89 2004-04-21 devnull yylval.val = fmtcharstod(gdigit, 0);
276 17e5fb89 2004-04-21 devnull return VAL;
277 17e5fb89 2004-04-21 devnull }
278 17e5fb89 2004-04-21 devnull
279 17e5fb89 2004-04-21 devnull void
280 17e5fb89 2004-04-21 devnull main(int argc, char *argv[])
281 17e5fb89 2004-04-21 devnull {
282 17e5fb89 2004-04-21 devnull char *file;
283 17e5fb89 2004-04-21 devnull
284 17e5fb89 2004-04-21 devnull ARGBEGIN {
285 17e5fb89 2004-04-21 devnull default:
286 17e5fb89 2004-04-21 devnull print("usage: units [-v] [file]\n");
287 17e5fb89 2004-04-21 devnull exits("usage");
288 17e5fb89 2004-04-21 devnull case 'v':
289 17e5fb89 2004-04-21 devnull vflag = 1;
290 17e5fb89 2004-04-21 devnull break;
291 17e5fb89 2004-04-21 devnull } ARGEND
292 17e5fb89 2004-04-21 devnull
293 17e5fb89 2004-04-21 devnull file = unsharp("#9/lib/units");
294 17e5fb89 2004-04-21 devnull if(argc > 0)
295 17e5fb89 2004-04-21 devnull file = argv[0];
296 17e5fb89 2004-04-21 devnull fi = Bopen(file, OREAD);
297 17e5fb89 2004-04-21 devnull if(fi == 0) {
298 17e5fb89 2004-04-21 devnull print("cant open: %s\n", file);
299 17e5fb89 2004-04-21 devnull exits("open");
300 17e5fb89 2004-04-21 devnull }
301 17e5fb89 2004-04-21 devnull fmtinstall('U', Ufmt);
302 17e5fb89 2004-04-21 devnull one.val = 1;
303 17e5fb89 2004-04-21 devnull
304 17e5fb89 2004-04-21 devnull /*
305 17e5fb89 2004-04-21 devnull * read the 'units' file to
306 17e5fb89 2004-04-21 devnull * develope a database
307 17e5fb89 2004-04-21 devnull */
308 17e5fb89 2004-04-21 devnull lineno = 0;
309 17e5fb89 2004-04-21 devnull for(;;) {
310 17e5fb89 2004-04-21 devnull lineno++;
311 17e5fb89 2004-04-21 devnull if(readline())
312 17e5fb89 2004-04-21 devnull break;
313 17e5fb89 2004-04-21 devnull if(line[0] == 0 || line[0] == '/')
314 17e5fb89 2004-04-21 devnull continue;
315 17e5fb89 2004-04-21 devnull peekrune = ':';
316 17e5fb89 2004-04-21 devnull yyparse();
317 17e5fb89 2004-04-21 devnull }
318 17e5fb89 2004-04-21 devnull
319 17e5fb89 2004-04-21 devnull /*
320 17e5fb89 2004-04-21 devnull * read the console to
321 17e5fb89 2004-04-21 devnull * print ratio of pairs
322 17e5fb89 2004-04-21 devnull */
323 17e5fb89 2004-04-21 devnull Bterm(fi);
324 17e5fb89 2004-04-21 devnull fi = &linebuf;
325 17e5fb89 2004-04-21 devnull Binit(fi, 0, OREAD);
326 17e5fb89 2004-04-21 devnull lineno = 0;
327 17e5fb89 2004-04-21 devnull for(;;) {
328 17e5fb89 2004-04-21 devnull if(lineno & 1)
329 17e5fb89 2004-04-21 devnull print("you want: ");
330 17e5fb89 2004-04-21 devnull else
331 17e5fb89 2004-04-21 devnull print("you have: ");
332 17e5fb89 2004-04-21 devnull if(readline())
333 17e5fb89 2004-04-21 devnull break;
334 17e5fb89 2004-04-21 devnull peekrune = '?';
335 17e5fb89 2004-04-21 devnull nerrors = 0;
336 17e5fb89 2004-04-21 devnull yyparse();
337 17e5fb89 2004-04-21 devnull if(nerrors)
338 17e5fb89 2004-04-21 devnull continue;
339 17e5fb89 2004-04-21 devnull if(lineno & 1) {
340 17e5fb89 2004-04-21 devnull if(specialcase(&retnode, &retnode2, &retnode1))
341 17e5fb89 2004-04-21 devnull print("\tis %U\n", &retnode);
342 17e5fb89 2004-04-21 devnull else {
343 17e5fb89 2004-04-21 devnull div(&retnode, &retnode2, &retnode1);
344 17e5fb89 2004-04-21 devnull print("\t* %U\n", &retnode);
345 17e5fb89 2004-04-21 devnull div(&retnode, &retnode1, &retnode2);
346 17e5fb89 2004-04-21 devnull print("\t/ %U\n", &retnode);
347 17e5fb89 2004-04-21 devnull }
348 17e5fb89 2004-04-21 devnull } else
349 17e5fb89 2004-04-21 devnull retnode2 = retnode1;
350 17e5fb89 2004-04-21 devnull lineno++;
351 17e5fb89 2004-04-21 devnull }
352 17e5fb89 2004-04-21 devnull print("\n");
353 17e5fb89 2004-04-21 devnull exits(0);
354 17e5fb89 2004-04-21 devnull }
355 17e5fb89 2004-04-21 devnull
356 17e5fb89 2004-04-21 devnull /*
357 17e5fb89 2004-04-21 devnull * all characters that have some
358 17e5fb89 2004-04-21 devnull * meaning. rest are usable as names
359 17e5fb89 2004-04-21 devnull */
360 17e5fb89 2004-04-21 devnull int
361 17e5fb89 2004-04-21 devnull ralpha(int c)
362 17e5fb89 2004-04-21 devnull {
363 17e5fb89 2004-04-21 devnull switch(c) {
364 17e5fb89 2004-04-21 devnull case 0:
365 17e5fb89 2004-04-21 devnull case '+':
366 17e5fb89 2004-04-21 devnull case '-':
367 17e5fb89 2004-04-21 devnull case '*':
368 17e5fb89 2004-04-21 devnull case '/':
369 17e5fb89 2004-04-21 devnull case '[':
370 17e5fb89 2004-04-21 devnull case ']':
371 17e5fb89 2004-04-21 devnull case '(':
372 17e5fb89 2004-04-21 devnull case ')':
373 17e5fb89 2004-04-21 devnull case '^':
374 17e5fb89 2004-04-21 devnull case ':':
375 17e5fb89 2004-04-21 devnull case '?':
376 17e5fb89 2004-04-21 devnull case ' ':
377 17e5fb89 2004-04-21 devnull case '\t':
378 17e5fb89 2004-04-21 devnull case '.':
379 17e5fb89 2004-04-21 devnull case '|':
380 17e5fb89 2004-04-21 devnull case '#':
381 17e5fb89 2004-04-21 devnull case 0xb9:
382 17e5fb89 2004-04-21 devnull case 0x2071:
383 17e5fb89 2004-04-21 devnull case 0xb2:
384 17e5fb89 2004-04-21 devnull case 0x2072:
385 17e5fb89 2004-04-21 devnull case 0xb3:
386 17e5fb89 2004-04-21 devnull case 0x2073:
387 17e5fb89 2004-04-21 devnull case 0xd7:
388 17e5fb89 2004-04-21 devnull case 0xf7:
389 17e5fb89 2004-04-21 devnull return 0;
390 17e5fb89 2004-04-21 devnull }
391 17e5fb89 2004-04-21 devnull return 1;
392 17e5fb89 2004-04-21 devnull }
393 17e5fb89 2004-04-21 devnull
394 17e5fb89 2004-04-21 devnull int
395 17e5fb89 2004-04-21 devnull gdigit(void *v)
396 17e5fb89 2004-04-21 devnull {
397 17e5fb89 2004-04-21 devnull int c;
398 17e5fb89 2004-04-21 devnull
399 17e5fb89 2004-04-21 devnull USED(v);
400 17e5fb89 2004-04-21 devnull c = digval;
401 17e5fb89 2004-04-21 devnull if(c) {
402 17e5fb89 2004-04-21 devnull digval = 0;
403 17e5fb89 2004-04-21 devnull return c;
404 17e5fb89 2004-04-21 devnull }
405 17e5fb89 2004-04-21 devnull c = line[linep++];
406 17e5fb89 2004-04-21 devnull peekrune = c;
407 17e5fb89 2004-04-21 devnull return c;
408 17e5fb89 2004-04-21 devnull }
409 17e5fb89 2004-04-21 devnull
410 17e5fb89 2004-04-21 devnull void
411 17e5fb89 2004-04-21 devnull yyerror(char *fmt, ...)
412 17e5fb89 2004-04-21 devnull {
413 17e5fb89 2004-04-21 devnull va_list arg;
414 17e5fb89 2004-04-21 devnull
415 17e5fb89 2004-04-21 devnull /*
416 17e5fb89 2004-04-21 devnull * hack to intercept message from yaccpar
417 17e5fb89 2004-04-21 devnull */
418 17e5fb89 2004-04-21 devnull if(strcmp(fmt, "syntax error") == 0) {
419 17e5fb89 2004-04-21 devnull yyerror("syntax error, last name: %S", sym);
420 17e5fb89 2004-04-21 devnull return;
421 17e5fb89 2004-04-21 devnull }
422 17e5fb89 2004-04-21 devnull va_start(arg, fmt);
423 17e5fb89 2004-04-21 devnull vseprint(buf, buf+sizeof(buf), fmt, arg);
424 17e5fb89 2004-04-21 devnull va_end(arg);
425 17e5fb89 2004-04-21 devnull print("%ld: %S\n\t%s\n", lineno, line, buf);
426 17e5fb89 2004-04-21 devnull nerrors++;
427 17e5fb89 2004-04-21 devnull if(nerrors > 5) {
428 17e5fb89 2004-04-21 devnull print("too many errors\n");
429 17e5fb89 2004-04-21 devnull exits("errors");
430 17e5fb89 2004-04-21 devnull }
431 17e5fb89 2004-04-21 devnull }
432 17e5fb89 2004-04-21 devnull
433 17e5fb89 2004-04-21 devnull void
434 17e5fb89 2004-04-21 devnull add(Node *c, Node *a, Node *b)
435 17e5fb89 2004-04-21 devnull {
436 17e5fb89 2004-04-21 devnull int i, d;
437 17e5fb89 2004-04-21 devnull
438 17e5fb89 2004-04-21 devnull for(i=0; i<Ndim; i++) {
439 17e5fb89 2004-04-21 devnull d = a->dim[i];
440 17e5fb89 2004-04-21 devnull c->dim[i] = d;
441 17e5fb89 2004-04-21 devnull if(d != b->dim[i])
442 17e5fb89 2004-04-21 devnull yyerror("add must be like units");
443 17e5fb89 2004-04-21 devnull }
444 17e5fb89 2004-04-21 devnull c->val = fadd(a->val, b->val);
445 17e5fb89 2004-04-21 devnull }
446 17e5fb89 2004-04-21 devnull
447 17e5fb89 2004-04-21 devnull void
448 17e5fb89 2004-04-21 devnull sub(Node *c, Node *a, Node *b)
449 17e5fb89 2004-04-21 devnull {
450 17e5fb89 2004-04-21 devnull int i, d;
451 17e5fb89 2004-04-21 devnull
452 17e5fb89 2004-04-21 devnull for(i=0; i<Ndim; i++) {
453 17e5fb89 2004-04-21 devnull d = a->dim[i];
454 17e5fb89 2004-04-21 devnull c->dim[i] = d;
455 17e5fb89 2004-04-21 devnull if(d != b->dim[i])
456 17e5fb89 2004-04-21 devnull yyerror("sub must be like units");
457 17e5fb89 2004-04-21 devnull }
458 17e5fb89 2004-04-21 devnull c->val = fadd(a->val, -b->val);
459 17e5fb89 2004-04-21 devnull }
460 17e5fb89 2004-04-21 devnull
461 17e5fb89 2004-04-21 devnull void
462 17e5fb89 2004-04-21 devnull mul(Node *c, Node *a, Node *b)
463 17e5fb89 2004-04-21 devnull {
464 17e5fb89 2004-04-21 devnull int i;
465 17e5fb89 2004-04-21 devnull
466 17e5fb89 2004-04-21 devnull for(i=0; i<Ndim; i++)
467 17e5fb89 2004-04-21 devnull c->dim[i] = a->dim[i] + b->dim[i];
468 17e5fb89 2004-04-21 devnull c->val = fmul(a->val, b->val);
469 17e5fb89 2004-04-21 devnull }
470 17e5fb89 2004-04-21 devnull
471 17e5fb89 2004-04-21 devnull void
472 17e5fb89 2004-04-21 devnull div(Node *c, Node *a, Node *b)
473 17e5fb89 2004-04-21 devnull {
474 17e5fb89 2004-04-21 devnull int i;
475 17e5fb89 2004-04-21 devnull
476 17e5fb89 2004-04-21 devnull for(i=0; i<Ndim; i++)
477 17e5fb89 2004-04-21 devnull c->dim[i] = a->dim[i] - b->dim[i];
478 17e5fb89 2004-04-21 devnull c->val = fdiv(a->val, b->val);
479 17e5fb89 2004-04-21 devnull }
480 17e5fb89 2004-04-21 devnull
481 17e5fb89 2004-04-21 devnull void
482 17e5fb89 2004-04-21 devnull xpn(Node *c, Node *a, int b)
483 17e5fb89 2004-04-21 devnull {
484 17e5fb89 2004-04-21 devnull int i;
485 17e5fb89 2004-04-21 devnull
486 17e5fb89 2004-04-21 devnull *c = one;
487 17e5fb89 2004-04-21 devnull if(b < 0) {
488 17e5fb89 2004-04-21 devnull b = -b;
489 17e5fb89 2004-04-21 devnull for(i=0; i<b; i++)
490 17e5fb89 2004-04-21 devnull div(c, c, a);
491 17e5fb89 2004-04-21 devnull } else
492 17e5fb89 2004-04-21 devnull for(i=0; i<b; i++)
493 17e5fb89 2004-04-21 devnull mul(c, c, a);
494 17e5fb89 2004-04-21 devnull }
495 17e5fb89 2004-04-21 devnull
496 17e5fb89 2004-04-21 devnull int
497 17e5fb89 2004-04-21 devnull specialcase(Node *c, Node *a, Node *b)
498 17e5fb89 2004-04-21 devnull {
499 17e5fb89 2004-04-21 devnull int i, d, d1, d2;
500 17e5fb89 2004-04-21 devnull
501 17e5fb89 2004-04-21 devnull d1 = 0;
502 17e5fb89 2004-04-21 devnull d2 = 0;
503 17e5fb89 2004-04-21 devnull for(i=1; i<Ndim; i++) {
504 17e5fb89 2004-04-21 devnull d = a->dim[i];
505 17e5fb89 2004-04-21 devnull if(d) {
506 17e5fb89 2004-04-21 devnull if(d != 1 || d1)
507 17e5fb89 2004-04-21 devnull return 0;
508 17e5fb89 2004-04-21 devnull d1 = i;
509 17e5fb89 2004-04-21 devnull }
510 17e5fb89 2004-04-21 devnull d = b->dim[i];
511 17e5fb89 2004-04-21 devnull if(d) {
512 17e5fb89 2004-04-21 devnull if(d != 1 || d2)
513 17e5fb89 2004-04-21 devnull return 0;
514 17e5fb89 2004-04-21 devnull d2 = i;
515 17e5fb89 2004-04-21 devnull }
516 17e5fb89 2004-04-21 devnull }
517 17e5fb89 2004-04-21 devnull if(d1 == 0 || d2 == 0)
518 17e5fb89 2004-04-21 devnull return 0;
519 17e5fb89 2004-04-21 devnull
520 17e5fb89 2004-04-21 devnull if(memcmp(fund[d1]->name, L"°C", 3*sizeof(Rune)) == 0 &&
521 17e5fb89 2004-04-21 devnull memcmp(fund[d2]->name, L"°F", 3*sizeof(Rune)) == 0 &&
522 17e5fb89 2004-04-21 devnull b->val == 1) {
523 17e5fb89 2004-04-21 devnull memcpy(c->dim, b->dim, sizeof(c->dim));
524 17e5fb89 2004-04-21 devnull c->val = a->val * 9. / 5. + 32.;
525 17e5fb89 2004-04-21 devnull return 1;
526 17e5fb89 2004-04-21 devnull }
527 17e5fb89 2004-04-21 devnull
528 17e5fb89 2004-04-21 devnull if(memcmp(fund[d1]->name, L"°F", 3*sizeof(Rune)) == 0 &&
529 17e5fb89 2004-04-21 devnull memcmp(fund[d2]->name, L"°C", 3*sizeof(Rune)) == 0 &&
530 17e5fb89 2004-04-21 devnull b->val == 1) {
531 17e5fb89 2004-04-21 devnull memcpy(c->dim, b->dim, sizeof(c->dim));
532 17e5fb89 2004-04-21 devnull c->val = (a->val - 32.) * 5. / 9.;
533 17e5fb89 2004-04-21 devnull return 1;
534 17e5fb89 2004-04-21 devnull }
535 17e5fb89 2004-04-21 devnull return 0;
536 17e5fb89 2004-04-21 devnull }
537 17e5fb89 2004-04-21 devnull
538 17e5fb89 2004-04-21 devnull void
539 17e5fb89 2004-04-21 devnull printdim(char *str, int d, int n)
540 17e5fb89 2004-04-21 devnull {
541 17e5fb89 2004-04-21 devnull Var *v;
542 17e5fb89 2004-04-21 devnull
543 17e5fb89 2004-04-21 devnull if(n) {
544 17e5fb89 2004-04-21 devnull v = fund[d];
545 17e5fb89 2004-04-21 devnull if(v)
546 17e5fb89 2004-04-21 devnull sprint(strchr(str, 0), " %S", v->name);
547 17e5fb89 2004-04-21 devnull else
548 17e5fb89 2004-04-21 devnull sprint(strchr(str, 0), " [%d]", d);
549 17e5fb89 2004-04-21 devnull switch(n) {
550 17e5fb89 2004-04-21 devnull case 1:
551 17e5fb89 2004-04-21 devnull break;
552 17e5fb89 2004-04-21 devnull case 2:
553 17e5fb89 2004-04-21 devnull strcat(str, "²");
554 17e5fb89 2004-04-21 devnull break;
555 17e5fb89 2004-04-21 devnull case 3:
556 17e5fb89 2004-04-21 devnull strcat(str, "³");
557 17e5fb89 2004-04-21 devnull break;
558 17e5fb89 2004-04-21 devnull default:
559 17e5fb89 2004-04-21 devnull sprint(strchr(str, 0), "^%d", n);
560 17e5fb89 2004-04-21 devnull }
561 17e5fb89 2004-04-21 devnull }
562 17e5fb89 2004-04-21 devnull }
563 17e5fb89 2004-04-21 devnull
564 17e5fb89 2004-04-21 devnull int
565 17e5fb89 2004-04-21 devnull Ufmt(Fmt *fp)
566 17e5fb89 2004-04-21 devnull {
567 17e5fb89 2004-04-21 devnull char str[200];
568 17e5fb89 2004-04-21 devnull Node *n;
569 17e5fb89 2004-04-21 devnull int f, i, d;
570 17e5fb89 2004-04-21 devnull
571 17e5fb89 2004-04-21 devnull n = va_arg(fp->args, Node*);
572 17e5fb89 2004-04-21 devnull sprint(str, "%g", n->val);
573 17e5fb89 2004-04-21 devnull
574 17e5fb89 2004-04-21 devnull f = 0;
575 17e5fb89 2004-04-21 devnull for(i=1; i<Ndim; i++) {
576 17e5fb89 2004-04-21 devnull d = n->dim[i];
577 17e5fb89 2004-04-21 devnull if(d > 0)
578 17e5fb89 2004-04-21 devnull printdim(str, i, d);
579 17e5fb89 2004-04-21 devnull else
580 17e5fb89 2004-04-21 devnull if(d < 0)
581 17e5fb89 2004-04-21 devnull f = 1;
582 17e5fb89 2004-04-21 devnull }
583 17e5fb89 2004-04-21 devnull
584 17e5fb89 2004-04-21 devnull if(f) {
585 17e5fb89 2004-04-21 devnull strcat(str, " /");
586 17e5fb89 2004-04-21 devnull for(i=1; i<Ndim; i++) {
587 17e5fb89 2004-04-21 devnull d = n->dim[i];
588 17e5fb89 2004-04-21 devnull if(d < 0)
589 17e5fb89 2004-04-21 devnull printdim(str, i, -d);
590 17e5fb89 2004-04-21 devnull }
591 17e5fb89 2004-04-21 devnull }
592 17e5fb89 2004-04-21 devnull
593 17e5fb89 2004-04-21 devnull return fmtstrcpy(fp, str);
594 17e5fb89 2004-04-21 devnull }
595 17e5fb89 2004-04-21 devnull
596 17e5fb89 2004-04-21 devnull int
597 17e5fb89 2004-04-21 devnull readline(void)
598 17e5fb89 2004-04-21 devnull {
599 17e5fb89 2004-04-21 devnull int i, c;
600 17e5fb89 2004-04-21 devnull
601 17e5fb89 2004-04-21 devnull linep = 0;
602 17e5fb89 2004-04-21 devnull for(i=0;; i++) {
603 17e5fb89 2004-04-21 devnull c = Bgetrune(fi);
604 17e5fb89 2004-04-21 devnull if(c < 0)
605 17e5fb89 2004-04-21 devnull return 1;
606 17e5fb89 2004-04-21 devnull if(c == '\n')
607 17e5fb89 2004-04-21 devnull break;
608 17e5fb89 2004-04-21 devnull if(i < nelem(line))
609 17e5fb89 2004-04-21 devnull line[i] = c;
610 17e5fb89 2004-04-21 devnull }
611 17e5fb89 2004-04-21 devnull if(i >= nelem(line))
612 17e5fb89 2004-04-21 devnull i = nelem(line)-1;
613 17e5fb89 2004-04-21 devnull line[i] = 0;
614 17e5fb89 2004-04-21 devnull return 0;
615 17e5fb89 2004-04-21 devnull }
616 17e5fb89 2004-04-21 devnull
617 17e5fb89 2004-04-21 devnull Var*
618 17e5fb89 2004-04-21 devnull lookup(int f)
619 17e5fb89 2004-04-21 devnull {
620 17e5fb89 2004-04-21 devnull int i;
621 17e5fb89 2004-04-21 devnull Var *v, *w;
622 17e5fb89 2004-04-21 devnull double p;
623 17e5fb89 2004-04-21 devnull ulong h;
624 17e5fb89 2004-04-21 devnull
625 17e5fb89 2004-04-21 devnull h = 0;
626 17e5fb89 2004-04-21 devnull for(i=0; sym[i]; i++)
627 17e5fb89 2004-04-21 devnull h = h*13 + sym[i];
628 17e5fb89 2004-04-21 devnull h %= nelem(vars);
629 17e5fb89 2004-04-21 devnull
630 17e5fb89 2004-04-21 devnull for(v=vars[h]; v; v=v->link)
631 17e5fb89 2004-04-21 devnull if(memcmp(sym, v->name, sizeof(sym)) == 0)
632 17e5fb89 2004-04-21 devnull return v;
633 17e5fb89 2004-04-21 devnull if(f)
634 17e5fb89 2004-04-21 devnull return 0;
635 17e5fb89 2004-04-21 devnull v = malloc(sizeof(*v));
636 17e5fb89 2004-04-21 devnull if(v == nil) {
637 17e5fb89 2004-04-21 devnull fprint(2, "out of memory\n");
638 17e5fb89 2004-04-21 devnull exits("mem");
639 17e5fb89 2004-04-21 devnull }
640 17e5fb89 2004-04-21 devnull memset(v, 0, sizeof(*v));
641 17e5fb89 2004-04-21 devnull memcpy(v->name, sym, sizeof(sym));
642 17e5fb89 2004-04-21 devnull v->link = vars[h];
643 17e5fb89 2004-04-21 devnull vars[h] = v;
644 17e5fb89 2004-04-21 devnull
645 17e5fb89 2004-04-21 devnull p = 1;
646 17e5fb89 2004-04-21 devnull for(;;) {
647 17e5fb89 2004-04-21 devnull p = fmul(p, pname());
648 17e5fb89 2004-04-21 devnull if(p == 0)
649 17e5fb89 2004-04-21 devnull break;
650 17e5fb89 2004-04-21 devnull w = lookup(1);
651 17e5fb89 2004-04-21 devnull if(w) {
652 17e5fb89 2004-04-21 devnull v->node = w->node;
653 17e5fb89 2004-04-21 devnull v->node.val = fmul(v->node.val, p);
654 17e5fb89 2004-04-21 devnull break;
655 17e5fb89 2004-04-21 devnull }
656 17e5fb89 2004-04-21 devnull }
657 17e5fb89 2004-04-21 devnull return v;
658 17e5fb89 2004-04-21 devnull }
659 17e5fb89 2004-04-21 devnull
660 17e5fb89 2004-04-21 devnull Prefix prefix[] =
661 17e5fb89 2004-04-21 devnull {
662 17e5fb89 2004-04-21 devnull 1e-24, "yocto", 0,
663 17e5fb89 2004-04-21 devnull 1e-21, "zepto", 0,
664 17e5fb89 2004-04-21 devnull 1e-18, "atto", 0,
665 17e5fb89 2004-04-21 devnull 1e-15, "femto", 0,
666 17e5fb89 2004-04-21 devnull 1e-12, "pico", 0,
667 17e5fb89 2004-04-21 devnull 1e-9, "nano", 0,
668 17e5fb89 2004-04-21 devnull 1e-6, "micro", 0,
669 17e5fb89 2004-04-21 devnull 1e-6, "μ", 0,
670 17e5fb89 2004-04-21 devnull 1e-3, "milli", 0,
671 17e5fb89 2004-04-21 devnull 1e-2, "centi", 0,
672 17e5fb89 2004-04-21 devnull 1e-1, "deci", 0,
673 17e5fb89 2004-04-21 devnull 1e1, "deka", 0,
674 17e5fb89 2004-04-21 devnull 1e2, "hecta", 0,
675 17e5fb89 2004-04-21 devnull 1e2, "hecto", 0,
676 17e5fb89 2004-04-21 devnull 1e3, "kilo", 0,
677 17e5fb89 2004-04-21 devnull 1e6, "mega", 0,
678 17e5fb89 2004-04-21 devnull 1e6, "meg", 0,
679 17e5fb89 2004-04-21 devnull 1e9, "giga", 0,
680 17e5fb89 2004-04-21 devnull 1e12, "tera", 0,
681 17e5fb89 2004-04-21 devnull 1e15, "peta", 0,
682 17e5fb89 2004-04-21 devnull 1e18, "exa", 0,
683 17e5fb89 2004-04-21 devnull 1e21, "zetta", 0,
684 17e5fb89 2004-04-21 devnull 1e24, "yotta", 0,
685 17e5fb89 2004-04-21 devnull 0, 0, 0,
686 17e5fb89 2004-04-21 devnull };
687 17e5fb89 2004-04-21 devnull
688 17e5fb89 2004-04-21 devnull double
689 17e5fb89 2004-04-21 devnull pname(void)
690 17e5fb89 2004-04-21 devnull {
691 17e5fb89 2004-04-21 devnull Rune *p;
692 17e5fb89 2004-04-21 devnull int i, j, c;
693 17e5fb89 2004-04-21 devnull
694 17e5fb89 2004-04-21 devnull /*
695 17e5fb89 2004-04-21 devnull * rip off normal prefixs
696 17e5fb89 2004-04-21 devnull */
697 17e5fb89 2004-04-21 devnull if(prefix[0].pname == nil){
698 17e5fb89 2004-04-21 devnull for(i=0; prefix[i].name; i++)
699 17e5fb89 2004-04-21 devnull prefix[i].pname = runesmprint("%s", prefix[i].name);
700 17e5fb89 2004-04-21 devnull }
701 17e5fb89 2004-04-21 devnull
702 17e5fb89 2004-04-21 devnull for(i=0; p=prefix[i].pname; i++) {
703 17e5fb89 2004-04-21 devnull for(j=0; c=p[j]; j++)
704 17e5fb89 2004-04-21 devnull if(c != sym[j])
705 17e5fb89 2004-04-21 devnull goto no;
706 17e5fb89 2004-04-21 devnull memmove(sym, sym+j, (Nsym-j)*sizeof(*sym));
707 17e5fb89 2004-04-21 devnull memset(sym+(Nsym-j), 0, j*sizeof(*sym));
708 17e5fb89 2004-04-21 devnull return prefix[i].val;
709 17e5fb89 2004-04-21 devnull no:;
710 17e5fb89 2004-04-21 devnull }
711 17e5fb89 2004-04-21 devnull
712 17e5fb89 2004-04-21 devnull /*
713 17e5fb89 2004-04-21 devnull * rip off 's' suffixes
714 17e5fb89 2004-04-21 devnull */
715 17e5fb89 2004-04-21 devnull for(j=0; sym[j]; j++)
716 17e5fb89 2004-04-21 devnull ;
717 17e5fb89 2004-04-21 devnull j--;
718 17e5fb89 2004-04-21 devnull /* j>1 is special hack to disallow ms finding m */
719 17e5fb89 2004-04-21 devnull if(j > 1 && sym[j] == 's') {
720 17e5fb89 2004-04-21 devnull sym[j] = 0;
721 17e5fb89 2004-04-21 devnull return 1;
722 17e5fb89 2004-04-21 devnull }
723 17e5fb89 2004-04-21 devnull return 0;
724 17e5fb89 2004-04-21 devnull }
725 17e5fb89 2004-04-21 devnull
726 17e5fb89 2004-04-21 devnull /*
727 17e5fb89 2004-04-21 devnull * careful floating point
728 17e5fb89 2004-04-21 devnull */
729 17e5fb89 2004-04-21 devnull double
730 17e5fb89 2004-04-21 devnull fmul(double a, double b)
731 17e5fb89 2004-04-21 devnull {
732 17e5fb89 2004-04-21 devnull double l;
733 17e5fb89 2004-04-21 devnull
734 17e5fb89 2004-04-21 devnull if(a <= 0) {
735 17e5fb89 2004-04-21 devnull if(a == 0)
736 17e5fb89 2004-04-21 devnull return 0;
737 17e5fb89 2004-04-21 devnull l = log(-a);
738 17e5fb89 2004-04-21 devnull } else
739 17e5fb89 2004-04-21 devnull l = log(a);
740 17e5fb89 2004-04-21 devnull
741 17e5fb89 2004-04-21 devnull if(b <= 0) {
742 17e5fb89 2004-04-21 devnull if(b == 0)
743 17e5fb89 2004-04-21 devnull return 0;
744 17e5fb89 2004-04-21 devnull l += log(-b);
745 17e5fb89 2004-04-21 devnull } else
746 17e5fb89 2004-04-21 devnull l += log(b);
747 17e5fb89 2004-04-21 devnull
748 17e5fb89 2004-04-21 devnull if(l > Maxe) {
749 17e5fb89 2004-04-21 devnull yyerror("overflow in multiply");
750 17e5fb89 2004-04-21 devnull return 1;
751 17e5fb89 2004-04-21 devnull }
752 17e5fb89 2004-04-21 devnull if(l < -Maxe) {
753 17e5fb89 2004-04-21 devnull yyerror("underflow in multiply");
754 17e5fb89 2004-04-21 devnull return 0;
755 17e5fb89 2004-04-21 devnull }
756 17e5fb89 2004-04-21 devnull return a*b;
757 17e5fb89 2004-04-21 devnull }
758 17e5fb89 2004-04-21 devnull
759 17e5fb89 2004-04-21 devnull double
760 17e5fb89 2004-04-21 devnull fdiv(double a, double b)
761 17e5fb89 2004-04-21 devnull {
762 17e5fb89 2004-04-21 devnull double l;
763 17e5fb89 2004-04-21 devnull
764 17e5fb89 2004-04-21 devnull if(a <= 0) {
765 17e5fb89 2004-04-21 devnull if(a == 0)
766 17e5fb89 2004-04-21 devnull return 0;
767 17e5fb89 2004-04-21 devnull l = log(-a);
768 17e5fb89 2004-04-21 devnull } else
769 17e5fb89 2004-04-21 devnull l = log(a);
770 17e5fb89 2004-04-21 devnull
771 17e5fb89 2004-04-21 devnull if(b <= 0) {
772 17e5fb89 2004-04-21 devnull if(b == 0) {
773 17e5fb89 2004-04-21 devnull yyerror("division by zero");
774 17e5fb89 2004-04-21 devnull return 1;
775 17e5fb89 2004-04-21 devnull }
776 17e5fb89 2004-04-21 devnull l -= log(-b);
777 17e5fb89 2004-04-21 devnull } else
778 17e5fb89 2004-04-21 devnull l -= log(b);
779 17e5fb89 2004-04-21 devnull
780 17e5fb89 2004-04-21 devnull if(l > Maxe) {
781 17e5fb89 2004-04-21 devnull yyerror("overflow in divide");
782 17e5fb89 2004-04-21 devnull return 1;
783 17e5fb89 2004-04-21 devnull }
784 17e5fb89 2004-04-21 devnull if(l < -Maxe) {
785 17e5fb89 2004-04-21 devnull yyerror("underflow in divide");
786 17e5fb89 2004-04-21 devnull return 0;
787 17e5fb89 2004-04-21 devnull }
788 17e5fb89 2004-04-21 devnull return a/b;
789 17e5fb89 2004-04-21 devnull }
790 17e5fb89 2004-04-21 devnull
791 17e5fb89 2004-04-21 devnull double
792 17e5fb89 2004-04-21 devnull fadd(double a, double b)
793 17e5fb89 2004-04-21 devnull {
794 17e5fb89 2004-04-21 devnull return a + b;
795 17e5fb89 2004-04-21 devnull }