Resolve function types when they're created.

This commit is contained in:
2018-06-17 19:01:15 -07:00
parent b9b6a8ec4b
commit f83b7d169c
4 changed files with 118 additions and 43 deletions

View File

@@ -45,7 +45,7 @@ libab_result _libab_check_parsetype(libab_parsetype* to_check) {
libab_result result = LIBAB_SUCCESS;
return result;
}
libab_result libab_resolve_parsetype(libab_parsetype* to_resolve,
libab_result libab_resolve_parsetype_inplace(libab_parsetype* to_resolve,
libab_table* scope) {
libab_result result = LIBAB_SUCCESS;
int resolve_name, check_parents;
@@ -61,7 +61,7 @@ libab_result libab_resolve_parsetype(libab_parsetype* to_resolve,
if (resolve_name && result == LIBAB_SUCCESS) {
libab_basetype* basetype =
libab_table_search_basetype(scope, to_resolve->data_u.name);
libab_get_basetype(to_resolve, scope);
if (basetype) {
free(to_resolve->data_u.name);
to_resolve->data_u.base = basetype;
@@ -81,7 +81,7 @@ libab_result libab_resolve_parsetype(libab_parsetype* to_resolve,
if (to_resolve->variant & LIBABACUS_TYPE_F_PARENT) {
while (result == LIBAB_SUCCESS && index < to_resolve->children.size) {
result = libab_resolve_parsetype(
result = libab_resolve_parsetype_inplace(
libab_ref_get(&to_resolve->children.data[index]), scope);
index++;
}
@@ -90,14 +90,61 @@ libab_result libab_resolve_parsetype(libab_parsetype* to_resolve,
return result;
}
void _libab_free_parsetype(void* parsetype) {
libab_parsetype_free(parsetype);
free(parsetype);
}
libab_result libab_resolve_parsetype_copy(libab_parsetype* to_resolve,
libab_table* scope,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS;
libab_parsetype* parsetype;
if((parsetype = malloc(sizeof(*parsetype)))) {
parsetype->variant = to_resolve->variant | LIBABACUS_TYPE_F_RESOLVED;
} else {
result = LIBAB_MALLOC;
}
void _libab_parsetype_free(void* parsetype) {
libab_parsetype_free(parsetype);
free(parsetype);
if(result == LIBAB_SUCCESS) {
libab_basetype* parent_basetype = libab_get_basetype(to_resolve, scope);
if(parent_basetype) {
parsetype->data_u.base = parent_basetype;
} else {
result = LIBAB_UNKNOWN_TYPE;
}
}
if(result == LIBAB_SUCCESS && (to_resolve->variant & LIBABACUS_TYPE_F_PARENT)) {
result = libab_ref_vec_init(&parsetype->children);
}
if(result == LIBAB_SUCCESS && (to_resolve->variant & LIBABACUS_TYPE_F_PARENT)) {
size_t i;
libab_ref temp;
libab_ref new_type;
for(i = 0; i < to_resolve->children.size && result == LIBAB_SUCCESS; i++) {
libab_ref_vec_index(&to_resolve->children, i, &temp);
result = libab_resolve_parsetype_copy(libab_ref_get(&temp), scope, &new_type);
if(result == LIBAB_SUCCESS) {
libab_ref_vec_insert(&parsetype->children, &new_type);
}
libab_ref_free(&new_type);
libab_ref_free(&temp);
}
if(result != LIBAB_SUCCESS) {
libab_ref_vec_free(&parsetype->children);
}
}
if(result == LIBAB_SUCCESS) {
result = libab_ref_new(into, parsetype, free_parsetype);
if(result != LIBAB_SUCCESS) libab_parsetype_free(parsetype);
}
if(result != LIBAB_SUCCESS) {
free(parsetype);
libab_ref_null(into);
}
return result;
}
libab_result libab_instantiate_basetype(libab_basetype* to_instantiate,
@@ -115,7 +162,7 @@ libab_result libab_instantiate_basetype(libab_basetype* to_instantiate,
}
if (result == LIBAB_SUCCESS) {
result = libab_ref_new(into, parsetype, _libab_parsetype_free);
result = libab_ref_new(into, parsetype, free_parsetype);
if (result != LIBAB_SUCCESS) {
libab_parsetype_free(parsetype);
}
@@ -332,6 +379,22 @@ libab_result libab_put_table_value(libab_table* table, const char* key,
return result;
}
libab_basetype* libab_get_basetype(libab_parsetype* type, libab_table* scope) {
libab_ref type_param;
libab_basetype* to_return;
if(type->variant & LIBABACUS_TYPE_F_RESOLVED) {
to_return = type->data_u.base;
} else {
to_return = libab_table_search_basetype(scope, type->data_u.name);
if(to_return == NULL) {
libab_table_search_type_param(scope, type->data_u.name, &type_param);
to_return = libab_ref_get(&type_param);
libab_ref_free(&type_param);
}
}
return to_return;
}
void* libab_unwrap_value(libab_ref* ref) {
libab_value* value = libab_ref_get(ref);
return libab_ref_get(&value->data);