diff --git a/fx/include/fx/value.h b/fx/include/fx/value.h new file mode 100644 index 0000000..ef81602 --- /dev/null +++ b/fx/include/fx/value.h @@ -0,0 +1,100 @@ +#ifndef FX_VALUE_H_ +#define FX_VALUE_H_ + +#include +#include +#include + +#define FX_VALUE_BOOL(v) \ + ((fx_value) { \ + .v_type.t_primitive = FX_VALUE_TYPE_BOOL, \ + .v_bool = (v), \ + }) +#define FX_VALUE_INT(v) \ + ((fx_value) { \ + .v_type.t_primitive = FX_VALUE_TYPE_INT, \ + .v_int = (v), \ + }) +#define FX_VALUE_UINT(v) \ + ((fx_value) { \ + .v_type.t_primitive = FX_VALUE_TYPE_UINT, \ + .v_uint = (v), \ + }) +#define FX_VALUE_DOUBLE(v) \ + ((fx_value) { \ + .v_type.t_primitive = FX_VALUE_TYPE_DOUBLE, \ + .v_double = (v), \ + }) +#define FX_VALUE_CSTR(v) \ + ((fx_value) { \ + .v_type.t_primitive = FX_VALUE_TYPE_CSTR, \ + .v_cstr = (v), \ + }) +#define FX_VALUE_POINTER(v) \ + ((fx_value) { \ + .v_type.t_primitive = FX_VALUE_TYPE_POINTER, \ + .v_pointer = (v), \ + }) + +typedef enum fx_value_type { + FX_VALUE_TYPE_NONE = 0, + FX_VALUE_TYPE_BOOL, + FX_VALUE_TYPE_INT, + FX_VALUE_TYPE_UINT, + FX_VALUE_TYPE_DOUBLE, + FX_VALUE_TYPE_CSTR, + FX_VALUE_TYPE_POINTER, + + /* any value greater than this represents an object fx_type */ + __FX_VALUE_TYPE_OBJECT_BOUNDARY = 1024, +} fx_value_type; + +typedef struct fx_value { + union { + fx_value_type t_primitive; + fx_type t_object; + } v_type; + + union { + bool v_bool; + intptr_t v_int; + uintptr_t v_uint; + double v_double; + const char *v_cstr; + void *v_pointer; + fx_object *v_object; + }; +} fx_value; + +FX_API void fx_value_init(fx_value *v, fx_type type); +FX_API void fx_value_init_primitive(fx_value *v, fx_value_type type); + +FX_API void fx_value_unset(fx_value *v); + +FX_API void fx_value_set_bool(fx_value *v, bool b); +FX_API void fx_value_set_int(fx_value *v, intptr_t i); +FX_API void fx_value_set_uint(fx_value *v, uintptr_t u); +FX_API void fx_value_set_double(fx_value *v, double d); +FX_API void fx_value_set_static_cstr(fx_value *v, const char *cstr); +FX_API void fx_value_set_pointer(fx_value *v, void *p); +FX_API void fx_value_set_object(fx_value *v, fx_object *obj); + +FX_API bool fx_value_is_bool(const fx_value *v); +FX_API bool fx_value_is_int(const fx_value *v); +FX_API bool fx_value_is_uint(const fx_value *v); +FX_API bool fx_value_is_double(const fx_value *v); +FX_API bool fx_value_is_string(const fx_value *v); +FX_API bool fx_value_is_pointer(const fx_value *v); +FX_API bool fx_value_is_object(const fx_value *v, fx_type type); + +FX_API bool fx_value_get_bool(const fx_value *v); +FX_API intptr_t fx_value_get_int(const fx_value *v); +FX_API uintptr_t fx_value_get_uint(const fx_value *v); +FX_API double fx_value_get_double(const fx_value *v); +FX_API const char *fx_value_get_cstr(const fx_value *v); +FX_API void *fx_value_get_pointer(fx_value *v); +FX_API const void *fx_value_get_pointer_c(const fx_value *v); +FX_API fx_object *fx_value_get_object(fx_value *v); +FX_API const fx_object *fx_value_get_object_c(const fx_value *v); + +#endif diff --git a/fx/value.c b/fx/value.c new file mode 100644 index 0000000..044b29d --- /dev/null +++ b/fx/value.c @@ -0,0 +1,248 @@ +#include +#include +#include +#include +#include +#include + +void fx_value_init(fx_value *v, fx_type type) +{ +} + +void fx_value_init_primitive(fx_value *v, fx_value_type type) +{ +} + +void fx_value_unset(fx_value *v) +{ +} + +void fx_value_set_bool(fx_value *v, bool b) +{ +} + +void fx_value_set_int(fx_value *v, intptr_t i) +{ +} + +void fx_value_set_uint(fx_value *v, uintptr_t u) +{ +} + +void fx_value_set_double(fx_value *v, double d) +{ +} + +void fx_value_set_static_cstr(fx_value *v, const char *cstr) +{ +} + +void fx_value_set_pointer(fx_value *v, void *p) +{ +} + +void fx_value_set_object(fx_value *v, fx_object *obj) +{ +} + +bool fx_value_is_bool(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_BOOL) { + return true; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_BOOL)) { + return true; + } + } + + return false; +} + +bool fx_value_is_int(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_INT) { + return true; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_INT)) { + return true; + } + } + + return false; +} + +bool fx_value_is_uint(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_UINT) { + return true; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_UINT)) { + return true; + } + } + + return false; +} + +bool fx_value_is_double(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_DOUBLE) { + return true; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_DOUBLE)) { + return true; + } + } + + return false; +} + +bool fx_value_is_string(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_CSTR) { + return true; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_STRING)) { + return true; + } + } + + return false; +} + +bool fx_value_is_pointer(const fx_value *v) +{ + return (v->v_type.t_primitive == FX_VALUE_TYPE_POINTER); +} + +bool fx_value_is_object(const fx_value *v, fx_type type) +{ + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, type)) { + return true; + } + } + + return false; +} + +bool fx_value_get_bool(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_BOOL) { + return v->v_bool; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_BOOL)) { + return fx_bool_get_value(v->v_object); + } + } + + return false; +} + +intptr_t fx_value_get_int(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_INT) { + return v->v_int; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_INT)) { + return fx_int_get_value(v->v_object); + } + } + + return 0; +} + +uintptr_t fx_value_get_uint(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_UINT) { + return v->v_uint; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_UINT)) { + return fx_uint_get_value(v->v_object); + } + } + + return 0; +} + +double fx_value_get_double(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_DOUBLE) { + return v->v_uint; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_DOUBLE)) { + return fx_double_get_value(v->v_object); + } + } + + return 0; +} + +const char *fx_value_get_cstr(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_CSTR) { + return v->v_cstr; + } + + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + if (fx_type_id_compare(v->v_type.t_object, FX_TYPE_STRING)) { + return fx_string_get_cstr(v->v_object); + } + } + + return NULL; +} + +void *fx_value_get_pointer(fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_POINTER) { + return v->v_pointer; + } + + return NULL; +} + +const void *fx_value_get_pointer_c(const fx_value *v) +{ + if (v->v_type.t_primitive == FX_VALUE_TYPE_POINTER) { + return v->v_pointer; + } + + return NULL; +} + +fx_object *fx_value_get_object(fx_value *v) +{ + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + return v->v_object; + } + + return NULL; +} + +const fx_object *fx_value_get_object_c(const fx_value *v) +{ + if (v->v_type.t_primitive > __FX_VALUE_TYPE_OBJECT_BOUNDARY) { + return v->v_object; + } + + return NULL; +}