00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CUEX_OPN_H
00019 #define CUEX_OPN_H
00020
00021 #include <cuex/fwd.h>
00022 #include <cuex/ex.h>
00023 #include <cuoo/halloc.h>
00024 #include <cu/clos.h>
00025 #include <cu/ptr_seq.h>
00026
00027 CU_BEGIN_DECLARATIONS
00028
00029
00030
00031 struct cuex_opn
00032 {
00033 CUOO_HCOBJ
00034 cuex_t operand_arr[1];
00035 };
00036 #define cuex_sizeof_opn(N) \
00037 (sizeof(struct cuex_opn) - sizeof(void *) + (N)*sizeof(void *))
00038
00039
00040
00041
00042 cuex_opn_t cuex_opn(cuex_meta_t opr, ...);
00043
00044
00045 cuex_opn_t cuex_opn_by_valist(cuex_meta_t opr, va_list operand_valist);
00046
00047 cuex_opn_t cuexP_opn_by_arr_with_ctor(cuex_meta_t opr, cuex_t *arr);
00048
00049
00050
00051
00052 CU_SINLINE cuex_opn_t
00053 cuex_opn_by_arr(cuex_meta_t opr, cuex_t *arr)
00054 {
00055 if (cu_expect_false(cuex_opr_has_ctor(opr)))
00056 return cuexP_opn_by_arr_with_ctor(opr, arr);
00057 return (cuex_opn_t)cuexP_halloc_raw(
00058 opr,
00059 CUOO_HCOBJ_KEY_SIZEW(cuex_opr_r(opr)*sizeof(cuex_t) + CUOO_HCOBJ_SHIFT),
00060 arr);
00061 }
00062
00063
00064 CU_SINLINE cu_rank_t cuex_opn_arity(cuex_t opn)
00065 { return cuex_opr_r(cuex_meta(opn)); }
00066
00067
00068 CU_SINLINE cuex_t cuex_opn_at(cuex_t opn, int i)
00069 { return ((cuex_opn_t)opn)->operand_arr[i]; }
00070
00071
00072 CU_SINLINE cuex_t *cuex_opn_begin(cuex_t opn)
00073 { return ((cuex_opn_t)opn)->operand_arr; }
00074
00075
00076 CU_SINLINE cuex_t *cuex_opn_end(cuex_t opn)
00077 { return ((cuex_opn_t)opn)->operand_arr + cuex_opr_r(cuex_meta(opn)); }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #define CUEX_OPN_ITER(opr, opn, sub, STMT) \
00089 do { \
00090 int cuexL_i, cuexL_r = cuex_opr_r(opr); \
00091 for (cuexL_i = 0; cuexL_i < cuexL_r; ++cuexL_i) { \
00092 cuex_t sub = cuex_opn_at(opn, cuexL_i); \
00093 STMT; \
00094 } \
00095 } while (0)
00096
00097
00098
00099
00100
00101
00102
00103 #define CUEX_OPN_CONJ_RETURN(opr, opn, sub, EXPR) \
00104 do { \
00105 int cuexL_i, cuexL_r = cuex_opr_r(opr); \
00106 for (cuexL_i = 0; cuexL_i < cuexL_r; ++cuexL_i) { \
00107 cuex_t sub = cuex_opn_at(opn, cuexL_i); \
00108 if (!(EXPR)) \
00109 return cu_false; \
00110 } \
00111 } while (0)
00112
00113
00114
00115 #define CUEX_OPN_DISJ_RETURN(opr, opn, sub, EXPR) \
00116 do { \
00117 int cuexL_i, cuexL_r = cuex_opr_r(opr); \
00118 for (cuexL_i = 0; cuexL_i < cuexL_r; ++cuexL_i) { \
00119 cuex_t sub = cuex_opn_at(opn, cuexL_i); \
00120 if (EXPR) \
00121 return cu_true; \
00122 } \
00123 } while (0)
00124
00125
00126
00127
00128
00129
00130
00131 #define CUEX_OPN_TRAN(opr, opn, old_sub, EXPR) \
00132 do { \
00133 int cuexL_i, cuexL_r = cuex_opr_r(opr); \
00134 for (cuexL_i = 0; cuexL_i < cuexL_r; ++cuexL_i) { \
00135 cuex_t old_sub, cuexL_new_sub; \
00136 old_sub = cuex_opn_at(opn, cuexL_i); \
00137 cuexL_new_sub = EXPR; \
00138 if (old_sub != cuexL_new_sub) { \
00139 cuex_t *new_arr = cu_salloc(sizeof(cuex_t)*cuexL_r); \
00140 memcpy(new_arr, cuex_opn_begin(opn), sizeof(cuex_t)*cuexL_r); \
00141 new_arr[cuexL_i] = cuexL_new_sub; \
00142 for (++cuexL_i; cuexL_i < cuexL_r; ++cuexL_i) { \
00143 old_sub = cuex_opn_at(opn, cuexL_i); \
00144 new_arr[cuexL_i] = EXPR; \
00145 } \
00146 opn = cuex_opn_by_arr(opr, new_arr); \
00147 break; \
00148 } \
00149 } \
00150 } while (0)
00151
00152
00153
00154
00155
00156 #define CUEX_OPN_TRAN_NULL(opr, opn, old_sub, EXPR) \
00157 do { \
00158 int cuexL_i, cuexL_r = cuex_opr_r(opr); \
00159 for (cuexL_i = 0; cuexL_i < cuexL_r; ++cuexL_i) { \
00160 cuex_t old_sub, cuexL_new_sub; \
00161 old_sub = cuex_opn_at(opn, cuexL_i); \
00162 cuexL_new_sub = EXPR; \
00163 if (!cuexL_new_sub) { \
00164 opn = NULL; \
00165 break; \
00166 } \
00167 if (old_sub != cuexL_new_sub) { \
00168 cuex_t *new_arr = cu_salloc(sizeof(cuex_t)*cuexL_r); \
00169 memcpy(new_arr, cuex_opn_begin(opn), sizeof(cuex_t)*cuexL_r); \
00170 new_arr[cuexL_i] = cuexL_new_sub; \
00171 for (++cuexL_i; cuexL_i < cuexL_r; ++cuexL_i) { \
00172 old_sub = cuex_opn_at(opn, cuexL_i); \
00173 new_arr[cuexL_i] = EXPR; \
00174 if (new_arr[cuexL_i] == NULL) \
00175 break; \
00176 } \
00177 if (cuexL_i == cuexL_r) \
00178 opn = cuex_opn_by_arr(opr, new_arr); \
00179 else \
00180 opn = NULL; \
00181 break; \
00182 } \
00183 } \
00184 } while (0)
00185
00186
00187
00188
00189 cuex_opn_t cuex_opn2_left(cuex_meta_t opr, cuex_t x, cuex_t y);
00190
00191
00192
00193
00194 cuex_opn_t cuex_opn2_right(cuex_meta_t opr, cuex_t x, cuex_t y);
00195
00196
00197
00198 cu_rank_t cuex_arity(cuex_t e);
00199
00200 #define cuex_opn_comm_A cuex_opn_comm_iterA
00201 #define cuex_opn_comm_Ak cuex_opn_comm_iterAk
00202 #define cuex_opn_comm_img cuex_opn_comm_iterimg
00203 #define cuex_opn_comm_imgk cuex_opn_comm_iterimgk
00204
00205 cu_bool_t cuex_opn_comm_iterA(cu_clop(f, cu_bool_t, cuex_t), cuex_t e);
00206 cu_bool_t cuex_opn_comm_iterAk(cu_clop(f, cu_bool_t, int, cuex_t), cuex_t e);
00207 cuex_t cuex_opn_comm_iterimg(cu_clop(f, cuex_t, cuex_t), cuex_t e);
00208 cuex_t cuex_opn_comm_iterimgk(cu_clop(f, cuex_t, int, cuex_t), cuex_t e);
00209
00210 struct cuex_opn_source
00211 {
00212 cu_inherit (cu_ptr_source);
00213 int i;
00214 cuex_t e;
00215 };
00216
00217 void cuex_opn_ncomm_source_init(cuex_opn_source_t src, cuex_t e);
00218
00219 cu_ptr_source_t cuex_opn_ncomm_source(cuex_t e);
00220
00221 void cuex_opn_comm_source_init(cuex_opn_source_t src, cuex_t e);
00222
00223 cu_ptr_source_t cuex_opn_comm_source(cuex_t e);
00224
00225
00226 CU_END_DECLARATIONS
00227
00228 #endif