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