Update concept of implicit type conversion

This commit is contained in:
Gregory Lirent 2022-06-06 11:20:20 +03:00
parent 8058daf234
commit 4d50d639cc
1 changed files with 49 additions and 12 deletions

View File

@ -3,6 +3,7 @@
#include "__internal/assert.h" #include "__internal/assert.h"
#include "__internal/vnode.h" #include "__internal/vnode.h"
#include "../include/string.h"
/*#####################################################################################################################*/ /*#####################################################################################################################*/
@ -10,6 +11,17 @@
static vnode_t create_value(vtype xt, const void* v, vtype t) { static vnode_t create_value(vtype xt, const void* v, vtype t) {
var_t _; var_t _;
if (t == VTYPE_FLOAT) {
_.u64 = (s64_t)roundf(*(fl_t*)v);
t = VTYPE_INT64;
} else if (t == VTYPE_DOUBLE) {
_.u64 = (s64_t)round (*(dbl_t*)v);
t = VTYPE_INT64;
} else {
_.u64 = (s64_t)roundl(*(ldbl_t*)v);
t = VTYPE_INT64;
}
if (sizeof(void*) == 8) { if (sizeof(void*) == 8) {
if (t == VTYPE_UINT8 || t == VTYPE_INT8 || t == VTYPE_BOOLEAN ) { if (t == VTYPE_UINT8 || t == VTYPE_INT8 || t == VTYPE_BOOLEAN ) {
_.u64 = *(u8_t*)v; _.u64 = *(u8_t*)v;
@ -63,11 +75,27 @@ static vnode_t create_value(vtype xt, const void* v, vtype t) {
static vnode_t create_float(vtype xt, const void* v, vtype t) { static vnode_t create_float(vtype xt, const void* v, vtype t) {
var_t _; var_t _;
if (t == VTYPE_FLOAT) { if (t == VTYPE_UINT8 || t == VTYPE_BOOLEAN ) {
_.ld = *(u8_t*)v;
} else if (t == VTYPE_UINT16) {
_.ld = *(u16_t*)v;
} else if (t == VTYPE_UINT32 || (sizeof(void*) == 4 && t == VTYPE_POINTER)) {
_.ld = *(u32_t*)v;
} else if (t == VTYPE_UINT64 || (sizeof(void*) == 8 && t == VTYPE_POINTER)) {
_.ld = *(u64_t*)v;
} else if (t == VTYPE_INT8) {
_.ld = *(s8_t*)v;
} else if (t == VTYPE_INT16) {
_.ld = *(s16_t*)v;
} else if (t == VTYPE_INT32) {
_.ld = *(s32_t*)v;
} else if (t == VTYPE_INT64) {
_.ld = *(s64_t*)v;
} else if (t == VTYPE_FLOAT) {
_.ld = *(fl_t*)v; _.ld = *(fl_t*)v;
} else if (t == VTYPE_DOUBLE) { } else if (t == VTYPE_DOUBLE) {
_.ld = *(dbl_t*)v; _.ld = *(dbl_t*)v;
} else { // (t == VTYPE_LDOUBLE) } else {
_.ld = *(ldbl_t*)v; _.ld = *(ldbl_t*)v;
} }
@ -81,7 +109,7 @@ static vnode_t create_float(vtype xt, const void* v, vtype t) {
if (!is_permissible(dbl_t)) { if (!is_permissible(dbl_t)) {
_.ptr = memndup(&_.d, sizeof(_.d)); _.ptr = memndup(&_.d, sizeof(_.d));
} }
} else { // (xt == VTYPE_LDOUBLE) } else {
if (!is_permissible(ldbl_t)) { if (!is_permissible(ldbl_t)) {
_.ptr = memndup(&_.ld, sizeof(_.ld)); _.ptr = memndup(&_.ld, sizeof(_.ld));
} }
@ -135,7 +163,9 @@ vnode_t libcdsb_vnode_create(const void* v, vtype t) {
case VTYPE_POINTER: _.ptr = *(void**)v; case VTYPE_POINTER: _.ptr = *(void**)v;
break; break;
case VTYPE_STRING: _.ptr = string_duplicate(v); case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) {
_.ptr = strdup(*(char**)v);
} else _.ptr = string_duplicate(v);
break; break;
case VTYPE_MAP: _.ptr = map_duplicate(v); case VTYPE_MAP: _.ptr = map_duplicate(v);
@ -178,7 +208,7 @@ void* libcdsb_vnode_peek(const vnode_t* x, vtype t) {
case VTYPE_UINT32: case VTYPE_UINT32:
vt_: return (void*)x; vt_: return (void*)x;
case VTYPE_STRING: case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) goto vt_;
case VTYPE_MAP: case VTYPE_MAP:
case VTYPE_ARRAY: case VTYPE_ARRAY:
case VTYPE_LIST: case VTYPE_LIST:
@ -210,7 +240,10 @@ void libcdsb_vnode_free(vnode_t* x, vtype t) {
vt_: vt_:
break; break;
case VTYPE_STRING: string_free(*x); goto pt_; case VTYPE_STRING: if (sizeof(str_t) > sizeof(void*)) {
string_free(*x);
}
goto pt_;
case VTYPE_MAP: map_free(*x); goto pt_; case VTYPE_MAP: map_free(*x); goto pt_;
case VTYPE_ARRAY: array_free(*x); goto pt_; case VTYPE_ARRAY: array_free(*x); goto pt_;
case VTYPE_LIST: list_free(*x); goto pt_; case VTYPE_LIST: list_free(*x); goto pt_;
@ -229,18 +262,22 @@ void libcdsb_vnode_free(vnode_t* x, vtype t) {
vnode_t libcdsb_vnode_create_target(vtype xt, const void* v, vtype t) { vnode_t libcdsb_vnode_create_target(vtype xt, const void* v, vtype t) {
var_t _ = { .ptr = 0 }; var_t _ = { .ptr = 0 };
if (is_integer(xt)) { if (xt <= VTYPE_LDOUBLE) {
tvalue_assert(t); if (t >= VTYPE_STRING) t = VTYPE_POINTER;
if (xt <= VTYPE_INT64)
return create_value(xt, v, t);
return create_value(xt, v, t); return create_value(xt, v, t);
} else if (is_float(xt)) { } else if (t == VTYPE_POINTER && (t = xt) > VTYPE_STRING) {
tfloat_assert(t); v = *(void**)v;
return create_float(xt, v, t);
} }
type_assert(xt, t); type_assert(xt, t);
switch (xt) { default: abort(); switch (xt) { default: abort();
case VTYPE_STRING: _.ptr = string_duplicate(v); case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) {
_.ptr = strdup(*(char**)v);
} else _.ptr = string_duplicate(v);
break; break;
case VTYPE_MAP: _.ptr = map_duplicate(v); case VTYPE_MAP: _.ptr = map_duplicate(v);