diff --git a/include/vtype.h b/include/vtype.h index 465e988..8468322 100644 --- a/include/vtype.h +++ b/include/vtype.h @@ -80,8 +80,8 @@ typedef struct libcdsb_string vtype_string; typedef struct libcdsb_variable vtype_variable; -extern const char* libcdsb_vtype_name (vtype t) Warn_unused_result__; -extern const char* libcdsb_vtype_stringify(const void* value, vtype t) Warn_unused_result__; +extern const char* libcdsb_vtype_name (vtype t) Warn_unused_result__; +extern const char* libcdsb_vtype_stringify(vtype_variable value) Warn_unused_result__; inline vtype_variable libcdsb_variable_build(void* value, vtype t) Always_inline__; diff --git a/src/__internal/include.h b/src/__internal/include.h index ab46005..5593756 100644 --- a/src/__internal/include.h +++ b/src/__internal/include.h @@ -60,9 +60,8 @@ typedef vtype_hash hash_t; extern const size_t LIBCDSB_BUILTIN_VTYPE_SIZES[19]; -extern int libcdsb_builtin_vtype_compare_values (const void* s0, vtype t0, const void* s1, vtype t1) pure__ wur__; -extern int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) pure__ wur__; -extern hash_t libcdsb_builtin_vtype_hash (const void* value, vtype type) pure__ wur__; +extern int libcdsb_builtin_variable_compare(vtype_variable s0, vtype_variable s1) pure__ wur__; +extern hash_t libcdsb_builtin_vtype_hash (const void* value, vtype type) pure__ wur__; ainline(stack_t* libcdsb_builtin_stack_insert(stack_t* x, void* v)) { stack_t* p = x->prev; @@ -95,9 +94,9 @@ ainline(stack_t* libcdsb_builtin_stack_insert(stack_t* x, void* v)) { #define vtype_stringify libcdsb_vtype_stringify #define vtype_name libcdsb_vtype_name -#define vtype_compare libcdsb_builtin_vtype_compare_values -#define vtype_compare_eq libcdsb_builtin_vtype_compare_values_eq #define vtype_hash libcdsb_builtin_vtype_hash #define vtype_size(type) (LIBCDSB_BUILTIN_VTYPE_SIZES[type]) +#define variable_compare libcdsb_builtin_variable_compare + #endif /* LIBCDSB_SRC_INTERNAL_INCLUDE */ diff --git a/src/__internal/vnode.h b/src/__internal/vnode.h index 06f021d..4d3502b 100644 --- a/src/__internal/vnode.h +++ b/src/__internal/vnode.h @@ -23,7 +23,9 @@ extern vnode_t libcdsb_builtin_vnode_create (const void* value, vtype type extern vnode_t libcdsb_builtin_vnode_create_target(vtype target_type, const void* value, vtype type) wur__; extern void libcdsb_builtin_vnode_free(vnode_t* x, vtype type) Nonnull__(1); -extern void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype type) pure__ wur__ Nonnull__(1); + +extern vtype_variable libcdsb_builtin_vnode_peek(const vnode_t* x, vtype type) pure__ wur__ Nonnull__(1); + ainline(void libcdsb_builtin_vnode_attach(vnode_t* node, const void* value, vtype type)) { if (type < VTYPE_STRING) { @@ -58,12 +60,12 @@ ainline(void libcdsb_builtin_vnode_tattach(vnode_t* node, vtype target_type, con #define vnode_peek libcdsb_builtin_vnode_peek #define vnode_free libcdsb_builtin_vnode_free -#define vnode_hash(vnode, type) vtype_hash(vnode_peek(vnode, type), type) -#define vnode_compare(s0, t0, s1, t1) vtype_compare(vnode_peek(s0, t0), t0, vnode_peek(s1, t1), t1) -#define vnode_compare_eq(s0, s1, t) vtype_compare_eq(vnode_peek(s0, t), vnode_peek(s1, t), t) -#define vnode_duplicate(vnode, type) vnode_create(vnode_peek(vnode, type), type) +#define vnode_hash(vnode, type) vtype_hash(vnode_peek(vnode, type).pointer, type) +#define vnode_compare(s0, t0, s1, t1) variable_compare(vnode_peek(s0, t0), vnode_peek(s1, t1)) +#define vnode_compare_eq(s0, s1, t) variable_compare(vnode_peek(s0, t ), vnode_peek(s1, t )) +#define vnode_duplicate(vnode, type) vnode_create(vnode_peek(vnode, type).pointer, type) #define vnode_tduplicate(target_type, vnode, type) vnode_tcreate(target_type, vnode_peek(vnode, type), type) -#define vnode_stringify(n, t) vtype_stringify(vnode_peek(n, t), t) +#define vnode_stringify(n, t) vtype_stringify(vnode_peek(n, t)) #endif /* LIBCDSB_SRC_INTERNAL_VNODE_H */ diff --git a/src/array/access.c b/src/array/access.c index 8c61107..2f34201 100644 --- a/src/array/access.c +++ b/src/array/access.c @@ -35,7 +35,7 @@ int libcdsb_array_find(arr_t* x, vtype_variable var, void* _, array_access_callb i = 0; do { - cmp = vtype_compare(p, x->type, var.pointer, var.type); + cmp = variable_compare(libcdsb_variable_build(p, x->type), var); if (cmp == 0) break; @@ -50,7 +50,7 @@ int libcdsb_array_find(arr_t* x, vtype_variable var, void* _, array_access_callb while (i--) { p -= vtype_size(x->type); - cmp = vtype_compare(p, x->type, var.pointer, var.type); + cmp = variable_compare(libcdsb_variable_build(p, x->type), var); if (cmp == 0) break; } diff --git a/src/array/comparison.c b/src/array/comparison.c index f073b46..fa74476 100644 --- a/src/array/comparison.c +++ b/src/array/comparison.c @@ -22,7 +22,7 @@ int array_compare(const arr_t* s0, const arr_t* s1) { e = array_end(s0); do { - cmp = vtype_compare_eq(p0, p1, s0->type); + cmp = variable_compare(libcdsb_variable_build(p0, s0->type), libcdsb_variable_build(p1, s0->type)); if (cmp == 0) { p0 += vtype_size(s0->type); diff --git a/src/array/compute.c b/src/array/compute.c index 1052a7e..cd7f898 100644 --- a/src/array/compute.c +++ b/src/array/compute.c @@ -35,7 +35,7 @@ size_t libcdsb_array_count(const arr_t* s, vtype_variable var) { n = 0; do { - cmp = vtype_compare(p, s->type, var.pointer, var.type); + cmp = variable_compare(libcdsb_variable_build(p, s->type), var); if (cmp == 0) ++n; diff --git a/src/array/modify.c b/src/array/modify.c index 64a180e..ada7bb1 100644 --- a/src/array/modify.c +++ b/src/array/modify.c @@ -15,7 +15,7 @@ ssize_t libcdsb_array_insert(arr_t* x, vtype_variable var) { if (var.type < VTYPE_STRING) { n = vnode_tcreate(x->type, var.pointer, var.type); - memcpy(array_internal_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type)); + memcpy(array_internal_at(x, i), vnode_peek(&n, x->type).pointer, vtype_size(x->type)); if (vtype_size(x->type) > sizeof(vnode_t)) vnode_free(&n, x->type); @@ -38,7 +38,7 @@ ssize_t libcdsb_array_attach(arr_t* x, vtype_variable var) { if (var.type < VTYPE_STRING) { n = vnode_tcreate(x->type, var.pointer, var.type); - memcpy(array_internal_at(x, i), vnode_peek(&n, x->type), vtype_size(x->type)); + memcpy(array_internal_at(x, i), vnode_peek(&n, x->type).pointer, vtype_size(x->type)); if (vtype_size(x->type) > sizeof(vnode_t)) vnode_free(&n, x->type); diff --git a/src/dict/access.c b/src/dict/access.c index 367154d..216ed6f 100644 --- a/src/dict/access.c +++ b/src/dict/access.c @@ -4,18 +4,19 @@ #include "include.h" int libcdsb_dict_find(dict_t* x, vtype_variable kvar, void* dt, dict_access_callback callback, bool cut) { - dnode_t *c, **p; - int r; - void* key; + dnode_t *c, **p; + int r; + vtype_variable k, v; if (x->capacity) { c = *(p = x->nodes + (vtype_hash(kvar.pointer, kvar.type) % x->capacity)); while (!is_null(c)) { - key = vnode_peek(&c->key, c->key_type); - if (vtype_compare(kvar.pointer, kvar.type, key, c->key_type) == 0) { - r = (callback) ? callback(libcdsb_variable_build(key, c->key_type), - libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt) : 0; + k = vnode_peek(&c->key, c->key_type); + v = vnode_peek(&c->value, c->value_type); + + if (variable_compare(k, kvar) == 0) { + r = (callback) ? callback(k, v, dt) : 0; if (cut) { *p = c->prev; @@ -38,6 +39,7 @@ int libcdsb_dict_foreach(dict_t* x, void* dt, dict_access_callback callback, boo dnode_t *c; ssize_t i; int r; + vtype_variable k, v; r = 0; i = x->capacity; @@ -46,9 +48,10 @@ int libcdsb_dict_foreach(dict_t* x, void* dt, dict_access_callback callback, boo c = x->nodes[--i]; while (!is_null(c)) { - r = callback(libcdsb_variable_build(vnode_peek(&c->key, c->key_type), c->key_type), - libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt); + k = vnode_peek(&c->key, c->key_type); + v = vnode_peek(&c->value, c->value_type); + r = callback(k, v, dt); c = c->prev; if (r) { diff --git a/src/dict/modify.c b/src/dict/modify.c index 75c511b..7df42a2 100644 --- a/src/dict/modify.c +++ b/src/dict/modify.c @@ -51,7 +51,8 @@ bool libcdsb_dict_shrink_to_fit(dict_t* s) { bool libcdsb_dict_update(dict_t* x, vtype_variable key, vtype_variable value, void* dt, dict_access_callback callback) { - dnode_t *c, **p; + dnode_t *c, **p; + vtype_variable k; if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX) libcdsb_builtin_rehash(x, x->capacity + CAPACITY_BLOCK); @@ -59,9 +60,10 @@ bool libcdsb_dict_update(dict_t* x, vtype_variable key, vtype_variable value, vo c = *(p = x->nodes + (vtype_hash(key.pointer, key.type) % x->capacity)); while (!is_null(c)) { - if (vtype_compare(key.pointer, key.type, vnode_peek(&c->key, c->key_type), c->key_type) == 0) { - if (callback) callback(libcdsb_variable_build(vnode_peek(&c->key, c->key_type), c->key_type), - libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt); + k = vnode_peek(&c->key, c->key_type); + + if (variable_compare(k, key) == 0) { + if (callback) callback(k, vnode_peek(&c->value, c->value_type), dt); vnode_free(&c->value, c->value_type); @@ -85,7 +87,8 @@ bool libcdsb_dict_update(dict_t* x, vtype_variable key, vtype_variable value, vo bool libcdsb_dict_inject(dict_t* x, vtype_variable key, vtype_variable value, void* dt, dict_access_callback callback) { - dnode_t *c, **p; + dnode_t *c, **p; + vtype_variable k; if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX) libcdsb_builtin_rehash(x, x->capacity + CAPACITY_BLOCK); @@ -93,9 +96,10 @@ bool libcdsb_dict_inject(dict_t* x, vtype_variable key, vtype_variable value, vo c = *(p = x->nodes + (vtype_hash(key.pointer, key.type) % x->capacity)); while (!is_null(c)) { - if (vtype_compare(key.pointer, key.type, vnode_peek(&c->key, c->key_type), c->key_type) == 0) { - if (callback) callback(libcdsb_variable_build(vnode_peek(&c->key, c->key_type), c->key_type), - libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt); + k = vnode_peek(&c->key, c->key_type); + + if (variable_compare(k, key) == 0) { + if (callback) callback(k, vnode_peek(&c->value, c->value_type), dt); vnode_free(&c->key, c->key_type); vnode_free(&c->value, c->value_type); diff --git a/src/list/access.c b/src/list/access.c index a9cc5f3..dcca0a9 100644 --- a/src/list/access.c +++ b/src/list/access.c @@ -21,7 +21,6 @@ static void libcdsb_builtin_cut(list_t* s, lnode_t* cur) { /*#####################################################################################################################*/ int libcdsb_list_get(vtype_list* x, ssize_t i, void* _, list_access_callback callback, bool cut) { - ldir_t dir; lnode_t* c; size_t n; @@ -43,7 +42,7 @@ int libcdsb_list_get(vtype_list* x, ssize_t i, void* _, list_access_callback cal if (n || is_null(c)) return -1; - i = (callback) ? callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), i, _) : 0; + i = (callback) ? callback(vnode_peek(&c->node, c->type), i, _) : 0; if (cut) libcdsb_builtin_cut(x, c); @@ -56,16 +55,18 @@ int libcdsb_list_find(vtype_list* x, vtype_variable value, void* _, list_access_ lnode_t* c; ssize_t i; int cmp; + vtype_variable v; dir = r ? LD_PREV : LD_NEXT; c = ldir_dir((lnode_t*)x, dir); i = 0; while (!is_null(c)) { - cmp = vtype_compare(vnode_peek(&c->node, c->type), c->type, value.pointer, value.type); + v = vnode_peek(&c->node, c->type); + cmp = variable_compare(v, value); if (cmp == 0) { - i = (callback) ? callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), (r)?~i:i, _) : 0; + i = (callback) ? callback(v, (r)?~i:i, _) : 0; if (cut) libcdsb_builtin_cut(x, c); @@ -81,7 +82,6 @@ int libcdsb_list_find(vtype_list* x, vtype_variable value, void* _, list_access_ int libcdsb_list_foreach(vtype_list* x, void* data, list_access_callback callback, bool flush) { - lnode_t* n; lnode_t* c; size_t i; @@ -91,7 +91,7 @@ int libcdsb_list_foreach(vtype_list* x, void* data, list_access_callback callbac i = 0; while (!is_null(c)) { - if ((r = callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), i, data)) != 0) + if ((r = callback(vnode_peek(&c->node, c->type), i, data)) != 0) break; n = c->next; diff --git a/src/list/compute.c b/src/list/compute.c index bfe75cc..f408798 100644 --- a/src/list/compute.c +++ b/src/list/compute.c @@ -37,7 +37,6 @@ hash_t list_hash(const list_t* s) { size_t libcdsb_list_count(const list_t* s, vtype_variable value) { - lnode_t* c; size_t n; int cmp; @@ -46,7 +45,7 @@ size_t libcdsb_list_count(const list_t* s, vtype_variable value) { n = 0; while (!is_null(c)) { - cmp = vtype_compare(vnode_peek(&c->node, c->type), c->type, value.pointer, value.type); + cmp = variable_compare(vnode_peek(&c->node, c->type), value); if (cmp == 0) ++n; diff --git a/src/list/modify.c b/src/list/modify.c index e102e04..744a42e 100644 --- a/src/list/modify.c +++ b/src/list/modify.c @@ -4,7 +4,6 @@ #include "include.h" bool libcdsb_list_insert(list_t* x, ssize_t i, vtype_variable value, int ins, void* dt, list_access_callback callback) { - ldir_t dir; lnode_t* c; @@ -42,7 +41,7 @@ bool libcdsb_list_insert(list_t* x, ssize_t i, vtype_variable value, int ins, vo ldir_dir(ldir_inv(c, dir), dir) = c; } else { - if (callback) callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), -1, dt); + if (callback) callback(vnode_peek(&c->node, c->type), -1, dt); vnode_free(&c->node, c->type); } @@ -53,7 +52,6 @@ bool libcdsb_list_insert(list_t* x, ssize_t i, vtype_variable value, int ins, vo bool libcdsb_list_attach(list_t* x, ssize_t i, vtype_variable value, int ins, void* dt, list_access_callback callback) { - ldir_t dir; lnode_t* c; @@ -91,7 +89,7 @@ bool libcdsb_list_attach(list_t* x, ssize_t i, vtype_variable value, int ins, vo ldir_dir(ldir_inv(c, dir), dir) = c; } else { - if (callback) callback(libcdsb_variable_build(vnode_peek(&c->node, c->type), c->type), -1, dt); + if (callback) callback(vnode_peek(&c->node, c->type), -1, dt); vnode_free(&c->node, c->type); } diff --git a/src/map/access.c b/src/map/access.c index 3d065a6..6c51ab5 100644 --- a/src/map/access.c +++ b/src/map/access.c @@ -22,8 +22,7 @@ static int libcdsb_builtin_foreach(map_t* x, void* data, map_access_callback cal if (!mnode_is_empty(n->right)) cur = stack_insert(cur, n->right); if (!r) { - r = callback(libcdsb_variable_build(vnode_peek(&n->key, x->type), x->type), - libcdsb_variable_build(vnode_peek(&n->value, n->type), n->type), data); + r = callback(vnode_peek(&n->key, x->type), vnode_peek(&n->value, n->type), data); } else { stack_flush(&z); return r; @@ -46,20 +45,19 @@ static int libcdsb_builtin_foreach(map_t* x, void* data, map_access_callback cal /*#####################################################################################################################*/ -int libcdsb_map_find(map_t* x, vtype_variable kvar, void* _, map_access_callback callback, bool cut) { +int libcdsb_map_find(map_t* x, vtype_variable key, void* _, map_access_callback callback, bool cut) { mnode_t* c; - void *key; int cmp; + vtype_variable k; c = x->root; while (!mnode_is_empty(c)) { - key = vnode_peek(&c->key, x->type); - cmp = vtype_compare(kvar.pointer, kvar.type, key, x->type); + k = vnode_peek(&c->key, x->type); + cmp = variable_compare(key, k); if (cmp == 0) { - cmp = (callback) ? callback(libcdsb_variable_build(key, x->type), - libcdsb_variable_build(vnode_peek(&c->value, c->type), c->type), _) : 0; + cmp = (callback) ? callback(k, vnode_peek(&c->value, c->type), _) : 0; if (cut) { c = mnode_delete(&x->root, c); @@ -98,8 +96,7 @@ int libcdsb_map_foreach(map_t* x, void* data, map_access_callback callback, rbfo while ((n = stack_pop(&iter))) { if (!r) { - r = callback(libcdsb_variable_build(vnode_peek(&n->key, x->type), x->type), - libcdsb_variable_build(vnode_peek(&n->value, n->type), n->type), data); + r = callback(vnode_peek(&n->key, x->type), vnode_peek(&n->value, n->type), data); } else if (!flush) { stack_flush(&iter); return r; diff --git a/src/map/modify.c b/src/map/modify.c index 7c77a3e..a43c9b4 100644 --- a/src/map/modify.c +++ b/src/map/modify.c @@ -7,15 +7,16 @@ bool libcdsb_map_update(map_t* x, vtype_variable key, vtype_variable value, void int cmp; mnode_t* n; mnode_t* p; + vtype_variable k; if (!mnode_is_empty(n = x->root)) { do { - p = n; - cmp = vtype_compare(key.pointer, key.type, vnode_peek(&n->key, x->type), x->type); + p = n; + k = vnode_peek(&n->key, x->type); + cmp = variable_compare(key, k); if (cmp == 0) { - if (callback) callback(libcdsb_variable_build(vnode_peek(&n->key, x->type), x->type), - libcdsb_variable_build(vnode_peek(&n->value, n->type), n->type), dt); + if (callback) callback(k, vnode_peek(&n->value, n->type), dt); vnode_free(&n->value, n->type); @@ -49,20 +50,21 @@ bool libcdsb_map_inject(map_t* x, vtype_variable key, vtype_variable value, void mnode_t* n; mnode_t* p; vnode_t kn; + vtype_variable k; vnode_tattach(&kn, x->type, key.pointer, key.type); n = x->root; key.type = x->type; - key.pointer = vnode_peek(&kn, key.type); + key.pointer = vnode_peek(&kn, key.type).pointer; if (!mnode_is_empty(n)) { do { + k = vnode_peek(&n->key, x->type); p = n; - cmp = vtype_compare(key.pointer, key.type, vnode_peek(&n->key, x->type), x->type); + cmp = variable_compare(key, k); if (cmp == 0) { - if (callback) callback(libcdsb_variable_build(vnode_peek(&n->key, x->type), x->type), - libcdsb_variable_build(vnode_peek(&n->value, n->type), n->type), dt); + if (callback) callback(k, vnode_peek(&n->value, n->type), dt); vnode_free(&n->key, x->type); vnode_free(&n->value, n->type); diff --git a/src/set/access.c b/src/set/access.c index d8c4015..16c9dd2 100644 --- a/src/set/access.c +++ b/src/set/access.c @@ -23,7 +23,7 @@ static int libcdsb_builtin_foreach(set_t* x, void* data, vset_access_callback ca if (!rbnode_is_empty(n->right)) cur = stack_insert(cur, n->right); if (!r) { - r = callback(libcdsb_variable_build(vnode_peek(&n->value, x->type), x->type), data); + r = callback(vnode_peek(&n->value, x->type), data); } else { stack_flush(&z); return r; @@ -48,17 +48,17 @@ static int libcdsb_builtin_foreach(set_t* x, void* data, vset_access_callback ca int libcdsb_vset_find(vtype_set* x, vtype_variable value, void* _, vset_access_callback callback, bool cut) { rbnode_t* c; - void *val; int cmp; + vtype_variable v; c = x->root; while (!rbnode_is_empty(c)) { - val = vnode_peek(&c->value, x->type); - cmp = vtype_compare(value.pointer, value.type, val, x->type); + v = vnode_peek(&c->value, x->type); + cmp = variable_compare(value, v); if (cmp == 0) { - cmp = (callback) ? callback(libcdsb_variable_build(val, x->type), _) : 0; + cmp = (callback) ? callback(v, _) : 0; if (cut) { c = rbnode_delete(&x->root, c); @@ -96,7 +96,7 @@ int libcdsb_vset_foreach(set_t* x, void* data, vset_access_callback callback, rb while ((n = stack_pop(&iter))) { if (!r) { - r = callback(libcdsb_variable_build(vnode_peek(&n->value, x->type), x->type), data); + r = callback(vnode_peek(&n->value, x->type), data); } else if (!flush) { stack_flush(&iter); return r; diff --git a/src/set/modify.c b/src/set/modify.c index 9f0abc3..11e8612 100644 --- a/src/set/modify.c +++ b/src/set/modify.c @@ -13,7 +13,7 @@ bool libcdsb_vset_insert(set_t* x, vtype_variable value) { if (!rbnode_is_empty(n = x->root)) { do { p = n; - cmp = vtype_compare(value.pointer, value.type, vnode_peek(&n->value, x->type), x->type); + cmp = variable_compare(value, vnode_peek(&n->value, x->type)); if (cmp == 0) return false; @@ -45,12 +45,12 @@ bool libcdsb_vset_attach(set_t* x, vtype_variable value) { vnode_tattach(&vn, x->type, value.pointer, value.type); n = x->root; value.type = x->type; - value.pointer = vnode_peek(&vn, value.type); + value.pointer = vnode_peek(&vn, value.type).pointer; if (!rbnode_is_empty(n)) { do { p = n; - cmp = vtype_compare(value.pointer, value.type, vnode_peek(&n->value, x->type), x->type); + cmp = variable_compare(value, vnode_peek(&n->value, x->type)); if (cmp == 0) { vnode_free(&vn, value.type); diff --git a/src/stringify.c b/src/stringify.c index 054ea29..c88e333 100644 --- a/src/stringify.c +++ b/src/stringify.c @@ -62,41 +62,41 @@ const char* libcdsb_vtype_name(vtype t) { } -const char* libcdsb_vtype_stringify(const void* v, vtype t) { - if (is_null(v) || (t == VTYPE_POINTER && is_null(*(void**)v))) return "null"; - if (t == VTYPE_BOOLEAN) return (*(vtype_bool*)v) ? "true" : "false"; - if (t == VTYPE_STRING) return *(char**)v; +const char* libcdsb_vtype_stringify(vtype_variable value) { + if (is_null(value.pointer) || (value.type == VTYPE_POINTER && is_null(*(void**)value.pointer))) return "null"; + if (value.type == VTYPE_BOOLEAN) return (*(vtype_bool*)value.pointer) ? "true" : "false"; + if (value.type == VTYPE_STRING) return *(char**)value.pointer; if (LIBCDSB_BUILTIN_COUNTER > 15) LIBCDSB_BUILTIN_COUNTER = 0; - switch (t) { - case VTYPE_INT8: stringify(*( s8_t*)v); break; - case VTYPE_INT16: stringify(*( s16_t*)v); break; - case VTYPE_INT32: stringify(*( s32_t*)v); break; - case VTYPE_INT64: stringify(*( s64_t*)v); break; - case VTYPE_UINT8: stringify(*( u8_t*)v); break; - case VTYPE_UINT16: stringify(*( u16_t*)v); break; - case VTYPE_UINT32: stringify(*( u32_t*)v); break; - case VTYPE_UINT64: stringify(*( u64_t*)v); break; - case VTYPE_FLOAT: if (abs(*(fl_t*)v) <= FLT_EPSILON) { + switch (value.type) { + case VTYPE_INT8: stringify(*( s8_t*)value.pointer); break; + case VTYPE_INT16: stringify(*( s16_t*)value.pointer); break; + case VTYPE_INT32: stringify(*( s32_t*)value.pointer); break; + case VTYPE_INT64: stringify(*( s64_t*)value.pointer); break; + case VTYPE_UINT8: stringify(*( u8_t*)value.pointer); break; + case VTYPE_UINT16: stringify(*( u16_t*)value.pointer); break; + case VTYPE_UINT32: stringify(*( u32_t*)value.pointer); break; + case VTYPE_UINT64: stringify(*( u64_t*)value.pointer); break; + case VTYPE_FLOAT: if (abs(*(fl_t*)value.pointer) <= FLT_EPSILON) { LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][0] = 0x30; LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][1] = 0x00; - } else stringify(*(fl_t*)v); + } else stringify(*(fl_t*)value.pointer); break; - case VTYPE_DOUBLE: if (abs(*(dbl_t*)v) <= DBL_EPSILON) { + case VTYPE_DOUBLE: if (abs(*(dbl_t*)value.pointer) <= DBL_EPSILON) { LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][0] = 0x30; LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][1] = 0x00; - } else stringify(*(dbl_t*)v); + } else stringify(*(dbl_t*)value.pointer); break; - case VTYPE_LDOUBLE: if (abs(*(ldbl_t*)v) <= LDBL_EPSILON) { + case VTYPE_LDOUBLE: if (abs(*(ldbl_t*)value.pointer) <= LDBL_EPSILON) { LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][0] = 0x30; LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER][1] = 0x00; - } else stringify(*(ldbl_t*)v); + } else stringify(*(ldbl_t*)value.pointer); break; - case VTYPE_POINTER: sprintf(LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER], (sizeof(void*) == 8) ? "0x%016lx" : "0x%08x", (uintptr_t)*(void**)v); break; + case VTYPE_POINTER: sprintf(LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER], (sizeof(void*) == 8) ? "0x%016lx" : "0x%08x", (uintptr_t)*(void**)value.pointer); break; - default: sprintf(LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER], "<%s>", libcdsb_vtype_name(t)); + default: sprintf(LIBCDSB_BUILTIN_BUFFER[LIBCDSB_BUILTIN_COUNTER], "<%s>", libcdsb_vtype_name(value.type)); break; } diff --git a/src/vnode.c b/src/vnode.c index 33babed..042f909 100644 --- a/src/vnode.c +++ b/src/vnode.c @@ -194,8 +194,10 @@ vnode_t libcdsb_builtin_vnode_create(const void* v, vtype t) { } -void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) { - switch (t) { default: abort(); +vtype_variable libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) { + vtype_variable var = { .type = t }; + + switch (var.type) { default: abort(); case VTYPE_FLOAT: if (is_permissible(fl_t)) goto vt_; else goto pt_; case VTYPE_DOUBLE: if (is_permissible(dbl_t)) goto vt_; else goto pt_; @@ -212,7 +214,8 @@ void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) { case VTYPE_UINT16: case VTYPE_INT32: case VTYPE_UINT32: - vt_: return (void*)x; + vt_: var.pointer = (void*)x; + break; case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) goto vt_; case VTYPE_MAP: @@ -220,8 +223,11 @@ void* libcdsb_builtin_vnode_peek(const vnode_t* x, vtype t) { case VTYPE_LIST: case VTYPE_SET: case VTYPE_DICT: - pt_: return *x; + pt_: var.pointer = *x; + break; } + + return var; } diff --git a/src/vtype.c b/src/vtype.c index e8389e5..3ef7134 100644 --- a/src/vtype.c +++ b/src/vtype.c @@ -59,25 +59,7 @@ static hash_t libcdsb_builtin_hash_float(ldbl_t s) { return hash; } -/*#####################################################################################################################*/ - -int libcdsb_builtin_vtype_compare_values(const void* s0, vtype t0, const void* s1, vtype t1) { - if (t0 == t1) return libcdsb_builtin_vtype_compare_values_eq(s0, s1, t0); - - if (t0 <= VTYPE_LDOUBLE && t1 <= VTYPE_LDOUBLE) { - ldbl_t d0, d1; - - d0 = libcdsb_builtin_normalize(s0, t0); - d1 = libcdsb_builtin_normalize(s1, t1); - - return (abs(d0 - d1) <= LDBL_EPSILON) ? 0 : (d0 < d1 ? -1 : 1); - } - - return t0 - t1; -} - - -int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) { +static int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtype t) { #define compare(T, s0, s1) *(T*)s0 == *(T*)s1 ? 0 : (*(T*)s0 < *(T*)s1 ? -1 : 1) @@ -117,6 +99,23 @@ int libcdsb_builtin_vtype_compare_values_eq(const void* s0, const void* s1, vtyp /*#####################################################################################################################*/ +int libcdsb_builtin_variable_compare(vtype_variable s0, vtype_variable s1) { + if (s0.type == s1.type) return libcdsb_builtin_vtype_compare_values_eq(s0.pointer, s1.pointer, s0.type); + + if (s0.type <= VTYPE_LDOUBLE && s0.type <= VTYPE_LDOUBLE) { + ldbl_t d0, d1; + + d0 = libcdsb_builtin_normalize(s0.pointer, s0.type); + d1 = libcdsb_builtin_normalize(s1.pointer, s1.type); + + return (abs(d0 - d1) <= LDBL_EPSILON) ? 0 : (d0 < d1 ? -1 : 1); + } + + return s0.type - s1.type; +} + +/*#####################################################################################################################*/ + hash_t libcdsb_builtin_vtype_hash(const void* v, vtype t) { switch (t) { default: abort(); diff --git a/tests/src/test.c b/tests/src/test.c index 32e11e4..ab6619a 100644 --- a/tests/src/test.c +++ b/tests/src/test.c @@ -70,7 +70,7 @@ void print_container_value(const ssize_t* index, const void* value, const vtype printf("\e[%dG ", hpos+1); } - printf("\e[31m%24s\e[m", libcdsb_vtype_stringify(value, type)); + printf("\e[31m%24s\e[m", libcdsb_vtype_stringify(libcdsb_variable_build((void*)value, type))); if (print_type) { printf(" \e[36m(\e[m\e[32;1m%s\e[m\e[36m)\e[m", libcdsb_vtype_name(type));