Merge type and parsetype into a single struct.

It doesn't make sense to re-create the same structure, or even
re-allocated any of the memory.
This commit is contained in:
Danila Fedorin 2018-04-17 15:49:09 -07:00
parent ade89ebf79
commit 264f420186
8 changed files with 35 additions and 75 deletions

View File

@ -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)

View File

@ -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;
/**

View File

@ -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

View File

@ -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.

View File

@ -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 {

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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);
}