diff --git a/CMakeLists.txt b/CMakeLists.txt index 89ab926..6377365 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) +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) add_executable(libabacus src/main.c) add_subdirectory(external/liblex) diff --git a/include/parsetype.h b/include/parsetype.h new file mode 100644 index 0000000..63cd443 --- /dev/null +++ b/include/parsetype.h @@ -0,0 +1,56 @@ +#ifndef LIBABACUS_PARSETYPE_H +#define LIBABACUS_PARSETYPE_H + +#include "result.h" +#include "vec.h" + +/** + * The variant of the given parse type. + */ +enum libab_parsetype_variant_e { + PT_STRING, + PT_PARENT +}; + +/** + * A parse type. + * A parse type is a type as it was parsed, not + * resolved. Effectively, it doesn't have to be valid, + * or it can contain references to types whose adresses + * are not yet known. The parse type is recursive, + * with PT_STRING being the "base case", and PT_PARENT + * meaning an initialized children vector with the sub-parse types. + */ +struct libab_parsetype_s { + /** + * The variant of the given parse type. + */ + enum libab_parsetype_variant_e variant; + /** + * The name of the type that this parse type describes. + */ + char* name; + /** + * A vector of children that this parse type contains. + * The children are effectively type parameters. + */ + vec children; +}; + +typedef enum libab_parsetype_variant_e libab_parsetype_variant; +typedef struct libab_parsetype_s libab_parsetype; + +/** + * Frees the data associated with this type, ignoring + * its children. + * @param type the type to free. + */ +void libab_parsetype_free(libab_parsetype* type); +/** + * Recursively frees the given parse type, calling free + * on every single type (including the one passed in). + * @param type the type to free. + */ +void libab_parsetype_free_recursive(libab_parsetype* type); + +#endif diff --git a/src/parsetype.c b/src/parsetype.c new file mode 100644 index 0000000..b2a5360 --- /dev/null +++ b/src/parsetype.c @@ -0,0 +1,18 @@ +#include "parsetype.h" +#include + +int _foreach_free_child(void* data, va_list args) { + libab_parsetype_free_recursive(data); + return 0; +} +void libab_parsetype_free(libab_parsetype* type) { + free(type->name); +} +void libab_parsetype_free_recursive(libab_parsetype* type) { + if(type->variant == PT_PARENT) { + vec_foreach(&(type->children), NULL, compare_always, _foreach_free_child); + vec_free(&(type->children)); + } + libab_parsetype_free(type); + free(type); +}