| 740 | |
| 741 | |
| 742 | static int ap_expr_eval(ap_expr_eval_ctx_t *ctx, const ap_expr_t *node) |
| 743 | { |
| 744 | const ap_expr_t *e1 = node->node_arg1; |
| 745 | const ap_expr_t *e2 = node->node_arg2; |
| 746 | int result = FALSE; |
| 747 | if (inc_rec(ctx)) |
| 748 | return result; |
| 749 | while (1) { |
| 750 | switch (node->node_op) { |
| 751 | case op_True: |
| 752 | result ^= TRUE; |
| 753 | goto out; |
| 754 | case op_False: |
| 755 | result ^= FALSE; |
| 756 | goto out; |
| 757 | case op_Not: |
| 758 | result = !result; |
| 759 | node = e1; |
| 760 | break; |
| 761 | case op_Or: |
| 762 | do { |
| 763 | if (e1->node_op == op_Not) { |
| 764 | if (!ap_expr_eval(ctx, e1->node_arg1)) { |
| 765 | result ^= TRUE; |
| 766 | goto out; |
| 767 | } |
| 768 | } |
| 769 | else { |
| 770 | if (ap_expr_eval(ctx, e1)) { |
| 771 | result ^= TRUE; |
| 772 | goto out; |
| 773 | } |
| 774 | } |
| 775 | node = node->node_arg2; |
| 776 | e1 = node->node_arg1; |
| 777 | } while (node->node_op == op_Or); |
| 778 | break; |
| 779 | case op_And: |
| 780 | do { |
| 781 | if (e1->node_op == op_Not) { |
| 782 | if (ap_expr_eval(ctx, e1->node_arg1)) { |
| 783 | result ^= FALSE; |
| 784 | goto out; |
| 785 | } |
| 786 | } |
| 787 | else { |
| 788 | if (!ap_expr_eval(ctx, e1)) { |
| 789 | result ^= FALSE; |
| 790 | goto out; |
| 791 | } |
| 792 | } |
| 793 | node = node->node_arg2; |
| 794 | e1 = node->node_arg1; |
| 795 | } while (node->node_op == op_And); |
| 796 | break; |
| 797 | case op_UnaryOpCall: |
| 798 | result ^= ap_expr_eval_unary_op(ctx, e1, e2); |
| 799 | goto out; |
no test coverage detected