diff --git a/include/interpreter.h b/include/interpreter.h index e738752..ee8eadb 100644 --- a/include/interpreter.h +++ b/include/interpreter.h @@ -34,6 +34,18 @@ void libab_interpreter_init(libab_interpreter* intr, struct libab_s* ab); */ libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree, libab_ref* into); +/** + * Calls a function with the given parameters. + * @param intr the interpreter to use to call the function. + * @param function the function to call. + * @param params the parameters to pass to the function. + * @param into the reference to store the result into. + * @return the result of the call. + */ +libab_result libab_interpreter_run_function(libab_interpreter* intr, + const char* function, + libab_ref_vec* params, + libab_ref* into); /** * Frees the given interpreter. * @param intr the interpreter to free. diff --git a/include/libabacus.h b/include/libabacus.h index 8dc1460..66bc6ae 100644 --- a/include/libabacus.h +++ b/include/libabacus.h @@ -174,6 +174,17 @@ void libab_get_type_function_list(libab* ab, libab_ref* into); * @return the result of the computation. */ libab_result libab_run(libab* ab, const char* string, libab_ref* value); +/** + * Calls a function with the given name and parameters. + * @param ab the libabacus instance to use to call the function. + * @param function the name of the function to call. + * @param iunto the reference into which to store the result. + * @param param_count the number of parameters given to this function. + * @return the result of the call. + */ +libab_result libab_run_function(libab* ab, const char* function, + libab_ref* into, + size_t param_count, ...); /** * Releases all the resources allocated by libabacus. diff --git a/src/interpreter.c b/src/interpreter.c index e66f1be..dcc761e 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -820,4 +820,27 @@ libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree, return result; } +libab_result libab_interpreter_run_function(libab_interpreter* intr, + const char* function, + libab_ref_vec* params, + libab_ref* into) { + struct interpreter_state state; + libab_ref function_value; + libab_result result; + + _interpreter_init(&state, intr); + + libab_ref_null(into); + result = _interpreter_require_value(&state.ab->table, + function, &function_value); + if(result == LIBAB_SUCCESS) { + libab_ref_free(into); + _interpreter_try_call(&state, &function_value, params, into); + } + + _interpreter_free(&state); + + return result; +} + void libab_interpreter_free(libab_interpreter* intr) {} diff --git a/src/libabacus.c b/src/libabacus.c index dad412d..a3eca22 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -375,6 +375,33 @@ libab_result libab_run(libab* ab, const char* string, libab_ref* value) { return result; } +libab_result libab_run_function(libab* ab, const char* function, + libab_ref* into, + size_t param_count, ...) { + libab_ref_vec params; + va_list args; + libab_result result = LIBAB_SUCCESS; + + va_start(args, param_count); + libab_ref_null(into); + result = libab_ref_vec_init(¶ms); + if(result == LIBAB_SUCCESS) { + while(result == LIBAB_SUCCESS && param_count--) { + result = libab_ref_vec_insert(¶ms, va_arg(args, libab_ref*)); + } + + if(result == LIBAB_SUCCESS) { + libab_ref_free(into); + result = libab_interpreter_run_function(&ab->intr, function, ¶ms, into); + } + + libab_ref_vec_free(¶ms); + } + va_end(args); + + return result; +} + libab_result libab_free(libab* ab) { libab_table_free(libab_ref_get(&ab->table)); libab_ref_free(&ab->table);