calc: boolean expressions
[m6w6/ext-psi] / src / types / num_exp.c
index aba528853b6ec4f7208ee8c18089d3365bb20106..3d73207ad68f3a1b4350a0e9050bd987f17629fe 100644 (file)
@@ -87,6 +87,16 @@ struct psi_num_exp *psi_num_exp_copy(struct psi_num_exp *exp)
                cpy->data.u = psi_num_exp_copy(exp->data.u);
                break;
 
+       case PSI_T_OR:
+       case PSI_T_AND:
+
+       case PSI_T_CMP_EQ:
+       case PSI_T_CMP_NE:
+       case PSI_T_CMP_LE:
+       case PSI_T_CMP_GE:
+       case PSI_T_RCHEVR:
+       case PSI_T_LCHEVR:
+
        case PSI_T_PIPE:
        case PSI_T_CARET:
        case PSI_T_AMPERSAND:
@@ -129,6 +139,16 @@ void psi_num_exp_free(struct psi_num_exp **c_ptr)
                        psi_num_exp_free(&c->data.u);
                        break;
 
+               case PSI_T_OR:
+               case PSI_T_AND:
+
+               case PSI_T_CMP_EQ:
+               case PSI_T_CMP_NE:
+               case PSI_T_CMP_LE:
+               case PSI_T_CMP_GE:
+               case PSI_T_RCHEVR:
+               case PSI_T_LCHEVR:
+
                case PSI_T_PIPE:
                case PSI_T_CARET:
                case PSI_T_AMPERSAND:
@@ -189,6 +209,24 @@ static inline wint_t psi_num_exp_op_tok(token_t op)
        case PSI_T_MODULO:
                return L'%';
 
+       case PSI_T_OR:
+               return L'∨';
+       case PSI_T_AND:
+               return L'∧';
+
+       case PSI_T_CMP_EQ:
+               return L'≣';
+       case PSI_T_CMP_NE:
+               return L'≠';
+       case PSI_T_CMP_LE:
+               return L'≤';
+       case PSI_T_CMP_GE:
+               return L'≥';
+       case PSI_T_RCHEVR:
+               return L'>';
+       case PSI_T_LCHEVR:
+               return L'<';
+
        default:
                assert(0);
        }
@@ -214,6 +252,17 @@ void psi_num_exp_dump(int fd, struct psi_num_exp *exp)
                dprintf(fd, ")");
                break;
 
+
+       case PSI_T_OR:
+       case PSI_T_AND:
+
+       case PSI_T_CMP_EQ:
+       case PSI_T_CMP_NE:
+       case PSI_T_CMP_LE:
+       case PSI_T_CMP_GE:
+       case PSI_T_RCHEVR:
+       case PSI_T_LCHEVR:
+
        case PSI_T_PIPE:
        case PSI_T_CARET:
        case PSI_T_AMPERSAND:
@@ -247,6 +296,31 @@ bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp,
                        exp->calc = psi_calc_bin_not;
                        break;
 
+               case PSI_T_OR:
+                       exp->calc = psi_calc_or;
+                       break;
+               case PSI_T_AND:
+                       exp->calc = psi_calc_and;
+                       break;
+               case PSI_T_CMP_EQ:
+                       exp->calc = psi_calc_cmp_eq;
+                       break;
+               case PSI_T_CMP_NE:
+                       exp->calc = psi_calc_cmp_ne;
+                       break;
+               case PSI_T_CMP_LE:
+                       exp->calc = psi_calc_cmp_le;
+                       break;
+               case PSI_T_CMP_GE:
+                       exp->calc = psi_calc_cmp_ge;
+                       break;
+               case PSI_T_LCHEVR:
+                       exp->calc = psi_calc_cmp_lt;
+                       break;
+               case PSI_T_RCHEVR:
+                       exp->calc = psi_calc_cmp_gt;
+                       break;
+
                case PSI_T_LPAREN:
                        break;
 
@@ -297,6 +371,16 @@ bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp,
                return psi_num_exp_validate(data, exp->data.u, impl, cb_decl, current_let, current_set, current_enum);
                break;
 
+       case PSI_T_OR:
+       case PSI_T_AND:
+
+       case PSI_T_CMP_EQ:
+       case PSI_T_CMP_NE:
+       case PSI_T_CMP_LE:
+       case PSI_T_CMP_GE:
+       case PSI_T_RCHEVR:
+       case PSI_T_LCHEVR:
+
        case PSI_T_PIPE:
        case PSI_T_CARET:
        case PSI_T_AMPERSAND:
@@ -346,6 +430,7 @@ static inline void psi_impl_val_dump(token_t t, impl_val *res,
                assert(0);
        }
 }
+
 static inline void psi_num_exp_verify_result(token_t t, impl_val *res, struct psi_call_frame *frame)
 {
        if (frame) PSI_DEBUG_PRINT(frame->context, "%s", " = ");
@@ -353,6 +438,23 @@ static inline void psi_num_exp_verify_result(token_t t, impl_val *res, struct ps
        if (frame) PSI_DEBUG_PRINT(frame->context, "%s", "\n");
 }
 
+static inline int psi_num_exp_op_cmp(token_t op1, token_t op2)
+{
+       if (PSI_T_LPAREN == op2) {
+               return -1;
+       } else if (PSI_T_LPAREN == op1) {
+               return 1;
+       } else if (op1 == op2) {
+               return 0;
+       } else if (!op1) {
+               return 1;
+       } else if (!op2) {
+               return -1;
+       }
+
+       return psi_token_oper_cmp(op1, op2);
+}
+
 static void psi_num_exp_reduce(struct psi_num_exp *exp, struct psi_plist **output_ptr,
                struct psi_plist **input_ptr, struct psi_call_frame *frame)
 {
@@ -463,6 +565,16 @@ token_t psi_num_exp_exec(struct psi_num_exp *exp, impl_val *res,
                        psi_num_exp_verify_result(entry.type, &entry.data.value, frame);
                        break;
 
+               case PSI_T_OR:
+               case PSI_T_AND:
+
+               case PSI_T_CMP_EQ:
+               case PSI_T_CMP_NE:
+               case PSI_T_CMP_LE:
+               case PSI_T_CMP_GE:
+               case PSI_T_RCHEVR:
+               case PSI_T_LCHEVR:
+
                case PSI_T_PIPE:
                case PSI_T_CARET:
                case PSI_T_AMPERSAND: