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/vnode.h"
#include "../include/string.h"
/*#####################################################################################################################*/
@ -10,6 +11,17 @@
static vnode_t create_value(vtype xt, const void* v, vtype 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 (t == VTYPE_UINT8 || t == VTYPE_INT8 || t == VTYPE_BOOLEAN ) {
_.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) {
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;
} else if (t == VTYPE_DOUBLE) {
_.ld = *(dbl_t*)v;
} else { // (t == VTYPE_LDOUBLE)
} else {
_.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)) {
_.ptr = memndup(&_.d, sizeof(_.d));
}
} else { // (xt == VTYPE_LDOUBLE)
} else {
if (!is_permissible(ldbl_t)) {
_.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;
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;
case VTYPE_MAP: _.ptr = map_duplicate(v);
@ -178,7 +208,7 @@ void* libcdsb_vnode_peek(const vnode_t* x, vtype t) {
case VTYPE_UINT32:
vt_: return (void*)x;
case VTYPE_STRING:
case VTYPE_STRING: if (sizeof(str_t) == sizeof(void*)) goto vt_;
case VTYPE_MAP:
case VTYPE_ARRAY:
case VTYPE_LIST:
@ -210,7 +240,10 @@ void libcdsb_vnode_free(vnode_t* x, vtype t) {
vt_:
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_ARRAY: array_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) {
var_t _ = { .ptr = 0 };
if (is_integer(xt)) {
tvalue_assert(t);
if (xt <= VTYPE_LDOUBLE) {
if (t >= VTYPE_STRING) t = VTYPE_POINTER;
if (xt <= VTYPE_INT64)
return create_value(xt, v, t);
return create_value(xt, v, t);
} else if (is_float(xt)) {
tfloat_assert(t);
return create_float(xt, v, t);
} else if (t == VTYPE_POINTER && (t = xt) > VTYPE_STRING) {
v = *(void**)v;
}
type_assert(xt, t);
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;
case VTYPE_MAP: _.ptr = map_duplicate(v);