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