simplify calc/oper
[m6w6/ext-psi] / src / calc / oper.h
1 /*******************************************************************************
2 Copyright (c) 2016, Michael Wallner <mike@php.net>.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *******************************************************************************/
25
26 #include "php_psi_stdinc.h"
27 #include <assert.h>
28
29 #include "token.h"
30
31 static inline int psi_calc_oper(token_t op1, token_t op2)
32 {
33 if (PSI_T_LPAREN == op2) {
34 return -1;
35 } else if (PSI_T_LPAREN == op1) {
36 return 1;
37 } else if (op1 == op2) {
38 return 0;
39 } else if (!op1 || op1 == PSI_T_NUMBER) {
40 return 1;
41 } else if (!op2 || op2 == PSI_T_NUMBER) {
42 return -1;
43 }
44
45 switch (op1) {
46 case PSI_T_NOT:
47 switch (op2) {
48 case PSI_T_NOT:
49 case PSI_T_TILDE:
50 case PSI_T_CAST:
51 return 0;
52
53 case PSI_T_ASTERISK:
54 case PSI_T_SLASH:
55 case PSI_T_MODULO:
56 case PSI_T_PLUS:
57 case PSI_T_MINUS:
58 case PSI_T_LSHIFT:
59 case PSI_T_RSHIFT:
60 case PSI_T_LCHEVR:
61 case PSI_T_CMP_LE:
62 case PSI_T_RCHEVR:
63 case PSI_T_CMP_GE:
64 case PSI_T_AMPERSAND:
65 case PSI_T_CMP_EQ:
66 case PSI_T_CMP_NE:
67 case PSI_T_CARET:
68 case PSI_T_PIPE:
69 case PSI_T_AND:
70 case PSI_T_OR:
71 return -1;
72 default:
73 assert(0);
74 break;
75 }
76 break;
77
78 case PSI_T_TILDE:
79 switch (op2) {
80 case PSI_T_NOT:
81 case PSI_T_TILDE:
82 case PSI_T_CAST:
83 return 0;
84
85 case PSI_T_ASTERISK:
86 case PSI_T_SLASH:
87 case PSI_T_MODULO:
88 case PSI_T_PLUS:
89 case PSI_T_MINUS:
90 case PSI_T_LSHIFT:
91 case PSI_T_RSHIFT:
92 case PSI_T_LCHEVR:
93 case PSI_T_CMP_LE:
94 case PSI_T_RCHEVR:
95 case PSI_T_CMP_GE:
96 case PSI_T_AMPERSAND:
97 case PSI_T_CMP_EQ:
98 case PSI_T_CMP_NE:
99 case PSI_T_CARET:
100 case PSI_T_PIPE:
101 case PSI_T_AND:
102 case PSI_T_OR:
103 return -1;
104 default:
105 assert(0);
106 break;
107 }
108 break;
109
110 case PSI_T_CAST:
111 switch (op2) {
112 case PSI_T_NOT:
113 case PSI_T_TILDE:
114 case PSI_T_CAST:
115 return 0;
116
117 case PSI_T_ASTERISK:
118 case PSI_T_SLASH:
119 case PSI_T_MODULO:
120 case PSI_T_PLUS:
121 case PSI_T_MINUS:
122 case PSI_T_LSHIFT:
123 case PSI_T_RSHIFT:
124 case PSI_T_LCHEVR:
125 case PSI_T_CMP_LE:
126 case PSI_T_RCHEVR:
127 case PSI_T_CMP_GE:
128 case PSI_T_AMPERSAND:
129 case PSI_T_CMP_EQ:
130 case PSI_T_CMP_NE:
131 case PSI_T_CARET:
132 case PSI_T_PIPE:
133 case PSI_T_AND:
134 case PSI_T_OR:
135 return -1;
136 default:
137 assert(0);
138 break;
139 }
140 break;
141
142 case PSI_T_ASTERISK:
143 switch (op2) {
144 case PSI_T_NOT:
145 case PSI_T_TILDE:
146 case PSI_T_CAST:
147 return 1;
148
149 case PSI_T_ASTERISK:
150 case PSI_T_SLASH:
151 case PSI_T_MODULO:
152 return 0;
153
154 case PSI_T_PLUS:
155 case PSI_T_MINUS:
156 case PSI_T_LSHIFT:
157 case PSI_T_RSHIFT:
158 case PSI_T_LCHEVR:
159 case PSI_T_CMP_LE:
160 case PSI_T_RCHEVR:
161 case PSI_T_CMP_GE:
162 case PSI_T_AMPERSAND:
163 case PSI_T_CMP_EQ:
164 case PSI_T_CMP_NE:
165 case PSI_T_CARET:
166 case PSI_T_PIPE:
167 case PSI_T_AND:
168 case PSI_T_OR:
169 return -1;
170 default:
171 assert(0);
172 break;
173 }
174 break;
175
176 case PSI_T_SLASH:
177 switch (op2) {
178 case PSI_T_NOT:
179 case PSI_T_TILDE:
180 case PSI_T_CAST:
181 return 1;
182
183 case PSI_T_ASTERISK:
184 case PSI_T_SLASH:
185 case PSI_T_MODULO:
186 return 0;
187
188 case PSI_T_PLUS:
189 case PSI_T_MINUS:
190 case PSI_T_LSHIFT:
191 case PSI_T_RSHIFT:
192 case PSI_T_LCHEVR:
193 case PSI_T_CMP_LE:
194 case PSI_T_RCHEVR:
195 case PSI_T_CMP_GE:
196 case PSI_T_AMPERSAND:
197 case PSI_T_CMP_EQ:
198 case PSI_T_CMP_NE:
199 case PSI_T_CARET:
200 case PSI_T_PIPE:
201 case PSI_T_AND:
202 case PSI_T_OR:
203 return -1;
204 default:
205 assert(0);
206 break;
207 }
208 break;
209
210 case PSI_T_MODULO:
211 switch (op2) {
212 case PSI_T_NOT:
213 case PSI_T_TILDE:
214 case PSI_T_CAST:
215 return 1;
216
217 case PSI_T_ASTERISK:
218 case PSI_T_SLASH:
219 case PSI_T_MODULO:
220 return 0;
221
222 case PSI_T_PLUS:
223 case PSI_T_MINUS:
224 case PSI_T_LSHIFT:
225 case PSI_T_RSHIFT:
226 case PSI_T_LCHEVR:
227 case PSI_T_CMP_LE:
228 case PSI_T_RCHEVR:
229 case PSI_T_CMP_GE:
230 case PSI_T_AMPERSAND:
231 case PSI_T_CMP_EQ:
232 case PSI_T_CMP_NE:
233 case PSI_T_CARET:
234 case PSI_T_PIPE:
235 case PSI_T_AND:
236 case PSI_T_OR:
237 return -1;
238 default:
239 assert(0);
240 break;
241 }
242 break;
243
244 case PSI_T_PLUS:
245 switch (op2) {
246 case PSI_T_NOT:
247 case PSI_T_TILDE:
248 case PSI_T_CAST:
249 case PSI_T_ASTERISK:
250 case PSI_T_SLASH:
251 case PSI_T_MODULO:
252 return 1;
253
254 case PSI_T_PLUS:
255 case PSI_T_MINUS:
256 return 0;
257
258 case PSI_T_LSHIFT:
259 case PSI_T_RSHIFT:
260 case PSI_T_LCHEVR:
261 case PSI_T_CMP_LE:
262 case PSI_T_RCHEVR:
263 case PSI_T_CMP_GE:
264 case PSI_T_AMPERSAND:
265 case PSI_T_CMP_EQ:
266 case PSI_T_CMP_NE:
267 case PSI_T_CARET:
268 case PSI_T_PIPE:
269 case PSI_T_AND:
270 case PSI_T_OR:
271 return -1;
272 default:
273 assert(0);
274 break;
275 }
276 break;
277
278 case PSI_T_MINUS:
279 switch (op2) {
280 case PSI_T_NOT:
281 case PSI_T_TILDE:
282 case PSI_T_CAST:
283 case PSI_T_ASTERISK:
284 case PSI_T_SLASH:
285 case PSI_T_MODULO:
286 return 1;
287
288 case PSI_T_PLUS:
289 case PSI_T_MINUS:
290 return 0;
291
292 case PSI_T_LSHIFT:
293 case PSI_T_RSHIFT:
294 case PSI_T_LCHEVR:
295 case PSI_T_CMP_LE:
296 case PSI_T_RCHEVR:
297 case PSI_T_CMP_GE:
298 case PSI_T_AMPERSAND:
299 case PSI_T_CMP_EQ:
300 case PSI_T_CMP_NE:
301 case PSI_T_CARET:
302 case PSI_T_PIPE:
303 case PSI_T_AND:
304 case PSI_T_OR:
305 return -1;
306 default:
307 assert(0);
308 break;
309 }
310 break;
311
312 case PSI_T_LSHIFT:
313 switch (op2) {
314 case PSI_T_NOT:
315 case PSI_T_TILDE:
316 case PSI_T_CAST:
317 case PSI_T_ASTERISK:
318 case PSI_T_SLASH:
319 case PSI_T_MODULO:
320 case PSI_T_PLUS:
321 case PSI_T_MINUS:
322 return 1;
323
324 case PSI_T_LSHIFT:
325 case PSI_T_RSHIFT:
326 return 0;
327
328 case PSI_T_LCHEVR:
329 case PSI_T_CMP_LE:
330 case PSI_T_RCHEVR:
331 case PSI_T_CMP_GE:
332 case PSI_T_AMPERSAND:
333 case PSI_T_CMP_EQ:
334 case PSI_T_CMP_NE:
335 case PSI_T_CARET:
336 case PSI_T_PIPE:
337 case PSI_T_AND:
338 case PSI_T_OR:
339 return -1;
340 default:
341 assert(0);
342 break;
343 }
344 break;
345
346 case PSI_T_RSHIFT:
347 switch (op2) {
348 case PSI_T_NOT:
349 case PSI_T_TILDE:
350 case PSI_T_CAST:
351 case PSI_T_ASTERISK:
352 case PSI_T_SLASH:
353 case PSI_T_MODULO:
354 case PSI_T_PLUS:
355 case PSI_T_MINUS:
356 return 1;
357
358 case PSI_T_LSHIFT:
359 case PSI_T_RSHIFT:
360 return 0;
361
362 case PSI_T_LCHEVR:
363 case PSI_T_CMP_LE:
364 case PSI_T_RCHEVR:
365 case PSI_T_CMP_GE:
366 case PSI_T_AMPERSAND:
367 case PSI_T_CMP_EQ:
368 case PSI_T_CMP_NE:
369 case PSI_T_CARET:
370 case PSI_T_PIPE:
371 case PSI_T_AND:
372 case PSI_T_OR:
373 return -1;
374 default:
375 assert(0);
376 break;
377 }
378 break;
379
380 case PSI_T_LCHEVR:
381 switch (op2) {
382 case PSI_T_NOT:
383 case PSI_T_TILDE:
384 case PSI_T_CAST:
385 case PSI_T_ASTERISK:
386 case PSI_T_SLASH:
387 case PSI_T_MODULO:
388 case PSI_T_PLUS:
389 case PSI_T_MINUS:
390 case PSI_T_LSHIFT:
391 case PSI_T_RSHIFT:
392 return 1;
393
394 case PSI_T_LCHEVR:
395 case PSI_T_CMP_LE:
396 case PSI_T_RCHEVR:
397 case PSI_T_CMP_GE:
398 return 0;
399
400 case PSI_T_AMPERSAND:
401 case PSI_T_CMP_EQ:
402 case PSI_T_CMP_NE:
403 case PSI_T_CARET:
404 case PSI_T_PIPE:
405 case PSI_T_AND:
406 case PSI_T_OR:
407 return -1;
408 default:
409 assert(0);
410 break;
411 }
412 break;
413
414 case PSI_T_CMP_LE:
415 switch (op2) {
416 case PSI_T_NOT:
417 case PSI_T_TILDE:
418 case PSI_T_CAST:
419 case PSI_T_ASTERISK:
420 case PSI_T_SLASH:
421 case PSI_T_MODULO:
422 case PSI_T_PLUS:
423 case PSI_T_MINUS:
424 case PSI_T_LSHIFT:
425 case PSI_T_RSHIFT:
426 return 1;
427
428 case PSI_T_LCHEVR:
429 case PSI_T_CMP_LE:
430 case PSI_T_RCHEVR:
431 case PSI_T_CMP_GE:
432 return 0;
433
434 case PSI_T_AMPERSAND:
435 case PSI_T_CMP_EQ:
436 case PSI_T_CMP_NE:
437 case PSI_T_CARET:
438 case PSI_T_PIPE:
439 case PSI_T_AND:
440 case PSI_T_OR:
441 return -1;
442 default:
443 assert(0);
444 break;
445 }
446 break;
447
448 case PSI_T_RCHEVR:
449 switch (op2) {
450 case PSI_T_NOT:
451 case PSI_T_TILDE:
452 case PSI_T_CAST:
453 case PSI_T_ASTERISK:
454 case PSI_T_SLASH:
455 case PSI_T_MODULO:
456 case PSI_T_PLUS:
457 case PSI_T_MINUS:
458 case PSI_T_LSHIFT:
459 case PSI_T_RSHIFT:
460 return 1;
461
462 case PSI_T_LCHEVR:
463 case PSI_T_CMP_LE:
464 case PSI_T_RCHEVR:
465 case PSI_T_CMP_GE:
466 return 0;
467
468 case PSI_T_AMPERSAND:
469 case PSI_T_CMP_EQ:
470 case PSI_T_CMP_NE:
471 case PSI_T_CARET:
472 case PSI_T_PIPE:
473 case PSI_T_AND:
474 case PSI_T_OR:
475 return -1;
476 default:
477 assert(0);
478 break;
479 }
480 break;
481
482 case PSI_T_CMP_GE:
483 switch (op2) {
484 case PSI_T_NOT:
485 case PSI_T_TILDE:
486 case PSI_T_CAST:
487 case PSI_T_ASTERISK:
488 case PSI_T_SLASH:
489 case PSI_T_MODULO:
490 case PSI_T_PLUS:
491 case PSI_T_MINUS:
492 case PSI_T_LSHIFT:
493 case PSI_T_RSHIFT:
494 return 1;
495
496 case PSI_T_LCHEVR:
497 case PSI_T_CMP_LE:
498 case PSI_T_RCHEVR:
499 case PSI_T_CMP_GE:
500 return 0;
501
502 case PSI_T_AMPERSAND:
503 case PSI_T_CMP_EQ:
504 case PSI_T_CMP_NE:
505 case PSI_T_CARET:
506 case PSI_T_PIPE:
507 case PSI_T_AND:
508 case PSI_T_OR:
509 return -1;
510 default:
511 assert(0);
512 break;
513 }
514 break;
515
516 case PSI_T_AMPERSAND:
517 switch (op2) {
518 case PSI_T_NOT:
519 case PSI_T_TILDE:
520 case PSI_T_CAST:
521 case PSI_T_ASTERISK:
522 case PSI_T_SLASH:
523 case PSI_T_MODULO:
524 case PSI_T_PLUS:
525 case PSI_T_MINUS:
526 case PSI_T_LSHIFT:
527 case PSI_T_RSHIFT:
528 case PSI_T_LCHEVR:
529 case PSI_T_CMP_LE:
530 case PSI_T_RCHEVR:
531 case PSI_T_CMP_GE:
532 return 1;
533
534 case PSI_T_AMPERSAND:
535 return 0;
536
537 case PSI_T_CMP_EQ:
538 case PSI_T_CMP_NE:
539 case PSI_T_CARET:
540 case PSI_T_PIPE:
541 case PSI_T_AND:
542 case PSI_T_OR:
543 return -1;
544 default:
545 assert(0);
546 break;
547 }
548 break;
549
550 case PSI_T_CMP_EQ:
551 switch (op2) {
552 case PSI_T_NOT:
553 case PSI_T_TILDE:
554 case PSI_T_CAST:
555 case PSI_T_ASTERISK:
556 case PSI_T_SLASH:
557 case PSI_T_MODULO:
558 case PSI_T_PLUS:
559 case PSI_T_MINUS:
560 case PSI_T_LSHIFT:
561 case PSI_T_RSHIFT:
562 case PSI_T_LCHEVR:
563 case PSI_T_CMP_LE:
564 case PSI_T_RCHEVR:
565 case PSI_T_CMP_GE:
566 case PSI_T_AMPERSAND:
567 return 1;
568
569 case PSI_T_CMP_EQ:
570 case PSI_T_CMP_NE:
571 return 0;
572
573 case PSI_T_CARET:
574 case PSI_T_PIPE:
575 case PSI_T_AND:
576 case PSI_T_OR:
577 return -1;
578 default:
579 assert(0);
580 break;
581 }
582 break;
583
584 case PSI_T_CMP_NE:
585 switch (op2) {
586 case PSI_T_NOT:
587 case PSI_T_TILDE:
588 case PSI_T_CAST:
589 case PSI_T_ASTERISK:
590 case PSI_T_SLASH:
591 case PSI_T_MODULO:
592 case PSI_T_PLUS:
593 case PSI_T_MINUS:
594 case PSI_T_LSHIFT:
595 case PSI_T_RSHIFT:
596 case PSI_T_LCHEVR:
597 case PSI_T_CMP_LE:
598 case PSI_T_RCHEVR:
599 case PSI_T_CMP_GE:
600 case PSI_T_AMPERSAND:
601 return 1;
602
603 case PSI_T_CMP_EQ:
604 case PSI_T_CMP_NE:
605 return 0;
606
607 case PSI_T_CARET:
608 case PSI_T_PIPE:
609 case PSI_T_AND:
610 case PSI_T_OR:
611 return -1;
612 default:
613 assert(0);
614 break;
615 }
616 break;
617
618 case PSI_T_CARET:
619 switch (op2) {
620 case PSI_T_NOT:
621 case PSI_T_TILDE:
622 case PSI_T_CAST:
623 case PSI_T_ASTERISK:
624 case PSI_T_SLASH:
625 case PSI_T_MODULO:
626 case PSI_T_PLUS:
627 case PSI_T_MINUS:
628 case PSI_T_LSHIFT:
629 case PSI_T_RSHIFT:
630 case PSI_T_LCHEVR:
631 case PSI_T_CMP_LE:
632 case PSI_T_RCHEVR:
633 case PSI_T_CMP_GE:
634 case PSI_T_AMPERSAND:
635 case PSI_T_CMP_EQ:
636 case PSI_T_CMP_NE:
637 return 1;
638
639 case PSI_T_CARET:
640 return 0;
641
642 case PSI_T_PIPE:
643 case PSI_T_AND:
644 case PSI_T_OR:
645 return -1;
646 default:
647 assert(0);
648 break;
649 }
650 break;
651
652 case PSI_T_PIPE:
653 switch (op2) {
654 case PSI_T_NOT:
655 case PSI_T_TILDE:
656 case PSI_T_CAST:
657 case PSI_T_ASTERISK:
658 case PSI_T_SLASH:
659 case PSI_T_MODULO:
660 case PSI_T_PLUS:
661 case PSI_T_MINUS:
662 case PSI_T_LSHIFT:
663 case PSI_T_RSHIFT:
664 case PSI_T_LCHEVR:
665 case PSI_T_CMP_LE:
666 case PSI_T_RCHEVR:
667 case PSI_T_CMP_GE:
668 case PSI_T_AMPERSAND:
669 case PSI_T_CMP_EQ:
670 case PSI_T_CMP_NE:
671 case PSI_T_CARET:
672 return 1;
673
674 case PSI_T_PIPE:
675 return 0;
676
677 case PSI_T_AND:
678 case PSI_T_OR:
679 return -1;
680 default:
681 assert(0);
682 break;
683 }
684 break;
685
686 case PSI_T_AND:
687 switch (op2) {
688 case PSI_T_NOT:
689 case PSI_T_TILDE:
690 case PSI_T_CAST:
691 case PSI_T_ASTERISK:
692 case PSI_T_SLASH:
693 case PSI_T_MODULO:
694 case PSI_T_PLUS:
695 case PSI_T_MINUS:
696 case PSI_T_LSHIFT:
697 case PSI_T_RSHIFT:
698 case PSI_T_LCHEVR:
699 case PSI_T_CMP_LE:
700 case PSI_T_RCHEVR:
701 case PSI_T_CMP_GE:
702 case PSI_T_AMPERSAND:
703 case PSI_T_CMP_EQ:
704 case PSI_T_CMP_NE:
705 case PSI_T_CARET:
706 case PSI_T_PIPE:
707 return 1;
708
709 case PSI_T_AND:
710 return 0;
711
712 case PSI_T_OR:
713 return -1;
714 default:
715 assert(0);
716 break;
717 }
718 break;
719
720 case PSI_T_OR:
721 switch (op2) {
722 case PSI_T_NOT:
723 case PSI_T_TILDE:
724 case PSI_T_CAST:
725 case PSI_T_ASTERISK:
726 case PSI_T_SLASH:
727 case PSI_T_MODULO:
728 case PSI_T_PLUS:
729 case PSI_T_MINUS:
730 case PSI_T_LSHIFT:
731 case PSI_T_RSHIFT:
732 case PSI_T_LCHEVR:
733 case PSI_T_CMP_LE:
734 case PSI_T_RCHEVR:
735 case PSI_T_CMP_GE:
736 case PSI_T_AMPERSAND:
737 case PSI_T_CMP_EQ:
738 case PSI_T_CMP_NE:
739 case PSI_T_CARET:
740 case PSI_T_PIPE:
741 case PSI_T_AND:
742 return 1;
743
744 case PSI_T_OR:
745 return 0;
746 default:
747 assert(0);
748 break;
749 }
750 break;
751
752 default:
753 assert(0);
754 break;
755 }
756 return 0;
757 }