00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CUEX_VAR_H
00019 #define CUEX_VAR_H
00020
00021 #include <cu/fwd.h>
00022 #include <cuex/fwd.h>
00023 #include <cuex/qcode.h>
00024 #include <cu/conf.h>
00025 #include <cuoo/oalloc.h>
00026 #include <cuoo/halloc.h>
00027 #include <cufo/fwd.h>
00028
00029 CU_BEGIN_DECLARATIONS
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 typedef enum {
00045 cuex_varkind_svar,
00046 cuex_varkind_tvar,
00047 cuex_varkind_tpvar,
00048 cuex_varkind_fpvar,
00049 cuex_varkind_pvar,
00050 cuex_varkind_ivar,
00051 cuex_varkind_rvar,
00052 cuex_varkind_xvar,
00053 } cuex_varkind_t;
00054
00055
00056 #define CUEXP_VARMETA_QCODE_WIDTH 2
00057 #define CUEXP_VARMETA_KIND_WIDTH 3
00058 #if CUCONF_SIZEOF_VOID_P == 4
00059 # define CUEXP_VARMETA_INDEX_WIDTH 22
00060 #elif CUCONF_SIZEOF_VOID_P == 8
00061 # define CUEXP_VARMETA_INDEX_WIDTH 54
00062 #else
00063 # error Unexpected word size, hand-tune new case here.
00064 #endif
00065
00066 #define CUEXP_VARMETA_QCODE_SHIFT \
00067 (CUEXP_VARMETA_WSIZE_SHIFT + CUEXP_VARMETA_WSIZE_WIDTH)
00068 #define CUEXP_VARMETA_KIND_SHIFT \
00069 (CUEXP_VARMETA_QCODE_SHIFT + CUEXP_VARMETA_QCODE_WIDTH)
00070 #define CUEXP_VARMETA_INDEX_SHIFT \
00071 (CUEXP_VARMETA_KIND_SHIFT + CUEXP_VARMETA_KIND_WIDTH)
00072 #define CUEXP_VARMETA_QCODE_MASK \
00073 CUEX_META_MASK(CUEXP_VARMETA_QCODE_SHIFT, CUEXP_VARMETA_QCODE_WIDTH)
00074 #define CUEXP_VARMETA_KIND_MASK \
00075 CUEX_META_MASK(CUEXP_VARMETA_KIND_SHIFT, CUEXP_VARMETA_KIND_WIDTH)
00076 #define CUEXP_VARMETA_INDEX_MASK \
00077 CUEX_META_MASK(CUEXP_VARMETA_INDEX_SHIFT, CUEXP_VARMETA_INDEX_WIDTH)
00078
00079 #if CUEXP_VARMETA_INDEX_SHIFT+CUEXP_VARMETA_INDEX_WIDTH!=CUCONF_WIDTHOF_VOID_P
00080 # error Widths for variable meta fields do not add up to word size.
00081 #endif
00082
00083
00084 #define cuex_varmeta_kqis(kind, qcode, index, wsize) \
00085 (CUEXP_VARMETA_SELECT_VALUE \
00086 | ((wsize) << CUEXP_VARMETA_WSIZE_SHIFT) \
00087 | ((kind) << CUEXP_VARMETA_KIND_SHIFT) \
00088 | ((qcode) << CUEXP_VARMETA_QCODE_SHIFT) \
00089 | ((index) << CUEXP_VARMETA_INDEX_SHIFT) )
00090
00091
00092 #define cuex_varmeta_kqi(kind, qcode, index) \
00093 cuex_varmeta_kqis(kind, qcode, index, 0)
00094
00095
00096 #define cuex_is_varmeta_kqis(meta, kind, qcode, index, wsize) \
00097 ((meta) == cuex_varmeta_kqis(kind, qcode, index, wsize))
00098
00099
00100 #define cuex_is_varmeta_kqi(meta, kind, qcode, index) \
00101 ((meta) == cuex_varmeta_kqi(kind, qcode, index))
00102
00103
00104 #define cuex_is_varmeta_kq(meta, kind, qcode) \
00105 ((( CUEXP_VARMETA_SELECT_MASK \
00106 | CUEXP_VARMETA_KIND_MASK \
00107 | CUEXP_VARMETA_QCODE_MASK ) & (meta)) \
00108 == cuex_varmeta_kqi(kind, qcode, 0))
00109
00110 #define cuex_is_varmeta_ki(meta, kind, index) \
00111 ((( CUEXP_VARMETA_SELECT_MASK \
00112 | CUEXP_VARMETA_KIND_MASK \
00113 | CUEXP_VARMETA_INDEX_MASK ) & (meta)) \
00114 == cuex_varmeta_kqi(kind, 0, index))
00115
00116
00117 #define cuex_is_varmeta_k(meta, kind) \
00118 ((( CUEXP_VARMETA_SELECT_MASK \
00119 | CUEXP_VARMETA_KIND_MASK ) & (meta)) \
00120 == cuex_varmeta_kqi(kind, 0, 0))
00121
00122
00123 #define cuex_is_varmeta_q(meta, qcode) \
00124 ((( CUEXP_VARMETA_SELECT_MASK \
00125 | CUEXP_VARMETA_QCODE_MASK ) & (meta)) \
00126 == cuex_varmeta_kqi(0, qcode, 0))
00127
00128
00129
00130
00131
00132
00133 #define cuex_is_varmeta(meta) \
00134 (((CUEXP_VARMETA_SELECT_MASK) & (meta)) == cuex_varmeta_kqi(0, 0, 0))
00135
00136
00137 #define cuex_varmeta_qcode(meta) \
00138 ((cuex_qcode_t) \
00139 (((meta) & CUEXP_VARMETA_QCODE_MASK) >> CUEXP_VARMETA_QCODE_SHIFT))
00140
00141
00142 #define cuex_varmeta_index(meta) \
00143 (((meta) & CUEXP_VARMETA_INDEX_MASK ) >> CUEXP_VARMETA_INDEX_SHIFT)
00144
00145 #define cuex_is_varmeta_u(meta) cuex_is_varmeta_q(meta, cuex_qcode_u)
00146 #define cuex_is_varmeta_e(meta) cuex_is_varmeta_q(meta, cuex_qcode_e)
00147 #define cuex_is_varmeta_w(meta) cuex_is_varmeta_q(meta, cuex_qcode_w)
00148 #define cuex_is_varmeta_n(meta) cuex_is_varmeta_q(meta, cuex_qcode_n)
00149
00150
00151
00152
00153
00154
00155 CU_SINLINE cu_bool_t cuex_is_var(cuex_t ex)
00156 { return cuex_is_varmeta(cuex_meta(ex)); }
00157
00158 #define cuex_var_to_ex(var) ((cuex_t)(var))
00159 #define cuex_var_from_ex(ex) ((cuex_var_t)(ex))
00160
00161
00162 #define cuex_var_qcode(var) cuex_varmeta_qcode(cuex_meta(var))
00163
00164
00165
00166 CU_SINLINE cuex_var_t cuex_var_new(cuex_qcode_t qcode)
00167 { return (cuex_var_t)cuexP_oalloc(cuex_varmeta_kqi(cuex_varkind_svar,
00168 qcode, 0), 0); }
00169
00170
00171 #define cuex_var_new_e() cuex_var_new(cuex_qcode_e)
00172
00173
00174 #define cuex_var_new_u() cuex_var_new(cuex_qcode_u)
00175
00176
00177
00178
00179
00180 #define cuex_var_new_w() cuex_var_new(cuex_qcode_w)
00181
00182
00183
00184 #define cuex_var_new_n() cuex_var_new(cuex_qcode_n)
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 #define cuex_ivarmeta(qcode, index) \
00199 cuex_varmeta_kqi(cuex_varkind_ivar, qcode, index)
00200
00201
00202 #define cuex_is_ivarmeta(meta) cuex_is_varmeta_k(meta, cuex_varkind_ivar)
00203
00204
00205 #define cuex_is_ivarmeta_q(meta, qcode) \
00206 cuex_is_varmeta_kq(meta, cuex_varkind_ivar, qcode)
00207
00208
00209
00210 CU_SINLINE cuex_var_t cuex_ivar(cuex_qcode_t qcode, unsigned int index)
00211 { return (cuex_var_t)cuexP_halloc(cuex_ivarmeta(qcode, index), 0, NULL); }
00212 #define cuex_ivar_e(i) cuex_ivar(cuex_qcode_e, i)
00213 #define cuex_ivar_u(i) cuex_ivar(cuex_qcode_u, i)
00214 #define cuex_ivar_w(i) cuex_ivar(cuex_qcode_w, i)
00215 #define cuex_ivar_n(i) cuex_ivar(cuex_qcode_n, i)
00216
00217
00218 CU_SINLINE unsigned int cuex_ivar_index(cuex_var_t var)
00219 { return cuex_varmeta_index(cuex_meta(var)); }
00220
00221
00222
00223
00224 #define cuex_rvarmeta(index) \
00225 cuex_varmeta_kqi(cuex_varkind_rvar, cuex_qcode_n, index)
00226
00227
00228 #define cuex_is_rvarmeta(meta) cuex_is_varmeta_k(meta, cuex_varkind_rvar)
00229
00230
00231
00232 CU_SINLINE cuex_var_t cuex_rvar(unsigned int index)
00233 { return (cuex_var_t)cuexP_halloc(cuex_rvarmeta(index), 0, NULL); }
00234
00235
00236 #define cuex_rvar_index(var) cuex_ivar_index(var)
00237
00238
00239
00240 typedef struct cuex_xvarops *cuex_xvarops_t;
00241 struct cuex_xvarops
00242 {
00243 void (*foprint)(cufo_stream_t fos, void *);
00244 };
00245
00246 extern struct cucon_umap cuexP_xvarops;
00247
00248
00249
00250
00251 #define cuex_xvarmeta(qcode, subkind, wsize) \
00252 cuex_varmeta_kqis(cuex_varkind_xvar, qcode, subkind, wsize)
00253
00254
00255
00256
00257
00258
00259
00260
00261 cuex_meta_t cuex_register_xvarkind(cuex_meta_t subkind, unsigned int wsize,
00262 cuex_xvarops_t ops);
00263
00264
00265 CU_SINLINE cu_bool_t
00266 cuex_is_xvarmeta(cuex_meta_t meta)
00267 { return cuex_is_varmeta_k(meta, cuex_varkind_xvar); }
00268
00269
00270 CU_SINLINE cu_bool_t
00271 cuex_is_xvarmeta_k(cuex_meta_t meta, cuex_varkind_t subkind)
00272 { return cuex_is_varmeta_ki(meta, cuex_varkind_xvar, subkind); }
00273
00274
00275
00276 CU_SINLINE cu_bool_t
00277 cuex_is_xvarmeta_kq(cuex_meta_t meta, cuex_varkind_t subkind,
00278 cuex_qcode_t qcode)
00279 { return cuex_is_varmeta_kqi(meta, cuex_varkind_xvar, qcode, subkind); }
00280
00281
00282
00283 CU_SINLINE cuex_meta_t
00284 cuex_xvarmeta_subkind(cuex_meta_t meta)
00285 { return cuex_varmeta_index(meta); }
00286
00287
00288 CU_SINLINE cuex_t
00289 cuex_xvar_alloc(cuex_meta_t xvarmeta)
00290 {
00291 return cuexP_oalloc(xvarmeta,
00292 cuexP_varmeta_wsize(xvarmeta)*sizeof(cu_word_t));
00293 }
00294
00295
00296 CU_END_DECLARATIONS
00297
00298 #endif