From 59e4b15fad4eb107037c5acaeac767d622e86ffb Mon Sep 17 00:00:00 2001 From: "J.-F. Cap" Date: Fri, 22 Feb 2019 10:54:22 +0100 Subject: [PATCH] added some abstract type instrospection capabilities registering abstract type in vm_register table --- src/core/typedarray.c | 25 +++++++++++++++++++++++++ src/core/util.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/include/janet.h | 11 +++++++++++ 3 files changed, 77 insertions(+) diff --git a/src/core/typedarray.c b/src/core/typedarray.c index 7ba04859..f1b48e4c 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -320,6 +320,25 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { return janet_wrap_struct(janet_struct_end(props)); } +static Janet cfun_abstract_properties(int32_t argc, Janet *argv) { + janet_fixarity(argc, 1); + JanetAbstractTypeInfo * info; + if (janet_checktype(argv[0],JANET_KEYWORD)) { + const uint8_t *keyw = janet_unwrap_keyword(argv[0]); + info=janet_get_abstract_type_info_byname((const char*)keyw); + } else { + uint32_t tag = (uint32_t)janet_getinteger(argv, 0); + info=janet_get_abstract_type_info(tag); + } + if (info==NULL) { + return janet_wrap_nil(); + } + JanetKV *props = janet_struct_begin(2); + janet_struct_put(props, janet_ckeywordv("tag"), janet_wrap_number(info->tag)); + janet_struct_put(props, janet_ckeywordv("name"), janet_ckeywordv(info->type.name)); + return janet_wrap_struct(janet_struct_end(props)); +} + static const JanetReg ta_cfuns[] = { @@ -343,6 +362,11 @@ static const JanetReg ta_cfuns[] = { JDOC("(tarray/properties array )\n\n" "return typed array properties as a struct") }, + { + "abstract/properties", cfun_abstract_properties, + JDOC("(abstract/properties tag)\n\n" + "return abstract type properties as a struct") + }, {NULL, NULL, NULL} }; @@ -351,4 +375,5 @@ static const JanetReg ta_cfuns[] = { /* Module entry point */ void janet_lib_typed_array(JanetTable *env) { janet_core_cfuns(env, NULL, ta_cfuns); + janet_register_abstract_type(&ta_buffer_type,1111); } diff --git a/src/core/util.c b/src/core/util.c index c51a7cd5..831b8251 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -284,6 +284,47 @@ void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns) } } +static const JanetAbstractType type_info = {"core/type_info", NULL, NULL, NULL, NULL}; + +void janet_register_abstract_type(const JanetAbstractType *atype,uint32_t tag) { + JanetAbstractTypeInfo * abstract =(JanetAbstractTypeInfo *)janet_abstract(&type_info,sizeof(JanetAbstractTypeInfo)); + abstract->type=*atype; + abstract->tag=tag; + if (!(janet_checktype(janet_table_get(janet_vm_registry,janet_wrap_number(tag)),JANET_NIL)) || + !(janet_checktype(janet_table_get(janet_vm_registry,janet_ckeywordv(atype->name)),JANET_NIL))) { + janet_panic("Register abstract type fail, a type with same name or tag exist"); + } + janet_table_put(janet_vm_registry,janet_wrap_number(tag), janet_wrap_abstract(abstract)); + janet_table_put(janet_vm_registry,janet_ckeywordv(atype->name), janet_wrap_abstract(abstract)); +} + +JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag) { + Janet info=janet_table_get(janet_vm_registry,janet_wrap_number(tag)); + if (janet_checktype(info, JANET_NIL)) { + return NULL; + } + if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { + janet_panic("expected type_info"); + } + JanetAbstractTypeInfo * type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); + return type_info; +} + +JanetAbstractTypeInfo * janet_get_abstract_type_info_byname(const char * name) { + Janet info=janet_table_get(janet_vm_registry,janet_ckeywordv(name)); + if (janet_checktype(info, JANET_NIL)) { + return NULL; + } + if (!janet_checktype(info, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(info)) != &type_info)) { + janet_panic("expected type_info"); + } + JanetAbstractTypeInfo * type_info = (JanetAbstractTypeInfo *)janet_unwrap_abstract(info); + return type_info; +} + + + + #ifndef JANET_BOOTSTRAP void janet_core_def(JanetTable *env, const char *name, Janet x, const void *p) { (void) p; diff --git a/src/include/janet.h b/src/include/janet.h index cf46b8f2..81e71ba4 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1191,6 +1191,17 @@ JANET_API JanetRange janet_getslice(int32_t argc, const Janet *argv); JANET_API int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const char *which); JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which); + +typedef struct { + JanetAbstractType type; + uint32_t tag; +} JanetAbstractTypeInfo; + +JANET_API void janet_register_abstract_type(const JanetAbstractType *atype,uint32_t tag); +JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info(uint32_t tag); + /*JANET_API uint32_t janet_get_abstract_type_tag(const JanetAbstractType *atype);*/ +JANET_API JanetAbstractTypeInfo * janet_get_abstract_type_info_byname(const char * name); + /***** END SECTION MAIN *****/ #ifdef __cplusplus