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