diff --git a/CMakeLists.txt b/CMakeLists.txt index 919f0f4..c113045 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project(libabacus) add_compile_options(-pedantic -Wall) -add_library(abacus STATIC src/lexer.c src/util.c src/table.c src/parser.c src/libabacus.c src/tree.c src/debug.c src/parsetype.c src/reserved.c src/trie.c src/refcount.c src/ref_vec.c src/ref_trie.c src/basetype.c src/type.c src/value.c src/custom.c) +add_library(abacus STATIC src/lexer.c src/util.c src/table.c src/parser.c src/libabacus.c src/tree.c src/debug.c src/parsetype.c src/reserved.c src/trie.c src/refcount.c src/ref_vec.c src/ref_trie.c src/basetype.c src/value.c src/custom.c) add_executable(libabacus src/main.c) add_subdirectory(external/liblex) diff --git a/include/parsetype.h b/include/parsetype.h index c9f8d58..acfa4bd 100644 --- a/include/parsetype.h +++ b/include/parsetype.h @@ -3,15 +3,11 @@ #include "result.h" #include "vec.h" +#include "basetype.h" -/** - * The variant of the given parse type. - */ -enum libab_parsetype_variant_e { - PT_STRING, - PT_PLACEHOLDER, - PT_PARENT -}; +#define LIBABACUS_TYPE_F_PARENT (1) +#define LIBABACUS_TYPE_F_PLACE (1 << 1) +#define LIBABACUS_TYPE_F_RESOLVED (1 << 2) /** * A parse type. @@ -26,11 +22,20 @@ struct libab_parsetype_s { /** * The variant of the given parse type. */ - enum libab_parsetype_variant_e variant; + int variant; /** - * The name of the type that this parse type describes. + * Union that represents the data carried by this type. */ - char* name; + union { + /** + * The name of the type that this parse type describes. + */ + char* name; + /** + * The pointer to the base of this type. + */ + libab_basetype* base; + } data_u; /** * A vector of children that this parse type contains. * The children are effectively type parameters. @@ -38,7 +43,6 @@ struct libab_parsetype_s { vec children; }; -typedef enum libab_parsetype_variant_e libab_parsetype_variant; typedef struct libab_parsetype_s libab_parsetype; /** diff --git a/include/type.h b/include/type.h deleted file mode 100644 index 631f571..0000000 --- a/include/type.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef LIBABACUS_TYPE_H -#define LIBABACUS_TYPE_H - -#include "ref_vec.h" -#include "basetype.h" - -/** - * A type instance. This is created at runtime - * for every value that has a type, and represents an instance - * of a basetype with concrete (though possibly templated) parameters. - */ -struct libab_type_s { - /** - * The base type that this type is an instance of. - */ - libab_basetype* base; - /** - * The list of parameters this type holds. - */ - libab_ref_vec params; -}; - -typedef struct libab_type_s libab_type; - -/** - * Initializes a given type with the given basetype. - * @param type the type to initialize. - * @param base the base type to use. - * @return the result of the initialization. - */ -libab_result libab_type_init(libab_type* type, libab_basetype* base); -/** - * Frees the memory allocated by the given type. - * @param type the type to free. - */ -void libab_type_free(libab_type* type); - -#endif diff --git a/include/value.h b/include/value.h index d523f6b..25cac6b 100644 --- a/include/value.h +++ b/include/value.h @@ -1,8 +1,8 @@ #ifndef LIBABACUS_VALUE_H #define LIBABACUS_VALUE_H -#include "type.h" #include "result.h" +#include "refcount.h" /** * A struct that represents a value. diff --git a/src/parser.c b/src/parser.c index e00d71d..e91943b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -122,7 +122,8 @@ libab_result _parse_braced_block(struct parser_state* state, libab_tree** store_ libab_result _parser_allocate_type(libab_parsetype** into, const char* source, size_t from, size_t to) { libab_result result = LIBAB_SUCCESS; if((*into = malloc(sizeof(**into)))) { - result = libab_copy_string_range(&(*into)->name, source, from, to); + (*into)->variant = 0; + result = libab_copy_string_range(&(*into)->data_u.name, source, from, to); } else { result = LIBAB_MALLOC; } @@ -177,7 +178,7 @@ libab_result _parse_type_id(struct parser_state* state, libab_parsetype** into) *into = NULL; if(_parser_is_char(state, '\'')) { - placeholder_flag = 1; + placeholder_flag = LIBABACUS_TYPE_F_PLACE; _parser_state_step(state); } @@ -189,7 +190,7 @@ libab_result _parse_type_id(struct parser_state* state, libab_parsetype** into) } if(result == LIBAB_SUCCESS) { - (*into)->variant = placeholder_flag ? PT_PLACEHOLDER : PT_STRING; + (*into)->variant |= placeholder_flag; _parser_state_step(state); } @@ -199,11 +200,11 @@ libab_result _parse_type_id(struct parser_state* state, libab_parsetype** into) } else { result = libab_convert_ds_result(vec_init(&(*into)->children)); if(result != LIBAB_SUCCESS) { - free((*into)->name); + free((*into)->data_u.name); free(*into); *into = NULL; } else { - (*into)->variant = PT_PARENT; + (*into)->variant |= LIBABACUS_TYPE_F_PARENT; _parser_state_step(state); result = _parse_type_list(state, &(*into)->children, ')'); } @@ -222,10 +223,10 @@ libab_result _parse_type_function(struct parser_state* state, libab_parsetype** into) { libab_result result = _parser_allocate_type(into, "function", 0, 8); if(result == LIBAB_SUCCESS) { - (*into)->variant = PT_PARENT; + (*into)->variant |= LIBABACUS_TYPE_F_PARENT; result = libab_convert_ds_result(vec_init(&(*into)->children)); if(result != LIBAB_SUCCESS) { - free((*into)->name); + free((*into)->data_u.name); free(*into); *into = NULL; } else { @@ -257,10 +258,10 @@ libab_result _parse_type_array(struct parser_state* state, libab_parsetype** into) { libab_result result = _parser_allocate_type(into, "array", 0, 5); if(result == LIBAB_SUCCESS) { - (*into)->variant = PT_PARENT; + (*into)->variant |= LIBABACUS_TYPE_F_PARENT; result = libab_convert_ds_result(vec_init(&(*into)->children)); if(result != LIBAB_SUCCESS) { - free((*into)->name); + free((*into)->data_u.name); free(*into); *into = NULL; } else { diff --git a/src/parsetype.c b/src/parsetype.c index b2a5360..e270ab0 100644 --- a/src/parsetype.c +++ b/src/parsetype.c @@ -6,10 +6,12 @@ int _foreach_free_child(void* data, va_list args) { return 0; } void libab_parsetype_free(libab_parsetype* type) { - free(type->name); + if(!(type->variant & LIBABACUS_TYPE_F_RESOLVED)) { + free(type->data_u.name); + } } void libab_parsetype_free_recursive(libab_parsetype* type) { - if(type->variant == PT_PARENT) { + if(type->variant & LIBABACUS_TYPE_F_PARENT) { vec_foreach(&(type->children), NULL, compare_always, _foreach_free_child); vec_free(&(type->children)); } diff --git a/src/type.c b/src/type.c deleted file mode 100644 index 8cb1cef..0000000 --- a/src/type.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "type.h" - -libab_result libab_type_init(libab_type* type, libab_basetype* base) { - type->base = base; - return libab_ref_vec_init(&type->params); -} - -void libab_type_free(libab_type* type) { - libab_ref_vec_free(&type->params); -} diff --git a/src/value.c b/src/value.c index 6515065..99c5be1 100644 --- a/src/value.c +++ b/src/value.c @@ -1,4 +1,5 @@ #include "value.h" +#include "parsetype.h" void libab_value_init(libab_value* value, void* data, libab_ref* type) { value->data = data; @@ -7,9 +8,9 @@ void libab_value_init(libab_value* value, void* data, libab_ref* type) { void libab_value_free(libab_value* value) { void (*free_function)(void*); - libab_type* value_type; + libab_parsetype* value_type; libab_ref_free(&value->type); value_type = libab_ref_get(&value->type); - free_function = value_type->base->free_function; + free_function = value_type->data_u.base->free_function; if(free_function) free_function(value->data); }