diff --git a/CMakeLists.txt b/CMakeLists.txt index b630868..40ac8da 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) +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) add_executable(libabacus src/main.c) add_subdirectory(external/liblex) diff --git a/include/type.h b/include/type.h new file mode 100644 index 0000000..631f571 --- /dev/null +++ b/include/type.h @@ -0,0 +1,38 @@ +#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 new file mode 100644 index 0000000..d523f6b --- /dev/null +++ b/include/value.h @@ -0,0 +1,37 @@ +#ifndef LIBABACUS_VALUE_H +#define LIBABACUS_VALUE_H + +#include "type.h" +#include "result.h" + +/** + * A struct that represents a value. + */ +struct libab_value_s { + /** + * The type of the value. + */ + libab_ref type; + /** + * The data that is specific to this value. + */ + void* data; +}; + +typedef struct libab_value_s libab_value; + +/** + * Initializes a new value with the given allocated memory for the data, + * and the given type. + * @param data the data for this value. It is freed when the value is released + * according to the free function of the base type. + * @param type the type of this value. + */ +void libab_value_init(libab_value* value, void* data, libab_ref* type); +/** + * Frees the given value. + * @param value the value to free. + */ +void libab_value_free(libab_value* value); + +#endif diff --git a/src/type.c b/src/type.c new file mode 100644 index 0000000..8cb1cef --- /dev/null +++ b/src/type.c @@ -0,0 +1,10 @@ +#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 new file mode 100644 index 0000000..6515065 --- /dev/null +++ b/src/value.c @@ -0,0 +1,15 @@ +#include "value.h" + +void libab_value_init(libab_value* value, void* data, libab_ref* type) { + value->data = data; + libab_ref_copy(type, &value->type); +} + +void libab_value_free(libab_value* value) { + void (*free_function)(void*); + libab_type* value_type; + libab_ref_free(&value->type); + value_type = libab_ref_get(&value->type); + free_function = value_type->base->free_function; + if(free_function) free_function(value->data); +}