"Fossies" - the Fresh Open Source Software Archive 
Member "teapot-2.3.0/eval.c" (6 Feb 2012, 27738 Bytes) of package /linux/privat/old/teapot-2.3.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "eval.c" see the
Fossies "Dox" file reference documentation.
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
615 Token tfuncall(Token *ident, int argc, Token argv[])
616 {
617 return tfunc[ident->u.fident].func(argc, argv);
618 }
619 /*}}}*/
620 /* tlt -- < operator */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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 */ /*{{{*/
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