261 lines
7.8 KiB
C
261 lines
7.8 KiB
C
/* This software is licensed by the MIT License, see LICENSE file */
|
|
/* Copyright © 2022 Gregory Lirent */
|
|
|
|
#include "__internal/assert.h"
|
|
#include "__internal/vnode.h"
|
|
|
|
/*#####################################################################################################################*/
|
|
|
|
|
|
static vnode_t create_value(vtype xt, const void* v, vtype t) {
|
|
var_t _;
|
|
|
|
if (sizeof(void*) == 8) {
|
|
if (t == VTYPE_UINT8 || t == VTYPE_INT8 || t == VTYPE_BOOLEAN ) {
|
|
_.u64 = *(u8_t*)v;
|
|
} else if (t == VTYPE_UINT16 || t == VTYPE_INT16) {
|
|
_.u64 = *(u16_t*)v;
|
|
} else if (t == VTYPE_UINT32 || t == VTYPE_INT32 || (sizeof(void*) == 4 && t == VTYPE_POINTER)) {
|
|
_.u64 = *(u32_t*)v;
|
|
} else if (t == VTYPE_UINT64 || t == VTYPE_INT64 || (sizeof(void*) == 8 && t == VTYPE_POINTER)) {
|
|
_.u64 = *(u64_t*)v;
|
|
}
|
|
|
|
if (is_big_endian) {
|
|
if (xt == VTYPE_BOOLEAN) _.u8 = (_.u64 == 0) ? 0 : 1;
|
|
else if (xt == VTYPE_UINT8 || xt == VTYPE_INT8) {
|
|
_.u64 <<= 56;
|
|
} else if (xt == VTYPE_UINT16 || xt == VTYPE_INT16) {
|
|
_.u64 <<= 48;
|
|
} else if (xt == VTYPE_UINT32 || xt == VTYPE_INT32) {
|
|
_.u64 <<= 32;
|
|
}
|
|
} else if (xt == VTYPE_BOOLEAN) _.u64 = (_.u64 == 0) ? 0 : 1;
|
|
|
|
} else {
|
|
if (t == VTYPE_UINT8 || t == VTYPE_INT8 || t == VTYPE_BOOLEAN ) {
|
|
_.u64 = *(u8_t*)v;
|
|
} else if (t == VTYPE_UINT16 || t == VTYPE_INT16) {
|
|
_.u64 = *(u16_t*)v;
|
|
} else if (t == VTYPE_UINT32 || t == VTYPE_INT32 || (sizeof(void*) == 4 && t == VTYPE_POINTER)) {
|
|
_.u64 = *(u32_t*)v;
|
|
} else if (t == VTYPE_UINT64 || t == VTYPE_INT64 || (sizeof(void*) == 8 && t == VTYPE_POINTER)) {
|
|
_.u64 = *(u64_t*)v;
|
|
}
|
|
|
|
if (xt == VTYPE_UINT64 || xt == VTYPE_UINT32) {
|
|
_.ptr = memndup(&_.u64, sizeof(_.u64));
|
|
} else if (is_big_endian) {
|
|
_.u64 <<= 32;
|
|
if (xt == VTYPE_BOOLEAN) _.u8 = (_.u32 == 0) ? 0 : 1;
|
|
else if (xt == VTYPE_UINT8 || xt == VTYPE_INT8) {
|
|
_.u32 <<= 24;
|
|
} else if (xt == VTYPE_UINT16 || xt == VTYPE_INT16) {
|
|
_.u32 <<= 16;
|
|
}
|
|
} else if (xt == VTYPE_BOOLEAN) _.u32 = (_.u32 == 0) ? 0 : 1;
|
|
}
|
|
|
|
return _.ptr;
|
|
}
|
|
|
|
|
|
static vnode_t create_float(vtype xt, const void* v, vtype t) {
|
|
var_t _;
|
|
|
|
if (t == VTYPE_FLOAT) {
|
|
_.ld = *(fl_t*)v;
|
|
} else if (t == VTYPE_DOUBLE) {
|
|
_.ld = *(dbl_t*)v;
|
|
} else { // (t == VTYPE_LDOUBLE)
|
|
_.ld = *(ldbl_t*)v;
|
|
}
|
|
|
|
if (xt == VTYPE_FLOAT) {
|
|
_.f = _.ld;
|
|
if (!is_permissible(fl_t)) {
|
|
_.ptr = memndup(&_.f, sizeof(_.f));
|
|
}
|
|
} else if (xt == VTYPE_DOUBLE) {
|
|
_.f = _.d;
|
|
if (!is_permissible(dbl_t)) {
|
|
_.ptr = memndup(&_.d, sizeof(_.d));
|
|
}
|
|
} else { // (xt == VTYPE_LDOUBLE)
|
|
if (!is_permissible(ldbl_t)) {
|
|
_.ptr = memndup(&_.ld, sizeof(_.ld));
|
|
}
|
|
}
|
|
|
|
return _.ptr;
|
|
}
|
|
|
|
|
|
/*#####################################################################################################################*/
|
|
|
|
|
|
vnode_t libcdsb_vnode_create(const void* v, vtype t) {
|
|
var_t _ = { .ptr = 0 };
|
|
|
|
switch (t) { default: abort();
|
|
|
|
case VTYPE_INT8:
|
|
case VTYPE_UINT8: _.u8 = *(u8_t*)v;
|
|
break;
|
|
|
|
case VTYPE_INT16:
|
|
case VTYPE_UINT16: _.u16 = *(u16_t*)v;
|
|
break;
|
|
|
|
case VTYPE_INT32:
|
|
case VTYPE_UINT32: _.u32 = *(u32_t*)v;
|
|
break;
|
|
|
|
case VTYPE_INT64:
|
|
case VTYPE_UINT64: if (is_x64) _.u64 = *(u64_t*)v;
|
|
else _.ptr = memndup(v, sizeof(u64_t));
|
|
break;
|
|
|
|
case VTYPE_FLOAT: if (is_permissible(fl_t)) _.ld = *(fl_t*)v;
|
|
else _.ptr = memndup(v, sizeof(fl_t));
|
|
break;
|
|
|
|
case VTYPE_DOUBLE: if (is_permissible(dbl_t)) _.ld = *(dbl_t*)v;
|
|
else _.ptr = memndup(v, sizeof(dbl_t));
|
|
break;
|
|
|
|
case VTYPE_LDOUBLE: if (is_permissible(ldbl_t)) _.ld = *(ldbl_t*)v;
|
|
else _.ptr = memndup(v, sizeof(ldbl_t));
|
|
break;
|
|
|
|
|
|
case VTYPE_BOOLEAN: _.b = *(_Bool*)v;
|
|
break;
|
|
|
|
case VTYPE_POINTER: _.ptr = *(void**)v;
|
|
break;
|
|
|
|
case VTYPE_STRING: _.ptr = string_duplicate(v);
|
|
break;
|
|
|
|
case VTYPE_MAP: _.ptr = map_duplicate(v);
|
|
break;
|
|
|
|
case VTYPE_ARRAY: _.ptr = array_duplicate(v);
|
|
break;
|
|
|
|
case VTYPE_LIST: _.ptr = list_duplicate(v);
|
|
break;
|
|
|
|
case VTYPE_SET: _.ptr = vset_duplicate(v);
|
|
break;
|
|
}
|
|
|
|
return _.ptr;
|
|
}
|
|
|
|
|
|
/*#####################################################################################################################*/
|
|
|
|
|
|
void* libcdsb_vnode_peek(const vnode_t* x, vtype t) {
|
|
switch (t) { 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_;
|
|
case VTYPE_LDOUBLE: if (is_permissible(ldbl_t)) goto vt_; else goto pt_;
|
|
|
|
case VTYPE_INT64:
|
|
case VTYPE_UINT64: if (!is_x64) goto pt_;
|
|
|
|
case VTYPE_BOOLEAN:
|
|
case VTYPE_POINTER:
|
|
case VTYPE_INT8:
|
|
case VTYPE_UINT8:
|
|
case VTYPE_INT16:
|
|
case VTYPE_UINT16:
|
|
case VTYPE_INT32:
|
|
case VTYPE_UINT32:
|
|
vt_: return (void*)x;
|
|
|
|
case VTYPE_STRING:
|
|
case VTYPE_MAP:
|
|
case VTYPE_ARRAY:
|
|
case VTYPE_LIST:
|
|
case VTYPE_SET:
|
|
pt_: return *x;
|
|
}
|
|
}
|
|
|
|
|
|
void libcdsb_vnode_free(vnode_t* x, vtype t) {
|
|
|
|
switch (t) { 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_;
|
|
case VTYPE_LDOUBLE: if (is_permissible(ldbl_t)) goto vt_; else goto pt_;
|
|
|
|
case VTYPE_INT64:
|
|
case VTYPE_UINT64: if (!is_x64) goto pt_;
|
|
|
|
case VTYPE_BOOLEAN:
|
|
case VTYPE_POINTER:
|
|
case VTYPE_INT8:
|
|
case VTYPE_UINT8:
|
|
case VTYPE_INT16:
|
|
case VTYPE_UINT16:
|
|
case VTYPE_INT32:
|
|
case VTYPE_UINT32:
|
|
vt_:
|
|
break;
|
|
|
|
case VTYPE_STRING: string_free(*x); goto pt_;
|
|
case VTYPE_MAP: map_free(*x); goto pt_;
|
|
case VTYPE_ARRAY: array_free(*x); goto pt_;
|
|
case VTYPE_LIST: list_free(*x); goto pt_;
|
|
case VTYPE_SET: vset_free(*x);
|
|
pt_: free(*x);
|
|
break;
|
|
}
|
|
|
|
*x = 0;
|
|
}
|
|
|
|
|
|
/*#####################################################################################################################*/
|
|
|
|
|
|
vnode_t libcdsb_vnode_create_target(vtype xt, const void* v, vtype t) {
|
|
var_t _ = { .ptr = 0 };
|
|
|
|
if (is_integer(xt)) {
|
|
tvalue_assert(t);
|
|
return create_value(xt, v, t);
|
|
} else if (is_float(xt)) {
|
|
tfloat_assert(t);
|
|
return create_float(xt, v, t);
|
|
}
|
|
|
|
type_assert(xt, t);
|
|
|
|
switch (xt) { default: abort();
|
|
case VTYPE_STRING: _.ptr = string_duplicate(v);
|
|
break;
|
|
|
|
case VTYPE_MAP: _.ptr = map_duplicate(v);
|
|
break;
|
|
|
|
case VTYPE_ARRAY: _.ptr = array_duplicate(v);
|
|
break;
|
|
|
|
case VTYPE_LIST: _.ptr = list_duplicate(v);
|
|
break;
|
|
|
|
case VTYPE_SET: _.ptr = vset_duplicate(v);
|
|
break;
|
|
}
|
|
|
|
return _.ptr;
|
|
}
|