update dev300-m58
[ooovba.git] / soltools / cpp / _eval.c
blob82ea036ac35a85847bebd8ce854762784ea93dfa
1 #include <stdlib.h>
2 #include <string.h>
3 #include "cpp.h"
5 #define NSTAK 32
6 #define SGN 0
7 #define UNS 1
8 #define UND 2
10 #define UNSMARK 0x1000
12 struct value
14 long val;
15 int type;
18 /* conversion types */
19 #define RELAT 1
20 #define ARITH 2
21 #define LOGIC 3
22 #define SPCL 4
23 #define SHIFT 5
24 #define UNARY 6
26 /* operator priority, arity, and conversion type, indexed by tokentype */
27 struct pri
29 char pri;
30 char arity;
31 char ctype;
32 } priority[] =
36 0, 0, 0
37 }, /* END */
39 0, 0, 0
40 }, /* UNCLASS */
42 0, 0, 0
43 }, /* NAME */
45 0, 0, 0
46 }, /* NUMBER */
48 0, 0, 0
49 }, /* STRING */
51 0, 0, 0
52 }, /* CCON */
54 0, 0, 0
55 }, /* NL */
57 0, 0, 0
58 }, /* WS */
60 0, 0, 0
61 }, /* DSHARP */
63 11, 2, RELAT
64 }, /* EQ */
66 11, 2, RELAT
67 }, /* NEQ */
69 12, 2, RELAT
70 }, /* LEQ */
72 12, 2, RELAT
73 }, /* GEQ */
75 13, 2, SHIFT
76 }, /* LSH */
78 13, 2, SHIFT
79 }, /* RSH */
81 7, 2, LOGIC
82 }, /* LAND */
84 6, 2, LOGIC
85 }, /* LOR */
87 0, 0, 0
88 }, /* PPLUS */
90 0, 0, 0
91 }, /* MMINUS */
93 0, 0, 0
94 }, /* ARROW */
96 0, 0, 0
97 }, /* SBRA */
99 0, 0, 0
100 }, /* SKET */
102 3, 0, 0
103 }, /* LP */
105 3, 0, 0
106 }, /* RP */
108 0, 0, 0
109 }, /* DOT */
111 10, 2, ARITH
112 }, /* AND */
114 15, 2, ARITH
115 }, /* STAR */
117 14, 2, ARITH
118 }, /* PLUS */
120 14, 2, ARITH
121 }, /* MINUS */
123 16, 1, UNARY
124 }, /* TILDE */
126 16, 1, UNARY
127 }, /* NOT */
129 15, 2, ARITH
130 }, /* SLASH */
132 15, 2, ARITH
133 }, /* PCT */
135 12, 2, RELAT
136 }, /* LT */
138 12, 2, RELAT
139 }, /* GT */
141 9, 2, ARITH
142 }, /* CIRC */
144 8, 2, ARITH
145 }, /* OR */
147 5, 2, SPCL
148 }, /* QUEST */
150 5, 2, SPCL
151 }, /* COLON */
153 0, 0, 0
154 }, /* ASGN */
156 4, 2, 0
157 }, /* COMMA */
159 0, 0, 0
160 }, /* SHARP */
162 0, 0, 0
163 }, /* SEMIC */
165 0, 0, 0
166 }, /* CBRA */
168 0, 0, 0
169 }, /* CKET */
171 0, 0, 0
172 }, /* ASPLUS */
174 0, 0, 0
175 }, /* ASMINUS */
177 0, 0, 0
178 }, /* ASSTAR */
180 0, 0, 0
181 }, /* ASSLASH */
183 0, 0, 0
184 }, /* ASPCT */
186 0, 0, 0
187 }, /* ASCIRC */
189 0, 0, 0
190 }, /* ASLSH */
192 0, 0, 0
193 }, /* ASRSH */
195 0, 0, 0
196 }, /* ASOR */
198 0, 0, 0
199 }, /* ASAND */
201 0, 0, 0
202 }, /* ELLIPS */
204 0, 0, 0
205 }, /* DSHARP1 */
207 0, 0, 0
208 }, /* NAME1 */
210 0, 0, 0
211 }, /* NAME2 */
213 16, 1, UNARY
214 }, /* DEFINED */
216 16, 0, UNARY
217 }, /* UMINUS */
219 16, 1, UNARY
220 }, /* ARCHITECTURE */
223 int evalop(struct pri);
224 struct value tokval(Token *);
225 struct value vals[NSTAK], *vp;
226 enum toktype ops[NSTAK], *op;
229 * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword.
231 long
232 eval(Tokenrow * trp, int kw)
234 Token *tp;
235 Nlist *np;
236 int ntok, rnd;
238 trp->tp++;
239 if (kw == KIFDEF || kw == KIFNDEF)
241 if (trp->lp - trp->bp != 4 || trp->tp->type != NAME)
243 error(ERROR, "Syntax error in #ifdef/#ifndef");
244 return 0;
246 np = lookup(trp->tp, 0);
247 return (kw == KIFDEF) == (np && np->flag & (ISDEFINED | ISMAC));
249 ntok = trp->tp - trp->bp;
250 kwdefined->val = KDEFINED; /* activate special meaning of
251 * defined */
252 expandrow(trp, "<if>");
253 kwdefined->val = NAME;
254 vp = vals;
255 op = ops;
256 *op++ = END;
257 for (rnd = 0, tp = trp->bp + ntok; tp < trp->lp; tp++)
259 switch (tp->type)
261 case WS:
262 case NL:
263 continue;
265 /* nilary */
266 case NAME:
267 case NAME1:
268 case NAME2:
269 case NUMBER:
270 case CCON:
271 case STRING:
272 if (rnd)
273 goto syntax;
274 *vp++ = tokval(tp);
275 rnd = 1;
276 continue;
278 /* unary */
279 case DEFINED:
280 case TILDE:
281 case NOT:
282 if (rnd)
283 goto syntax;
284 *op++ = tp->type;
285 continue;
287 /* unary-binary */
288 case PLUS:
289 case MINUS:
290 case STAR:
291 case AND:
292 if (rnd == 0)
294 if (tp->type == MINUS)
295 *op++ = UMINUS;
296 if (tp->type == STAR || tp->type == AND)
298 error(ERROR, "Illegal operator * or & in #if/#elsif");
299 return 0;
301 continue;
303 /* flow through */
305 /* plain binary */
306 case EQ:
307 case NEQ:
308 case LEQ:
309 case GEQ:
310 case LSH:
311 case RSH:
312 case LAND:
313 case LOR:
314 case SLASH:
315 case PCT:
316 case LT:
317 case GT:
318 case CIRC:
319 case OR:
320 case QUEST:
321 case COLON:
322 case COMMA:
323 if (rnd == 0)
324 goto syntax;
325 if (evalop(priority[tp->type]) != 0)
326 return 0;
327 *op++ = tp->type;
328 rnd = 0;
329 continue;
331 case LP:
332 if (rnd)
333 goto syntax;
334 *op++ = LP;
335 continue;
337 case RP:
338 if (!rnd)
339 goto syntax;
340 if (evalop(priority[RP]) != 0)
341 return 0;
342 if (op <= ops || op[-1] != LP)
344 goto syntax;
346 op--;
347 continue;
349 case SHARP:
350 if ((tp + 1) < trp->lp)
352 np = lookup(tp + 1, 0);
353 if (np && (np->val == KMACHINE))
355 tp++;
356 if (rnd)
357 goto syntax;
358 *op++ = ARCHITECTURE;
359 continue;
362 /* fall through */
364 default:
365 error(ERROR, "Bad operator (%t) in #if/#elsif", tp);
366 return 0;
369 if (rnd == 0)
370 goto syntax;
371 if (evalop(priority[END]) != 0)
372 return 0;
373 if (op != &ops[1] || vp != &vals[1])
375 error(ERROR, "Botch in #if/#elsif");
376 return 0;
378 if (vals[0].type == UND)
379 error(ERROR, "Undefined expression value");
380 return vals[0].val;
381 syntax:
382 error(ERROR, "Syntax error in #if/#elsif");
383 return 0;
387 evalop(struct pri pri)
389 struct value v1;
390 struct value v2 = { 0, UND };
391 long rv1, rv2;
392 int rtype, oper;
394 rv2 = 0;
395 rtype = 0;
396 while (pri.pri < priority[op[-1]].pri)
398 oper = *--op;
399 if (priority[oper].arity == 2)
401 v2 = *--vp;
402 rv2 = v2.val;
404 v1 = *--vp;
405 rv1 = v1.val;
406 /*lint -e574 -e644 */
407 switch (priority[oper].ctype)
409 case 0:
410 default:
411 error(WARNING, "Syntax error in #if/#endif");
412 return 1;
413 case ARITH:
414 case RELAT:
415 if (v1.type == UNS || v2.type == UNS)
416 rtype = UNS;
417 else
418 rtype = SGN;
419 if (v1.type == UND || v2.type == UND)
420 rtype = UND;
421 if (priority[oper].ctype == RELAT && rtype == UNS)
423 oper |= UNSMARK;
424 rtype = SGN;
426 break;
427 case SHIFT:
428 if (v1.type == UND || v2.type == UND)
429 rtype = UND;
430 else
431 rtype = v1.type;
432 if (rtype == UNS)
433 oper |= UNSMARK;
434 break;
435 case UNARY:
436 rtype = v1.type;
437 break;
438 case LOGIC:
439 case SPCL:
440 break;
442 switch (oper)
444 case EQ:
445 case EQ | UNSMARK:
446 rv1 = rv1 == rv2;
447 break;
448 case NEQ:
449 case NEQ | UNSMARK:
450 rv1 = rv1 != rv2;
451 break;
452 case LEQ:
453 rv1 = rv1 <= rv2;
454 break;
455 case GEQ:
456 rv1 = rv1 >= rv2;
457 break;
458 case LT:
459 rv1 = rv1 < rv2;
460 break;
461 case GT:
462 rv1 = rv1 > rv2;
463 break;
464 case LEQ | UNSMARK:
465 rv1 = (unsigned long)rv1 <= (unsigned long)rv2;
466 break;
467 case GEQ | UNSMARK:
468 rv1 = (unsigned long)rv1 >= (unsigned long)rv2;
469 break;
470 case LT | UNSMARK:
471 rv1 = (unsigned long)rv1 < (unsigned long)rv2;
472 break;
473 case GT | UNSMARK:
474 rv1 = (unsigned long)rv1 > (unsigned long)rv2;
475 break;
476 case LSH:
477 rv1 <<= rv2;
478 break;
479 case LSH | UNSMARK:
480 rv1 = (unsigned long) rv1 << rv2;
481 break;
482 case RSH:
483 rv1 >>= rv2;
484 break;
485 case RSH | UNSMARK:
486 rv1 = (unsigned long) rv1 >> rv2;
487 break;
488 case LAND:
489 rtype = UND;
490 if (v1.type == UND)
491 break;
492 if (rv1 != 0)
494 if (v2.type == UND)
495 break;
496 rv1 = rv2 != 0;
498 else
499 rv1 = 0;
500 rtype = SGN;
501 break;
502 case LOR:
503 rtype = UND;
504 if (v1.type == UND)
505 break;
506 if (rv1 == 0)
508 if (v2.type == UND)
509 break;
510 rv1 = rv2 != 0;
512 else
513 rv1 = 1;
514 rtype = SGN;
515 break;
516 case AND:
517 rv1 &= rv2;
518 break;
519 case STAR:
520 rv1 *= rv2;
521 break;
522 case PLUS:
523 rv1 += rv2;
524 break;
525 case MINUS:
526 rv1 -= rv2;
527 break;
528 case UMINUS:
529 if (v1.type == UND)
530 rtype = UND;
531 rv1 = -rv1;
532 break;
533 case OR:
534 rv1 |= rv2;
535 break;
536 case CIRC:
537 rv1 ^= rv2;
538 break;
539 case TILDE:
540 rv1 = ~rv1;
541 break;
542 case NOT:
543 rv1 = !rv1;
544 if (rtype != UND)
545 rtype = SGN;
546 break;
547 case SLASH:
548 if (rv2 == 0)
550 rtype = UND;
551 break;
553 if (rtype == UNS)
554 rv1 /= (unsigned long) rv2;
555 else
556 rv1 /= rv2;
557 break;
558 case PCT:
559 if (rv2 == 0)
561 rtype = UND;
562 break;
564 if (rtype == UNS)
565 rv1 %= (unsigned long) rv2;
566 else
567 rv1 %= rv2;
568 break;
569 case COLON:
570 if (op[-1] != QUEST)
571 error(ERROR, "Bad ?: in #if/endif");
572 else
574 op--;
575 if ((--vp)->val == 0)
576 v1 = v2;
577 rtype = v1.type;
578 rv1 = v1.val;
580 break;
582 case DEFINED:
583 case ARCHITECTURE:
584 break;
586 default:
587 error(ERROR, "Eval botch (unknown operator)");
588 return 1;
590 /*lint +e574 +e644 */
591 v1.val = rv1;
592 v1.type = rtype;
593 *vp++ = v1;
595 return 0;
598 struct value
599 tokval(Token * tp)
601 struct value v;
602 Nlist *np;
603 int i, base;
604 unsigned long n;
605 uchar *p, c;
607 v.type = SGN;
608 v.val = 0;
609 switch (tp->type)
612 case NAME:
613 v.val = 0;
614 break;
616 case NAME1:
617 if ((np = lookup(tp, 0)) != NULL && np->flag & (ISDEFINED | ISMAC))
618 v.val = 1;
619 break;
621 case NAME2:
622 if ((np = lookup(tp, 0)) != NULL && np->flag & (ISARCHITECTURE))
623 v.val = 1;
624 break;
626 case NUMBER:
627 n = 0;
628 base = 10;
629 p = tp->t;
630 c = p[tp->len];
631 p[tp->len] = '\0';
632 if (*p == '0')
634 base = 8;
635 if (p[1] == 'x' || p[1] == 'X')
637 base = 16;
638 p++;
640 p++;
642 for (;; p++)
644 if ((i = digit(*p)) < 0)
645 break;
646 if (i >= base)
647 error(WARNING,
648 "Bad digit in number %t", tp);
649 n *= base;
650 n += i;
652 if (n >= 0x80000000 && base != 10)
653 v.type = UNS;
654 for (; *p; p++)
656 if (*p == 'u' || *p == 'U')
657 v.type = UNS;
658 else
659 if (*p == 'l' || *p == 'L')
661 else
663 error(ERROR,
664 "Bad number %t in #if/#elsif", tp);
665 break;
668 v.val = n;
669 tp->t[tp->len] = c;
670 break;
672 case CCON:
673 n = 0;
674 p = tp->t;
675 if (*p == 'L')
677 p += 1;
678 error(WARNING, "Wide char constant value undefined");
680 p += 1;
681 if (*p == '\\')
683 p += 1;
684 if ((i = digit(*p)) >= 0 && i <= 7)
686 n = i;
687 p += 1;
688 if ((i = digit(*p)) >= 0 && i <= 7)
690 p += 1;
691 n <<= 3;
692 n += i;
693 if ((i = digit(*p)) >= 0 && i <= 7)
695 p += 1;
696 n <<= 3;
697 n += i;
701 else
702 if (*p == 'x')
704 p += 1;
705 while ((i = digit(*p)) >= 0 && i <= 15)
707 p += 1;
708 n <<= 4;
709 n += i;
712 else
714 static char cvcon[]
715 = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
716 size_t j;
718 for (j = 0; j < sizeof(cvcon); j += 2)
720 if (*p == cvcon[j])
722 n = cvcon[j + 1];
723 break;
726 p += 1;
727 if (j >= sizeof(cvcon))
728 error(WARNING,
729 "Undefined escape in character constant");
732 else
733 if (*p == '\'')
734 error(ERROR, "Empty character constant");
735 else
736 n = *p++;
737 if (*p != '\'')
738 error(WARNING, "Multibyte character constant undefined");
739 else
740 if (n > 127)
741 error(WARNING, "Character constant taken as not signed");
742 v.val = n;
743 break;
745 case STRING:
746 error(ERROR, "String in #if/#elsif");
747 break;
749 return v;
753 digit(int i)
755 if ('0' <= i && i <= '9')
756 i -= '0';
757 else
758 if ('a' <= i && i <= 'f')
759 i -= 'a' - 10;
760 else
761 if ('A' <= i && i <= 'F')
762 i -= 'A' - 10;
763 else
764 i = -1;
765 return i;