1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | #include "cpp.h" |
21 | |
22 | #define NSTAK32 32 |
23 | #define SGN0 0 |
24 | #define UNS1 1 |
25 | #define UND2 2 |
26 | |
27 | #define UNSMARK0x1000 0x1000 |
28 | |
29 | struct value |
30 | { |
31 | long val; |
32 | int type; |
33 | }; |
34 | |
35 | |
36 | #define RELAT1 1 |
37 | #define ARITH2 2 |
38 | #define LOGIC3 3 |
39 | #define SPCL4 4 |
40 | #define SHIFT5 5 |
41 | #define UNARY6 6 |
42 | |
43 | |
44 | struct pri |
45 | { |
46 | char pri; |
47 | char arity; |
48 | char ctype; |
49 | } priority[] = |
50 | |
51 | { |
52 | { |
53 | 0, 0, 0 |
54 | }, |
55 | { |
56 | 0, 0, 0 |
57 | }, |
58 | { |
59 | 0, 0, 0 |
60 | }, |
61 | { |
62 | 0, 0, 0 |
63 | }, |
64 | { |
65 | 0, 0, 0 |
66 | }, |
67 | { |
68 | 0, 0, 0 |
69 | }, |
70 | { |
71 | 0, 0, 0 |
72 | }, |
73 | { |
74 | 0, 0, 0 |
75 | }, |
76 | { |
77 | 0, 0, 0 |
78 | }, |
79 | { |
80 | 11, 2, RELAT1 |
81 | }, |
82 | { |
83 | 11, 2, RELAT1 |
84 | }, |
85 | { |
86 | 12, 2, RELAT1 |
87 | }, |
88 | { |
89 | 12, 2, RELAT1 |
90 | }, |
91 | { |
92 | 13, 2, SHIFT5 |
93 | }, |
94 | { |
95 | 13, 2, SHIFT5 |
96 | }, |
97 | { |
98 | 7, 2, LOGIC3 |
99 | }, |
100 | { |
101 | 6, 2, LOGIC3 |
102 | }, |
103 | { |
104 | 0, 0, 0 |
105 | }, |
106 | { |
107 | 0, 0, 0 |
108 | }, |
109 | { |
110 | 0, 0, 0 |
111 | }, |
112 | { |
113 | 0, 0, 0 |
114 | }, |
115 | { |
116 | 0, 0, 0 |
117 | }, |
118 | { |
119 | 3, 0, 0 |
120 | }, |
121 | { |
122 | 3, 0, 0 |
123 | }, |
124 | { |
125 | 0, 0, 0 |
126 | }, |
127 | { |
128 | 10, 2, ARITH2 |
129 | }, |
130 | { |
131 | 15, 2, ARITH2 |
132 | }, |
133 | { |
134 | 14, 2, ARITH2 |
135 | }, |
136 | { |
137 | 14, 2, ARITH2 |
138 | }, |
139 | { |
140 | 16, 1, UNARY6 |
141 | }, |
142 | { |
143 | 16, 1, UNARY6 |
144 | }, |
145 | { |
146 | 15, 2, ARITH2 |
147 | }, |
148 | { |
149 | 15, 2, ARITH2 |
150 | }, |
151 | { |
152 | 12, 2, RELAT1 |
153 | }, |
154 | { |
155 | 12, 2, RELAT1 |
156 | }, |
157 | { |
158 | 9, 2, ARITH2 |
159 | }, |
160 | { |
161 | 8, 2, ARITH2 |
162 | }, |
163 | { |
164 | 5, 2, SPCL4 |
165 | }, |
166 | { |
167 | 5, 2, SPCL4 |
168 | }, |
169 | { |
170 | 0, 0, 0 |
171 | }, |
172 | { |
173 | 4, 2, 0 |
174 | }, |
175 | { |
176 | 0, 0, 0 |
177 | }, |
178 | { |
179 | 0, 0, 0 |
180 | }, |
181 | { |
182 | 0, 0, 0 |
183 | }, |
184 | { |
185 | 0, 0, 0 |
186 | }, |
187 | { |
188 | 0, 0, 0 |
189 | }, |
190 | { |
191 | 0, 0, 0 |
192 | }, |
193 | { |
194 | 0, 0, 0 |
195 | }, |
196 | { |
197 | 0, 0, 0 |
198 | }, |
199 | { |
200 | 0, 0, 0 |
201 | }, |
202 | { |
203 | 0, 0, 0 |
204 | }, |
205 | { |
206 | 0, 0, 0 |
207 | }, |
208 | { |
209 | 0, 0, 0 |
210 | }, |
211 | { |
212 | 0, 0, 0 |
213 | }, |
214 | { |
215 | 0, 0, 0 |
216 | }, |
217 | { |
218 | 0, 0, 0 |
219 | }, |
220 | { |
221 | 0, 0, 0 |
222 | }, |
223 | { |
224 | 0, 0, 0 |
225 | }, |
226 | { |
227 | 0, 0, 0 |
228 | }, |
229 | { |
230 | 16, 1, UNARY6 |
231 | }, |
232 | { |
233 | 16, 0, UNARY6 |
234 | }, |
235 | { |
236 | 16, 1, UNARY6 |
237 | }, |
238 | }; |
239 | |
240 | int evalop(struct pri); |
241 | struct value tokval(Token *); |
242 | struct value vals[NSTAK32], *vp; |
243 | enum toktype ops[NSTAK32], *op; |
244 | |
245 | |
246 | |
247 | |
248 | long |
249 | eval(Tokenrow * trp, int kw) |
250 | { |
251 | Token *tp; |
252 | Nlist *np; |
253 | size_t ntok; |
254 | int rnd; |
255 | |
256 | trp->tp++; |
257 | if (kw == KIFDEF || kw == KIFNDEF) |
258 | { |
259 | if (trp->lp - trp->bp != 4 || trp->tp->type != NAME) |
260 | { |
261 | error(ERROR, "Syntax error in #ifdef/#ifndef"); |
262 | return 0; |
263 | } |
264 | np = lookup(trp->tp, 0); |
265 | return (kw == KIFDEF) == (np && np->flag & (ISDEFINED0x01 | ISMAC0x08)); |
266 | } |
267 | ntok = trp->tp - trp->bp; |
268 | kwdefined->val = KDEFINED; |
269 | |
270 | expandrow(trp, "<if>"); |
271 | kwdefined->val = NAME; |
272 | vp = vals; |
273 | op = ops; |
274 | *op++ = END; |
275 | for (rnd = 0, tp = trp->bp + ntok; tp < trp->lp; tp++) |
276 | { |
277 | switch (tp->type) |
278 | { |
279 | case WS: |
280 | case NL: |
281 | continue; |
282 | |
283 | |
284 | case NAME: |
285 | case NAME1: |
286 | case NAME2: |
287 | case NUMBER: |
288 | case CCON: |
289 | case STRING: |
290 | if (rnd) |
291 | goto syntax; |
292 | *vp++ = tokval(tp); |
293 | rnd = 1; |
294 | continue; |
295 | |
296 | |
297 | case DEFINED: |
298 | case TILDE: |
299 | case NOT: |
300 | if (rnd) |
301 | goto syntax; |
302 | *op++ = tp->type; |
303 | continue; |
304 | |
305 | |
306 | case PLUS: |
307 | case MINUS: |
308 | case STAR: |
309 | case AND: |
310 | if (rnd == 0) |
311 | { |
312 | if (tp->type == MINUS) |
313 | *op++ = UMINUS; |
314 | if (tp->type == STAR || tp->type == AND) |
315 | { |
316 | error(ERROR, "Illegal operator * or & in #if/#elsif"); |
317 | return 0; |
318 | } |
319 | continue; |
320 | } |
321 | |
322 | |
323 | |
324 | case EQ: |
325 | case NEQ: |
326 | case LEQ: |
327 | case GEQ: |
328 | case LSH: |
329 | case RSH: |
330 | case LAND: |
331 | case LOR: |
332 | case SLASH: |
333 | case PCT: |
334 | case LT: |
335 | case GT: |
336 | case CIRC: |
337 | case OR: |
338 | case QUEST: |
339 | case COLON: |
340 | case COMMA: |
341 | if (rnd == 0) |
342 | goto syntax; |
343 | if (evalop(priority[tp->type]) != 0) |
344 | return 0; |
345 | *op++ = tp->type; |
346 | rnd = 0; |
347 | continue; |
348 | |
349 | case LP: |
350 | if (rnd) |
351 | goto syntax; |
352 | *op++ = LP; |
353 | continue; |
354 | |
355 | case RP: |
356 | if (!rnd) |
357 | goto syntax; |
358 | if (evalop(priority[RP]) != 0) |
359 | return 0; |
360 | if (op <= ops || op[-1] != LP) |
361 | { |
362 | goto syntax; |
363 | } |
364 | op--; |
365 | continue; |
366 | |
367 | case SHARP: |
368 | if ((tp + 1) < trp->lp) |
369 | { |
370 | np = lookup(tp + 1, 0); |
371 | if (np && (np->val == KMACHINE)) |
372 | { |
373 | tp++; |
374 | if (rnd) |
375 | goto syntax; |
376 | *op++ = ARCHITECTURE; |
377 | continue; |
378 | } |
379 | } |
380 | |
381 | |
382 | default: |
383 | error(ERROR, "Bad operator (%t) in #if/#elsif", tp); |
384 | return 0; |
385 | } |
386 | } |
387 | if (rnd == 0) |
388 | goto syntax; |
389 | if (evalop(priority[END]) != 0) |
390 | return 0; |
391 | if (op != &ops[1] || vp != &vals[1]) |
392 | { |
393 | error(ERROR, "Botch in #if/#elsif"); |
394 | return 0; |
395 | } |
396 | if (vals[0].type == UND2) |
397 | error(ERROR, "Undefined expression value"); |
398 | return vals[0].val; |
399 | syntax: |
400 | error(ERROR, "Syntax error in #if/#elsif"); |
401 | return 0; |
402 | } |
403 | |
404 | int |
405 | evalop(struct pri pri) |
406 | { |
407 | struct value v1; |
408 | struct value v2 = { 0, UND2 }; |
409 | long rv1, rv2; |
410 | int rtype, oper; |
411 | |
412 | rv2 = 0; |
413 | rtype = 0; |
414 | while (pri.pri < priority[op[-1]].pri) |
| 1 | Loop condition is true. Entering loop body | |
|
| 7 | | Loop condition is true. Entering loop body | |
|
| 13 | | Loop condition is true. Entering loop body | |
|
| 21 | | Loop condition is true. Entering loop body | |
|
415 | { |
416 | oper = *--op; |
417 | if (priority[oper].arity == 2) |
| |
| |
| |
| |
418 | { |
419 | v2 = *--vp; |
420 | rv2 = v2.val; |
421 | } |
422 | v1 = *--vp; |
423 | rv1 = v1.val; |
424 | |
425 | switch (priority[oper].ctype) |
| 3 | | Control jumps to 'case 3:' at line 456 | |
|
| 9 | | Control jumps to 'case 3:' at line 456 | |
|
| 15 | | Control jumps to 'case 3:' at line 456 | |
|
| 23 | | Control jumps to 'case 4:' at line 457 | |
|
426 | { |
427 | case 0: |
428 | default: |
429 | error(WARNING, "Syntax error in #if/#endif"); |
430 | return 1; |
431 | case ARITH2: |
432 | case RELAT1: |
433 | if (v1.type == UNS1 || v2.type == UNS1) |
434 | rtype = UNS1; |
435 | else |
436 | rtype = SGN0; |
437 | if (v1.type == UND2 || v2.type == UND2) |
438 | rtype = UND2; |
439 | if (priority[oper].ctype == RELAT1 && rtype == UNS1) |
440 | { |
441 | oper |= UNSMARK0x1000; |
442 | rtype = SGN0; |
443 | } |
444 | break; |
445 | case SHIFT5: |
446 | if (v1.type == UND2 || v2.type == UND2) |
447 | rtype = UND2; |
448 | else |
449 | rtype = v1.type; |
450 | if (rtype == UNS1) |
451 | oper |= UNSMARK0x1000; |
452 | break; |
453 | case UNARY6: |
454 | rtype = v1.type; |
455 | break; |
456 | case LOGIC3: |
457 | case SPCL4: |
458 | break; |
| 4 | | Execution continues on line 460 | |
|
| 10 | | Execution continues on line 460 | |
|
| 16 | | Execution continues on line 460 | |
|
| 24 | | Execution continues on line 460 | |
|
459 | } |
460 | switch (oper) |
| 5 | | Control jumps to 'case DEFINED:' at line 600 | |
|
| 11 | | Control jumps to 'case DEFINED:' at line 600 | |
|
| 17 | | Control jumps to 'case COLON:' at line 587 | |
|
| 25 | | Control jumps to 'case COLON:' at line 587 | |
|
461 | { |
462 | case EQ: |
463 | case EQ | UNSMARK0x1000: |
464 | rv1 = rv1 == rv2; |
465 | break; |
466 | case NEQ: |
467 | case NEQ | UNSMARK0x1000: |
468 | rv1 = rv1 != rv2; |
469 | break; |
470 | case LEQ: |
471 | rv1 = rv1 <= rv2; |
472 | break; |
473 | case GEQ: |
474 | rv1 = rv1 >= rv2; |
475 | break; |
476 | case LT: |
477 | rv1 = rv1 < rv2; |
478 | break; |
479 | case GT: |
480 | rv1 = rv1 > rv2; |
481 | break; |
482 | case LEQ | UNSMARK0x1000: |
483 | rv1 = (unsigned long)rv1 <= (unsigned long)rv2; |
484 | break; |
485 | case GEQ | UNSMARK0x1000: |
486 | rv1 = (unsigned long)rv1 >= (unsigned long)rv2; |
487 | break; |
488 | case LT | UNSMARK0x1000: |
489 | rv1 = (unsigned long)rv1 < (unsigned long)rv2; |
490 | break; |
491 | case GT | UNSMARK0x1000: |
492 | rv1 = (unsigned long)rv1 > (unsigned long)rv2; |
493 | break; |
494 | case LSH: |
495 | rv1 <<= rv2; |
496 | break; |
497 | case LSH | UNSMARK0x1000: |
498 | rv1 = (unsigned long) rv1 << rv2; |
499 | break; |
500 | case RSH: |
501 | rv1 >>= rv2; |
502 | break; |
503 | case RSH | UNSMARK0x1000: |
504 | rv1 = (unsigned long) rv1 >> rv2; |
505 | break; |
506 | case LAND: |
507 | rtype = UND2; |
508 | if (v1.type == UND2) |
509 | break; |
510 | if (rv1 != 0) |
511 | { |
512 | if (v2.type == UND2) |
513 | break; |
514 | rv1 = rv2 != 0; |
515 | } |
516 | else |
517 | rv1 = 0; |
518 | rtype = SGN0; |
519 | break; |
520 | case LOR: |
521 | rtype = UND2; |
522 | if (v1.type == UND2) |
523 | break; |
524 | if (rv1 == 0) |
525 | { |
526 | if (v2.type == UND2) |
527 | break; |
528 | rv1 = rv2 != 0; |
529 | } |
530 | else |
531 | rv1 = 1; |
532 | rtype = SGN0; |
533 | break; |
534 | case AND: |
535 | rv1 &= rv2; |
536 | break; |
537 | case STAR: |
538 | rv1 *= rv2; |
539 | break; |
540 | case PLUS: |
541 | rv1 += rv2; |
542 | break; |
543 | case MINUS: |
544 | rv1 -= rv2; |
545 | break; |
546 | case UMINUS: |
547 | if (v1.type == UND2) |
548 | rtype = UND2; |
549 | rv1 = -rv1; |
550 | break; |
551 | case OR: |
552 | rv1 |= rv2; |
553 | break; |
554 | case CIRC: |
555 | rv1 ^= rv2; |
556 | break; |
557 | case TILDE: |
558 | rv1 = ~rv1; |
559 | break; |
560 | case NOT: |
561 | rv1 = !rv1; |
562 | if (rtype != UND2) |
563 | rtype = SGN0; |
564 | break; |
565 | case SLASH: |
566 | if (rv2 == 0) |
567 | { |
568 | rtype = UND2; |
569 | break; |
570 | } |
571 | if (rtype == UNS1) |
572 | rv1 /= (unsigned long) rv2; |
573 | else |
574 | rv1 /= rv2; |
575 | break; |
576 | case PCT: |
577 | if (rv2 == 0) |
578 | { |
579 | rtype = UND2; |
580 | break; |
581 | } |
582 | if (rtype == UNS1) |
583 | rv1 %= (unsigned long) rv2; |
584 | else |
585 | rv1 %= rv2; |
586 | break; |
587 | case COLON: |
588 | if (op[-1] != QUEST) |
| |
| |
589 | error(ERROR, "Bad ?: in #if/endif"); |
590 | else |
591 | { |
592 | op--; |
593 | if ((--vp)->val == 0) |
| |
| 27 | | The left operand of '==' is a garbage value |
|
594 | v1 = v2; |
595 | rtype = v1.type; |
596 | rv1 = v1.val; |
597 | } |
598 | break; |
| 20 | | Execution continues on line 609 | |
|
599 | |
600 | case DEFINED: |
601 | case ARCHITECTURE: |
602 | break; |
| 6 | | Execution continues on line 609 | |
|
| 12 | | Execution continues on line 609 | |
|
603 | |
604 | default: |
605 | error(ERROR, "Eval botch (unknown operator)"); |
606 | return 1; |
607 | } |
608 | |
609 | v1.val = rv1; |
610 | v1.type = rtype; |
611 | *vp++ = v1; |
612 | } |
613 | return 0; |
614 | } |
615 | |
616 | struct value |
617 | tokval(Token * tp) |
618 | { |
619 | struct value v; |
620 | Nlist *np; |
621 | int i, base; |
622 | unsigned long n; |
623 | uchar *p, c; |
624 | |
625 | v.type = SGN0; |
626 | v.val = 0; |
627 | switch (tp->type) |
628 | { |
629 | |
630 | case NAME: |
631 | v.val = 0; |
632 | break; |
633 | |
634 | case NAME1: |
635 | if ((np = lookup(tp, 0)) != NULL((void*)0) && np->flag & (ISDEFINED0x01 | ISMAC0x08)) |
636 | v.val = 1; |
637 | break; |
638 | |
639 | case NAME2: |
640 | if ((np = lookup(tp, 0)) != NULL((void*)0) && np->flag & (ISARCHITECTURE0x10)) |
641 | v.val = 1; |
642 | break; |
643 | |
644 | case NUMBER: |
645 | n = 0; |
646 | base = 10; |
647 | p = tp->t; |
648 | c = p[tp->len]; |
649 | p[tp->len] = '\0'; |
650 | if (*p == '0') |
651 | { |
652 | base = 8; |
653 | if (p[1] == 'x' || p[1] == 'X') |
654 | { |
655 | base = 16; |
656 | p++; |
657 | } |
658 | p++; |
659 | } |
660 | for (;; p++) |
661 | { |
662 | if ((i = digit(*p)) < 0) |
663 | break; |
664 | if (i >= base) |
665 | error(WARNING, |
666 | "Bad digit in number %t", tp); |
667 | n *= base; |
668 | n += i; |
669 | } |
670 | if (n >= 0x80000000 && base != 10) |
671 | v.type = UNS1; |
672 | for (; *p; p++) |
673 | { |
674 | if (*p == 'u' || *p == 'U') |
675 | v.type = UNS1; |
676 | else |
677 | if (*p == 'l' || *p == 'L') |
678 | ; |
679 | else |
680 | { |
681 | error(ERROR, |
682 | "Bad number %t in #if/#elsif", tp); |
683 | break; |
684 | } |
685 | } |
686 | v.val = n; |
687 | tp->t[tp->len] = c; |
688 | break; |
689 | |
690 | case CCON: |
691 | n = 0; |
692 | p = tp->t; |
693 | if (*p == 'L') |
694 | { |
695 | p += 1; |
696 | error(WARNING, "Wide char constant value undefined"); |
697 | } |
698 | p += 1; |
699 | if (*p == '\\') |
700 | { |
701 | p += 1; |
702 | if ((i = digit(*p)) >= 0 && i <= 7) |
703 | { |
704 | n = i; |
705 | p += 1; |
706 | if ((i = digit(*p)) >= 0 && i <= 7) |
707 | { |
708 | p += 1; |
709 | n <<= 3; |
710 | n += i; |
711 | if ((i = digit(*p)) >= 0 && i <= 7) |
712 | { |
713 | p += 1; |
714 | n <<= 3; |
715 | n += i; |
716 | } |
717 | } |
718 | } |
719 | else |
720 | if (*p == 'x') |
721 | { |
722 | p += 1; |
723 | while ((i = digit(*p)) >= 0 && i <= 15) |
724 | { |
725 | p += 1; |
726 | n <<= 4; |
727 | n += i; |
728 | } |
729 | } |
730 | else |
731 | { |
732 | static char cvcon[] = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; |
733 | static size_t cvlen = sizeof(cvcon) - 1; |
734 | |
735 | size_t j; |
736 | for (j = 0; j < cvlen; j += 2) |
737 | { |
738 | if (*p == cvcon[j]) |
739 | { |
740 | n = cvcon[j + 1]; |
741 | break; |
742 | } |
743 | } |
744 | p += 1; |
745 | if (j >= cvlen) |
746 | error(WARNING, |
747 | "Undefined escape in character constant"); |
748 | } |
749 | } |
750 | else |
751 | if (*p == '\'') |
752 | error(ERROR, "Empty character constant"); |
753 | else |
754 | n = *p++; |
755 | if (*p != '\'') |
756 | error(WARNING, "Multibyte character constant undefined"); |
757 | else |
758 | if (n > 127) |
759 | error(WARNING, "Character constant taken as not signed"); |
760 | v.val = n; |
761 | break; |
762 | |
763 | case STRING: |
764 | error(ERROR, "String in #if/#elsif"); |
765 | break; |
766 | } |
767 | return v; |
768 | } |
769 | |
770 | int |
771 | digit(int i) |
772 | { |
773 | if ('0' <= i && i <= '9') |
774 | i -= '0'; |
775 | else |
776 | if ('a' <= i && i <= 'f') |
777 | i -= 'a' - 10; |
778 | else |
779 | if ('A' <= i && i <= 'F') |
780 | i -= 'A' - 10; |
781 | else |
782 | i = -1; |
783 | return i; |
784 | } |
785 | |
786 | |