Search scope as well as type map for type parameters.
This commit is contained in:
parent
065554bcdf
commit
763cfdd7a3
|
@ -74,6 +74,28 @@ int _interpreter_type_contains_placeholders(libab_ref* type) {
|
||||||
return placeholder;
|
return placeholder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _interpreter_search_type_param(libab_ref_trie* params,
|
||||||
|
libab_ref* scope,
|
||||||
|
const char* name,
|
||||||
|
libab_ref* into) {
|
||||||
|
libab_ref_trie_get(params, name, into);
|
||||||
|
|
||||||
|
if(libab_ref_get(into) == NULL) {
|
||||||
|
libab_table_search_type_param(libab_ref_get(scope), name, into);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libab_parsetype* _interpreter_search_type_param_raw(libab_ref_trie* params,
|
||||||
|
libab_ref* scope,
|
||||||
|
const char* name) {
|
||||||
|
libab_ref into;
|
||||||
|
libab_parsetype* to_return;
|
||||||
|
_interpreter_search_type_param(params, scope, name, &into);
|
||||||
|
to_return = libab_ref_get(&into);
|
||||||
|
libab_ref_free(&into);
|
||||||
|
return to_return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares the two types, filling in any missing type parameters
|
* Compares the two types, filling in any missing type parameters
|
||||||
* in the respective type tries.
|
* in the respective type tries.
|
||||||
|
@ -86,13 +108,13 @@ int _interpreter_type_contains_placeholders(libab_ref* type) {
|
||||||
libab_result _interpreter_compare_types(libab_ref* left_type,
|
libab_result _interpreter_compare_types(libab_ref* left_type,
|
||||||
libab_ref* right_type,
|
libab_ref* right_type,
|
||||||
libab_ref_trie* left_params,
|
libab_ref_trie* left_params,
|
||||||
libab_ref_trie* right_params) {
|
libab_ref_trie* right_params,
|
||||||
|
libab_ref* scope) {
|
||||||
libab_result result = LIBAB_SUCCESS;
|
libab_result result = LIBAB_SUCCESS;
|
||||||
int left_placeholder;
|
int left_placeholder;
|
||||||
int right_placeholder;
|
int right_placeholder;
|
||||||
libab_parsetype* left = libab_ref_get(left_type);
|
libab_parsetype* left = libab_ref_get(left_type);
|
||||||
libab_parsetype* right = libab_ref_get(right_type);
|
libab_parsetype* right = libab_ref_get(right_type);
|
||||||
libab_ref param_type;
|
|
||||||
|
|
||||||
left_placeholder = left->variant & LIBABACUS_TYPE_F_PLACE;
|
left_placeholder = left->variant & LIBABACUS_TYPE_F_PLACE;
|
||||||
right_placeholder = right->variant & LIBABACUS_TYPE_F_PLACE;
|
right_placeholder = right->variant & LIBABACUS_TYPE_F_PLACE;
|
||||||
|
@ -101,9 +123,7 @@ libab_result _interpreter_compare_types(libab_ref* left_type,
|
||||||
} else {
|
} else {
|
||||||
if (left_placeholder) {
|
if (left_placeholder) {
|
||||||
const char* name = left->data_u.name;
|
const char* name = left->data_u.name;
|
||||||
libab_ref_trie_get(left_params, name, ¶m_type);
|
left = _interpreter_search_type_param_raw(left_params, scope, name);
|
||||||
left = libab_ref_get(¶m_type);
|
|
||||||
libab_ref_free(¶m_type);
|
|
||||||
if (left == NULL) {
|
if (left == NULL) {
|
||||||
if (!_interpreter_type_contains_placeholders(right_type)) {
|
if (!_interpreter_type_contains_placeholders(right_type)) {
|
||||||
result = libab_ref_trie_put(left_params, name, right_type);
|
result = libab_ref_trie_put(left_params, name, right_type);
|
||||||
|
@ -113,9 +133,7 @@ libab_result _interpreter_compare_types(libab_ref* left_type,
|
||||||
}
|
}
|
||||||
} else if (right_placeholder) {
|
} else if (right_placeholder) {
|
||||||
const char* name = right->data_u.name;
|
const char* name = right->data_u.name;
|
||||||
libab_ref_trie_get(right_params, name, ¶m_type);
|
right = _interpreter_search_type_param_raw(right_params, scope, name);
|
||||||
right = libab_ref_get(¶m_type);
|
|
||||||
libab_ref_free(¶m_type);
|
|
||||||
if (right == NULL) {
|
if (right == NULL) {
|
||||||
if (!_interpreter_type_contains_placeholders(left_type)) {
|
if (!_interpreter_type_contains_placeholders(left_type)) {
|
||||||
result = libab_ref_trie_put(right_params, name, left_type);
|
result = libab_ref_trie_put(right_params, name, left_type);
|
||||||
|
@ -149,7 +167,7 @@ libab_result _interpreter_compare_types(libab_ref* left_type,
|
||||||
libab_ref_vec_index(&left->children, index, &temp_left);
|
libab_ref_vec_index(&left->children, index, &temp_left);
|
||||||
libab_ref_vec_index(&right->children, index, &temp_right);
|
libab_ref_vec_index(&right->children, index, &temp_right);
|
||||||
result = _interpreter_compare_types(
|
result = _interpreter_compare_types(
|
||||||
&temp_left, &temp_right, left_params, right_params);
|
&temp_left, &temp_right, left_params, right_params, scope);
|
||||||
libab_ref_free(&temp_left);
|
libab_ref_free(&temp_left);
|
||||||
libab_ref_free(&temp_right);
|
libab_ref_free(&temp_right);
|
||||||
}
|
}
|
||||||
|
@ -170,6 +188,7 @@ libab_result _interpreter_compare_types(libab_ref* left_type,
|
||||||
*/
|
*/
|
||||||
libab_result _interpreter_copy_resolved_type(libab_ref* type,
|
libab_result _interpreter_copy_resolved_type(libab_ref* type,
|
||||||
libab_ref_trie* params,
|
libab_ref_trie* params,
|
||||||
|
libab_ref* scope,
|
||||||
libab_ref* into) {
|
libab_ref* into) {
|
||||||
libab_result result = LIBAB_SUCCESS;
|
libab_result result = LIBAB_SUCCESS;
|
||||||
libab_parsetype* copy;
|
libab_parsetype* copy;
|
||||||
|
@ -177,7 +196,7 @@ libab_result _interpreter_copy_resolved_type(libab_ref* type,
|
||||||
|
|
||||||
original = libab_ref_get(type);
|
original = libab_ref_get(type);
|
||||||
if (original->variant & LIBABACUS_TYPE_F_PLACE) {
|
if (original->variant & LIBABACUS_TYPE_F_PLACE) {
|
||||||
libab_ref_trie_get(params, original->data_u.name, into);
|
_interpreter_search_type_param(params, scope, original->data_u.name, into);
|
||||||
} else if ((copy = malloc(sizeof(*copy)))) {
|
} else if ((copy = malloc(sizeof(*copy)))) {
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
copy->variant = original->variant;
|
copy->variant = original->variant;
|
||||||
|
@ -190,7 +209,7 @@ libab_result _interpreter_copy_resolved_type(libab_ref* type,
|
||||||
index++) {
|
index++) {
|
||||||
libab_ref_vec_index(&original->children, index, &temp_child);
|
libab_ref_vec_index(&original->children, index, &temp_child);
|
||||||
result = _interpreter_copy_resolved_type(&temp_child, params,
|
result = _interpreter_copy_resolved_type(&temp_child, params,
|
||||||
&child_copy);
|
scope, &child_copy);
|
||||||
if (result == LIBAB_SUCCESS) {
|
if (result == LIBAB_SUCCESS) {
|
||||||
result = libab_ref_vec_insert(©->children, &child_copy);
|
result = libab_ref_vec_insert(©->children, &child_copy);
|
||||||
}
|
}
|
||||||
|
@ -230,10 +249,11 @@ libab_result _interpreter_copy_resolved_type(libab_ref* type,
|
||||||
*/
|
*/
|
||||||
libab_result _interpreter_resolve_type_params(libab_ref* type,
|
libab_result _interpreter_resolve_type_params(libab_ref* type,
|
||||||
libab_ref_trie* params,
|
libab_ref_trie* params,
|
||||||
|
libab_ref* scope,
|
||||||
libab_ref* into) {
|
libab_ref* into) {
|
||||||
libab_result result = LIBAB_SUCCESS;
|
libab_result result = LIBAB_SUCCESS;
|
||||||
if (_interpreter_type_contains_placeholders(type)) {
|
if (_interpreter_type_contains_placeholders(type)) {
|
||||||
result = _interpreter_copy_resolved_type(type, params, into);
|
result = _interpreter_copy_resolved_type(type, params, scope, into);
|
||||||
} else {
|
} else {
|
||||||
libab_ref_copy(type, into);
|
libab_ref_copy(type, into);
|
||||||
}
|
}
|
||||||
|
@ -251,6 +271,7 @@ libab_result _interpreter_resolve_type_params(libab_ref* type,
|
||||||
libab_result _interpreter_check_types(libab_ref_vec* reference_types,
|
libab_result _interpreter_check_types(libab_ref_vec* reference_types,
|
||||||
libab_ref_vec* params,
|
libab_ref_vec* params,
|
||||||
libab_ref_vec* types,
|
libab_ref_vec* types,
|
||||||
|
libab_ref* scope,
|
||||||
libab_ref_trie* param_map) {
|
libab_ref_trie* param_map) {
|
||||||
libab_result result = LIBAB_SUCCESS;
|
libab_result result = LIBAB_SUCCESS;
|
||||||
libab_ref_trie function_params;
|
libab_ref_trie function_params;
|
||||||
|
@ -274,11 +295,11 @@ libab_result _interpreter_check_types(libab_ref_vec* reference_types,
|
||||||
right_temp =
|
right_temp =
|
||||||
&((libab_value*)libab_ref_get(&right_value_temp))->type;
|
&((libab_value*)libab_ref_get(&right_value_temp))->type;
|
||||||
result = _interpreter_compare_types(
|
result = _interpreter_compare_types(
|
||||||
&left_temp, right_temp, &function_params, &child_params);
|
&left_temp, right_temp, &function_params, &child_params, scope);
|
||||||
|
|
||||||
if (result == LIBAB_SUCCESS) {
|
if (result == LIBAB_SUCCESS) {
|
||||||
result = _interpreter_resolve_type_params(
|
result = _interpreter_resolve_type_params(
|
||||||
right_temp, &child_params, &produced_type);
|
right_temp, &child_params, scope, &produced_type);
|
||||||
if (result != LIBAB_SUCCESS) {
|
if (result != LIBAB_SUCCESS) {
|
||||||
libab_ref_free(&produced_type);
|
libab_ref_free(&produced_type);
|
||||||
}
|
}
|
||||||
|
@ -329,15 +350,18 @@ libab_result _interpreter_find_match(libab_function_list* function_values,
|
||||||
libab_ref_trie temp_param_map;
|
libab_ref_trie temp_param_map;
|
||||||
libab_ref_vec temp_new_types;
|
libab_ref_vec temp_new_types;
|
||||||
libab_ref temp_function_value;
|
libab_ref temp_function_value;
|
||||||
|
libab_value* temp_value;
|
||||||
libab_parsetype* temp_function_type;
|
libab_parsetype* temp_function_type;
|
||||||
|
libab_function* temp_function;
|
||||||
|
|
||||||
libab_ref_null(match);
|
libab_ref_null(match);
|
||||||
result = libab_ref_vec_init(&temp_new_types);
|
result = libab_ref_vec_init(&temp_new_types);
|
||||||
|
|
||||||
for (; index < list_size && result == LIBAB_SUCCESS; index++) {
|
for (; index < list_size && result == LIBAB_SUCCESS; index++) {
|
||||||
libab_function_list_index(function_values, index, &temp_function_value);
|
libab_function_list_index(function_values, index, &temp_function_value);
|
||||||
temp_function_type = libab_ref_get(
|
temp_value = libab_ref_get(&temp_function_value);
|
||||||
&((libab_value*)libab_ref_get(&temp_function_value))->type);
|
temp_function_type = libab_ref_get(&temp_value->type);
|
||||||
|
temp_function = libab_ref_get(&temp_value->data);
|
||||||
|
|
||||||
if (((temp_function_type->children.size == params->size + 1) &&
|
if (((temp_function_type->children.size == params->size + 1) &&
|
||||||
!partial) ||
|
!partial) ||
|
||||||
|
@ -345,7 +369,7 @@ libab_result _interpreter_find_match(libab_function_list* function_values,
|
||||||
partial)) {
|
partial)) {
|
||||||
/* We found a function that has the correct number of parameters. */
|
/* We found a function that has the correct number of parameters. */
|
||||||
result = _interpreter_check_types(
|
result = _interpreter_check_types(
|
||||||
&temp_function_type->children, params, &temp_new_types, &temp_param_map);
|
&temp_function_type->children, params, &temp_new_types, &temp_function->scope, &temp_param_map);
|
||||||
if (result == LIBAB_MISMATCHED_TYPE) {
|
if (result == LIBAB_MISMATCHED_TYPE) {
|
||||||
/* Mismatch is OK. */
|
/* Mismatch is OK. */
|
||||||
result = LIBAB_SUCCESS;
|
result = LIBAB_SUCCESS;
|
||||||
|
@ -766,15 +790,17 @@ libab_result _interpreter_call_function(struct interpreter_state* state,
|
||||||
libab_ref_trie param_map;
|
libab_ref_trie param_map;
|
||||||
libab_value* function_value;
|
libab_value* function_value;
|
||||||
libab_parsetype* function_type;
|
libab_parsetype* function_type;
|
||||||
|
libab_function* function_instance;
|
||||||
|
|
||||||
function_value = libab_ref_get(function);
|
function_value = libab_ref_get(function);
|
||||||
function_type = libab_ref_get(&function_value->type);
|
function_type = libab_ref_get(&function_value->type);
|
||||||
|
function_instance = libab_ref_get(&function_value->data);
|
||||||
libab_ref_null(into);
|
libab_ref_null(into);
|
||||||
|
|
||||||
result = libab_ref_vec_init(&temp_new_types);
|
result = libab_ref_vec_init(&temp_new_types);
|
||||||
if (result == LIBAB_SUCCESS) {
|
if (result == LIBAB_SUCCESS) {
|
||||||
result = _interpreter_check_types(&function_type->children,
|
result = _interpreter_check_types(&function_type->children,
|
||||||
params, &temp_new_types, ¶m_map);
|
params, &temp_new_types, &function_instance->scope, ¶m_map);
|
||||||
|
|
||||||
if (result == LIBAB_SUCCESS) {
|
if (result == LIBAB_SUCCESS) {
|
||||||
libab_ref_free(into);
|
libab_ref_free(into);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user