fx: support for registering callable functions with types
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#include <fx/macros.h>
|
||||
#include <fx/reflection/assembly.h>
|
||||
|
||||
FX_ASSEMBLY_BEGIN()
|
||||
FX_ASSEMBLY_BEGIN(fx_cmdline)
|
||||
FX_ASSEMBLY_NAME("fx.cmdline");
|
||||
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
|
||||
FX_ASSEMBLY_END()
|
||||
FX_ASSEMBLY_END(fx_cmdline)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <fx/macros.h>
|
||||
#include <fx/reflection/assembly.h>
|
||||
|
||||
FX_ASSEMBLY_BEGIN()
|
||||
FX_ASSEMBLY_BEGIN(fx_compression)
|
||||
FX_ASSEMBLY_NAME("fx.compression");
|
||||
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
|
||||
FX_ASSEMBLY_END()
|
||||
FX_ASSEMBLY_END(fx_compression)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <fx/macros.h>
|
||||
#include <fx/reflection/assembly.h>
|
||||
|
||||
FX_ASSEMBLY_BEGIN()
|
||||
FX_ASSEMBLY_NAME("fx.io");
|
||||
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
|
||||
FX_ASSEMBLY_END()
|
||||
FX_ASSEMBLY_BEGIN(fx_io)
|
||||
FX_ASSEMBLY_NAME("fx.io");
|
||||
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
|
||||
FX_ASSEMBLY_END(fx_io)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <fx/macros.h>
|
||||
#include <fx/reflection/assembly.h>
|
||||
|
||||
FX_ASSEMBLY_BEGIN()
|
||||
FX_ASSEMBLY_BEGIN(fx_runtime)
|
||||
FX_ASSEMBLY_NAME("fx.runtime");
|
||||
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
|
||||
FX_ASSEMBLY_EXPORT_TYPE("fx", "stream", fx_stream);
|
||||
@@ -9,4 +9,4 @@ FX_ASSEMBLY_BEGIN()
|
||||
FX_ASSEMBLY_EXPORT_TYPE("fx", "stringstream", fx_stringstream);
|
||||
FX_ASSEMBLY_EXPORT_TYPE("fx", "iterator", fx_iterator);
|
||||
FX_ASSEMBLY_EXPORT_TYPE("fx.reflection", "assembly", fx_assembly);
|
||||
FX_ASSEMBLY_END()
|
||||
FX_ASSEMBLY_END(fx_runtime)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <fx/macros.h>
|
||||
#include <fx/reflection/assembly.h>
|
||||
|
||||
FX_ASSEMBLY_BEGIN()
|
||||
FX_ASSEMBLY_BEGIN(fx_serial)
|
||||
FX_ASSEMBLY_NAME("fx.serial");
|
||||
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
|
||||
FX_ASSEMBLY_END()
|
||||
FX_ASSEMBLY_END(fx_serial)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <fx/macros.h>
|
||||
#include <fx/reflection/assembly.h>
|
||||
|
||||
FX_ASSEMBLY_BEGIN()
|
||||
FX_ASSEMBLY_BEGIN(fx_term)
|
||||
FX_ASSEMBLY_NAME("fx.term");
|
||||
FX_ASSEMBLY_VERSION(1, 0, 0, 0);
|
||||
FX_ASSEMBLY_END()
|
||||
FX_ASSEMBLY_END(fx_term)
|
||||
|
||||
@@ -22,6 +22,11 @@ struct fx_function_p {
|
||||
|
||||
/*** PRIVATE FUNCTIONS ********************************************************/
|
||||
|
||||
static const char *function_get_name(const struct fx_function_p *func)
|
||||
{
|
||||
return func->func_name;
|
||||
}
|
||||
|
||||
static fx_status function_bind(
|
||||
struct fx_function_p *func,
|
||||
fx_value *args,
|
||||
@@ -98,10 +103,9 @@ static fx_status function_invoke(
|
||||
return FX_SUCCESS;
|
||||
}
|
||||
|
||||
/*** PUBLIC FUNCTIONS
|
||||
* *********************************************************/
|
||||
/*** PUBLIC FUNCTIONS *********************************************************/
|
||||
|
||||
FX_API fx_function *fx_function_create(
|
||||
fx_function *fx_function_create(
|
||||
const char *name,
|
||||
fx_function_flags flags,
|
||||
fx_function_impl impl,
|
||||
@@ -118,6 +122,10 @@ FX_API fx_function *fx_function_create(
|
||||
func,
|
||||
FX_REFLECTION_TYPE_FUNCTION);
|
||||
|
||||
if (nr_args == 1 && args[0] == FX_VALUE_TYPE_NONE) {
|
||||
nr_args = 0;
|
||||
}
|
||||
|
||||
p->func_name = fx_strdup(name);
|
||||
p->func_flags = flags;
|
||||
p->func_impl = impl;
|
||||
@@ -131,6 +139,14 @@ FX_API fx_function *fx_function_create(
|
||||
return func;
|
||||
}
|
||||
|
||||
const char *fx_function_get_name(const fx_function *func)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_0(
|
||||
FX_REFLECTION_TYPE_FUNCTION,
|
||||
function_get_name,
|
||||
func);
|
||||
}
|
||||
|
||||
fx_status fx_function_bind(fx_function *func, fx_value *args, size_t nr_args)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC(
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef enum fx_function_flags {
|
||||
FX_FUNCTION_F_STATIC = 0x01u,
|
||||
FX_FUNCTION_F_VIRTUAL = 0x02u,
|
||||
FX_FUNCTION_F_VARARG = 0x04u,
|
||||
FX_FUNCTION_F_CONSTRUCTOR = 0x08u,
|
||||
} fx_function_flags;
|
||||
|
||||
typedef void (*fx_function_impl)();
|
||||
@@ -25,6 +26,8 @@ FX_TYPE_CLASS_DECLARATION_END(fx_function)
|
||||
|
||||
FX_API fx_type_id fx_function_get_type();
|
||||
|
||||
FX_API const char *fx_function_get_name(const fx_function *func);
|
||||
|
||||
FX_API fx_function *fx_function_create(
|
||||
const char *name,
|
||||
fx_function_flags flags,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define FX_REFLECTION_TYPE_H_
|
||||
|
||||
#include <fx/macros.h>
|
||||
#include <fx/reflection/function.h>
|
||||
|
||||
FX_DECLS_BEGIN;
|
||||
|
||||
@@ -17,6 +18,9 @@ FX_TYPE_CLASS_DECLARATION_END(fx_type)
|
||||
FX_API fx_type_id fx_type_get_type();
|
||||
|
||||
FX_API const char *fx_type_get_name(const fx_type *ty);
|
||||
FX_API const fx_function *fx_type_get_function(
|
||||
const fx_type *ty,
|
||||
const char *name);
|
||||
|
||||
FX_API const fx_type *fx_type_get_by_id(fx_type_id id);
|
||||
FX_API const fx_type *fx_type_get_by_name(const char *name);
|
||||
|
||||
@@ -12,12 +12,22 @@ struct fx_type_p {
|
||||
|
||||
extern struct fx_type_info *fx_type_info_get_by_id(const union fx_type_id *key);
|
||||
extern struct fx_type_info *fx_type_info_get_by_name(const char *name);
|
||||
extern fx_function *fx_type_info_get_function_by_name(
|
||||
const struct fx_type_info *ty,
|
||||
const char *name);
|
||||
|
||||
static const char *type_get_name(const struct fx_type_p *ty)
|
||||
{
|
||||
return ty->ty_info->ty_name;
|
||||
}
|
||||
|
||||
const fx_function *type_get_function(
|
||||
const struct fx_type_p *ty,
|
||||
const char *name)
|
||||
{
|
||||
return fx_type_info_get_function_by_name(ty->ty_info, name);
|
||||
}
|
||||
|
||||
/*** PUBLIC FUNCTIONS *********************************************************/
|
||||
|
||||
fx_type *__fx_type_create(struct fx_type_info *type_info)
|
||||
@@ -40,6 +50,15 @@ const char *fx_type_get_name(const fx_type *ty)
|
||||
FX_CLASS_DISPATCH_STATIC_0(FX_REFLECTION_TYPE_TYPE, type_get_name, ty);
|
||||
}
|
||||
|
||||
const fx_function *fx_type_get_function(const fx_type *ty, const char *name)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC(
|
||||
FX_REFLECTION_TYPE_TYPE,
|
||||
type_get_function,
|
||||
ty,
|
||||
name);
|
||||
}
|
||||
|
||||
const fx_type *fx_type_get_by_id(fx_type_id id)
|
||||
{
|
||||
struct fx_type_info *ty = fx_type_info_get_by_id(id);
|
||||
|
||||
+8
-1
@@ -73,9 +73,16 @@ fx_result fx_class_instantiate(
|
||||
c_entry);
|
||||
const struct fx_type_info *class_info = comp->c_type;
|
||||
void *class_data = (char *)out + comp->c_class_data_offset;
|
||||
struct fx_type_info *main_class_param = NULL;
|
||||
if (class_info == type) {
|
||||
main_class_param = type;
|
||||
}
|
||||
|
||||
if (class_info->ty_class_init) {
|
||||
class_info->ty_class_init(out, class_data);
|
||||
class_info->ty_class_init(
|
||||
out,
|
||||
main_class_param,
|
||||
class_data);
|
||||
}
|
||||
|
||||
entry = fx_queue_next(entry);
|
||||
|
||||
+49
-5
@@ -5,6 +5,7 @@
|
||||
#include <fx/object.h>
|
||||
#include <fx/thread.h>
|
||||
#include <fx/type.h>
|
||||
#include <fx/value.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define __FX_IFACE_I0(p, x) p##x
|
||||
@@ -13,7 +14,10 @@
|
||||
/* Type definitions macros (for use in .c source file) */
|
||||
|
||||
#define FX_TYPE_CLASS_BEGIN(type_name) \
|
||||
static void type_name##_class_init(fx_class *p, void *d) \
|
||||
static void type_name##_class_init( \
|
||||
fx_class *p, \
|
||||
fx_type_info *ty, \
|
||||
void *d) \
|
||||
{
|
||||
#define FX_TYPE_CLASS_END(type_name) }
|
||||
|
||||
@@ -21,9 +25,49 @@
|
||||
static void type_name##_type_functionality_init(void *opaque) \
|
||||
{
|
||||
#define FX_TYPE_FUNCTIONALITY_END(type_name) }
|
||||
#define FX_TYPE_CONSTRUCTOR(name, impl, ...)
|
||||
#define FX_TYPE_METHOD(return_type, name, impl, ...)
|
||||
#define FX_TYPE_FUNCTION(return_type, name, impl, ...)
|
||||
#define FX_TYPE_CONSTRUCTOR(name, impl, flags, ...) \
|
||||
do { \
|
||||
if (ty) { \
|
||||
fx_value_type args[] = {__VA_ARGS__}; \
|
||||
fx_function *func = fx_function_create( \
|
||||
name, \
|
||||
FX_FUNCTION_F_CONSTRUCTOR \
|
||||
| FX_FUNCTION_F_STATIC | (flags), \
|
||||
(fx_function_impl)impl, \
|
||||
args, \
|
||||
sizeof args / sizeof args[0], \
|
||||
FX_VALUE_TYPE_POINTER); \
|
||||
fx_type_add_function(ty, func); \
|
||||
} \
|
||||
} while (0)
|
||||
#define FX_TYPE_METHOD(return_type, name, impl, flags, ...) \
|
||||
do { \
|
||||
if (ty) { \
|
||||
fx_value_type args[] = {__VA_ARGS__}; \
|
||||
fx_function *func = fx_function_create( \
|
||||
name, \
|
||||
(flags), \
|
||||
(fx_function_impl)impl, \
|
||||
args, \
|
||||
sizeof args / sizeof args[0], \
|
||||
return_type); \
|
||||
fx_type_add_function(ty, func); \
|
||||
} \
|
||||
} while (0)
|
||||
#define FX_TYPE_FUNCTION(return_type, name, impl, ...) \
|
||||
do { \
|
||||
if (ty) { \
|
||||
fx_value_type args[] = {__VA_ARGS__}; \
|
||||
fx_function *func = fx_function_create( \
|
||||
name, \
|
||||
FX_FUNCTION_F_STATIC | (flags), \
|
||||
(fx_function_impl)impl, \
|
||||
args, \
|
||||
sizeof args / sizeof args[0], \
|
||||
return_type); \
|
||||
fx_type_add_function(ty, func); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FX_TYPE_VTABLE_INTERFACE_BEGIN(interface_name, interface_id) \
|
||||
interface_name##_class *__FX_IFACE_I1(iface, __LINE__) \
|
||||
@@ -43,7 +87,7 @@
|
||||
|
||||
#define FX_TYPE_DEFINITION_BEGIN(name) \
|
||||
static fx_type_info name##_type_info = {0}; \
|
||||
static void name##_class_init(fx_class *, void *); \
|
||||
static void name##_class_init(fx_class *, fx_type_info *, void *); \
|
||||
static void name##_type_init(void) \
|
||||
{ \
|
||||
fx_type_info *type_info = &name##_type_info; \
|
||||
|
||||
@@ -14,8 +14,12 @@
|
||||
|
||||
struct _fx_class;
|
||||
struct _fx_object;
|
||||
struct fx_type_info;
|
||||
|
||||
typedef void (*fx_class_init_function)(struct _fx_class *, void *);
|
||||
typedef void (*fx_class_init_function)(
|
||||
struct _fx_class *,
|
||||
struct fx_type_info *,
|
||||
void *);
|
||||
typedef void (*fx_instance_init_function)(struct _fx_object *, void *);
|
||||
typedef void (*fx_instance_fini_function)(struct _fx_object *, void *);
|
||||
|
||||
@@ -86,5 +90,7 @@ static inline int fx_type_id_compare(fx_type_id a, fx_type_id b)
|
||||
}
|
||||
|
||||
FX_API fx_result fx_type_register(fx_type_info *info);
|
||||
FX_API fx_result
|
||||
fx_type_add_function(fx_type_info *info, struct _fx_object *func);
|
||||
|
||||
#endif
|
||||
|
||||
+14
@@ -1,4 +1,5 @@
|
||||
#include <ctype.h>
|
||||
#include <fx/reflection/function.h>
|
||||
#include <fx/stream.h>
|
||||
#include <fx/string.h>
|
||||
#include <fx/stringstream.h>
|
||||
@@ -1716,6 +1717,19 @@ FX_TYPE_CLASS_BEGIN(fx_string)
|
||||
FX_INTERFACE_ENTRY(it_begin) = iterator_begin;
|
||||
FX_INTERFACE_ENTRY(it_cbegin) = iterator_cbegin;
|
||||
FX_TYPE_VTABLE_INTERFACE_END(fx_iterable, FX_TYPE_ITERABLE)
|
||||
|
||||
FX_TYPE_CONSTRUCTOR("create", fx_string_create, 0, FX_VALUE_TYPE_NONE);
|
||||
FX_TYPE_CONSTRUCTOR(
|
||||
"create_from_cstr",
|
||||
fx_string_create_from_cstr,
|
||||
1,
|
||||
FX_VALUE_TYPE_CSTR);
|
||||
FX_TYPE_METHOD(
|
||||
FX_VALUE_TYPE_CSTR,
|
||||
"get_cstr",
|
||||
fx_string_get_cstr,
|
||||
0,
|
||||
FX_VALUE_TYPE_POINTER);
|
||||
FX_TYPE_CLASS_END(fx_string)
|
||||
|
||||
FX_TYPE_DEFINITION_BEGIN(fx_string)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <fx/bst.h>
|
||||
#include <fx/endian.h>
|
||||
#include <fx/object.h>
|
||||
#include <fx/reflection/function.h>
|
||||
#include <fx/type.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -343,6 +344,29 @@ fx_result fx_type_register(struct fx_type_info *info)
|
||||
return FX_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
fx_result fx_type_add_function(fx_type_info *info, struct _fx_object *func)
|
||||
{
|
||||
const char *name = fx_function_get_name(func);
|
||||
struct fx_namemap_entry *entry = fx_namemap_get(
|
||||
&info->ty_functions,
|
||||
name);
|
||||
if (entry) {
|
||||
return FX_RESULT_ERR(NAME_EXISTS);
|
||||
}
|
||||
|
||||
struct fx_type_function *ty_func = malloc(sizeof *ty_func);
|
||||
if (!ty_func) {
|
||||
return FX_RESULT_ERR(NO_MEMORY);
|
||||
}
|
||||
|
||||
memset(ty_func, 0x0, sizeof *ty_func);
|
||||
|
||||
ty_func->f_func = func;
|
||||
fx_namemap_put(&info->ty_functions, name, &ty_func->f_entry);
|
||||
|
||||
return FX_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
struct fx_type_info *fx_type_info_get_by_id(const union fx_type_id *key)
|
||||
{
|
||||
return get_type(&type_idmap, key);
|
||||
@@ -357,3 +381,19 @@ struct fx_type_info *fx_type_info_get_by_name(const char *name)
|
||||
|
||||
return fx_unbox(struct fx_type_info, entry, ty_namemap_entry);
|
||||
}
|
||||
|
||||
fx_function *fx_type_info_get_function_by_name(
|
||||
const struct fx_type_info *ty,
|
||||
const char *name)
|
||||
{
|
||||
fx_namemap_entry *entry = fx_namemap_get(&ty->ty_functions, name);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct fx_type_function *func = fx_unbox(
|
||||
struct fx_type_function,
|
||||
entry,
|
||||
f_entry);
|
||||
return func->f_func;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <fx/bst.h>
|
||||
#include <fx/namemap.h>
|
||||
#include <fx/queue.h>
|
||||
#include <fx/reflection/function.h>
|
||||
#include <fx/reflection/type.h>
|
||||
#include <fx/type.h>
|
||||
#include <stddef.h>
|
||||
@@ -20,7 +21,7 @@ struct fx_type_component {
|
||||
|
||||
struct fx_type_function {
|
||||
struct fx_namemap_entry f_entry;
|
||||
struct fx_function *f_func;
|
||||
fx_function *f_func;
|
||||
};
|
||||
|
||||
extern struct fx_type_registration *fx_type_get_registration(fx_type_id id);
|
||||
@@ -29,5 +30,8 @@ extern struct fx_type_component *fx_type_get_component(
|
||||
const union fx_type_id *key);
|
||||
extern struct fx_type_info *fx_type_info_get_by_id(const union fx_type_id *key);
|
||||
extern struct fx_type_info *fx_type_info_get_by_name(const char *name);
|
||||
extern fx_function *fx_type_info_get_function_by_name(
|
||||
const struct fx_type_info *ty,
|
||||
const char *name);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user