add increase and decrease features
[calc.git] / parser.c
CommitLineData
bc97a989 1#include <malloc.h>
f2927108 2#include <math.h>
87621fe1 3#include <stdio.h>
bc97a989
LM
4#include <stdlib.h>
5
6#include "debug.h"
bc97a989
LM
7
8#include "parser.h"
9
5075f6ea
LM
10/* global variables */
11
12double answer = 0;
13
6ba1dd0f
LM
14#define STORAGE_SIZE 10
15double storage[STORAGE_SIZE] = {0};
16
bc97a989
LM
17/* compare codes */
18
19int codecmp (char *ref, char *str)
20{
21 int sig;
22
23 while (*ref != '\0') {
0b9cc9b0
LM
24 if (*ref == '\t') {
25 sig = (*str == '.') ? -1 : ((*str >= '0') && (*str <= '9'));
26 } else {
27 sig = *str - *ref;
28 }
bc97a989
LM
29 if (sig != 0) {
30 return (sig > 0) ? 1 : -1;
31 }
0b9cc9b0
LM
32 str++;
33 ref++;
bc97a989
LM
34 }
35
36 return 0;
37}
38
39/* allocate new element */
40
11cda8d7 41element_t *newelement (func_t function, int nbops, int prio)
bc97a989
LM
42{
43 element_t *new = (element_t *) calloc (1, sizeof (element_t));
44 if (new == NULL) {
04d68907 45 VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n"));
bc97a989
LM
46 return NULL;
47 }
48 new->func = function;
49 new->nbops = nbops;
11cda8d7 50 new->prio = prio;
bc97a989
LM
51
52 return new;
53}
54
031d7bba
LM
55/* desallocate element */
56
57void delelement (element_t *root)
58{
59 int i;
60 if ((root != NULL) && (root != ERROR_OP)) {
61 for (i = 0; i < root->nbops; i++) {
62 if ((root->ops[i] != NULL) && (root->ops[i] != ERROR_OP)) {
63 delelement (root->ops[i]);
64 }
65 }
66 free (root);
67 }
68}
69
bc97a989
LM
70/* functions */
71
ca3e2a2f 72#define NB_OPERATORS 14
bc97a989 73keyword_t operators[NB_OPERATORS] = {
11cda8d7
LM
74 { "+\t", Add, 2, 1, 1},
75 { "-\t", Sub, 2, 1, 1},
76 { "*", Mul, 2, 1, 2},
77 { "/", Div, 2, 1, 2},
c47a9298 78 { "%", Mod, 2, 1, 3},
7fe742c9 79 { "^", Pow, 2, 1, 4},
ca3e2a2f
LM
80 { "==", Equal, 2, 2, -1},
81 { "!=", Diff, 2, 2, -1},
82 { ">=", Ge, 2, 2, -1},
83 { "<=", Le, 2, 2, -1},
84 { ">", Gt, 2, 1, -1},
85 { "<", Lt, 2, 1, -1},
86 { "&", And, 2, 1, -2},
87 { "|", Or, 2, 1, -2}
bc97a989
LM
88};
89
a8cf32ba 90#define NB_FUNCTIONS 16
bc97a989 91keyword_t functions[NB_FUNCTIONS] = {
c47a9298
LM
92 { "sqrt", Sqr, 1, 4, 5},
93 { "pow", Pow, 2, 3, 5},
94 { "cos", Cos, 1, 3, 5},
95 { "sin", Sin, 1, 3, 5},
471da7c9 96 { "atan", Atan, 1, 4, 5},
c47a9298 97 { "exp", Exp, 1, 3, 5},
89cf0955 98 { "log", Log, 1, 3, 5},
ca3e2a2f 99 { "sto", Store, 2, 3, 9},
6ba1dd0f 100 { "rcl", Recall, 1, 3, 5},
a8cf32ba
LM
101 { "inc", Inc, 1, 3, 5},
102 { "dec", Dec, 1, 3, 5},
ca3e2a2f
LM
103 { "disp", Disp, 0, 4, 9},
104 { "quit", Quit, 0, 4, 9},
105 { "help", Help, 0, 4, 9},
94b4e517
LM
106 { "!", Not, 1, 1, 6},
107 { "cond", Cond, 3, 4, 5}
471da7c9
LM
108};
109
5075f6ea 110#define NB_CONSTANTS 3
471da7c9 111keyword_t constants[NB_CONSTANTS] = {
5075f6ea
LM
112 { "ans", Ans, 0, 3, 5},
113 { "e", E, 0, 1, 5},
114 { "pi", Pi, 0, 2, 5}
bc97a989
LM
115};
116
d2ff8478
LM
117/* subparser function */
118
119element_t *subparser (element_t **proot, char **pstr, func_t func, int nbops, int prio)
120{
121 element_t *new = newelement (func, nbops, prio);
122 if (new == NULL) {
123 return ERROR_OP;
124 }
125 new->ops[0] = *proot;
126 new->ops[1] = parser (*pstr, pstr, new->prio);
686c4bc2 127 if ((new->ops[1] == NULL) || ((new->ops[1] != ERROR_OP) && (new->ops[1]->prio == 9))) {
67b13e3d
LM
128 delelement (new->ops[1]);
129 new->ops[1] = ERROR_OP;
130 }
d2ff8478 131 if (new->ops[1] == ERROR_OP) {
031d7bba
LM
132 delelement (new);
133 *proot = NULL;
d2ff8478
LM
134 return ERROR_OP;
135 }
3b4b0bbe 136 *proot = newelement (Val, 1, 5);
031d7bba
LM
137 if (*proot == NULL) {
138 delelement (new);
d2ff8478
LM
139 return ERROR_OP;
140 }
141 (*proot)->ops[0] = new;
142
143 return *proot;
144}
145
bc97a989
LM
146/* parser function */
147
ef37d966 148element_t *parser (char *str, char **next, int prio)
0b489a77 149{
bc97a989 150 element_t *root = NULL;
85b4a72c 151 int i;
bc97a989 152
04d68907 153 VERBOSE (DEBUG, fprintf (stdout, "Starting parsing\n"));
49223129 154
bc97a989
LM
155 /* main loop */
156 while (*str != '\0') {
157 int found = 0;
158 element_t *new = NULL;
04d68907 159 VERBOSE (INFO, fprintf (stdout, "Processing: %s\n", str));
bc97a989
LM
160
161 /* skip spaces and tabs */
162
163 if ((*str == ' ') || (*str == '\t')) {
164 str++;
165 continue;
166 }
167
85b4a72c 168 /* check for open bracket */
0b489a77 169
0b489a77 170 if (*str == '(') {
04d68907 171 VERBOSE (DEBUG, fprintf (stdout, "start processing bracket\n"));
0b489a77 172 if (root) {
85b4a72c
LM
173 do {
174 found = 0;
ef37d966 175 new = parser (str + 1, &str, 0);
686c4bc2 176 if ((new == NULL) || ((new != ERROR_OP) && (new->prio == 9))) {
67b13e3d
LM
177 delelement (new);
178 new = ERROR_OP;
179 }
686c4bc2 180 if ((new == NULL) || (new == ERROR_OP)) {
031d7bba 181 delelement (root);
85b4a72c
LM
182 return ERROR_OP;
183 }
184 for (i = 0; i < root->nbops; i++) {
185 if (root->ops[i] == NULL) {
0b489a77
LM
186 root->ops[i] = new;
187 found = 1;
188 break;
189 }
190 }
85b4a72c 191 if (!found) {
031d7bba
LM
192 delelement (new);
193 delelement (root);
85b4a72c
LM
194 return ERROR_OP;
195 }
196 } while (*str == ',');
197 } else {
3b4b0bbe 198 root = newelement (Val, 1, 5);
85b4a72c 199 if (root == NULL) {
0b489a77
LM
200 return ERROR_OP;
201 }
ef37d966 202 new = parser (str + 1, &str, 0);
686c4bc2 203 if ((new == NULL) || ((new != ERROR_OP) && (new->prio == 9))) {
67b13e3d
LM
204 delelement (new);
205 new = ERROR_OP;
206 }
686c4bc2 207 if ((new == NULL) || (new == ERROR_OP) || (*str == ',')) {
031d7bba
LM
208 delelement (new);
209 delelement (root);
efdfb543
LM
210 return ERROR_OP;
211 }
85b4a72c 212 root->ops[0] = new;
0b489a77 213 }
3c0db5bc
LM
214 if (*str != ')') {
215 delelement (root);
216 return ERROR_OP;
217 }
85b4a72c 218 str++;
04d68907 219 VERBOSE (DEBUG, fprintf (stdout, "stop processing bracket\n"));
efdfb543 220 continue;
49223129 221 }
85b4a72c
LM
222
223 /* check for closing bracket or koma */
224
225 if ((*str == ')') || (*str == ',')) {
49223129 226 if (next != NULL) {
85b4a72c 227 *next = str;
49223129
LM
228 }
229 return root;
0b489a77
LM
230 }
231
bc97a989
LM
232 /* look for operators */
233
234 for (i = 0; i < NB_OPERATORS; i++) {
235 keyword_t *operator = operators + i;
236 if (codecmp (operator->keyword, str) == 0) {
04d68907 237 VERBOSE (DEBUG, fprintf (stdout, "start processing operator\n"));
11cda8d7 238 if (root) {
ef37d966 239 if ((prio) && (prio > operator->prio)) {
04d68907 240 VERBOSE (DEBUG, fprintf (stdout, "stop because operator priority\n"));
ef37d966
LM
241 *next = str;
242 return root;
243 }
244 str += operator->offset;
04d68907 245 VERBOSE (INFO, fprintf (stdout, "Oper: %d\n", operator->func));
d2ff8478 246 if (subparser (&root, &str, operator->func, operator->nbops, operator->prio) == ERROR_OP) {
031d7bba 247 delelement (root);
ef37d966 248 return ERROR_OP;
11cda8d7 249 }
3b4b0bbe
LM
250 } else if (*str == '-') {
251 new = newelement (Sig, 1, 9);
252 if (new == NULL) {
253 return ERROR_OP;
254 }
255 root = new;
49223129 256 } else {
0b489a77 257 return ERROR_OP;
bc97a989 258 }
bc97a989 259 found = 1;
04d68907 260 VERBOSE (DEBUG, fprintf (stdout, "stop processing operator\n"));
bc97a989
LM
261 break;
262 }
263 }
264 if (found) {
bc97a989
LM
265 continue;
266 }
49223129 267
bc97a989
LM
268 /* look for functions */
269
270 for (i = 0; i < NB_FUNCTIONS; i++) {
271 keyword_t *function = functions + i;
272 if (codecmp (function->keyword, str) == 0) {
04d68907 273 VERBOSE (DEBUG, fprintf (stdout, "start processing function\n"));
bc97a989 274 if (root == NULL) {
04d68907 275 VERBOSE (INFO, fprintf (stdout, "Func: %d\n", function->func));
11cda8d7 276 new = newelement (function->func, function->nbops, function->prio);
bc97a989 277 if (new == NULL) {
0b489a77 278 return ERROR_OP;
bc97a989
LM
279 }
280 root = new;
031d7bba
LM
281 } else {
282 delelement (root);
0b489a77 283 return ERROR_OP;
bc97a989
LM
284 }
285 str += function->offset;
286 found = 1;
04d68907 287 VERBOSE (DEBUG, fprintf (stdout, "stop processing function\n"));
bc97a989
LM
288 break;
289 }
290 }
291 if (found) {
bc97a989
LM
292 continue;
293 }
294
471da7c9
LM
295 /* look for constant */
296
297 for (i = 0; i < NB_CONSTANTS; i++) {
298 keyword_t *constant = constants + i;
299 if (codecmp (constant->keyword, str) == 0) {
300 VERBOSE (DEBUG, fprintf (stdout, "start processing constant\n"));
301 if (root == NULL) {
5075f6ea 302 VERBOSE (INFO, fprintf (stdout, "Const: %d\n", constant->func));
471da7c9
LM
303 new = newelement (constant->func, constant->nbops, constant->prio);
304 if (new == NULL) {
305 return ERROR_OP;
306 }
307 root = new;
308 } else {
309 delelement (root);
310 return ERROR_OP;
311 }
312 str += constant->offset;
313 found = 1;
314 VERBOSE (DEBUG, fprintf (stdout, "stop processing constant\n"));
315 break;
316 }
317 }
318 if (found) {
319 continue;
320 }
321
bc97a989
LM
322 /* look for number */
323
0b9cc9b0
LM
324 if (((*str >= '0') && (*str <= '9')) ||
325 (*str == '.') || (*str == '+') || (*str == '-')) {
04d68907 326 VERBOSE (DEBUG, fprintf (stdout, "start processing value\n"));
bc97a989 327 char *pt;
fd88e359 328 double value = strtod (str, &pt);
04d68907 329 VERBOSE (INFO, fprintf (stdout, "Value: %f\n", value));
bc97a989 330 if (str != pt) {
ce6627f2 331 if ((root == NULL) || (root->prio == 6)) {
3b4b0bbe 332 new = newelement (Val, 1, 5);
c47a9298
LM
333 if (new == NULL) {
334 return ERROR_OP;
335 }
336 new->value = value;
ce6627f2
LM
337 if (root == NULL) {
338 root = new;
339 } else {
340 for (i = 0; i < root->nbops; i++) {
341 if (root->ops[i] == NULL) {
342 root->ops[i] = new;
343 found = 1;
344 break;
345 }
346 }
347 if (!found) {
348 delelement (new);
349 delelement (root);
350 return ERROR_OP;
351 }
352 }
c47a9298 353 str = pt;
32741902
LM
354 } else if ((*str == '+') || (*str == '-')) {
355 if ((prio) && (prio > 1)) {
356 VERBOSE (DEBUG, fprintf (stdout, "stop because operator priority\n"));
357 *next = str;
358 return root;
359 }
360 if (subparser (&root, &str, Add, 2, 1) == ERROR_OP) {
031d7bba 361 delelement (root);
0b489a77 362 return ERROR_OP;
bc97a989 363 }
0b9cc9b0 364 } else {
031d7bba 365 delelement (root);
0b9cc9b0 366 return ERROR_OP;
bc97a989 367 }
bc97a989
LM
368 found = 1;
369 }
04d68907 370 VERBOSE (DEBUG, fprintf (stdout, "stop processing value\n"));
bc97a989
LM
371 }
372
373 /* error */
374
375 if (!found) {
031d7bba 376 delelement (root);
0b489a77 377 return ERROR_OP;
bc97a989
LM
378 }
379
380 }
381
49223129
LM
382 if (next != NULL) {
383 *next = str;
384 }
031d7bba 385
bc97a989
LM
386 return root;
387}
388
389/* print element tree */
390
391void print_element (element_t *root, int level)
392{
393 char *func = NULL;
394 int i;
395
49223129 396 if ((root == NULL) || (root == ERROR_OP)) {
bc97a989 397 return;
49223129
LM
398 }
399
bc97a989 400 for (i = 0; i < level; i++) {
04d68907 401 fprintf (stdout, " ");
bc97a989
LM
402 }
403
404 switch (root->func) {
405 case Val: func = "Value"; break;
89cf0955 406 case Sig: func = "Sign"; break;
bc97a989
LM
407 case Add: func = "Addition"; break;
408 case Sub: func = "Subtraction"; break;
409 case Mul: func = "Multiplication"; break;
410 case Div: func = "Division"; break;
c47a9298 411 case Mod: func = "Modulo"; break;
bc97a989
LM
412 case Pow: func = "Power"; break;
413 case Sqr: func = "Square Root"; break;
414 case Cos: func = "Cosine"; break;
415 case Sin: func = "Sine"; break;
471da7c9 416 case Atan: func = "Arc Tangent"; break;
bc97a989
LM
417 case Log: func = "Logarithm"; break;
418 case Exp: func = "Exponantial"; break;
6ba1dd0f
LM
419 case Store: func = "Store"; break;
420 case Recall: func = "Recall"; break;
a8cf32ba
LM
421 case Inc: func = "Increase"; break;
422 case Dec: func = "Decrease"; break;
6ba1dd0f 423 case Disp: func = "Display"; break;
471da7c9
LM
424 case Quit: func = "Quit"; break;
425 case Help: func = "Help"; break;
5075f6ea 426 case Ans: func = "Ans"; break;
471da7c9
LM
427 case Pi: func = "Pi"; break;
428 case E: func = "E"; break;
7fe742c9
LM
429 case Equal: func = "Equal"; break;
430 case Diff: func = "Different"; break;
431 case Ge: func = "Greater or equal"; break;
432 case Le: func = "Lesser or equal"; break;
433 case Gt: func = "Greater"; break;
434 case Lt: func = "Lesser"; break;
ca3e2a2f
LM
435 case And: func = "And"; break;
436 case Or: func = "Or"; break;
437 case Not: func = "Not"; break;
94b4e517 438 case Cond: func = "Condition"; break;
bc97a989
LM
439 }
440
04d68907 441 fprintf (stdout, "Function: %s\n", func);
bc97a989 442
85b4a72c 443 if ((root->func == Val) && (root->ops[0] == NULL)) {
bc97a989 444 for (i = 0; i < level; i++) {
04d68907 445 fprintf (stdout, " ");
bc97a989 446 }
04d68907 447 fprintf (stdout, "value: %f\n", root->value);
bc97a989
LM
448 } else {
449 for (i = 0; i < root->nbops; i++) {
450 print_element (root->ops[i], level + 1);
451 }
452 }
453}
454
6ba1dd0f
LM
455/* storage functions */
456
3639df66 457double store (int index, double value)
6ba1dd0f
LM
458{
459 if ((index > 0) && (index <= STORAGE_SIZE)) {
3639df66 460 storage[index - 1] = value;
6ba1dd0f
LM
461 } else {
462 VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [1, %d]\n", index, STORAGE_SIZE));
463 }
3639df66 464 return value;
6ba1dd0f
LM
465}
466
467double recall (int index)
468{
469 if ((index > 0) && (index <= STORAGE_SIZE)) {
470 return storage[index - 1];
471 } else {
472 VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [1, %d]\n", index, STORAGE_SIZE));
473 }
474 return 0;
475}
476
a8cf32ba
LM
477double increase (int index)
478{
479 if ((index > 0) && (index <= STORAGE_SIZE)) {
480 return storage[index - 1]++;
481 } else {
482 VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [1, %d]\n", index, STORAGE_SIZE));
483 }
484 return 0;
485}
486
487double decrease (int index)
488{
489 if ((index > 0) && (index <= STORAGE_SIZE)) {
490 return storage[index - 1]--;
491 } else {
492 VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [1, %d]\n", index, STORAGE_SIZE));
493 }
494 return 0;
495}
496
6ba1dd0f
LM
497void display (void)
498{
499 int i;
500 fprintf (stdout, "storage:");
501 for (i = 0; i < STORAGE_SIZE; i++) {
502 fprintf (stdout, " %g", storage[i]);
503 }
504 fprintf (stdout, "\n");
505}
506
89cf0955
LM
507/* quit function */
508
509void quit (void)
510{
04d68907 511 fprintf (stdout, "bye\n");
89cf0955
LM
512 exit (0);
513}
514
515/* help message */
516
517void help (void)
518{
04d68907 519 fprintf (stdout, "calc is a simple calculator\n\n");
94b4e517
LM
520 fprintf (stdout, "supported operators:");
521 fprintf (stdout, " + - * / %% ^\n");
522 fprintf (stdout, "camparison operators:");
523 fprintf (stdout, " == != >= <= > <\n");
524 fprintf (stdout, "logical operators:");
525 fprintf (stdout, " & | !\n");
526 fprintf (stdout, "supported functions:");
527 fprintf (stdout, " pow sqrt cos sin atan log exp\n");
528 fprintf (stdout, "storage functions:");
a8cf32ba 529 fprintf (stdout, " sto rcl inc dec\n");
94b4e517
LM
530 fprintf (stdout, "conditional functions:");
531 fprintf (stdout, " cond\n");
532 fprintf (stdout, "miscellaneous functions:");
533 fprintf (stdout, " quit help\n");
534 fprintf (stdout, "supported constants:");
471da7c9 535 fprintf (stdout, " e pi\n");
89cf0955 536}
3b4b0bbe 537
f2927108
LM
538/* evaluate element tree */
539
89cf0955
LM
540#define MASK_SUB 0x1
541#define MASK_DIV 0x2
542
3b4b0bbe 543double evaluate_element (element_t *root, char mask)
f2927108
LM
544{
545 double op0 = 0, op1 = 0;
3b4b0bbe 546 char nextmask = mask;
f2927108
LM
547
548 if ((root == NULL) || (root == ERROR_OP)) {
04d68907 549 VERBOSE (WARNING, fprintf (stdout, "error while evaluating\n"));
f2927108
LM
550 return 0;
551 }
552
3b4b0bbe
LM
553 /* mask to manage sub operator sub and div */
554 switch (root->func) {
555 case Add:
556 nextmask &= ~MASK_SUB;
557 nextmask &= ~MASK_DIV;
558 break;
559 case Sub:
560 nextmask |= MASK_SUB;
561 nextmask &= ~MASK_DIV;
562 break;
563 case Mul:
564 nextmask &= ~MASK_DIV;
565 break;
566 case Div:
567 nextmask |= MASK_DIV;
568 break;
569 default:
570 nextmask = mask;
571 }
572
f2927108
LM
573 switch (root->func) {
574 case Val:
3b4b0bbe
LM
575 case Sig:
576 op0 = (root->ops[0]) ? evaluate_element (root->ops[0], nextmask) : root->value;
f2927108
LM
577 break;
578 case Add:
579 case Sub:
580 case Mul:
581 case Div:
c47a9298 582 case Mod:
f2927108 583 case Pow:
3639df66 584 case Store:
7fe742c9
LM
585 case Equal:
586 case Diff:
587 case Ge:
588 case Le:
589 case Gt:
590 case Lt:
ca3e2a2f
LM
591 case And:
592 case Or:
f2927108 593 if (root->ops[1]) {
3b4b0bbe 594 op1 = evaluate_element (root->ops[1], nextmask);
3639df66 595 } else if (root->func != Store) {
04d68907 596 VERBOSE (WARNING, fprintf (stdout, "error while evaluating (op[1])\n"));
f2927108
LM
597 return 0;
598 }
599 /* fallthrough */
600 case Sqr:
601 case Cos:
602 case Sin:
471da7c9 603 case Atan:
f2927108
LM
604 case Log:
605 case Exp:
6ba1dd0f 606 case Recall:
a8cf32ba
LM
607 case Inc:
608 case Dec:
ca3e2a2f 609 case Not:
94b4e517 610 case Cond:
f2927108 611 if (root->ops[0]) {
3b4b0bbe 612 op0 = evaluate_element (root->ops[0], 0);
f2927108 613 } else {
04d68907 614 VERBOSE (WARNING, fprintf (stdout, "error while evaluating (op[0])\n"));
f2927108
LM
615 return 0;
616 }
89cf0955 617 break;
6ba1dd0f 618 case Disp:
471da7c9
LM
619 case Quit:
620 case Help:
5075f6ea 621 case Ans:
471da7c9
LM
622 case Pi:
623 case E:
89cf0955 624 break;
f2927108
LM
625 }
626
627 switch (root->func) {
3b4b0bbe
LM
628 case Val: return op0;
629 case Sig: return -op0;
630 case Add: return ((mask & MASK_SUB) == 0) ? op0 + op1 : op0 - op1;
631 case Sub: return ((mask & MASK_SUB) == 0) ? op0 - op1 : op0 + op1;
632 case Mul: return ((mask & MASK_DIV) == 0) ? op0 * op1 : op0 / op1;
633 case Div: return ((mask & MASK_DIV) == 0) ? op0 / op1 : op0 * op1;
c47a9298 634 case Mod: return fmod (op0, op1);
f2927108
LM
635 case Pow: return pow (op0, op1);
636 case Sqr: return sqrt (op0);
637 case Cos: return cos (op0);
638 case Sin: return sin (op0);
471da7c9 639 case Atan: return atan (op0);
f2927108
LM
640 case Log: return log (op0);
641 case Exp: return exp (op0);
3639df66 642 case Store: return store ((int)op0, (op1) ? op1 : answer);
6ba1dd0f 643 case Recall: return recall ((int)op0);
a8cf32ba
LM
644 case Inc: return increase ((int)op0);
645 case Dec: return decrease ((int)op0);
6ba1dd0f 646 case Disp: display (); break;
471da7c9
LM
647 case Quit: quit (); break;
648 case Help: help (); break;
5075f6ea 649 case Ans: return answer;
471da7c9
LM
650 case Pi: return M_PI;
651 case E: return M_E;
7fe742c9
LM
652 case Equal: return op0 == op1;
653 case Diff: return op0 != op1;
654 case Ge: return op0 >= op1;
655 case Le: return op0 <= op1;
656 case Gt: return op0 > op1;
657 case Lt: return op0 < op1;
ca3e2a2f
LM
658 case And: return (op0 != 0) && (op1 != 0);
659 case Or: return (op0 != 0) || (op1 != 0);
660 case Not: return (op0 == 0);
94b4e517
LM
661 case Cond:
662 if ((op0) && (root->ops[1])) {
663 return evaluate_element (root->ops[1], 0);
664 } else if ((!op0) && (root->ops[2])) {
665 return evaluate_element (root->ops[2], 0);
666 } else {
667 return 0;
668 }
f2927108
LM
669 }
670
671 return 0;
672}
673
bc97a989 674/* vim: set ts=4 sw=4 et: */