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 <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 
20 #include "eval.h"
21 #include "main.h"
22 #include "misc.h"
23 #include "parser.h"
24 #include "scanner.h"
25 #include "sheet.h"
26 /*}}}*/
27 /* #defines */ /*{{{*/
28 #define MAXARGC 16
29 /*}}}*/
30 
31 /* prototypes */ /*{{{*/
32 static Token term(Token *n[], int *i);
33 /*}}}*/
34 
35 /* primary   -- parse and evaluate a primary term */ /*{{{*/
primary(Token * n[],int * i)36 static Token primary(Token *n[], int *i)
37 {
38   /* variables */ /*{{{*/
39   int argc,j;
40   Token *ident,argv[MAXARGC],result;
41   /*}}}*/
42 
43   if (n[*i]==(Token*)0)
44   /* error */ /*{{{*/
45   {
46     result.type=EEK;
47     result.u.err=strcpy(malloc(strlen(_("missing operator"))+1),_("missing operator"));
48     return result;
49   }
50   /*}}}*/
51   else switch (n[*i]->type)
52   {
53     /* STRING, FLOAT, INT */ /*{{{*/
54     case STRING:
55     case FLOAT:
56     case INT:
57     {
58       return tcopy(*n[(*i)++]);
59     }
60     /*}}}*/
61     /* OPERATOR */ /*{{{*/
62     case OPERATOR:
63     {
64       if (n[*i]->u.op==OP)
65       /* return paren term */ /*{{{*/
66       {
67         ++(*i);
68         result=term(n,i);
69         if (result.type==EEK) return result;
70         if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP)
71         {
72           ++(*i);
73           return result;
74         }
75         tfree(&result);
76         result.type=EEK;
77         result.u.err=strcpy(malloc(strlen(_(") expected"))+1),_(") expected"));
78         return result;
79       }
80       /*}}}*/
81       else if (n[*i]->u.op==MINUS)
82       /* return negated term */ /*{{{*/
83       {
84         ++(*i);
85         return(tneg(primary(n,i)));
86       }
87       /*}}}*/
88       else
89       /* return error, value expected */ /*{{{*/
90       {
91         result.type=EEK;
92         result.u.err=mystrmalloc(_("value expected"));
93         return result;
94       }
95       /*}}}*/
96     }
97     /*}}}*/
98     /* LIDENT */ /*{{{*/
99     case LIDENT:
100     {
101       ident=n[*i];
102       ++(*i);
103       return findlabel(upd_sheet,ident->u.lident);
104     }
105     /*}}}*/
106     /* FIDENT */ /*{{{*/
107     case FIDENT:
108     {
109       ident=n[*i];
110       ++(*i);
111       if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==OP)
112       /* parse arguments and closing paren of function call, return its value */ /*{{{*/
113       {
114         ++(*i);
115         argc=0;
116         if (!(n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP))
117         /* parse at least one argument */ /*{{{*/
118         {
119           if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==COMMA)
120           /* empty argument */ /*{{{*/
121           {
122             argv[argc].type=EMPTY;
123           }
124           /*}}}*/
125           else argv[argc]=term(n,i);
126           if (argv[argc].type==EEK) return argv[argc];
127           ++argc;
128           while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==COMMA)
129           /* parse the following argument */ /*{{{*/
130           {
131             ++(*i);
132             if (argc<=MAXARGC)
133             {
134               if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==COMMA || n[*i]->u.op==CP))
135               {
136                 argv[argc].type=EMPTY;
137               }
138               else argv[argc]=term(n,i);
139             }
140             else
141             {
142               result.type=EEK;
143               result.u.err=strcpy(malloc(strlen(_("too many arguments"))+1),_("too many arguments"));
144               for (j=0; j<=argc; ++j) tfree(&argv[j]);
145               return result;
146             }
147             ++argc;
148           }
149           /*}}}*/
150         }
151         /*}}}*/
152         if (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==CP)
153         /* eval function */ /*{{{*/
154         {
155           ++(*i);
156           result=tfuncall(ident,argc,argv);
157           for (j=0; j<argc; ++j) tfree(&argv[j]);
158         }
159         /*}}}*/
160         else
161         /* ) expected */ /*{{{*/
162         {
163           for (j=0; j<argc; ++j) tfree(&argv[j]);
164           result.type=EEK;
165           result.u.err=strcpy(malloc(strlen(_(") expected"))+1),_(") expected"));
166         }
167         /*}}}*/
168         return result;
169       }
170       /*}}}*/
171       else
172       {
173         result.type=EEK;
174         result.u.err=mystrmalloc(_("( expected"));
175         return result;
176       }
177     }
178     /*}}}*/
179     default: ; /* fall through */
180   }
181   result.type=EEK;
182   result.u.err=mystrmalloc(_("value expected"));
183   return result;
184 }
185 /*}}}*/
186 /* powterm   -- parse and evaluate a x^y term */ /*{{{*/
powterm(Token * n[],int * i)187 static Token powterm(Token *n[], int *i)
188 {
189   Token l;
190 
191   l=primary(n,i);
192   if (l.type==EEK) return l;
193   while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op==POW)
194   {
195     Token result,r;
196 
197     ++(*i);
198     r=primary(n,i);
199     result=tpow(l,r);
200     tfree(&l);
201     tfree(&r);
202     if (result.type==EEK) return result;
203     l=result;
204   }
205   return l;
206 }
207 /*}}}*/
208 /* piterm    -- parse and evaluate a product/division/modulo term */ /*{{{*/
piterm(Token * n[],int * i)209 static Token piterm(Token *n[], int *i)
210 {
211   Token l;
212 
213   l=powterm(n,i);
214   if (l.type==EEK) return l;
215   while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==DIV || n[*i]->u.op==MUL || n[*i]->u.op==MOD))
216   {
217     Operator op;
218     Token result,r;
219 
220     op=n[*i]->u.op;
221     ++(*i);
222     r=powterm(n,i);
223     switch (op)
224     {
225       case MUL: result=tmul(l,r); break;
226       case DIV: result=tdiv(l,r); break;
227       case MOD: result=tmod(l,r); break;
228       default: assert(0);
229     }
230     tfree(&l);
231     tfree(&r);
232     if (result.type==EEK) return result;
233     l=result;
234   }
235   return l;
236 }
237 /*}}}*/
238 /* factor    -- parse and evaluate a factor of sums/differences */ /*{{{*/
factor(Token * n[],int * i)239 static Token factor(Token *n[], int *i)
240 {
241   Token l;
242 
243   l=piterm(n,i);
244   if (l.type==EEK) return l;
245   while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && (n[*i]->u.op==PLUS || n[*i]->u.op==MINUS))
246   {
247     Operator op;
248     Token result,r;
249 
250     op=n[*i]->u.op;
251     ++(*i);
252     r=piterm(n,i);
253     result=(op==PLUS ? tadd(l,r) : tsub(l,r));
254     tfree(&l);
255     tfree(&r);
256     if (result.type==EEK) return result;
257     l=result;
258   }
259   return l;
260 }
261 /*}}}*/
262 /* term      -- parse and evaluate a relational term */ /*{{{*/
term(Token * n[],int * i)263 static Token term(Token *n[], int *i)
264 {
265   Token l;
266 
267   l=factor(n,i);
268   if (l.type==EEK) return l;
269   while (n[*i]!=(Token*)0 && n[*i]->type==OPERATOR && n[*i]->u.op>=LT && n[*i]->u.op<=NE)
270   {
271     Operator op;
272     Token result,r;
273 
274     op=n[*i]->u.op;
275     ++(*i);
276     r=factor(n,i);
277     switch (op)
278     {
279       case LT: result=tlt(l,r); break;
280       case LE: result=tle(l,r); break;
281       case GE: result=tge(l,r); break;
282       case GT: result=tgt(l,r); break;
283       case ISEQUAL: result=teq(l,r); break;
284       case ABOUTEQ: result=tabouteq(l,r); break;
285       case NE: result=tne(l,r); break;
286       default: assert(0);
287     }
288     tfree(&l);
289     tfree(&r);
290     if (result.type==EEK) return result;
291     l=result;
292   }
293   return l;
294 }
295 /*}}}*/
296 
297 /* eval      -- parse and evaluate token sequence */ /*{{{*/
eval(Token ** n)298 Token eval(Token **n)
299 {
300   Token result;
301   int i;
302 
303   assert(upd_sheet!=(Sheet*)0);
304   i=0;
305   result=term(n,&i);
306   if (result.type==EEK) return result;
307   if (n[i]!=(Token*)0)
308   {
309     tfree(&result);
310     result.type=EEK;
311     result.u.err=strcpy(malloc(strlen(_("parse error after term"))+1),_("parse error after term"));
312     return result;
313   }
314   return result;
315 }
316 /*}}}*/
317