1 /* #includes */ /*{{{C}}}*//*{{{*/
2 #ifndef NO_POSIX_SOURCE
3 #undef _POSIX_SOURCE
4 #define _POSIX_SOURCE 1
5 #undef _POSIX_C_SOURCE
6 #define _POSIX_C_SOURCE 2
7 #endif
8
9 #ifdef DMALLOC
10 #include "dmalloc.h"
11 #endif
12
13 #include <assert.h>
14 #include <ctype.h>
15 #include <errno.h>
16 #include <float.h>
17 #include <limits.h>
18 #include <math.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23
24 #include "default.h"
25 #include "eval.h"
26 #include "func.h"
27 #include "main.h"
28 #include "misc.h"
29 #include "scanner.h"
30 #include "sheet.h"
31 /*}}}*/
32
33 /* tcopy -- return copy of token */ /*{{{*/
tcopy(Token n)34 Token tcopy(Token n)
35 {
36 /* result */ /*{{{*/
37 Token result;
38 /*}}}*/
39
40 result=n;
41 if (result.type==STRING) result.u.string=strcpy(malloc(strlen(n.u.string)+1),n.u.string);
42 else if (result.type==EEK) result.u.err=strcpy(malloc(strlen(n.u.err)+1),n.u.err);
43 else if (result.type==LIDENT) result.u.lident=strcpy(malloc(strlen(n.u.lident)+1),n.u.lident);
44 return result;
45 }
46 /*}}}*/
47 /* tfree -- free dynamic data of token */ /*{{{*/
tfree(Token * n)48 void tfree(Token *n)
49 {
50 if (n->type==STRING)
51 {
52 free(n->u.string);
53 n->u.string=(char*)0;
54 }
55 else if (n->type==EEK)
56 {
57 free(n->u.err);
58 n->u.err=(char*)0;
59 }
60 else if (n->type==LIDENT)
61 {
62 free(n->u.lident);
63 n->u.lident=(char*)0;
64 }
65 }
66 /*}}}*/
67 /* tvecfree -- free a vector of pointer to tokens entirely */ /*{{{*/
tvecfree(Token ** tvec)68 void tvecfree(Token **tvec)
69 {
70 if (tvec!=(Token**)0)
71 {
72 /* variables */ /*{{{*/
73 Token **t;
74 /*}}}*/
75
76 for (t=tvec; *t!=(Token*)0; ++t)
77 {
78 tfree(*t);
79 free(*t);
80 }
81 free(tvec);
82 }
83 }
84 /*}}}*/
85 /* tadd -- + operator */ /*{{{*/
tadd(Token l,Token r)86 Token tadd(Token l, Token r)
87 {
88 /* variables */ /*{{{*/
89 Token result;
90 const char *msg;
91 /*}}}*/
92
93 if (l.type==EEK)
94 /* return left error */ /*{{{*/
95 return tcopy(l);
96 /*}}}*/
97 else if (r.type==EEK)
98 /* return right error */ /*{{{*/
99 return tcopy(r);
100 /*}}}*/
101 else if (l.type==INT && r.type==INT)
102 /* result is int sum of two ints */ /*{{{*/
103 {
104 result.type=INT;
105 result.u.integer=l.u.integer+r.u.integer;
106 }
107 /*}}}*/
108 else if (l.type==STRING && r.type==STRING)
109 /* result is concatenated strings */ /*{{{*/
110 {
111 result.type=STRING;
112 result.u.string=malloc(strlen(l.u.string)+strlen(r.u.string)+1);
113 (void)strcpy(result.u.string,l.u.string);
114 (void)strcat(result.u.string,r.u.string);
115 }
116 /*}}}*/
117 else if (l.type==EMPTY && (r.type==INT || r.type==STRING || r.type==FLOAT || r.type==EMPTY))
118 /* return right argument */ /*{{{*/
119 return tcopy(r);
120 /*}}}*/
121 else if ((l.type==INT || l.type==STRING || l.type==FLOAT) && r.type==EMPTY)
122 /* return left argument */ /*{{{*/
123 return tcopy(l);
124 /*}}}*/
125 else if (l.type==INT && r.type==FLOAT)
126 /* result is float sum of int and float */ /*{{{*/
127 {
128 result.type=FLOAT;
129 result.u.flt=((double)l.u.integer)+r.u.flt;
130 }
131 /*}}}*/
132 else if (l.type==FLOAT && r.type==INT)
133 /* result is float sum of float and int */ /*{{{*/
134 {
135 result.type=FLOAT;
136 result.u.flt=l.u.flt+((double)r.u.integer);
137 }
138 /*}}}*/
139 else if (l.type==FLOAT && r.type==FLOAT)
140 /* result is float sum of float and float */ /*{{{*/
141 {
142 result.type=FLOAT;
143 result.u.flt=l.u.flt+r.u.flt;
144 }
145 /*}}}*/
146 else if (l.type==EMPTY && r.type==EMPTY)
147 /* result is emty */ /*{{{*/
148 {
149 result.type=EMPTY;
150 }
151 /*}}}*/
152 else
153 /* result is type error */ /*{{{*/
154 {
155 result.type=EEK;
156 result.u.err=strcpy(malloc(strlen(_("wrong types for + operator"))+1),_("wrong types for + operator"));
157 }
158 /*}}}*/
159 if (result.type==FLOAT && (msg=dblfinite(result.u.flt))!=(const char*)0)
160 /* result is error */ /*{{{*/
161 {
162 result.type=EEK;
163 result.u.err=malloc(strlen(msg)+4);
164 (void)strcpy(result.u.err,"+: ");
165 (void)strcat(result.u.err,msg);
166 }
167 /*}}}*/
168 return result;
169 }
170 /*}}}*/
171 /* tsub -- binary - operator */ /*{{{*/
tsub(Token l,Token r)172 Token tsub(Token l, Token r)
173 {
174 /* variables */ /*{{{*/
175 Token result;
176 const char *msg;
177 /*}}}*/
178
179 if (l.type==EEK)
180 /* return left error */ /*{{{*/
181 return tcopy(l);
182 /*}}}*/
183 else if (r.type==EEK)
184 /* return right error */ /*{{{*/
185 return tcopy(r);
186 /*}}}*/
187 else if (l.type==INT && r.type==INT)
188 /* result is int difference between left int and right int */ /*{{{*/
189 {
190 result.type=INT;
191 result.u.integer=l.u.integer-r.u.integer;
192 }
193 /*}}}*/
194 else if (l.type==FLOAT && r.type==FLOAT)
195 /* result is float difference between left float and right float */ /*{{{*/
196 {
197 result.type=FLOAT;
198 result.u.flt=l.u.flt-r.u.flt;
199 }
200 /*}}}*/
201 else if (l.type==EMPTY)
202 /* return negated right argument */ /*{{{*/
203 return tneg(r);
204 /*}}}*/
205 else if ((l.type==INT || l.type==FLOAT) && r.type==EMPTY)
206 /* return left argument */ /*{{{*/
207 return tcopy(l);
208 /*}}}*/
209 else if (l.type==INT && r.type==FLOAT)
210 /* result is float difference of left integer and right float */ /*{{{*/
211 {
212 result.type=FLOAT;
213 result.u.flt=((double)l.u.integer)-r.u.flt;
214 }
215 /*}}}*/
216 else if (l.type==FLOAT && r.type==INT)
217 /* result is float difference between left float and right integer */ /*{{{*/
218 {
219 result.type=FLOAT;
220 result.u.flt=l.u.flt-((double)r.u.integer);
221 }
222 /*}}}*/
223 else
224 /* result is difference type error */ /*{{{*/
225 {
226 result.type=EEK;
227 result.u.err=strcpy(malloc(strlen(_("wrong types for - operator"))+1),_("wrong types for - operator"));
228 }
229 /*}}}*/
230 if (result.type==FLOAT && (msg=dblfinite(result.u.flt))!=(const char*)0)
231 /* result is error */ /*{{{*/
232 {
233 result.type=EEK;
234 result.u.err=malloc(strlen(msg)+4);
235 (void)strcpy(result.u.err,"-: ");
236 (void)strcat(result.u.err,msg);
237 }
238 /*}}}*/
239 return result;
240 }
241 /*}}}*/
242 /* tdiv -- / operator */ /*{{{*/
tdiv(Token l,Token r)243 Token tdiv(Token l, Token r)
244 {
245 /* variables */ /*{{{*/
246 Token result;
247 const char *msg;
248 /*}}}*/
249
250 if (l.type==EEK)
251 /* return left error */ /*{{{*/
252 return tcopy(l);
253 /*}}}*/
254 else if (r.type==EEK)
255 /* return right error */ /*{{{*/
256 return tcopy(r);
257 /*}}}*/
258 else if ((r.type==INT && r.u.integer==0) || (r.type==FLOAT && r.u.flt==0.0) || (r.type==EMPTY))
259 /* result is division by 0 error */ /*{{{*/
260 {
261 result.type=EEK;
262 result.u.err=strcpy(malloc(strlen(_("division by 0"))+1),_("division by 0"));
263 }
264 /*}}}*/
265 else if (l.type==INT && r.type==INT)
266 /* result is quotient of left int and right int */ /*{{{*/
267 {
268 result.type=INT;
269 result.u.integer=l.u.integer/r.u.integer;
270 }
271 /*}}}*/
272 else if (l.type==FLOAT && r.type==FLOAT)
273 /* result is quotient of left float and right float */ /*{{{*/
274 {
275 result.type=FLOAT;
276 result.u.flt=l.u.flt/r.u.flt;
277 }
278 /*}}}*/
279 else if (l.type==EMPTY && r.type==INT)
280 /* result is 0 */ /*{{{*/
281 {
282 result.type=INT;
283 result.u.integer=0;
284 }
285 /*}}}*/
286 else if (l.type==EMPTY && r.type==FLOAT)
287 /* result is 0.0 */ /*{{{*/
288 {
289 result.type=FLOAT;
290 result.u.flt=0.0;
291 }
292 /*}}}*/
293 else if (l.type==INT && r.type==FLOAT)
294 /* result is float quotient of left int and right float */ /*{{{*/
295 {
296 result.type=FLOAT;
297 result.u.flt=((double)l.u.integer)/r.u.flt;
298 }
299 /*}}}*/
300 else if (l.type==FLOAT && r.type==INT)
301 /* result is float quotient of left float and right int */ /*{{{*/
302 {
303 result.type=FLOAT;
304 result.u.flt=l.u.flt/((double)r.u.integer);
305 }
306 /*}}}*/
307 else
308 /* result is quotient type error */ /*{{{*/
309 {
310 result.type=EEK;
311 result.u.err=strcpy(malloc(strlen(_("wrong types for / operator"))+1),_("wrong types for / operator"));
312 }
313 /*}}}*/
314 if (result.type==FLOAT && (msg=dblfinite(result.u.flt))!=(const char*)0)
315 /* result is error */ /*{{{*/
316 {
317 result.type=EEK;
318 result.u.err=malloc(strlen(msg)+4);
319 (void)strcpy(result.u.err,"/: ");
320 (void)strcat(result.u.err,msg);
321 }
322 /*}}}*/
323 return result;
324 }
325 /*}}}*/
326 /* tmod -- % operator */ /*{{{*/
tmod(Token l,Token r)327 Token tmod(Token l, Token r)
328 {
329 /* variables */ /*{{{*/
330 Token result;
331 const char *msg;
332 /*}}}*/
333
334 if (l.type==EEK) /* return left error */ /*{{{*/
335 return tcopy(l);
336 /*}}}*/
337 else if (r.type==EEK) /* return right error */ /*{{{*/
338 return tcopy(r);
339 /*}}}*/
340 else if ((r.type==INT && r.u.integer==0) || (r.type==FLOAT && r.u.flt==0.0) || (r.type==EMPTY)) /* result is modulo 0 error */ /*{{{*/
341 {
342 result.type=EEK;
343 result.u.err=strcpy(malloc(strlen(_("modulo 0"))+1),_("modulo 0"));
344 }
345 /*}}}*/
346 else if (l.type==INT && r.type==INT) /* result is remainder of left int and right int */ /*{{{*/
347 {
348 result.type=INT;
349 result.u.integer=l.u.integer%r.u.integer;
350 }
351 /*}}}*/
352 else if (l.type==FLOAT && r.type==FLOAT) /* result is remainder of left float and right float */ /*{{{*/
353 {
354 result.type=FLOAT;
355 result.u.flt=fmod(l.u.flt,r.u.flt);
356 }
357 /*}}}*/
358 else if (l.type==EMPTY && r.type==INT) /* result is 0 */ /*{{{*/
359 {
360 result.type=INT;
361 result.u.integer=0;
362 }
363 /*}}}*/
364 else if (l.type==EMPTY && r.type==FLOAT) /* result is 0.0 */ /*{{{*/
365 {
366 result.type=FLOAT;
367 result.u.flt=0.0;
368 }
369 /*}}}*/
370 else if (l.type==INT && r.type==FLOAT) /* result is float remainder of left int and right float */ /*{{{*/
371 {
372 result.type=FLOAT;
373 result.u.flt=fmod((double)l.u.integer,r.u.flt);
374 }
375 /*}}}*/
376 else if (l.type==FLOAT && r.type==INT) /* result is float remainder of left float and right int */ /*{{{*/
377 {
378 result.type=FLOAT;
379 result.u.flt=fmod(l.u.flt,(double)r.u.integer);
380 }
381 /*}}}*/
382 else /* result is remainder type error */ /*{{{*/
383 {
384 result.type=EEK;
385 result.u.err=strcpy(malloc(strlen(_("wrong types for % operator"))+1),_("wrong types for % operator"));
386 }
387 /*}}}*/
388 if (result.type==FLOAT && (msg=dblfinite(result.u.flt))!=(const char*)0) /* result is error */ /*{{{*/
389 {
390 result.type=EEK;
391 result.u.err=malloc(strlen(msg)+4);
392 (void)strcpy(result.u.err,"%: ");
393 (void)strcat(result.u.err,msg);
394 }
395 /*}}}*/
396 return result;
397 }
398 /*}}}*/
399 /* tmul -- * operator */ /*{{{*/
tmul(Token l,Token r)400 Token tmul(Token l, Token r)
401 {
402 /* variables */ /*{{{*/
403 Token result;
404 const char *msg;
405 /*}}}*/
406
407 if (l.type==EEK)
408 /* return left error */ /*{{{*/
409 result=tcopy(l);
410 /*}}}*/
411 else if (r.type==EEK)
412 /* return right error */ /*{{{*/
413 result=tcopy(r);
414 /*}}}*/
415 else if (l.type==INT && r.type==INT)
416 /* result is int product of left int and right int */ /*{{{*/
417 {
418 result=l;
419 result.u.integer=l.u.integer*r.u.integer;
420 }
421 /*}}}*/
422 else if (l.type==FLOAT && r.type==FLOAT)
423 /* result is float product of left float and right float */ /*{{{*/
424 {
425 result.type=FLOAT;
426 result.u.flt=l.u.flt*r.u.flt;
427 }
428 /*}}}*/
429 else if ((l.type==EMPTY && r.type==INT) || (l.type==INT && r.type==EMPTY))
430 /* result is 0 */ /*{{{*/
431 {
432 result.type=INT;
433 result.u.integer=0;
434 }
435 /*}}}*/
436 else if ((l.type==EMPTY && r.type==FLOAT) || (l.type==FLOAT && r.type==EMPTY))
437 /* result is 0.0 */ /*{{{*/
438 {
439 result.type=FLOAT;
440 result.u.flt=0.0;
441 }
442 /*}}}*/
443 else if (l.type==INT && r.type==FLOAT)
444 /* result is float product of left int and right float */ /*{{{*/
445 {
446 result.type=FLOAT;
447 result.u.flt=((double)l.u.integer)*r.u.flt;
448 }
449 /*}}}*/
450 else if (l.type==FLOAT && r.type==INT)
451 /* result is float product of left float and right int */ /*{{{*/
452 {
453 result.type=FLOAT;
454 result.u.flt=l.u.flt*((double)r.u.integer);
455 }
456 /*}}}*/
457 else if (l.type==EMPTY && r.type==EMPTY)
458 /* result is empty */ /*{{{*/
459 {
460 result.type=EMPTY;
461 }
462 /*}}}*/
463 else
464 /* result is product type error */ /*{{{*/
465 {
466 result.type=EEK;
467 result.u.err=strcpy(malloc(strlen(_("wrong types for * operator"))+1),_("wrong types for * operator"));
468 }
469 /*}}}*/
470 if (result.type==FLOAT && (msg=dblfinite(result.u.flt))!=(const char*)0)
471 /* result is error */ /*{{{*/
472 {
473 result.type=EEK;
474 result.u.err=malloc(strlen(msg)+4);
475 (void)strcpy(result.u.err,"*: ");
476 (void)strcat(result.u.err,msg);
477 }
478 /*}}}*/
479 return result;
480 }
481 /*}}}*/
482 /* tneg -- monadic - operator */ /*{{{*/
tneg(Token x)483 Token tneg(Token x)
484 {
485 /* variables */ /*{{{*/
486 Token result;
487 /*}}}*/
488
489 if (x.type==EEK)
490 /* return error */ /*{{{*/
491 return tcopy(x);
492 /*}}}*/
493 else if (x.type==INT)
494 /* result is negated int argument */ /*{{{*/
495 {
496 result.type=INT;
497 result.u.integer=-x.u.integer;
498 }
499 /*}}}*/
500 else if (x.type==FLOAT)
501 /* result is negated float argument */ /*{{{*/
502 {
503 result.type=FLOAT;
504 result.u.flt=-x.u.flt;
505 }
506 /*}}}*/
507 else if (x.type==EMPTY)
508 /* result is argument itself */ /*{{{*/
509 {
510 result=tcopy(x);
511 }
512 /*}}}*/
513 else
514 /* result is negation error */ /*{{{*/
515 {
516 result.type=EEK;
517 result.u.err=strcpy(malloc(strlen(_("wrong type for - operator"))+1),_("wrong type for - operator"));
518 }
519 /*}}}*/
520 return result;
521 }
522 /*}}}*/
523 /* tpow -- ^ operator */ /*{{{*/
tpow(Token l,Token r)524 Token tpow(Token l, Token r)
525 {
526 /* variables */ /*{{{*/
527 Token result;
528 const char *msg;
529 /*}}}*/
530
531 if (l.type==EEK) /* return left error */ /*{{{*/
532 return tcopy(l);
533 /*}}}*/
534 else if (r.type==EEK) /* return right error */ /*{{{*/
535 return tcopy(r);
536 /*}}}*/
537 else if ((l.type==INT || l.type==FLOAT || l.type==EMPTY) && (r.type==INT || r.type==FLOAT || l.type==EMPTY)) /* do the real work */ /*{{{*/
538 {
539 if ((l.type==INT || l.type==EMPTY) && ((r.type==INT && r.u.integer>=0) || r.type==EMPTY))
540 /* int^int, return int or error if 0^0 */ /*{{{*/
541 {
542 long x,y;
543
544 if (l.type==EMPTY) x=0;
545 else x=l.u.integer;
546 if (r.type==EMPTY) y=0;
547 else y=r.u.integer;
548 if (x==0 && y==0)
549 {
550 result.type=EEK;
551 result.u.err=strcpy(malloc(strlen(_("0^0 is not defined"))+1),_("0^0 is not defined"));
552 }
553 else
554 {
555 long i;
556
557 result.type=INT;
558 if (x==0) result.u.integer=0;
559 else if (y==0) result.u.integer=1;
560 else for (result.u.integer=x,i=1; i<y; ++i) result.u.integer*=x;
561 }
562 }
563 /*}}}*/
564 else
565 /* float^float */ /*{{{*/
566 {
567 double x=0.0,y=0.0;
568
569 switch (l.type)
570 {
571 case INT: x=(double)l.u.integer; break;
572 case FLOAT: x=l.u.flt; break;
573 case EMPTY: x=0.0; break;
574 default: assert(0);
575 }
576 switch (r.type)
577 {
578 case INT: y=(double)r.u.integer; break;
579 case FLOAT: y=r.u.flt; break;
580 case EMPTY: y=0.0; break;
581 default: assert(0);
582 }
583 result.type=FLOAT;
584 errno=0; /* there is no portable EOK :( */
585 result.u.flt=pow(x,y);
586 switch (errno)
587 {
588 case 0: result.type=FLOAT; break;
589 case ERANGE:
590 case EDOM: result.type=EEK; result.u.err=strcpy(malloc(strlen(_("^ caused a domain error"))+1),_("^ caused a domain error")); break;
591 default: assert(0);
592 }
593 }
594 /*}}}*/
595 }
596 /*}}}*/
597 else /* result is type error */ /*{{{*/
598 {
599 result.type=EEK;
600 result.u.err=strcpy(malloc(strlen(_("wrong types for ^ operator"))+1),_("wrong types for ^ operator"));
601 }
602 /*}}}*/
603 if (result.type==FLOAT && (msg=dblfinite(result.u.flt))!=(const char*)0) /* result is error */ /*{{{*/
604 {
605 result.type=EEK;
606 result.u.err=malloc(strlen(msg)+4);
607 (void)strcpy(result.u.err,"^: ");
608 (void)strcat(result.u.err,msg);
609 }
610 /*}}}*/
611 return result;
612 }
613 /*}}}*/
614 /* tfuncall -- function operator */ /*{{{*/
tfuncall(Token * ident,int argc,Token argv[])615 Token tfuncall(Token *ident, int argc, Token argv[])
616 {
617 return tfunc[ident->u.fident].func(argc, argv);
618 }
619 /*}}}*/
620 /* tlt -- < operator */ /*{{{*/
tlt(Token l,Token r)621 Token tlt(Token l, Token r)
622 {
623 /* variables */ /*{{{*/
624 Token result;
625 static char empty[]="";
626 /*}}}*/
627
628 if (l.type==EEK) /* return left error argument */ /*{{{*/
629 return tcopy(l);
630 /*}}}*/
631 if (r.type==EEK) /* return right error argument */ /*{{{*/
632 return tcopy(r);
633 /*}}}*/
634 if (l.type==EMPTY) /* try to assign 0 element of r.type */ /*{{{*/
635 {
636 l.type=r.type;
637 switch (r.type)
638 {
639 case INT: l.u.integer=0; break;
640 case FLOAT: l.u.flt=0.0; break;
641 case STRING: l.u.string=empty; break;
642 default: ;
643 }
644 }
645 /*}}}*/
646 if (r.type==EMPTY) /* try to assign 0 element of l.type */ /*{{{*/
647 {
648 r.type=l.type;
649 switch (l.type)
650 {
651 case INT: r.u.integer=0; break;
652 case FLOAT: r.u.flt=0.0; break;
653 case STRING: r.u.string=empty; break;
654 default: ;
655 }
656 }
657 /*}}}*/
658 if (l.type==INT && r.type==INT) /* return left int < right int */ /*{{{*/
659 {
660 result.type=INT;
661 result.u.integer=l.u.integer<r.u.integer;
662 }
663 /*}}}*/
664 else if (l.type==STRING && r.type==STRING) /* return left string < right string */ /*{{{*/
665 {
666 result.type=INT;
667 result.u.integer=(strcmp(l.u.string,r.u.string)<0);
668 }
669 /*}}}*/
670 else if (l.type==FLOAT && r.type==FLOAT) /* return left float < right float */ /*{{{*/
671 {
672 result.type=INT;
673 result.u.integer=l.u.flt<r.u.flt;
674 }
675 /*}}}*/
676 else if (l.type==FLOAT && r.type==INT) /* return left float < right float */ /*{{{*/
677 {
678 result.type=INT;
679 result.u.integer=l.u.flt<((double)r.u.integer);
680 }
681 /*}}}*/
682 else if (l.type==INT && r.type==FLOAT) /* return left int < right float */ /*{{{*/
683 {
684 result.type=INT;
685 result.u.integer=((double)l.u.integer)<r.u.flt;
686 }
687 /*}}}*/
688 else /* return < type error */ /*{{{*/
689 {
690 result.type=EEK;
691 result.u.err=strcpy(malloc(strlen(_("type mismatch for relational operator"))+1),_("type mismatch for relational operator"));
692 }
693 /*}}}*/
694 return result;
695 }
696 /*}}}*/
697 /* tle -- <= operator */ /*{{{*/
tle(Token l,Token r)698 Token tle(Token l, Token r)
699 {
700 /* variables */ /*{{{*/
701 Token result;
702 static char empty[]="";
703 /*}}}*/
704
705 if (l.type==EEK) /* return left error argument */ /*{{{*/
706 return tcopy(l);
707 /*}}}*/
708 if (r.type==EEK) /* return right error argument */ /*{{{*/
709 return tcopy(r);
710 /*}}}*/
711 if (l.type==EMPTY) /* try to assign 0 element of r.type */ /*{{{*/
712 {
713 l.type=r.type;
714 switch (r.type)
715 {
716 case INT: l.u.integer=0; break;
717 case FLOAT: l.u.flt=0.0; break;
718 case STRING: l.u.string=empty; break;
719 default: ;
720 }
721 }
722 /*}}}*/
723 if (r.type==EMPTY) /* try to assign 0 element of l.type */ /*{{{*/
724 {
725 r.type=l.type;
726 switch (l.type)
727 {
728 case INT: r.u.integer=0; break;
729 case FLOAT: r.u.flt=0.0; break;
730 case STRING: r.u.string=empty; break;
731 default: ;
732 }
733 }
734 /*}}}*/
735 if (l.type==INT && r.type==INT) /* result is left int <= right int */ /*{{{*/
736 {
737 result.type=INT;
738 result.u.integer=l.u.integer<=r.u.integer;
739 }
740 /*}}}*/
741 else if (l.type==STRING && r.type==STRING) /* result is left string <= right string */ /*{{{*/
742 {
743 result.type=INT;
744 result.u.integer=(strcmp(l.u.string,r.u.string)<=0);
745 }
746 /*}}}*/
747 else if (l.type==FLOAT && r.type==FLOAT) /* result is left float <= right float */ /*{{{*/
748 {
749 result.type=INT;
750 result.u.integer=l.u.flt<=r.u.flt;
751 }
752 /*}}}*/
753 else if (l.type==FLOAT && r.type==INT) /* result is left float <= (double)right int */ /*{{{*/
754 {
755 result.type=INT;
756 result.u.integer=l.u.flt<=((double)r.u.integer);
757 }
758 /*}}}*/
759 else if (l.type==INT && r.type==FLOAT) /* result is (double)left int <= right float */ /*{{{*/
760 {
761 result.type=INT;
762 result.u.integer=((double)l.u.integer)<=r.u.flt;
763 }
764 /*}}}*/
765 else if (l.type==EMPTY && r.type==EMPTY) /* result is 1 */ /*{{{*/
766 {
767 result.type=INT;
768 result.u.integer=1;
769 }
770 /*}}}*/
771 else /* result is <= type error */ /*{{{*/
772 {
773 result.type=EEK;
774 result.u.err=strcpy(malloc(strlen(_("type mismatch for relational operator"))+1),_("type mismatch for relational operator"));
775 }
776 /*}}}*/
777 return result;
778 }
779 /*}}}*/
780 /* tge -- >= operator */ /*{{{*/
tge(Token l,Token r)781 Token tge(Token l, Token r)
782 {
783 /* variables */ /*{{{*/
784 Token result;
785 static char empty[]="";
786 /*}}}*/
787
788 if (l.type==EEK) /* return left error argument */ /*{{{*/
789 return tcopy(l);
790 /*}}}*/
791 if (r.type==EEK) /* return right error argument */ /*{{{*/
792 return tcopy(r);
793 /*}}}*/
794 if (l.type==EMPTY) /* try to assign 0 element of r.type */ /*{{{*/
795 {
796 l.type=r.type;
797 switch (r.type)
798 {
799 case INT: l.u.integer=0; break;
800 case FLOAT: l.u.flt=0.0; break;
801 case STRING: l.u.string=empty; break;
802 default: ;
803 }
804 }
805 /*}}}*/
806 if (r.type==EMPTY) /* try to assign 0 element of l.type */ /*{{{*/
807 {
808 r.type=l.type;
809 switch (l.type)
810 {
811 case INT: r.u.integer=0; break;
812 case FLOAT: r.u.flt=0.0; break;
813 case STRING: r.u.string=empty; break;
814 default: ;
815 }
816 }
817 /*}}}*/
818 if (l.type==INT && r.type==INT) /* result is left int >= right int */ /*{{{*/
819 {
820 result.type=INT;
821 result.u.integer=l.u.integer>=r.u.integer;
822 }
823 /*}}}*/
824 else if (l.type==STRING && r.type==STRING) /* return left string >= right string */ /*{{{*/
825 {
826 result.type=INT;
827 result.u.integer=(strcmp(l.u.string,r.u.string)>=0);
828 }
829 /*}}}*/
830 else if (l.type==FLOAT && r.type==FLOAT) /* return left float >= right float */ /*{{{*/
831 {
832 result.type=INT;
833 result.u.integer=l.u.flt>=r.u.flt;
834 }
835 /*}}}*/
836 else if (l.type==FLOAT && r.type==INT) /* return left float >= (double) right int */ /*{{{*/
837 {
838 result.type=INT;
839 result.u.integer=l.u.flt>=((double)r.u.integer);
840 }
841 /*}}}*/
842 else if (l.type==INT && r.type==FLOAT) /* return (double) left int >= right float */ /*{{{*/
843 {
844 result.type=INT;
845 result.u.integer=((double)l.u.integer)>=r.u.flt;
846 }
847 /*}}}*/
848 else /* return >= type error */ /*{{{*/
849 {
850 result.type=EEK;
851 result.u.err=strcpy(malloc(strlen(_("type mismatch for relational operator"))+1),_("type mismatch for relational operator"));
852 }
853 /*}}}*/
854 return result;
855 }
856 /*}}}*/
857 /* tgt -- <= operator */ /*{{{*/
tgt(Token l,Token r)858 Token tgt(Token l, Token r)
859 {
860 /* variables */ /*{{{*/
861 Token result;
862 static char empty[]="";
863 /*}}}*/
864
865 if (l.type==EEK) /* return left error argument */ /*{{{*/
866 return tcopy(l);
867 /*}}}*/
868 if (r.type==EEK) /* return right error argument */ /*{{{*/
869 return tcopy(r);
870 /*}}}*/
871 if (l.type==EMPTY) /* try to assign 0 element of r.type */ /*{{{*/
872 {
873 l.type=r.type;
874 switch (r.type)
875 {
876 case INT: l.u.integer=0; break;
877 case FLOAT: l.u.flt=0.0; break;
878 case STRING: l.u.string=empty; break;
879 default: ;
880 }
881 }
882 /*}}}*/
883 if (r.type==EMPTY) /* try to assign 0 element of l.type */ /*{{{*/
884 {
885 r.type=l.type;
886 switch (l.type)
887 {
888 case INT: r.u.integer=0; break;
889 case FLOAT: r.u.flt=0.0; break;
890 case STRING: r.u.string=empty; break;
891 default: ;
892 }
893 }
894 /*}}}*/
895 if (l.type==INT && r.type==INT) /* result is left int > right int */ /*{{{*/
896 {
897 result.type=INT;
898 result.u.integer=l.u.integer>r.u.integer;
899 }
900 /*}}}*/
901 else if (l.type==STRING && r.type==STRING) /* result is left string > right string */ /*{{{*/
902 {
903 result.type=INT;
904 result.u.integer=(strcmp(l.u.string,r.u.string)>0);
905 }
906 /*}}}*/
907 else if (l.type==FLOAT && r.type==FLOAT) /* result is left float > right float */ /*{{{*/
908 {
909 result.type=INT;
910 result.u.integer=l.u.flt>r.u.flt;
911 }
912 /*}}}*/
913 else if (l.type==FLOAT && r.type==INT) /* result is left float > (double) right int */ /*{{{*/
914 {
915 result.type=INT;
916 result.u.integer=l.u.flt>((double)r.u.integer);
917 }
918 /*}}}*/
919 else if (l.type==INT && r.type==FLOAT) /* result is left int > right float */ /*{{{*/
920 {
921 result.type=INT;
922 result.u.integer=((double)l.u.integer)>r.u.flt;
923 }
924 /*}}}*/
925 else /* result is relation op type error */ /*{{{*/
926 {
927 result.type=EEK;
928 result.u.err=mystrmalloc(_("type mismatch for relational operator"));
929 }
930 /*}}}*/
931 return result;
932 }
933 /*}}}*/
934 /* teq -- == operator */ /*{{{*/
teq(Token l,Token r)935 Token teq(Token l, Token r)
936 {
937 /* variables */ /*{{{*/
938 Token result;
939 static char empty[]="";
940 /*}}}*/
941
942 if (l.type==EEK) return tcopy(l);
943 else if (r.type==EEK) return tcopy(r);
944 if (l.type==EMPTY)
945 /* try to assign 0 element of r.type */ /*{{{*/
946 {
947 l.type=r.type;
948 switch (r.type)
949 {
950 case INT: l.u.integer=0; break;
951 case FLOAT: l.u.flt=0.0; break;
952 case STRING: l.u.string=empty; break;
953 default: ;
954 }
955 }
956 /*}}}*/
957 if (r.type==EMPTY)
958 /* try to assign 0 element of l.type */ /*{{{*/
959 {
960 r.type=l.type;
961 switch (l.type)
962 {
963 case INT: r.u.integer=0; break;
964 case FLOAT: r.u.flt=0.0; break;
965 case STRING: r.u.string=empty; break;
966 default: ;
967 }
968 }
969 /*}}}*/
970 if (l.type==FLOAT && r.type==INT)
971 {
972 result.type=INT;
973 result.u.integer=l.u.flt==((double)r.u.integer);
974 }
975 else if (l.type==INT && r.type==FLOAT)
976 {
977 result.type=INT;
978 result.u.integer=((double)l.u.integer)==r.u.flt;
979 }
980 else if (l.type!=r.type)
981 {
982 result.type=INT;
983 result.u.integer=0;
984 }
985 else if (l.type==INT)
986 {
987 result.type=INT;
988 result.u.integer=l.u.integer==r.u.integer;
989 }
990 else if (l.type==STRING)
991 {
992 result.type=INT;
993 result.u.integer=(strcmp(l.u.string,r.u.string)==0);
994 }
995 else if (l.type==FLOAT)
996 {
997 result.type=INT;
998 result.u.integer=l.u.flt==r.u.flt;
999 }
1000 else if (l.type==EMPTY)
1001 {
1002 result.type=INT;
1003 result.u.integer=1;
1004 }
1005 else
1006 {
1007 result.type=EEK;
1008 result.u.err=strcpy(malloc(strlen(_("type mismatch for relational operator"))+1),_("type mismatch for relational operator"));
1009 }
1010 return result;
1011 }
1012 /*}}}*/
1013 /* tabouteq -- ~= operator */ /*{{{*/
tabouteq(Token l,Token r)1014 Token tabouteq(Token l, Token r)
1015 {
1016 /* variables */ /*{{{*/
1017 Token result;
1018 /*}}}*/
1019
1020 if (l.type==EEK) return tcopy(l);
1021 else if (r.type==EEK) return tcopy(r);
1022 if (l.type==EMPTY)
1023 /* try to assign 0 element of r.type */ /*{{{*/
1024 {
1025 l.type=r.type;
1026 switch (r.type)
1027 {
1028 case FLOAT: l.u.flt=0.0; break;
1029 default: ;
1030 }
1031 }
1032 /*}}}*/
1033 if (r.type==EMPTY)
1034 /* try to assign 0 element of l.type */ /*{{{*/
1035 {
1036 r.type=l.type;
1037 switch (l.type)
1038 {
1039 case FLOAT: r.u.flt=0.0; break;
1040 default: ;
1041 }
1042 }
1043 /*}}}*/
1044 if (l.type==FLOAT && r.type==FLOAT)
1045 {
1046 result.type=INT;
1047 result.u.integer=(fabs(l.u.flt-r.u.flt)<=DBL_EPSILON);
1048 }
1049 else
1050 {
1051 result.type=EEK;
1052 result.u.err=strcpy(malloc(strlen(_("type mismatch for relational operator"))+1),_("type mismatch for relational operator"));
1053 }
1054 return result;
1055 }
1056 /*}}}*/
1057 /* tne -- != operator */ /*{{{*/
tne(Token l,Token r)1058 Token tne(Token l, Token r)
1059 {
1060 /* variables */ /*{{{*/
1061 Token result;
1062 static char empty[]="";
1063 /*}}}*/
1064
1065 if (l.type==EEK) return tcopy(l);
1066 else if (r.type==EEK) return tcopy(r);
1067 if (l.type==EMPTY)
1068 /* try to assign 0 element of r.type */ /*{{{*/
1069 {
1070 l.type=r.type;
1071 switch (r.type)
1072 {
1073 case INT: l.u.integer=0; break;
1074 case FLOAT: l.u.flt=0.0; break;
1075 case STRING: l.u.string=empty; break;
1076 default: ;
1077 }
1078 }
1079 /*}}}*/
1080 if (r.type==EMPTY)
1081 /* try to assign 0 element of l.type */ /*{{{*/
1082 {
1083 r.type=l.type;
1084 switch (l.type)
1085 {
1086 case INT: r.u.integer=0; break;
1087 case FLOAT: r.u.flt=0.0; break;
1088 case STRING: r.u.string=empty; break;
1089 default: ;
1090 }
1091 }
1092 /*}}}*/
1093 if (l.type==FLOAT && r.type==INT)
1094 {
1095 result.type=INT;
1096 result.u.integer=l.u.flt!=((double)r.u.integer);
1097 }
1098 else if (l.type==INT && r.type==FLOAT)
1099 {
1100 result.type=INT;
1101 result.u.integer=((double)l.u.integer)!=r.u.flt;
1102 }
1103 else if (l.type!=r.type)
1104 {
1105 result.type=INT;
1106 result.u.integer=1;
1107 }
1108 else if (l.type==INT)
1109 {
1110 result.type=INT;
1111 result.u.integer=l.u.integer!=r.u.integer;
1112 }
1113 else if (l.type==STRING)
1114 {
1115 result.type=INT;
1116 result.u.integer=(strcmp(l.u.string,r.u.string)!=0);
1117 }
1118 else if (l.type==FLOAT)
1119 {
1120 result.type=INT;
1121 result.u.integer=l.u.flt!=r.u.flt;
1122 }
1123 else if (l.type==EMPTY)
1124 {
1125 result.type=INT;
1126 result.u.integer=0;
1127 }
1128 else
1129 {
1130 result.type=EEK;
1131 result.u.err=strcpy(malloc(strlen(_("type mismatch for relational operator"))+1),_("type mismatch for relational operator"));
1132 }
1133 return result;
1134 }
1135 /*}}}*/
1136
1137
1138