Compare commits

...

12 Commits

67 changed files with 2341 additions and 2811 deletions
+7 -3
View File
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(fx C) project(fx C ASM)
include (TestBigEndian) include (TestBigEndian)
@@ -9,6 +9,8 @@ set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(fx_source_root ${CMAKE_CURRENT_SOURCE_DIR})
set(fx_build_root ${CMAKE_CURRENT_BINARY_DIR})
file(GLOB _all_assemblies assemblies/* file(GLOB _all_assemblies assemblies/*
LIST_DIRECTORIES TRUE) LIST_DIRECTORIES TRUE)
@@ -33,8 +35,10 @@ message(STATUS "Floating point support: ${fx_enable_floating_point}")
set(fx_system_name ${CMAKE_SYSTEM_NAME}) set(fx_system_name ${CMAKE_SYSTEM_NAME})
string(TOLOWER ${fx_system_name} fx_system_name) string(TOLOWER ${fx_system_name} fx_system_name)
set(fx_system_arch ${CMAKE_SYSTEM_PROCESSOR})
string(TOLOWER ${fx_system_arch} fx_system_arch)
message(STATUS "System name: ${fx_system_name}") message(STATUS "Target system: ${fx_system_name}-${fx_system_arch}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
@@ -46,4 +50,4 @@ foreach (assembly ${fx_assemblies})
add_subdirectory(assemblies/${assembly}) add_subdirectory(assemblies/${assembly})
endforeach (assembly) endforeach (assembly)
add_executable(dynamic-test test/dynamic-test.c) add_subdirectory(test)
+10 -3
View File
@@ -20,7 +20,7 @@ function(add_fx_assembly)
set(assembly_sources ${CMAKE_CURRENT_SOURCE_DIR}/assembly.c) set(assembly_sources ${CMAKE_CURRENT_SOURCE_DIR}/assembly.c)
foreach (dir ${arg_NAMESPACES}) foreach (dir ${arg_NAMESPACES})
add_subdirectory(../../${dir} ../../namespaces/${dir}) add_subdirectory(${fx_source_root}/${dir} ${fx_build_root}/namespaces/${dir})
set(assembly_sources ${assembly_sources} ${namespace_sources}) set(assembly_sources ${assembly_sources} ${namespace_sources})
set(assembly_include_paths ${assembly_include_paths} ${namespace_include_paths}) set(assembly_include_paths ${assembly_include_paths} ${namespace_include_paths})
endforeach (dir) endforeach (dir)
@@ -80,7 +80,10 @@ macro(export_fx_namespace_details ns_name)
file(GLOB sys_sources file(GLOB sys_sources
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/*.c
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/*.h) ${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/*.h
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/${fx_system_arch}/*.c
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/${fx_system_arch}/*.h
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/${fx_system_arch}/*.S)
file(GLOB headers include/${namespace_path}/*.h) file(GLOB headers include/${namespace_path}/*.h)
set(namespace_sources set(namespace_sources
${namespace_sources} ${namespace_sources}
@@ -89,8 +92,12 @@ macro(export_fx_namespace_details ns_name)
${sys_sources} ${sys_sources}
${headers} ${headers}
PARENT_SCOPE) PARENT_SCOPE)
set(internal_include_dirs
${internal_include_dirs}
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/include
${CMAKE_CURRENT_SOURCE_DIR}/sys/${fx_system_name}/${fx_system_arch}/include
PARENT_SCOPE)
set(internal_libs ${internal_libs} PARENT_SCOPE) set(internal_libs ${internal_libs} PARENT_SCOPE)
set(internal_include_dirs ${internal_include_dirs} PARENT_SCOPE)
set(internal_defines ${internal_defines} PARENT_SCOPE) set(internal_defines ${internal_defines} PARENT_SCOPE)
endmacro(export_fx_namespace_details) endmacro(export_fx_namespace_details)
+3 -17
View File
@@ -1,4 +1,5 @@
#include <fx/collections/dict.h> #include <fx/collections/dict.h>
#include <fx/hash.h>
#include <fx/status.h> #include <fx/status.h>
#include <fx/stream.h> #include <fx/stream.h>
#include <fx/string.h> #include <fx/string.h>
@@ -47,21 +48,6 @@ static FX_BST_DEFINE_SIMPLE_INSERT(
bk_hash, bk_hash,
put_bucket); put_bucket);
uint64_t fx_cstr_hash(const char *s)
{
#define FNV1_OFFSET_BASIS 0xcbf29ce484222325
#define FNV1_PRIME 0x100000001b3
uint64_t hash = FNV1_OFFSET_BASIS;
size_t i = 0;
for (i = 0; s[i]; i++) {
hash ^= s[i];
hash *= FNV1_PRIME;
}
return hash;
}
/*** PRIVATE FUNCTIONS ********************************************************/ /*** PRIVATE FUNCTIONS ********************************************************/
static struct fx_dict_bucket *create_bucket(void) static struct fx_dict_bucket *create_bucket(void)
@@ -91,7 +77,7 @@ static fx_status dict_put(
const char *key, const char *key,
fx_object *value) fx_object *value)
{ {
uint64_t hash = fx_cstr_hash(key); uint64_t hash = fx_hash_cstr(key);
struct fx_dict_bucket *bucket = get_bucket(&dict->d_buckets, hash); struct fx_dict_bucket *bucket = get_bucket(&dict->d_buckets, hash);
if (!bucket) { if (!bucket) {
bucket = create_bucket(); bucket = create_bucket();
@@ -148,7 +134,7 @@ static fx_status dict_put_sk(
static fx_object *dict_at(const struct fx_dict_p *dict, const char *key) static fx_object *dict_at(const struct fx_dict_p *dict, const char *key)
{ {
uint64_t hash = fx_cstr_hash(key); uint64_t hash = fx_hash_cstr(key);
struct fx_dict_bucket *bucket = get_bucket(&dict->d_buckets, hash); struct fx_dict_bucket *bucket = get_bucket(&dict->d_buckets, hash);
if (!bucket) { if (!bucket) {
return NULL; return NULL;
@@ -1,256 +0,0 @@
#ifndef FX_DS_NUMBER_H
#define FX_DS_NUMBER_H
#include <fx/macros.h>
#include <stdbool.h>
FX_DECLS_BEGIN;
#define FX_INT8(v) (fx_number_create_int8(v))
#define FX_INT16(v) (fx_number_create_int16(v))
#define FX_INT32(v) (fx_number_create_int32(v))
#define FX_INT64(v) (fx_number_create_int64(v))
#define FX_FLOAT32(v) (fx_number_create_float32(v))
#define FX_FLOAT64(v) (fx_number_create_float64(v))
#define FX_CHAR(v) (fx_number_create_char(v))
#define FX_SHORT(v) (fx_number_create_short(v))
#define FX_INT(v) (fx_number_create_int(v))
#define FX_LONG(v) (fx_number_create_long(v))
#define FX_LONGLONG(v) (fx_number_create_longlong(v))
#define FX_FLOAT(v) (fx_number_create_float(v))
#define FX_DOUBLE(v) (fx_number_create_double(v))
#define FX_SIZE_T(v) (fx_number_create_size_t(v))
#define FX_RV_INT8(v) FX_RV(fx_number_create_int8(v))
#define FX_RV_INT16(v) FX_RV(fx_number_create_int16(v))
#define FX_RV_INT32(v) FX_RV(fx_number_create_int32(v))
#define FX_RV_INT64(v) FX_RV(fx_number_create_int64(v))
#define FX_RV_FLOAT32(v) FX_RV(fx_number_create_float32(v))
#define FX_RV_FLOAT64(v) FX_RV(fx_number_create_float64(v))
#define FX_RV_CHAR(v) FX_RV(fx_number_create_char(v))
#define FX_RV_SHORT(v) FX_RV(fx_number_create_short(v))
#define FX_RV_INT(v) FX_RV(fx_number_create_int(v))
#define FX_RV_LONG(v) FX_RV(fx_number_create_long(v))
#define FX_RV_LONGLONG(v) FX_RV(fx_number_create_longlong(v))
#define FX_RV_FLOAT(v) FX_RV(fx_number_create_float(v))
#define FX_RV_DOUBLE(v) FX_RV(fx_number_create_double(v))
#define FX_RV_SIZE_T(v) FX_RV(fx_number_create_size_t(v))
#define FX_NUMBER_IVAL(p) (fx_number_get_size_t(p))
#define FX_NUMBER_FVAL(p) (fx_number_get_double(p))
#define FX_TYPE_NUMBER (fx_number_get_type())
FX_DECLARE_TYPE(fx_number);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_number)
FX_TYPE_CLASS_DECLARATION_END(fx_number)
typedef enum fx_number_type {
FX_NUMBER_INT8,
FX_NUMBER_INT16,
FX_NUMBER_INT32,
FX_NUMBER_INT64,
FX_NUMBER_FLOAT32,
FX_NUMBER_FLOAT64,
FX_NUMBER_CHAR,
FX_NUMBER_SHORT,
FX_NUMBER_INT,
FX_NUMBER_LONG,
FX_NUMBER_LONGLONG,
FX_NUMBER_FLOAT,
FX_NUMBER_DOUBLE,
FX_NUMBER_SIZE_T,
FX_NUMBER_HANDLE,
FX_NUMBER_TYPE_COUNT,
FX_NUMBER_BYTE = FX_NUMBER_INT8,
FX_NUMBER_WORD = FX_NUMBER_INT16,
FX_NUMBER_DWORD = FX_NUMBER_INT32,
FX_NUMBER_QWORD = FX_NUMBER_INT64,
} fx_number_type;
FX_API fx_type fx_number_get_type(void);
FX_API fx_number *fx_number_create(fx_number_type type, void *value_ptr);
static inline fx_number *fx_number_create_int8(int8_t value)
{
return fx_number_create(FX_NUMBER_INT8, &value);
}
static inline fx_number *fx_number_create_int16(int16_t value)
{
return fx_number_create(FX_NUMBER_INT16, &value);
}
static inline fx_number *fx_number_create_int32(int32_t value)
{
return fx_number_create(FX_NUMBER_INT32, &value);
}
static inline fx_number *fx_number_create_int64(int64_t value)
{
return fx_number_create(FX_NUMBER_INT64, &value);
}
static inline fx_number *fx_number_create_float32(float value)
{
return fx_number_create(FX_NUMBER_FLOAT32, &value);
}
static inline fx_number *fx_number_create_float64(double value)
{
return fx_number_create(FX_NUMBER_FLOAT64, &value);
}
static inline fx_number *fx_number_create_char(char value)
{
return fx_number_create(FX_NUMBER_CHAR, &value);
}
static inline fx_number *fx_number_create_short(short value)
{
return fx_number_create(FX_NUMBER_SHORT, &value);
}
static inline fx_number *fx_number_create_int(int value)
{
return fx_number_create(FX_NUMBER_INT, &value);
}
static inline fx_number *fx_number_create_long(long value)
{
return fx_number_create(FX_NUMBER_LONG, &value);
}
static inline fx_number *fx_number_create_longlong(long long value)
{
return fx_number_create(FX_NUMBER_LONGLONG, &value);
}
static inline fx_number *fx_number_create_float(float value)
{
return fx_number_create(FX_NUMBER_FLOAT, &value);
}
static inline fx_number *fx_number_create_double(double value)
{
return fx_number_create(FX_NUMBER_DOUBLE, &value);
}
static inline fx_number *fx_number_create_size_t(size_t value)
{
return fx_number_create(FX_NUMBER_SIZE_T, &value);
}
FX_API fx_number_type fx_number_get_number_type(const fx_number *number);
FX_API int fx_number_get_value(
const fx_number *number,
fx_number_type type,
void *value_ptr);
static inline int8_t fx_number_get_int8(const fx_number *number)
{
int8_t v;
fx_number_get_value(number, FX_NUMBER_INT8, &v);
return v;
}
static inline int16_t fx_number_get_int16(const fx_number *number)
{
int16_t v;
fx_number_get_value(number, FX_NUMBER_INT16, &v);
return v;
}
static inline int32_t fx_number_get_int32(const fx_number *number)
{
int32_t v;
fx_number_get_value(number, FX_NUMBER_INT32, &v);
return v;
}
static inline int64_t fx_number_get_int64(const fx_number *number)
{
int64_t v;
fx_number_get_value(number, FX_NUMBER_INT64, &v);
return v;
}
static inline float fx_number_get_float32(const fx_number *number)
{
float v;
fx_number_get_value(number, FX_NUMBER_FLOAT32, &v);
return v;
}
static inline double fx_number_get_float64(const fx_number *number)
{
double v;
fx_number_get_value(number, FX_NUMBER_FLOAT64, &v);
return v;
}
static inline char fx_number_get_char(const fx_number *number)
{
char v;
fx_number_get_value(number, FX_NUMBER_CHAR, &v);
return v;
}
static inline short fx_number_get_short(const fx_number *number)
{
short v;
fx_number_get_value(number, FX_NUMBER_SHORT, &v);
return v;
}
static inline int fx_number_get_int(const fx_number *number)
{
int v;
fx_number_get_value(number, FX_NUMBER_INT, &v);
return v;
}
static inline long fx_number_get_long(const fx_number *number)
{
long v;
fx_number_get_value(number, FX_NUMBER_LONG, &v);
return v;
}
static inline long long fx_number_get_longlong(const fx_number *number)
{
long long v;
fx_number_get_value(number, FX_NUMBER_LONGLONG, &v);
return v;
}
static inline float fx_number_get_float(const fx_number *number)
{
float v;
fx_number_get_value(number, FX_NUMBER_FLOAT, &v);
return v;
}
static inline double fx_number_get_double(const fx_number *number)
{
double v;
fx_number_get_value(number, FX_NUMBER_DOUBLE, &v);
return v;
}
static inline size_t fx_number_get_size_t(const fx_number *number)
{
size_t v;
fx_number_get_value(number, FX_NUMBER_SIZE_T, &v);
return v;
}
FX_API bool fx_number_is_integer(const fx_number *number);
FX_API bool fx_number_is_float(const fx_number *number);
FX_API bool fx_number_is_inf(const fx_number *number);
FX_API bool fx_number_is_inf_positive(const fx_number *number);
FX_API bool fx_number_is_inf_negative(const fx_number *number);
FX_API bool fx_number_is_nan(const fx_number *number);
FX_API bool fx_number_is_nan_positive(const fx_number *number);
FX_API bool fx_number_is_nan_negative(const fx_number *number);
FX_API void fx_number_set_inf_positive(fx_number *number, bool v);
FX_API void fx_number_set_inf_negative(fx_number *number, bool v);
FX_API void fx_number_set_nan_positive(fx_number *number, bool v);
FX_API void fx_number_set_nan_negative(fx_number *number, bool v);
FX_API size_t fx_number_data_size(const fx_number *number);
FX_DECLS_END;
#endif
File diff suppressed because it is too large Load Diff
+86
View File
@@ -0,0 +1,86 @@
#include <fx/macros.h>
#include <fx/reflection/function.h>
#include <fx/string.h>
#include <fx/value.h>
#include <platform/callvm.h>
struct fx_function_context_p {
struct callvm ctx_vm;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static fx_status function_context_reset(
const struct fx_function_context_p *func)
{
return FX_SUCCESS;
}
static fx_status function_context_push_arg(
const struct fx_function_context_p *func,
const fx_value *arg)
{
return FX_SUCCESS;
}
/*** PUBLIC FUNCTIONS *********************************************************/
FX_API fx_function *fx_function_context_create(void)
{
fx_function_context *ctx
= fx_object_create(FX_REFLECTION_TYPE_FUNCTION_CONTEXT);
if (!ctx) {
return NULL;
}
struct fx_function_context_p *p = fx_object_get_private(
ctx,
FX_REFLECTION_TYPE_FUNCTION_CONTEXT);
return ctx;
}
FX_API void fx_function_context_reset(fx_function_context *ctx)
{
FX_CLASS_DISPATCH_STATIC_V0(
FX_REFLECTION_TYPE_FUNCTION_CONTEXT,
function_context_reset,
ctx);
}
FX_API void fx_function_context_push_arg(
fx_function_context *ctx,
const fx_value *value)
{
FX_CLASS_DISPATCH_STATIC_V(
FX_REFLECTION_TYPE_FUNCTION_CONTEXT,
function_context_push_arg,
ctx,
value);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void function_context_init(fx_object *obj, void *priv)
{
}
static void function_context_fini(fx_object *obj, void *priv)
{
}
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_function_context)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_function_context)
FX_TYPE_DEFINITION_BEGIN(fx_function_context)
FX_TYPE_ID(0x97d98a1a, 0x6312, 0x409e, 0xb47d, 0xc5d80daf9e50);
FX_TYPE_CLASS(fx_function_context_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_function_context_p);
FX_TYPE_INSTANCE_INIT(function_context_init);
FX_TYPE_INSTANCE_FINI(function_context_fini);
FX_TYPE_DEFINITION_END(fx_function_context)
+140
View File
@@ -0,0 +1,140 @@
#include <fx/macros.h>
#include <fx/reflection/function.h>
#include <fx/string.h>
#include <fx/value.h>
#include <platform/callvm.h>
struct fx_function_p {
char *func_name;
fx_function_flags func_flags;
fx_function_impl func_impl;
fx_value_type func_return_type;
fx_value_type *func_arg_types;
/* number of explicit arguments that the function takes.
* if the FX_FUNCTION_F_VARARG flag is set, the function supports a
* variable number of arguments, which may be handled differently by the
* ABI */
size_t func_nr_args;
};
/*** PRIVATE FUNCTIONS ********************************************************/
extern intptr_t fx_function_invoke_i(
fx_function_impl impl,
const fx_value *args,
size_t nr_args);
static fx_status function_invoke(
const struct fx_function_p *func,
const fx_value *args,
size_t nr_args,
fx_value *return_value)
{
if (nr_args < func->func_nr_args) {
return FX_ERR_INVALID_ARGUMENT;
}
if (nr_args > func->func_nr_args
&& !(func->func_flags & FX_FUNCTION_F_VARARG)) {
return FX_ERR_INVALID_ARGUMENT;
}
size_t nr_fixed_args = func->func_nr_args;
size_t nr_var_args = nr_args - nr_fixed_args;
struct callvm vm = {0};
callvm_reset(&vm, nr_fixed_args);
for (size_t i = 0; i < nr_args; i++) {
const fx_value *arg = &args[i];
callvm_push(&vm, arg);
}
*return_value
= callvm_invoke(&vm, func->func_impl, func->func_return_type);
callvm_reset(&vm, 0);
return FX_SUCCESS;
}
/*** PUBLIC FUNCTIONS *********************************************************/
FX_API fx_function *fx_function_create(
const char *name,
fx_function_flags flags,
fx_function_impl impl,
const fx_value_type *args,
size_t nr_args,
fx_value_type return_type)
{
fx_function *func = fx_object_create(FX_REFLECTION_TYPE_FUNCTION);
if (!func) {
return NULL;
}
struct fx_function_p *p
= fx_object_get_private(func, FX_REFLECTION_TYPE_FUNCTION);
p->func_name = fx_strdup(name);
p->func_flags = flags;
p->func_impl = impl;
p->func_nr_args = nr_args;
p->func_return_type = return_type;
p->func_arg_types = calloc(nr_args, sizeof *args);
for (size_t i = 0; i < nr_args; i++) {
p->func_arg_types[i] = args[i];
}
return func;
}
FX_API fx_status fx_function_invoke(
const fx_function *func,
const fx_value *args,
size_t nr_args,
fx_value *return_value)
{
FX_CLASS_DISPATCH_STATIC(
FX_REFLECTION_TYPE_FUNCTION,
function_invoke,
func,
args,
nr_args,
return_value);
}
/*** VIRTUAL FUNCTIONS
* ********************************************************/
static void function_init(fx_object *obj, void *priv)
{
}
static void function_fini(fx_object *obj, void *priv)
{
struct fx_function_p *p = priv;
if (p->func_name) {
free(p->func_name);
}
if (p->func_arg_types) {
free(p->func_arg_types);
}
}
/*** CLASS DEFINITION
* *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_function)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = NULL;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_function)
FX_TYPE_DEFINITION_BEGIN(fx_function)
FX_TYPE_ID(0x09e40174, 0x7443, 0x486e, 0xad21, 0xcc9374762e7e);
FX_TYPE_CLASS(fx_function_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_function_p);
FX_TYPE_INSTANCE_INIT(function_init);
FX_TYPE_INSTANCE_FINI(function_fini);
FX_TYPE_DEFINITION_END(fx_function)
@@ -0,0 +1,83 @@
#ifndef FX_REFLECTION_FUNCTION_H_
#define FX_REFLECTION_FUNCTION_H_
#include <fx/macros.h>
#include <fx/status.h>
#include <fx/value.h>
FX_DECLS_BEGIN;
#define FX_REFLECTION_TYPE_FUNCTION (fx_function_get_type())
#define FX_REFLECTION_TYPE_FUNCTION_CONTEXT (fx_function_context_get_type())
typedef enum fx_function_flags {
FX_FUNCTION_F_NONE = 0x00u,
FX_FUNCTION_F_STATIC = 0x01u,
FX_FUNCTION_F_VIRTUAL = 0x02u,
FX_FUNCTION_F_VARARG = 0x04u,
} fx_function_flags;
#if 0
#define FX_FUNCTION_VALUE(type) \
((fx_function_value) { \
.v_type = FX_FUNCTION_V_PRIMITIVE, \
.v_primitive = (type), \
})
typedef enum fx_function_value_type {
FX_FUNCTION_V_NONE = 0,
FX_FUNCTION_V_PRIMITIVE,
FX_FUNCTION_V_OBJECT,
} fx_function_value_type;
typedef struct fx_function_value {
fx_function_value_type v_type;
union {
fx_value_type v_primitive;
fx_type v_object;
};
} fx_function_value;
#endif
typedef void (*fx_function_impl)();
FX_DECLARE_TYPE(fx_function);
FX_DECLARE_TYPE(fx_function_context);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_function)
FX_TYPE_CLASS_DECLARATION_END(fx_function)
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_function_context)
FX_TYPE_CLASS_DECLARATION_END(fx_function_context)
FX_API fx_type fx_function_get_type();
FX_API fx_type fx_function_context_get_type();
FX_API fx_function_context *fx_function_context_create(void);
FX_API void fx_function_context_reset(fx_function_context *ctx);
FX_API void fx_function_context_push_arg(
fx_function_context *ctx,
const fx_value *value);
FX_API fx_function *fx_function_create(
const char *name,
fx_function_flags flags,
fx_function_impl impl,
const fx_value_type *args,
size_t nr_args,
fx_value_type return_type);
FX_API fx_status
fx_function_bind(const fx_function *func, const fx_value *args, size_t nr_args);
FX_API fx_status fx_function_invoke(
const fx_function *func,
const fx_value *args,
size_t nr_args,
fx_value *return_value);
FX_API fx_status fx_function_invoke_with_context(
const fx_function *func,
const fx_function_context *ctx,
fx_value *return_value);
FX_DECLS_END;
#endif
@@ -0,0 +1,4 @@
#ifndef FX_REFLECTION_PROPERTY_H_
#define FX_REFLECTION_PROPERTY_H_
#endif
View File
+110
View File
@@ -0,0 +1,110 @@
#include <platform/callvm.h>
#include <stdlib.h>
#if 0
switch (arg->v_type.t_primitive) {
case FX_VALUE_TYPE_DOUBLE:
break;
default:
callvm_push_int(&vm, (uintptr_t)arg->v_pointer);
break;
}
#endif
void callvm_reset(struct callvm *vm, unsigned int max_fixed_args)
{
vm->vm_arg_int_count = 0;
vm->vm_arg_double_count = 0;
vm->vm_arg_fixed = max_fixed_args;
vm->vm_arg_excess_count = 0;
}
static void expand_excess(struct callvm *vm)
{
size_t new_capacity = vm->vm_arg_excess_max * 2;
if (!new_capacity) {
new_capacity = 4;
}
void *buf = realloc(
vm->vm_arg_excess,
new_capacity * sizeof *vm->vm_arg_excess);
if (!buf) {
return;
}
vm->vm_arg_excess = buf;
vm->vm_arg_excess_max = new_capacity;
}
static void push_excess(struct callvm *vm, uintptr_t value)
{
if (vm->vm_arg_excess_count + 1 > vm->vm_arg_excess_max) {
expand_excess(vm);
}
vm->vm_arg_excess[vm->vm_arg_excess_count++] = value;
vm->vm_arg_count++;
}
static void push_int(struct callvm *vm, uintptr_t value)
{
if (vm->vm_arg_int_count >= MAX_INT_ARGS) {
push_excess(vm, value);
return;
}
vm->vm_arg_int[vm->vm_arg_int_count++] = value;
vm->vm_arg_count++;
}
static void push_double(struct callvm *vm, double value)
{
if (vm->vm_arg_double_count >= MAX_DOUBLE_ARGS) {
push_excess(vm, *(uintptr_t *)&value);
return;
}
vm->vm_arg_double[vm->vm_arg_double_count++] = value;
vm->vm_arg_count++;
}
void callvm_push(struct callvm *vm, const fx_value *value)
{
if (vm->vm_arg_count >= vm->vm_arg_fixed) {
push_excess(vm, (uintptr_t)value->v_pointer);
return;
}
switch (value->v_type.t_primitive) {
case FX_VALUE_TYPE_DOUBLE:
push_double(vm, value->v_double);
break;
default:
push_int(vm, (uintptr_t)value->v_pointer);
break;
}
}
extern uintptr_t callvm_invoke_i(fx_function_impl impl, struct callvm *vm);
extern double callvm_invoke_d(fx_function_impl impl, struct callvm *vm);
extern void callvm_invoke_v(fx_function_impl impl, struct callvm *vm);
fx_value callvm_invoke(
struct callvm *vm,
fx_function_impl impl,
fx_value_type return_type)
{
switch (return_type) {
case FX_VALUE_TYPE_NONE:
callvm_invoke_v(impl, vm);
break;
case FX_VALUE_TYPE_DOUBLE:
return FX_VALUE_DOUBLE(callvm_invoke_d(impl, vm));
default:
return FX_VALUE_INT(callvm_invoke_i(impl, vm));
}
return FX_VALUE_EMPTY;
}
@@ -0,0 +1,178 @@
.global _callvm_invoke_i
.align 4
# x0 = (function ptr) impl
# x1 = (struct callvm) context
_callvm_invoke_i:
# save the stack frame and link pointer
stp x29, x30, [sp, #-16]!
mov x29, sp
# store function pointer for later
mov x16, x0
mov x15, x1
# First, set up the fixed arguments
# x8 = fixed arg count
ldr x8, [x15, #0]
# arg[0]
cmp x8, #0
ble .iv.idone
ldr x0, [x15, #48]
# arg[1]
cmp x8, #1
ble .iv.idone
ldr x1, [x15, #56]
# arg[2]
cmp x8, #2
ble .iv.idone
ldr x2, [x15, #64]
# arg[3]
cmp x8, #3
ble .iv.idone
ldr x3, [x15, #72]
# arg[4]
cmp x8, #4
ble .iv.idone
ldr x4, [x15, #80]
# arg[5]
cmp x8, #5
ble .iv.idone
ldr x5, [x15, #88]
# arg[6]
cmp x8, #6
ble .iv.idone
ldr x6, [x15, #96]
# arg[7]
cmp x8, #7
ble .iv.idone
ldr x7, [x15, #104]
.iv.idone:
# Next, set up the fixed double arguments
# x8 = fixed double arg count
ldr x8, [x15, #8]
# arg[0]
cmp x8, #0
ble .iv.vdone
ldr d0, [x15, #112]
# arg[1]
cmp x8, #1
ble .iv.vdone
ldr d1, [x15, #120]
# arg[2]
cmp x8, #2
ble .iv.vdone
ldr d2, [x15, #128]
# arg[3]
cmp x8, #3
ble .iv.vdone
ldr d3, [x15, #136]
# arg[4]
cmp x8, #4
ble .iv.vdone
ldr d4, [x15, #144]
# arg[5]
cmp x8, #5
ble .iv.vdone
ldr d5, [x15, #152]
# arg[6]
cmp x8, #6
ble .iv.vdone
ldr d6, [x15, #160]
# arg[7]
cmp x8, #7
ble .iv.vdone
ldr d7, [x15, #168]
.iv.vdone:
# Finally, set up the variable arguments
# x8 = excess arg count
ldr x8, [x15, #32]
# calculate the amount of stack space needed for the varargs
mov x10, #0x10
mul x12, x8, x10
# x19 is caller-saved, and we'll need x12 later
str x19, [sp, #-16]!
mov x19, x12
# allocate the stack space
sub sp, sp, x19
mov x13, sp
# get a pointer to the end of the stack vararg buffer
#mov x14, #8
#mul x14, x14, x11
#add x13, x13, x14
# x8: number of var args (decrements with every iteration)
# x9: arg src buffer (increments with every iteration)
# x13: var arg dest pointer (starts at the end, decrements with every iteration)
ldr x9, [x15, #176]
.iv.loop:
cmp x8, #0
beq .iv.loop.end
# read the arg value from the src pointer
ldr x14, [x9]
# write it to the stack, and increment the dest pointer
str x14, [x13]
add x13, x13, #8
# increment the src pointer, decrement the arg count
sub x8, x8, #1
add x9, x9, #8
b .iv.loop
.iv.loop.end:
# call the function implementation
blr x16
# de-allocate the stack varargs buffer (the size is now stored in x19)
add sp, sp, x19
# restore the saved value of x19,
ldr x19, [sp], #16
# restore the saved stack frame and link pointer
ldp x29,x30, [sp], #16
ret
.global _callvm_invoke_d
.align 4
# x0 = (function ptr) impl
# x1 = (struct callvm) context
_callvm_invoke_d:
b _callvm_invoke_i
.global _callvm_invoke_v
.align 4
# x0 = (function ptr) impl
# x1 = (struct callvm) context
_callvm_invoke_v:
b _callvm_invoke_i
@@ -0,0 +1,221 @@
.global _fx_function_invoke_i
.align 4
# x0 = (function ptr) impl
# x1 = (fx_value[]) args
# x2 = (size_t) nr args
_fx_function_invoke_i:
# save the stack frame and link pointer
stp x29, x30, [sp, #-16]!
# store function pointer for later
str x0, [sp, #-16]!
# move arg array of of x1 and x2, so that they can be initialised for
# the function call
mov x8, x1
mov x9, x2
# arg[0]
cmp x9, #0
ble .i.done
ldr x0, [x8, #8]
# arg[1]
cmp x9, #1
ble .i.done
ldr x1, [x8, #24]
# arg[2]
cmp x9, #2
ble .i.done
ldr x2, [x8, #40]
# arg[3]
cmp x9, #3
ble .i.done
ldr x3, [x8, #56]
# arg[4]
cmp x9, #4
ble .i.done
ldr x4, [x8, #72]
# arg[5]
cmp x9, #5
ble .i.done
ldr x5, [x8, #88]
# arg[6]
cmp x9, #6
ble .i.done
ldr x6, [x8, #104]
# arg[7]
cmp x9, #7
ble .i.done
ldr x7, [x8, #120]
.i.done:
ldr x8, [sp], #16
blr x8
# restore the saved stack frame and link pointer
ldp x29,x30, [sp], #16
ret
.global _fx_function_invoke_d
.align 4
_fx_function_invoke_d:
mov x0, 888
ret
.global _fx_function_invoke_v
.align 4
_fx_function_invoke_v:
ret
.global _fx_function_invoke_iv
.align 4
# x0 = (function ptr) impl
# x1 = (fx_value[]) args
# x2 = (size_t) nr fixed args
# x3 = (size_t) nr var args
_fx_function_invoke_iv:
# save the stack frame and link pointer
stp x29, x30, [sp, #-16]!
mov x29, sp
# store function pointer for later
mov x15, x0
# move arg array of of x1,x2,x3, so that they can be initialised for
# the function call
mov x9, x1
mov x10, x2
mov x11, x3
# First, set up the fixed arguments
# arg[0]
cmp x10, #0
ble .iv.done
ldr x0, [x9, #8]
add x9, x9, #16
# arg[1]
cmp x10, #1
ble .iv.done
ldr x1, [x9, #8]
add x9, x9, #16
# arg[2]
cmp x10, #2
ble .iv.done
ldr x2, [x9, #8]
add x9, x9, #16
# arg[3]
cmp x10, #3
ble .iv.done
ldr x3, [x9, #8]
add x9, x9, #16
# arg[4]
cmp x10, #4
ble .iv.done
ldr x4, [x9, #8]
add x9, x9, #16
# arg[5]
cmp x10, #5
ble .iv.done
ldr x5, [x9, #8]
add x9, x9, #16
# arg[6]
cmp x10, #6
ble .iv.done
ldr x6, [x9, #8]
add x9, x9, #16
# arg[7]
cmp x10, #7
ble .iv.done
ldr x7, [x9, #8]
add x9, x9, #16
.iv.done:
# Next, set up the variable arguments
# calculate the amount of stack space needed for the varargs
mov x10, #0x10
mul x12, x11, x10
#and x12, x12, #0x10
#mov x10, #0x10
#add x12, x12, x10
# x19 is caller-saved, and we'll need x12 later
str x19, [sp, #-16]!
mov x19, x12
# allocate the stack space
sub sp, sp, x19
mov x13, sp
# get a pointer to the end of the stack vararg buffer
#mov x14, #8
#mul x14, x14, x11
#add x13, x13, x14
# x9: arg src buffer (starts at varargs, increments with every iteration)
# x11: number of var args (decrements with every iteration)
# x13: var arg dest pointer (starts at the end, decrements with every iteration)
.iv.loop:
cmp x11, #0
beq .iv.loop.end
# read the arg value from the src pointer
ldr x14, [x9, #8]
# write it to the stack, and increment the dest pointer
str x14, [x13]
add x13, x13, #8
# increment the src pointer, decrement the arg count
sub x11, x11, #1
add x9, x9, #16
b .iv.loop
.iv.loop.end:
# call the function implementation
blr x15
# de-allocate the stack varargs buffer (the size is now stored in x19)
add sp, sp, x19
# restore the saved value of x19,
ldr x19, [sp], #16
# restore the saved stack frame and link pointer
ldp x29,x30, [sp], #16
ret
.global _fx_function_invoke_dv
.align 4
_fx_function_invoke_dv:
ret
.global _fx_function_invoke_vv
.align 4
_fx_function_invoke_vv:
ret
@@ -0,0 +1,36 @@
#ifndef FX_REFLECTION_DARWIN_ARM64_CALLVM_H_
#define FX_REFLECTION_DARWIN_ARM64_CALLVM_H_
#include <fx/reflection/function.h>
#include <fx/value.h>
#include <stdint.h>
#define MAX_FIXED_ARGS ((unsigned int)-1)
#define MAX_DOUBLE_ARGS 8
#define MAX_INT_ARGS 8
/* dyn-dispatch.S depends on the layout of this struct */
struct callvm {
uint64_t vm_arg_int_count;
uint64_t vm_arg_double_count;
/* any args pushed after this limit is reached will be stored in the
* excess buffer. used for calling varargs functions */
uint64_t vm_arg_count, vm_arg_fixed;
uint64_t vm_arg_excess_count;
uint64_t vm_arg_excess_max;
uintptr_t vm_arg_int[MAX_INT_ARGS];
double vm_arg_double[MAX_DOUBLE_ARGS];
uintptr_t *vm_arg_excess;
};
extern void callvm_reset(struct callvm *vm, unsigned int max_fixed_args);
extern void callvm_push(struct callvm *vm, const fx_value *value);
extern fx_value callvm_invoke(
struct callvm *vm,
fx_function_impl impl,
fx_value_type return_type);
#endif
+15 -12
View File
@@ -1,14 +1,17 @@
#include <fx/bool.h>
#include <fx/collections/array.h> #include <fx/collections/array.h>
#include <fx/collections/datetime.h> #include <fx/collections/datetime.h>
#include <fx/collections/dict.h> #include <fx/collections/dict.h>
#include <fx/collections/hashmap.h> #include <fx/collections/hashmap.h>
#include <fx/collections/number.h> #include <fx/double.h>
#include <fx/error.h> #include <fx/error.h>
#include <fx/int.h>
#include <fx/serial/ctx.h> #include <fx/serial/ctx.h>
#include <fx/serial/toml.h> #include <fx/serial/toml.h>
#include <fx/status.h> #include <fx/status.h>
#include <fx/string.h> #include <fx/string.h>
#include <fx/stringstream.h> #include <fx/stringstream.h>
#include <fx/uint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -1688,22 +1691,22 @@ static fx_result parse_string(struct ctx *ctx, fx_object **result)
static fx_result parse_int(struct ctx *ctx, fx_object **result) static fx_result parse_int(struct ctx *ctx, fx_object **result)
{ {
struct token *tok = peek_token(ctx); struct token *tok = peek_token(ctx);
fx_number *val = FX_LONGLONG(tok->tok_value.i.v); fx_int *val = fx_int_create(tok->tok_value.i.v);
if (!val) { if (!val) {
return FX_RESULT_ERR(NO_MEMORY); return FX_RESULT_ERR(NO_MEMORY);
} }
if (tok->tok_value.i.inf) { if (tok->tok_value.i.inf) {
if (tok->tok_value.i.v >= 0) { if (tok->tok_value.i.v >= 0) {
fx_number_set_inf_positive(val, true); fx_int_set_value_inf(val);
} else { } else {
fx_number_set_inf_negative(val, true); fx_int_set_value_inf_negative(val);
} }
} else if (tok->tok_value.i.nan) { } else if (tok->tok_value.i.nan) {
if (tok->tok_value.i.v >= 0) { if (tok->tok_value.i.v >= 0) {
fx_number_set_nan_positive(val, true); fx_int_set_value_nan(val);
} else { } else {
fx_number_set_nan_negative(val, true); fx_int_set_value_nan_negative(val);
} }
} }
@@ -1714,22 +1717,22 @@ static fx_result parse_int(struct ctx *ctx, fx_object **result)
static fx_result parse_float(struct ctx *ctx, fx_object **result) static fx_result parse_float(struct ctx *ctx, fx_object **result)
{ {
struct token *tok = peek_token(ctx); struct token *tok = peek_token(ctx);
fx_number *val = FX_DOUBLE(tok->tok_value.f.v); fx_double *val = fx_double_create(tok->tok_value.f.v);
if (!val) { if (!val) {
return FX_RESULT_ERR(NO_MEMORY); return FX_RESULT_ERR(NO_MEMORY);
} }
if (tok->tok_value.f.inf) { if (tok->tok_value.f.inf) {
if (tok->tok_value.f.v >= 0) { if (tok->tok_value.f.v >= 0) {
fx_number_set_inf_positive(val, true); fx_double_set_value_inf(val);
} else { } else {
fx_number_set_inf_negative(val, true); fx_double_set_value_inf_negative(val);
} }
} else if (tok->tok_value.f.nan) { } else if (tok->tok_value.f.nan) {
if (tok->tok_value.f.v >= 0) { if (tok->tok_value.f.v >= 0) {
fx_number_set_nan_positive(val, true); fx_double_set_value_nan(val);
} else { } else {
fx_number_set_nan_negative(val, true); fx_double_set_value_nan_negative(val);
} }
} }
@@ -1740,7 +1743,7 @@ static fx_result parse_float(struct ctx *ctx, fx_object **result)
static fx_result parse_bool(struct ctx *ctx, fx_object **result) static fx_result parse_bool(struct ctx *ctx, fx_object **result)
{ {
struct token *tok = peek_token(ctx); struct token *tok = peek_token(ctx);
fx_number *val = FX_INT8(tok->tok_value.b); fx_bool *val = fx_bool_create(tok->tok_value.b);
if (!val) { if (!val) {
return FX_RESULT_ERR(NO_MEMORY); return FX_RESULT_ERR(NO_MEMORY);
} }
+84
View File
@@ -0,0 +1,84 @@
#include <fx/bool.h>
#include <fx/stream.h>
/*** PRIVATE DATA *************************************************************/
struct fx_bool_p {
bool b_value;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static void bool_set_value(struct fx_bool_p *i, bool v)
{
i->b_value = v;
}
static bool bool_get_value(struct fx_bool_p *i)
{
return i->b_value;
}
/*** PUBLIC FUNCTIONS *********************************************************/
fx_bool *fx_bool_create(bool value)
{
fx_bool *i = fx_object_create(FX_TYPE_BOOL);
if (!i) {
return NULL;
}
struct fx_bool_p *p = fx_object_get_private(i, FX_TYPE_BOOL);
p->b_value = value;
return i;
}
void fx_bool_set_value(fx_bool *i, bool v)
{
FX_CLASS_DISPATCH_STATIC_V(FX_TYPE_BOOL, bool_set_value, i, v);
}
bool fx_bool_get_value(const fx_bool *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_BOOL, bool_get_value, i);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void bool_init(fx_object *obj, void *priv)
{
struct fx_bool_p *i = priv;
i->b_value = false;
}
static void bool_fini(fx_object *obj, void *priv)
{
}
static void bool_to_string(const fx_object *obj, fx_stream *out)
{
struct fx_bool_p *i = fx_object_get_private(obj, FX_TYPE_BOOL);
if (i->b_value == false) {
fx_stream_write_cstr(out, "false", NULL);
} else {
fx_stream_write_cstr(out, "true", NULL);
}
}
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_bool)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = bool_to_string;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_bool)
FX_TYPE_DEFINITION_BEGIN(fx_bool)
FX_TYPE_ID(0x9c8453bf, 0xfc92, 0x4b0a, 0xbcaf, 0xd0c6cdba9310);
FX_TYPE_CLASS(fx_bool_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_bool_p);
FX_TYPE_INSTANCE_INIT(bool_init);
FX_TYPE_INSTANCE_FINI(bool_fini);
FX_TYPE_DEFINITION_END(fx_bool)
+280
View File
@@ -0,0 +1,280 @@
#include <fx/double.h>
#include <fx/stream.h>
#include <inttypes.h>
#include <stdint.h>
/*** PRIVATE DATA *************************************************************/
enum double_type {
DOUBLE_REGULAR = 0,
DOUBLE_INF_POSITIVE,
DOUBLE_INF_NEGATIVE,
DOUBLE_NAN_POSITIVE,
DOUBLE_NAN_NEGATIVE,
};
struct fx_double_p {
enum double_type i_type;
double i_value;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static bool double_get_value(const struct fx_double_p *i)
{
return i->i_value;
}
static void double_set_value(struct fx_double_p *i, double v)
{
i->i_type = DOUBLE_REGULAR;
i->i_value = v;
}
static void double_set_value_nan(struct fx_double_p *i)
{
i->i_type = DOUBLE_NAN_POSITIVE;
i->i_value = 0;
}
static void double_set_value_nan_negative(struct fx_double_p *i)
{
i->i_type = DOUBLE_NAN_NEGATIVE;
i->i_value = 0;
}
static void double_set_value_inf(struct fx_double_p *i)
{
i->i_type = DOUBLE_INF_POSITIVE;
i->i_value = 0;
}
static void double_set_value_inf_negative(struct fx_double_p *i)
{
i->i_type = DOUBLE_INF_NEGATIVE;
i->i_value = 0;
}
static bool double_is_nan(struct fx_double_p *i)
{
return i->i_type == DOUBLE_NAN_POSITIVE
|| i->i_type == DOUBLE_NAN_NEGATIVE;
}
static bool double_is_nan_positive(struct fx_double_p *i)
{
return i->i_type == DOUBLE_NAN_POSITIVE;
}
static bool double_is_nan_negative(struct fx_double_p *i)
{
return i->i_type == DOUBLE_NAN_NEGATIVE;
}
static bool double_is_inf(struct fx_double_p *i)
{
return i->i_type == DOUBLE_INF_POSITIVE
|| i->i_type == DOUBLE_INF_NEGATIVE;
}
static bool double_is_inf_positive(struct fx_double_p *i)
{
return i->i_type == DOUBLE_INF_POSITIVE;
}
static bool double_is_inf_negative(struct fx_double_p *i)
{
return i->i_type == DOUBLE_INF_NEGATIVE;
}
/*** PUBLIC FUNCTIONS *********************************************************/
fx_double *fx_double_create(double value)
{
fx_double *i = fx_object_create(FX_TYPE_DOUBLE);
if (!i) {
return NULL;
}
struct fx_double_p *p = fx_object_get_private(i, FX_TYPE_DOUBLE);
p->i_type = DOUBLE_REGULAR;
p->i_value = value;
return i;
}
fx_double *fx_double_create_nan(void)
{
fx_double *i = fx_object_create(FX_TYPE_DOUBLE);
if (!i) {
return NULL;
}
struct fx_double_p *p = fx_object_get_private(i, FX_TYPE_DOUBLE);
p->i_type = DOUBLE_NAN_POSITIVE;
p->i_value = 0;
return i;
}
fx_double *fx_double_create_nan_negative(void)
{
fx_double *i = fx_object_create(FX_TYPE_DOUBLE);
if (!i) {
return NULL;
}
struct fx_double_p *p = fx_object_get_private(i, FX_TYPE_DOUBLE);
p->i_type = DOUBLE_NAN_NEGATIVE;
p->i_value = 0;
return i;
}
fx_double *fx_double_create_inf(void)
{
fx_double *i = fx_object_create(FX_TYPE_DOUBLE);
if (!i) {
return NULL;
}
struct fx_double_p *p = fx_object_get_private(i, FX_TYPE_DOUBLE);
p->i_type = DOUBLE_INF_POSITIVE;
p->i_value = 0;
return i;
}
fx_double *fx_double_create_inf_negative(void)
{
fx_double *i = fx_object_create(FX_TYPE_DOUBLE);
if (!i) {
return NULL;
}
struct fx_double_p *p = fx_object_get_private(i, FX_TYPE_DOUBLE);
p->i_type = DOUBLE_INF_NEGATIVE;
p->i_value = 0;
return i;
}
double fx_double_get_value(const fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DOUBLE, double_get_value, i);
}
void fx_double_set_value(fx_double *i, double v)
{
FX_CLASS_DISPATCH_STATIC_V(FX_TYPE_DOUBLE, double_set_value, i, v);
}
void fx_double_set_value_nan(fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_DOUBLE, double_set_value_nan, i);
}
void fx_double_set_value_nan_negative(fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_V0(
FX_TYPE_DOUBLE,
double_set_value_nan_negative,
i);
}
void fx_double_set_value_inf(fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_DOUBLE, double_set_value_inf, i);
}
void fx_double_set_value_inf_negative(fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_V0(
FX_TYPE_DOUBLE,
double_set_value_inf_negative,
i);
}
bool fx_double_is_nan(const fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DOUBLE, double_is_nan, i);
}
bool fx_double_is_nan_positive(const fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DOUBLE, double_is_nan_positive, i);
}
bool fx_double_is_nan_negative(const fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DOUBLE, double_is_nan_negative, i);
}
bool fx_double_is_inf(const fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DOUBLE, double_is_inf, i);
}
bool fx_double_is_inf_positive(const fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DOUBLE, double_is_inf_positive, i);
}
bool fx_double_is_inf_negative(const fx_double *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_DOUBLE, double_is_inf_negative, i);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void double_init(fx_object *obj, void *priv)
{
struct fx_double_p *i = priv;
i->i_type = DOUBLE_REGULAR;
i->i_value = 0;
}
static void double_fini(fx_object *obj, void *priv)
{
}
static void double_to_string(const fx_object *obj, fx_stream *out)
{
struct fx_double_p *i = fx_object_get_private(obj, FX_TYPE_DOUBLE);
switch (i->i_type) {
case DOUBLE_REGULAR:
fx_stream_write_fmt(out, NULL, "%" PRIdPTR, i->i_value);
break;
case DOUBLE_INF_POSITIVE:
fx_stream_write_cstr(out, "inf", NULL);
break;
case DOUBLE_INF_NEGATIVE:
fx_stream_write_cstr(out, "-inf", NULL);
break;
case DOUBLE_NAN_POSITIVE:
fx_stream_write_cstr(out, "NaN", NULL);
break;
case DOUBLE_NAN_NEGATIVE:
fx_stream_write_cstr(out, "-NaN", NULL);
break;
default:
break;
}
}
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_double)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = double_to_string;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_double)
FX_TYPE_DEFINITION_BEGIN(fx_double)
FX_TYPE_ID(0x3b20f57a, 0x2ddf, 0x4682, 0x81c4, 0x4fe404a6524e);
FX_TYPE_CLASS(fx_double_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_double_p);
FX_TYPE_INSTANCE_INIT(double_init);
FX_TYPE_INSTANCE_FINI(double_fini);
FX_TYPE_DEFINITION_END(fx_double)
View File
+25
View File
@@ -0,0 +1,25 @@
#ifndef FX_BOOL_H_
#define FX_BOOL_H_
#include <fx/macros.h>
FX_DECLS_BEGIN;
#define FX_TYPE_BOOL (fx_bool_get_type())
FX_DECLARE_TYPE(fx_bool);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_bool)
FX_TYPE_CLASS_DECLARATION_END(fx_bool)
FX_API fx_type fx_bool_get_type(void);
FX_API fx_bool *fx_bool_create(bool value);
FX_API void fx_bool_set_value(fx_bool *i, bool v);
FX_API bool fx_bool_get_value(const fx_bool *i);
FX_DECLS_END;
#endif
+40
View File
@@ -0,0 +1,40 @@
#ifndef FX_DOUBLE_H_
#define FX_DOUBLE_H_
#include <fx/macros.h>
FX_DECLS_BEGIN;
#define FX_TYPE_DOUBLE (fx_double_get_type())
FX_DECLARE_TYPE(fx_double);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_double)
FX_TYPE_CLASS_DECLARATION_END(fx_double)
FX_API fx_type fx_double_get_type(void);
FX_API fx_double *fx_double_create(double value);
FX_API fx_double *fx_double_create_nan(void);
FX_API fx_double *fx_double_create_nan_negative(void);
FX_API fx_double *fx_double_create_inf(void);
FX_API fx_double *fx_double_create_inf_negative(void);
FX_API void fx_double_set_value(fx_double *i, double v);
FX_API void fx_double_set_value_nan(fx_double *i);
FX_API void fx_double_set_value_nan_negative(fx_double *i);
FX_API void fx_double_set_value_inf(fx_double *i);
FX_API void fx_double_set_value_inf_negative(fx_double *i);
FX_API bool fx_double_is_nan(const fx_double *i);
FX_API bool fx_double_is_nan_positive(const fx_double *i);
FX_API bool fx_double_is_nan_negative(const fx_double *i);
FX_API bool fx_double_is_inf(const fx_double *i);
FX_API bool fx_double_is_inf_positive(const fx_double *i);
FX_API bool fx_double_is_inf_negative(const fx_double *i);
FX_API double fx_double_get_value(const fx_double *i);
FX_DECLS_END;
#endif
+4
View File
@@ -0,0 +1,4 @@
#ifndef FX_ENUM_H_
#define FX_ENUM_H_
#endif
+40
View File
@@ -0,0 +1,40 @@
#ifndef FX_INT_H_
#define FX_INT_H_
#include <fx/macros.h>
FX_DECLS_BEGIN;
#define FX_TYPE_INT (fx_int_get_type())
FX_DECLARE_TYPE(fx_int);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_int)
FX_TYPE_CLASS_DECLARATION_END(fx_int)
FX_API fx_type fx_int_get_type(void);
FX_API fx_int *fx_int_create(intptr_t value);
FX_API fx_int *fx_int_create_nan(void);
FX_API fx_int *fx_int_create_nan_negative(void);
FX_API fx_int *fx_int_create_inf(void);
FX_API fx_int *fx_int_create_inf_negative(void);
FX_API void fx_int_set_value(fx_int *i, intptr_t v);
FX_API void fx_int_set_value_nan(fx_int *i);
FX_API void fx_int_set_value_nan_negative(fx_int *i);
FX_API void fx_int_set_value_inf(fx_int *i);
FX_API void fx_int_set_value_inf_negative(fx_int *i);
FX_API bool fx_int_is_nan(const fx_int *i);
FX_API bool fx_int_is_nan_positive(const fx_int *i);
FX_API bool fx_int_is_nan_negative(const fx_int *i);
FX_API bool fx_int_is_inf(const fx_int *i);
FX_API bool fx_int_is_inf_positive(const fx_int *i);
FX_API bool fx_int_is_inf_negative(const fx_int *i);
FX_API intptr_t fx_int_get_value(const fx_int *i);
FX_DECLS_END;
#endif
+32
View File
@@ -0,0 +1,32 @@
#ifndef FX_UINT_H_
#define FX_UINT_H_
#include <fx/macros.h>
FX_DECLS_BEGIN;
#define FX_TYPE_UINT (fx_uint_get_type())
FX_DECLARE_TYPE(fx_uint);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_uint)
FX_TYPE_CLASS_DECLARATION_END(fx_uint)
FX_API fx_type fx_uint_get_type(void);
FX_API fx_uint *fx_uint_create(uintptr_t value);
FX_API fx_uint *fx_uint_create_nan(void);
FX_API fx_uint *fx_uint_create_inf(void);
FX_API void fx_uint_set_value(fx_uint *i, uintptr_t v);
FX_API void fx_uint_set_value_nan(fx_uint *i);
FX_API void fx_uint_set_value_inf(fx_uint *i);
FX_API bool fx_uint_is_nan(const fx_uint *i);
FX_API bool fx_uint_is_inf(const fx_uint *i);
FX_API uintptr_t fx_uint_get_value(const fx_uint *i);
FX_DECLS_END;
#endif
+101
View File
@@ -0,0 +1,101 @@
#ifndef FX_VALUE_H_
#define FX_VALUE_H_
#include <fx/object.h>
#include <fx/type.h>
#include <stdint.h>
#define FX_VALUE_EMPTY ((fx_value) {})
#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
+272
View File
@@ -0,0 +1,272 @@
#include <fx/int.h>
#include <fx/stream.h>
#include <inttypes.h>
#include <stdint.h>
/*** PRIVATE DATA *************************************************************/
enum int_type {
INT_REGULAR = 0,
INT_INF_POSITIVE,
INT_INF_NEGATIVE,
INT_NAN_POSITIVE,
INT_NAN_NEGATIVE,
};
struct fx_int_p {
enum int_type i_type;
intptr_t i_value;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static bool int_get_value(const struct fx_int_p *i)
{
return i->i_value;
}
static void int_set_value(struct fx_int_p *i, intptr_t v)
{
i->i_type = INT_REGULAR;
i->i_value = v;
}
static void int_set_value_nan(struct fx_int_p *i)
{
i->i_type = INT_NAN_POSITIVE;
i->i_value = 0;
}
static void int_set_value_nan_negative(struct fx_int_p *i)
{
i->i_type = INT_NAN_NEGATIVE;
i->i_value = 0;
}
static void int_set_value_inf(struct fx_int_p *i)
{
i->i_type = INT_INF_POSITIVE;
i->i_value = 0;
}
static void int_set_value_inf_negative(struct fx_int_p *i)
{
i->i_type = INT_INF_NEGATIVE;
i->i_value = 0;
}
static bool int_is_nan(struct fx_int_p *i)
{
return i->i_type == INT_NAN_POSITIVE || i->i_type == INT_NAN_NEGATIVE;
}
static bool int_is_nan_positive(struct fx_int_p *i)
{
return i->i_type == INT_NAN_POSITIVE;
}
static bool int_is_nan_negative(struct fx_int_p *i)
{
return i->i_type == INT_NAN_NEGATIVE;
}
static bool int_is_inf(struct fx_int_p *i)
{
return i->i_type == INT_INF_POSITIVE || i->i_type == INT_INF_NEGATIVE;
}
static bool int_is_inf_positive(struct fx_int_p *i)
{
return i->i_type == INT_INF_POSITIVE;
}
static bool int_is_inf_negative(struct fx_int_p *i)
{
return i->i_type == INT_INF_NEGATIVE;
}
/*** PUBLIC FUNCTIONS *********************************************************/
fx_int *fx_int_create(intptr_t value)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_REGULAR;
p->i_value = value;
return i;
}
fx_int *fx_int_create_nan(void)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_NAN_POSITIVE;
p->i_value = 0;
return i;
}
fx_int *fx_int_create_nan_negative(void)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_NAN_NEGATIVE;
p->i_value = 0;
return i;
}
fx_int *fx_int_create_inf(void)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_INF_POSITIVE;
p->i_value = 0;
return i;
}
fx_int *fx_int_create_inf_negative(void)
{
fx_int *i = fx_object_create(FX_TYPE_INT);
if (!i) {
return NULL;
}
struct fx_int_p *p = fx_object_get_private(i, FX_TYPE_INT);
p->i_type = INT_INF_NEGATIVE;
p->i_value = 0;
return i;
}
intptr_t fx_int_get_value(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_get_value, i);
}
void fx_int_set_value(fx_int *i, intptr_t v)
{
FX_CLASS_DISPATCH_STATIC_V(FX_TYPE_INT, int_set_value, i, v);
}
void fx_int_set_value_nan(fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_INT, int_set_value_nan, i);
}
void fx_int_set_value_nan_negative(fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_INT, int_set_value_nan_negative, i);
}
void fx_int_set_value_inf(fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_INT, int_set_value_inf, i);
}
void fx_int_set_value_inf_negative(fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_INT, int_set_value_inf_negative, i);
}
bool fx_int_is_nan(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_nan, i);
}
bool fx_int_is_nan_positive(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_nan_positive, i);
}
bool fx_int_is_nan_negative(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_nan_negative, i);
}
bool fx_int_is_inf(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_inf, i);
}
bool fx_int_is_inf_positive(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_inf_positive, i);
}
bool fx_int_is_inf_negative(const fx_int *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_INT, int_is_inf_negative, i);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void int_init(fx_object *obj, void *priv)
{
struct fx_int_p *i = priv;
i->i_type = INT_REGULAR;
i->i_value = 0;
}
static void int_fini(fx_object *obj, void *priv)
{
}
static void int_to_string(const fx_object *obj, fx_stream *out)
{
struct fx_int_p *i = fx_object_get_private(obj, FX_TYPE_INT);
switch (i->i_type) {
case INT_REGULAR:
fx_stream_write_fmt(out, NULL, "%" PRIdPTR, i->i_value);
break;
case INT_INF_POSITIVE:
fx_stream_write_cstr(out, "inf", NULL);
break;
case INT_INF_NEGATIVE:
fx_stream_write_cstr(out, "-inf", NULL);
break;
case INT_NAN_POSITIVE:
fx_stream_write_cstr(out, "NaN", NULL);
break;
case INT_NAN_NEGATIVE:
fx_stream_write_cstr(out, "-NaN", NULL);
break;
default:
break;
}
}
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_int)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = int_to_string;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_int)
FX_TYPE_DEFINITION_BEGIN(fx_int)
FX_TYPE_ID(0x3b20f57a, 0x2ddf, 0x4682, 0x81c4, 0x4fe404a6524e);
FX_TYPE_CLASS(fx_int_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_int_p);
FX_TYPE_INSTANCE_INIT(int_init);
FX_TYPE_INSTANCE_FINI(int_fini);
FX_TYPE_DEFINITION_END(fx_int)
View File
+174
View File
@@ -0,0 +1,174 @@
#include <fx/stream.h>
#include <fx/uint.h>
#include <inttypes.h>
#include <stdint.h>
/*** PRIVATE DATA *************************************************************/
enum uint_type {
UINT_REGULAR = 0,
UINT_INF,
UINT_NAN,
};
struct fx_uint_p {
enum uint_type i_type;
uintptr_t i_value;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static uintptr_t uint_get_value(const struct fx_uint_p *i)
{
return i->i_value;
}
static void uint_set_value(struct fx_uint_p *i, uintptr_t v)
{
i->i_type = UINT_REGULAR;
i->i_value = v;
}
static void uint_set_value_nan(struct fx_uint_p *i)
{
i->i_type = UINT_NAN;
i->i_value = 0;
}
static void uint_set_value_inf(struct fx_uint_p *i)
{
i->i_type = UINT_INF;
i->i_value = 0;
}
static bool uint_is_nan(struct fx_uint_p *i)
{
return i->i_type == UINT_NAN;
}
static bool uint_is_inf(struct fx_uint_p *i)
{
return i->i_type == UINT_INF;
}
/*** PUBLIC FUNCTIONS *********************************************************/
fx_uint *fx_uint_create(uintptr_t value)
{
fx_uint *i = fx_object_create(FX_TYPE_UINT);
if (!i) {
return NULL;
}
struct fx_uint_p *p = fx_object_get_private(i, FX_TYPE_UINT);
p->i_type = UINT_REGULAR;
p->i_value = value;
return i;
}
fx_uint *fx_uint_create_nan(void)
{
fx_uint *i = fx_object_create(FX_TYPE_UINT);
if (!i) {
return NULL;
}
struct fx_uint_p *p = fx_object_get_private(i, FX_TYPE_UINT);
p->i_type = UINT_NAN;
p->i_value = 0;
return i;
}
fx_uint *fx_uint_create_inf(void)
{
fx_uint *i = fx_object_create(FX_TYPE_UINT);
if (!i) {
return NULL;
}
struct fx_uint_p *p = fx_object_get_private(i, FX_TYPE_UINT);
p->i_type = UINT_INF;
p->i_value = 0;
return i;
}
uintptr_t fx_uint_get_value(const fx_uint *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_UINT, uint_get_value, i);
}
void fx_uint_set_value(fx_uint *i, uintptr_t v)
{
FX_CLASS_DISPATCH_STATIC_V(FX_TYPE_UINT, uint_set_value, i, v);
}
void fx_uint_set_value_nan(fx_uint *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_UINT, uint_set_value_nan, i);
}
void fx_uint_set_value_inf(fx_uint *i)
{
FX_CLASS_DISPATCH_STATIC_V0(FX_TYPE_UINT, uint_set_value_inf, i);
}
bool fx_uint_is_nan(const fx_uint *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_UINT, uint_is_nan, i);
}
bool fx_uint_is_inf(const fx_uint *i)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_UINT, uint_is_inf, i);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void uint_init(fx_object *obj, void *priv)
{
struct fx_uint_p *i = priv;
i->i_type = UINT_REGULAR;
i->i_value = 0;
}
static void uint_fini(fx_object *obj, void *priv)
{
}
static void uint_to_string(const fx_object *obj, fx_stream *out)
{
struct fx_uint_p *i = fx_object_get_private(obj, FX_TYPE_UINT);
switch (i->i_type) {
case UINT_REGULAR:
fx_stream_write_fmt(out, NULL, "%" PRIdPTR, i->i_value);
break;
case UINT_INF:
fx_stream_write_cstr(out, "inf", NULL);
break;
case UINT_NAN:
fx_stream_write_cstr(out, "NaN", NULL);
break;
default:
break;
}
}
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_DEFINITION_BEGIN(fx_uint)
FX_TYPE_CLASS_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = uint_to_string;
FX_TYPE_CLASS_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_CLASS_DEFINITION_END(fx_uint)
FX_TYPE_DEFINITION_BEGIN(fx_uint)
FX_TYPE_ID(0x79aee484, 0x5dd5, 0x463a, 0xb0c8, 0x60873abdf088);
FX_TYPE_CLASS(fx_uint_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_uint_p);
FX_TYPE_INSTANCE_INIT(uint_init);
FX_TYPE_INSTANCE_FINI(uint_fini);
FX_TYPE_DEFINITION_END(fx_uint)
+1 -1
View File
@@ -1,7 +1,7 @@
#include <ctype.h> #include <ctype.h>
#include <fx/collections/uuid.h>
#include <fx/string.h> #include <fx/string.h>
#include <fx/stringstream.h> #include <fx/stringstream.h>
#include <fx/uuid.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
+248
View File
@@ -0,0 +1,248 @@
#include <fx/bool.h>
#include <fx/double.h>
#include <fx/int.h>
#include <fx/string.h>
#include <fx/uint.h>
#include <fx/value.h>
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;
}
+7
View File
@@ -0,0 +1,7 @@
file(GLOB test_sources *.c)
foreach (f ${test_sources})
get_filename_component(test_name ${f} NAME_WLE)
add_executable(${test_name} ${f})
target_link_libraries(${test_name} ${fx_assemblies})
endforeach (f)
+22
View File
@@ -0,0 +1,22 @@
#include <dlfcn.h>
#include <stdio.h>
int main(int argc, const char **argv)
{
printf("dynamic loader\n");
void *assembly = dlopen(argv[1], RTLD_LAZY);
if (!assembly) {
printf("cannot load %s\n", argv[1]);
return -1;
}
const void *(*asm_info)(void) = dlsym(assembly, "__fx_assembly_get");
if (!asm_info) {
printf("cannot find assembly info for %s", argv[1]);
return -1;
}
asm_info();
printf("OK\n");
return 0;
}
+3 -3
View File
@@ -1,8 +1,8 @@
#include <fx/core/stream.h>
#include <fx/core/stringstream.h>
#include <fx/ds/string.h>
#include <fx/io/file.h> #include <fx/io/file.h>
#include <fx/io/path.h> #include <fx/io/path.h>
#include <fx/stream.h>
#include <fx/string.h>
#include <fx/stringstream.h>
#include <stdio.h> #include <stdio.h>
int main(int argc, const char **argv) int main(int argc, const char **argv)
+3 -3
View File
@@ -1,8 +1,8 @@
#include <fx/core/stream.h>
#include <fx/core/stringstream.h>
#include <fx/ds/string.h>
#include <fx/io/file.h> #include <fx/io/file.h>
#include <fx/io/path.h> #include <fx/io/path.h>
#include <fx/stream.h>
#include <fx/string.h>
#include <fx/stringstream.h>
#include <stdio.h> #include <stdio.h>
int main(int argc, const char **argv) int main(int argc, const char **argv)
+30
View File
@@ -0,0 +1,30 @@
#include <fx/reflection/function.h>
#include <fx/value.h>
#include <inttypes.h>
#include <stdio.h>
int main(int argc, const char **argv)
{
fx_value_type arg_types[] = {
FX_VALUE_TYPE_CSTR,
};
fx_function *func = fx_function_create(
"test_function",
FX_FUNCTION_F_VARARG,
(fx_function_impl)printf,
arg_types,
1,
FX_VALUE_TYPE_INT);
fx_value args[] = {
FX_VALUE_CSTR("Hello %s! You are number %lf\n"),
FX_VALUE_CSTR("Jonh"),
FX_VALUE_DOUBLE(2.5),
};
fx_value result = FX_VALUE_EMPTY;
int r = fx_function_invoke(func, args, 3, &result);
printf("%" PRIdPTR "\n", result.v_int);
return 0;
}
+42 -14
View File
@@ -1,22 +1,50 @@
#include <dlfcn.h> #include <fx/reflection/function.h>
#include <fx/value.h>
#include <stdio.h> #include <stdio.h>
static double test_function(int a, double b, int c, ...)
{
#if 1
va_list args;
va_start(args, c);
int d = va_arg(args, int);
double e = va_arg(args, double);
int f = va_arg(args, int);
printf("a=%d, b=%lf, c=%d, d=%d, e=%lf, f=%d\n", a, b, c, d, e, f);
return (a + b + c + d + e + f) + 0.5;
#else
printf("a=%d, b=%lf, c=%d\n", a, b, c);
return 32;
#endif
}
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {
printf("dynamic loader\n"); fx_value_type arg_types[] = {
void *assembly = dlopen(argv[1], RTLD_LAZY); FX_VALUE_TYPE_INT,
if (!assembly) { FX_VALUE_TYPE_DOUBLE,
printf("cannot load %s\n", argv[1]); FX_VALUE_TYPE_INT,
return -1; };
}
const void *(*asm_info)(void) = dlsym(assembly, "__fx_assembly_get"); fx_function *func = fx_function_create(
if (!asm_info) { "test_function",
printf("cannot find assembly info for %s", argv[1]); FX_FUNCTION_F_VARARG,
return -1; (fx_function_impl)test_function,
} arg_types,
3,
FX_VALUE_TYPE_DOUBLE);
asm_info(); fx_value args[] = {
printf("OK\n"); FX_VALUE_INT(1),
FX_VALUE_DOUBLE(2.5),
FX_VALUE_INT(3),
FX_VALUE_INT(4),
FX_VALUE_DOUBLE(5.5),
FX_VALUE_INT(6),
};
fx_value result = FX_VALUE_EMPTY;
int r = fx_function_invoke(func, args, 6, &result);
printf("%lf\n", result.v_double);
return 0; return 0;
} }
+40
View File
@@ -0,0 +1,40 @@
#include <stdarg.h>
#include <stdio.h>
static double another_function(int a, double b, int c)
{
printf("a=%d, b=%lf, c=%d\n", a, b, c);
return 1.2;
}
static int test_function(int a, int b, int c, ...)
{
va_list args;
va_start(args, c);
int d = va_arg(args, int);
int e = va_arg(args, int);
int f = va_arg(args, int);
int g = va_arg(args, int);
int h = va_arg(args, int);
int i = va_arg(args, int);
int j = va_arg(args, int);
printf("a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d, j=%d\n",
a,
b,
c,
d,
e,
f,
g,
h,
i,
j);
return a + b + c + d + e;
}
int main(void)
{
test_function(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
another_function(1, 2.5, 5);
return 0;
}