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:
parent
ade89ebf79
commit
264f420186
|
@ -8,7 +8,7 @@ project(libabacus)
|
||||||
|
|
||||||
add_compile_options(-pedantic -Wall)
|
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_executable(libabacus src/main.c)
|
||||||
add_subdirectory(external/liblex)
|
add_subdirectory(external/liblex)
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,11 @@
|
||||||
|
|
||||||
#include "result.h"
|
#include "result.h"
|
||||||
#include "vec.h"
|
#include "vec.h"
|
||||||
|
#include "basetype.h"
|
||||||
|
|
||||||
/**
|
#define LIBABACUS_TYPE_F_PARENT (1)
|
||||||
* The variant of the given parse type.
|
#define LIBABACUS_TYPE_F_PLACE (1 << 1)
|
||||||
*/
|
#define LIBABACUS_TYPE_F_RESOLVED (1 << 2)
|
||||||
enum libab_parsetype_variant_e {
|
|
||||||
PT_STRING,
|
|
||||||
PT_PLACEHOLDER,
|
|
||||||
PT_PARENT
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A parse type.
|
* A parse type.
|
||||||
|
@ -26,11 +22,20 @@ struct libab_parsetype_s {
|
||||||
/**
|
/**
|
||||||
* The variant of the given parse type.
|
* 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.
|
* A vector of children that this parse type contains.
|
||||||
* The children are effectively type parameters.
|
* The children are effectively type parameters.
|
||||||
|
@ -38,7 +43,6 @@ struct libab_parsetype_s {
|
||||||
vec children;
|
vec children;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum libab_parsetype_variant_e libab_parsetype_variant;
|
|
||||||
typedef struct libab_parsetype_s libab_parsetype;
|
typedef struct libab_parsetype_s libab_parsetype;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef LIBABACUS_VALUE_H
|
#ifndef LIBABACUS_VALUE_H
|
||||||
#define LIBABACUS_VALUE_H
|
#define LIBABACUS_VALUE_H
|
||||||
|
|
||||||
#include "type.h"
|
|
||||||
#include "result.h"
|
#include "result.h"
|
||||||
|
#include "refcount.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A struct that represents a value.
|
* A struct that represents a value.
|
||||||
|
|
19
src/parser.c
19
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 _parser_allocate_type(libab_parsetype** into, const char* source, size_t from, size_t to) {
|
||||||
libab_result result = LIBAB_SUCCESS;
|
libab_result result = LIBAB_SUCCESS;
|
||||||
if((*into = malloc(sizeof(**into)))) {
|
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 {
|
} else {
|
||||||
result = LIBAB_MALLOC;
|
result = LIBAB_MALLOC;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +178,7 @@ libab_result _parse_type_id(struct parser_state* state, libab_parsetype** into)
|
||||||
*into = NULL;
|
*into = NULL;
|
||||||
|
|
||||||
if(_parser_is_char(state, '\'')) {
|
if(_parser_is_char(state, '\'')) {
|
||||||
placeholder_flag = 1;
|
placeholder_flag = LIBABACUS_TYPE_F_PLACE;
|
||||||
_parser_state_step(state);
|
_parser_state_step(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +190,7 @@ libab_result _parse_type_id(struct parser_state* state, libab_parsetype** into)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
(*into)->variant = placeholder_flag ? PT_PLACEHOLDER : PT_STRING;
|
(*into)->variant |= placeholder_flag;
|
||||||
_parser_state_step(state);
|
_parser_state_step(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,11 +200,11 @@ libab_result _parse_type_id(struct parser_state* state, libab_parsetype** into)
|
||||||
} else {
|
} else {
|
||||||
result = libab_convert_ds_result(vec_init(&(*into)->children));
|
result = libab_convert_ds_result(vec_init(&(*into)->children));
|
||||||
if(result != LIBAB_SUCCESS) {
|
if(result != LIBAB_SUCCESS) {
|
||||||
free((*into)->name);
|
free((*into)->data_u.name);
|
||||||
free(*into);
|
free(*into);
|
||||||
*into = NULL;
|
*into = NULL;
|
||||||
} else {
|
} else {
|
||||||
(*into)->variant = PT_PARENT;
|
(*into)->variant |= LIBABACUS_TYPE_F_PARENT;
|
||||||
_parser_state_step(state);
|
_parser_state_step(state);
|
||||||
result = _parse_type_list(state, &(*into)->children, ')');
|
result = _parse_type_list(state, &(*into)->children, ')');
|
||||||
}
|
}
|
||||||
|
@ -222,10 +223,10 @@ libab_result _parse_type_function(struct parser_state* state,
|
||||||
libab_parsetype** into) {
|
libab_parsetype** into) {
|
||||||
libab_result result = _parser_allocate_type(into, "function", 0, 8);
|
libab_result result = _parser_allocate_type(into, "function", 0, 8);
|
||||||
if(result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
(*into)->variant = PT_PARENT;
|
(*into)->variant |= LIBABACUS_TYPE_F_PARENT;
|
||||||
result = libab_convert_ds_result(vec_init(&(*into)->children));
|
result = libab_convert_ds_result(vec_init(&(*into)->children));
|
||||||
if(result != LIBAB_SUCCESS) {
|
if(result != LIBAB_SUCCESS) {
|
||||||
free((*into)->name);
|
free((*into)->data_u.name);
|
||||||
free(*into);
|
free(*into);
|
||||||
*into = NULL;
|
*into = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -257,10 +258,10 @@ libab_result _parse_type_array(struct parser_state* state,
|
||||||
libab_parsetype** into) {
|
libab_parsetype** into) {
|
||||||
libab_result result = _parser_allocate_type(into, "array", 0, 5);
|
libab_result result = _parser_allocate_type(into, "array", 0, 5);
|
||||||
if(result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
(*into)->variant = PT_PARENT;
|
(*into)->variant |= LIBABACUS_TYPE_F_PARENT;
|
||||||
result = libab_convert_ds_result(vec_init(&(*into)->children));
|
result = libab_convert_ds_result(vec_init(&(*into)->children));
|
||||||
if(result != LIBAB_SUCCESS) {
|
if(result != LIBAB_SUCCESS) {
|
||||||
free((*into)->name);
|
free((*into)->data_u.name);
|
||||||
free(*into);
|
free(*into);
|
||||||
*into = NULL;
|
*into = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -6,10 +6,12 @@ int _foreach_free_child(void* data, va_list args) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void libab_parsetype_free(libab_parsetype* type) {
|
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) {
|
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_foreach(&(type->children), NULL, compare_always, _foreach_free_child);
|
||||||
vec_free(&(type->children));
|
vec_free(&(type->children));
|
||||||
}
|
}
|
||||||
|
|
10
src/type.c
10
src/type.c
|
@ -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);
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
|
#include "parsetype.h"
|
||||||
|
|
||||||
void libab_value_init(libab_value* value, void* data, libab_ref* type) {
|
void libab_value_init(libab_value* value, void* data, libab_ref* type) {
|
||||||
value->data = data;
|
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 libab_value_free(libab_value* value) {
|
||||||
void (*free_function)(void*);
|
void (*free_function)(void*);
|
||||||
libab_type* value_type;
|
libab_parsetype* value_type;
|
||||||
libab_ref_free(&value->type);
|
libab_ref_free(&value->type);
|
||||||
value_type = libab_ref_get(&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);
|
if(free_function) free_function(value->data);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user