diff --git a/include/custom.h b/include/custom.h index 2222d9c..ac41239 100644 --- a/include/custom.h +++ b/include/custom.h @@ -94,6 +94,10 @@ struct libab_function_s { * if it was created via partial application. */ libab_ref_vec params; + /** + * The scope in which this function was declared. + */ + libab_ref scope; }; typedef enum libab_operator_variant_e libab_operator_variant; @@ -143,18 +147,22 @@ void libab_operator_free(libab_operator* op); * Initializes a function with the given internal behavior. * @param function the function to initialize. * @param fun the function implementation. + * @param the parent scope in which this function was declared. * @return the result of the initialization. */ libab_result libab_function_init_internal(libab_function* function, - libab_function_ptr fun); + libab_function_ptr fun, + libab_ref* scope); /** * Initializes a function with the given tree behavior. * @param function the function to initialize. * @param tree the tree that represents the function's behavior. + * @param scope the scope in which this function was declared. * @return the result of the initialization. */ libab_result libab_function_init_tree(libab_function* function, - libab_tree* tree); + libab_tree* tree, + libab_ref* scope); /** * Frees the given function. * @param fun the function to free. diff --git a/include/util.h b/include/util.h index 936c1cb..51eac55 100644 --- a/include/util.h +++ b/include/util.h @@ -96,21 +96,25 @@ libab_result libab_create_value_raw(libab_ref* into, void* data, * @param into the reference into which to store the new function. * @param free_function the free function used to free function instances. * @param fun the function implementation. + * @param scope the scope in which this function was declared. * @return libab_result the result of any necessary allocations. */ libab_result libab_create_function_internal(libab_ref* into, void (*free_function)(void*), - libab_function_ptr fun); + libab_function_ptr fun, + libab_ref* scope); /** * Allocates a function that uses a tree to run. * @param into the reference into which to store the new function. * @param free_function the free function used to free function instances. * @param tree the function implementation. + * @param scope the scope in which this function was declared. * @return libab_result the result of any necessary allocations. */ libab_result libab_create_function_tree(libab_ref* into, void (*free_function)(void*), - libab_tree* tree); + libab_tree* tree, + libab_ref* scope); /** * Creates a function list object, storing it in to the given reference. * @param into the reference to store into. diff --git a/src/custom.c b/src/custom.c index 119fa78..3da4a9c 100644 --- a/src/custom.c +++ b/src/custom.c @@ -32,22 +32,26 @@ void libab_operator_free(libab_operator* op) { libab_behavior_free(&op->behavior); } -libab_result _function_init(libab_function* function) { +libab_result _function_init(libab_function* function, libab_ref* scope) { + libab_ref_copy(scope, &function->scope); return libab_ref_vec_init(&function->params); } libab_result libab_function_init_internal(libab_function* function, - libab_function_ptr fun) { - libab_result result = _function_init(function); + libab_function_ptr fun, + libab_ref* scope) { + libab_result result = _function_init(function, scope); libab_behavior_init_internal(&function->behavior, fun); return result; } libab_result libab_function_init_tree(libab_function* function, - libab_tree* tree) { - libab_result result = _function_init(function); + libab_tree* tree, + libab_ref* scope) { + libab_result result = _function_init(function, scope); libab_behavior_init_tree(&function->behavior, tree); return result; } void libab_function_free(libab_function* fun) { libab_behavior_free(&fun->behavior); libab_ref_vec_free(&fun->params); + libab_ref_free(&fun->scope); } diff --git a/src/libabacus.c b/src/libabacus.c index 7026028..5f06a08 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -147,10 +147,11 @@ libab_result libab_register_operator_postfix(libab* ab, const char* op, } libab_result _create_value_function_internal(libab_ref* into, libab_ref* type, - libab_function_ptr func) { + libab_function_ptr func, + libab_ref* scope) { libab_ref function_ref; libab_result result = - libab_create_function_internal(&function_ref, _free_function, func); + libab_create_function_internal(&function_ref, _free_function, func, scope); libab_ref_null(into); if (result == LIBAB_SUCCESS) { libab_ref_free(into); @@ -233,7 +234,7 @@ libab_result libab_register_function(libab* ab, const char* name, libab_table_entry* existing_entry; libab_ref function_value; libab_result result = - _create_value_function_internal(&function_value, type, func); + _create_value_function_internal(&function_value, type, func, &ab->table); if (result == LIBAB_SUCCESS) { existing_entry = libab_table_search_filter( diff --git a/src/util.c b/src/util.c index de1c3ee..2454942 100644 --- a/src/util.c +++ b/src/util.c @@ -210,12 +210,13 @@ libab_result libab_create_value_raw(libab_ref* into, void* data, libab_result libab_create_function_internal(libab_ref* into, void (*free_function)(void*), - libab_function_ptr fun) { + libab_function_ptr fun, + libab_ref* scope) { libab_function* new_function; libab_result result = LIBAB_SUCCESS; if ((new_function = malloc(sizeof(*new_function)))) { - result = libab_function_init_internal(new_function, fun); + result = libab_function_init_internal(new_function, fun, scope); } else { result = LIBAB_MALLOC; } @@ -237,12 +238,13 @@ libab_result libab_create_function_internal(libab_ref* into, libab_result libab_create_function_tree(libab_ref* into, void (*free_function)(void*), - libab_tree* tree) { + libab_tree* tree, + libab_ref* scope) { libab_function* new_function; libab_result result = LIBAB_SUCCESS; if ((new_function = malloc(sizeof(*new_function)))) { - result = libab_function_init_tree(new_function, tree); + result = libab_function_init_tree(new_function, tree, scope); } else { result = LIBAB_MALLOC; }