Compare commits
7 Commits
899ac31210
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 06f17f491c | |||
| ca6075e8d5 | |||
| 4425b27b52 | |||
| 25dd70f040 | |||
| 5617484aff | |||
| b311c854ee | |||
| c4a7117704 |
@@ -135,8 +135,9 @@ void libab_behavior_free(libab_behavior* behavior);
|
||||
* @param associativity the associativity (left = -1, right = 1) of the
|
||||
* operator.
|
||||
* @param function the function this operator represents.
|
||||
* @result the result of the initialization.
|
||||
*/
|
||||
void libab_operator_init(libab_operator* op, libab_operator_variant variant,
|
||||
libab_result libab_operator_init(libab_operator* op, libab_operator_variant variant,
|
||||
int precedence, int associativity, const char* function);
|
||||
/**
|
||||
* Frees the given operator.
|
||||
|
||||
@@ -70,11 +70,25 @@ libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree,
|
||||
* @param into the reference to store the result into.
|
||||
* @return the result of the call.
|
||||
*/
|
||||
libab_result libab_interpreter_run_function(libab_interpreter* intr,
|
||||
libab_result libab_interpreter_call_function(libab_interpreter* intr,
|
||||
libab_ref* scope,
|
||||
const char* function,
|
||||
libab_ref_vec* params,
|
||||
libab_ref* into);
|
||||
/**
|
||||
* Calls a function value with the given parameters.
|
||||
* @param intr the interpreter to use to call the function.
|
||||
* @param scope the scope in which the function should be searched for.
|
||||
* @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_call_value(libab_interpreter* intr,
|
||||
libab_ref* scope,
|
||||
libab_ref* function,
|
||||
libab_ref_vec* params,
|
||||
libab_ref* into);
|
||||
/**
|
||||
* Gets the unit value from this interpreter.
|
||||
* @param intr the interpreter from which to get the unit value.
|
||||
|
||||
@@ -232,6 +232,13 @@ void libab_get_false_value(libab* ab, libab_ref* into);
|
||||
*/
|
||||
void libab_get_bool_value(libab* ab, int val, libab_ref* into);
|
||||
|
||||
/**
|
||||
* Parses the given piece of code using the given libabacus instance.
|
||||
* @param ab the instance to use to parse the code.
|
||||
* @param string the source code to parse.
|
||||
* @param into the value to store the newly parsed tree into.
|
||||
*/
|
||||
libab_result libab_parse(libab* ab, const char* string, libab_tree** into);
|
||||
/**
|
||||
* Executes the given string of code.
|
||||
* @param ab the libabacus instance to use for executing code.
|
||||
@@ -256,7 +263,7 @@ libab_result libab_run_tree(libab* ab, libab_tree* tree, libab_ref* value);
|
||||
* @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_result libab_call_function(libab* ab, const char* function,
|
||||
libab_ref* into,
|
||||
size_t param_count, ...);
|
||||
/**
|
||||
@@ -286,7 +293,7 @@ libab_result libab_run_tree_scoped(libab* ab, libab_tree* tree, libab_ref* scope
|
||||
* @param param_count the number of parameters given to this function.
|
||||
* @return the result of the call.
|
||||
*/
|
||||
libab_result libab_run_function_scoped(libab* ab, const char* function, libab_ref* scope,
|
||||
libab_result libab_call_function_scoped(libab* ab, const char* function, libab_ref* scope,
|
||||
libab_ref* into,
|
||||
size_t param_count, ...);
|
||||
|
||||
|
||||
@@ -103,6 +103,28 @@ libab_result libab_create_value_ref(libab* ab, libab_ref* into,
|
||||
*/
|
||||
libab_result libab_create_value_raw(libab* ab, libab_ref* into,
|
||||
void* data, libab_ref* type);
|
||||
/**
|
||||
* Overloads a function of the given name.
|
||||
* @param table the table to insert the function into.
|
||||
* @param name the name of the function.
|
||||
* @param function the function to register.
|
||||
* @return the result of the overload.
|
||||
*/
|
||||
libab_result libab_overload_function(libab* ab,
|
||||
libab_table* table,
|
||||
const char* name,
|
||||
libab_ref* function);
|
||||
/**
|
||||
* Sets a value under the given name, overriding
|
||||
* an existing value if it exists.
|
||||
* @param table the table to store the value into.
|
||||
* @param name the name of the variable.
|
||||
* @param the value of the new variable.
|
||||
* @return the result of setting the variable.
|
||||
*/
|
||||
libab_result libab_set_variable(libab_table* table,
|
||||
const char* name,
|
||||
libab_ref* value);
|
||||
/**
|
||||
* Allocates a function that uses internal code to run.
|
||||
* @param into the reference into which to store the new function.
|
||||
|
||||
11
src/custom.c
11
src/custom.c
@@ -1,4 +1,5 @@
|
||||
#include "custom.h"
|
||||
#include "util.h"
|
||||
|
||||
void libab_behavior_init_internal(libab_behavior* behavior,
|
||||
libab_function_ptr func) {
|
||||
@@ -26,16 +27,20 @@ void libab_behavior_free(libab_behavior* behavior) {
|
||||
}
|
||||
}
|
||||
|
||||
void libab_operator_init(libab_operator* op, libab_operator_variant variant,
|
||||
libab_result libab_operator_init(libab_operator* op, libab_operator_variant variant,
|
||||
int precedence, int associativity, const char* function) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
char* into;
|
||||
op->variant = variant;
|
||||
op->precedence = precedence;
|
||||
op->associativity = associativity;
|
||||
op->function = function;
|
||||
result = libab_copy_string(&into, function);
|
||||
op->function = into;
|
||||
return result;
|
||||
}
|
||||
|
||||
void libab_operator_free(libab_operator* op) {
|
||||
|
||||
free((char*) op->function);
|
||||
}
|
||||
|
||||
libab_result _function_init(libab_function* function, libab_ref* scope) {
|
||||
|
||||
@@ -198,7 +198,7 @@ libab_result loop(libab* ab, int interaction_count, libab_ref* scope) {
|
||||
if (eval_result != LIBAB_SUCCESS) {
|
||||
printf("Invalid input (error code %d).\n", eval_result);
|
||||
} else {
|
||||
result = libab_run_function_scoped(ab, "print", scope, &call_into, 1, &eval_into);
|
||||
result = libab_call_function_scoped(ab, "print", scope, &call_into, 1, &eval_into);
|
||||
if(result == LIBAB_BAD_CALL) {
|
||||
printf("(?)\n");
|
||||
result = LIBAB_SUCCESS;
|
||||
|
||||
@@ -1224,7 +1224,7 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree,
|
||||
_interpreter_create_function_value(state, tree, scope, &function);
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
result = libab_put_table_value(libab_ref_get(scope),
|
||||
result = libab_overload_function(state->ab, libab_ref_get(scope),
|
||||
tree->string_value, &function);
|
||||
if(result != LIBAB_SUCCESS) {
|
||||
libab_ref_free(&function);
|
||||
@@ -1297,7 +1297,7 @@ libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree,
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_interpreter_run_function(libab_interpreter* intr,
|
||||
libab_result libab_interpreter_call_function(libab_interpreter* intr,
|
||||
libab_ref* scope,
|
||||
const char* function,
|
||||
libab_ref_vec* params,
|
||||
@@ -1322,6 +1322,21 @@ libab_result libab_interpreter_run_function(libab_interpreter* intr,
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_interpreter_call_value(libab_interpreter* intr,
|
||||
libab_ref* scope,
|
||||
libab_ref* function,
|
||||
libab_ref_vec* params,
|
||||
libab_ref* into) {
|
||||
struct interpreter_state state;
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
|
||||
_interpreter_init(&state, intr, scope);
|
||||
result = _interpreter_try_call(&state, function, params, into);
|
||||
_interpreter_free(&state);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void libab_interpreter_unit_value(libab_interpreter* intr, libab_ref* into) {
|
||||
libab_ref_copy(&intr->value_unit, into);
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ libab_result _register_operator(libab* ab, const char* op,
|
||||
if ((new_entry = malloc(sizeof(*new_entry)))) {
|
||||
new_entry->variant = ENTRY_OP;
|
||||
new_operator = &(new_entry->data_u.op);
|
||||
libab_operator_init(new_operator, token_type, precedence, associativity,
|
||||
result = libab_operator_init(new_operator, token_type, precedence, associativity,
|
||||
function);
|
||||
} else {
|
||||
result = LIBAB_MALLOC;
|
||||
@@ -161,92 +161,16 @@ libab_result _create_value_function_internal(libab* ab,
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _create_value_function_list(libab* ab, libab_ref* into, libab_ref* type) {
|
||||
libab_ref list_ref;
|
||||
libab_result result = libab_create_function_list(ab, &list_ref, type);
|
||||
libab_ref_null(into);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
libab_ref_free(into);
|
||||
result = libab_create_value_ref(ab, into, &list_ref, type);
|
||||
}
|
||||
libab_ref_free(&list_ref);
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _libab_register_function_existing(libab* ab,
|
||||
libab_table_entry* entry,
|
||||
libab_ref* function_val) {
|
||||
libab_value* old_value;
|
||||
libab_parsetype* old_type;
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
|
||||
old_value = libab_ref_get(&entry->data_u.value);
|
||||
old_type = libab_ref_get(&old_value->type);
|
||||
|
||||
if (old_type->data_u.base == &_basetype_function_list) {
|
||||
libab_function_list* list = libab_ref_get(&old_value->data);
|
||||
result = libab_function_list_insert(list, function_val);
|
||||
} else if (old_type->data_u.base == &_basetype_function) {
|
||||
libab_ref new_list;
|
||||
result =
|
||||
_create_value_function_list(ab, &new_list, &ab->type_function_list);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
libab_function_list* list =
|
||||
libab_ref_get(&((libab_value*)libab_ref_get(&new_list))->data);
|
||||
result = libab_function_list_insert(list, &entry->data_u.value);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
result = libab_function_list_insert(list, function_val);
|
||||
}
|
||||
}
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
libab_ref_swap(&entry->data_u.value, &new_list);
|
||||
}
|
||||
libab_ref_free(&new_list);
|
||||
} else {
|
||||
libab_ref_swap(&entry->data_u.value, function_val);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _libab_register_function_new(libab* ab, const char* name,
|
||||
libab_ref* function_val) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_table_entry* entry;
|
||||
if ((entry = malloc(sizeof(*entry)))) {
|
||||
entry->variant = ENTRY_VALUE;
|
||||
libab_ref_copy(function_val, &entry->data_u.value);
|
||||
result = libab_table_put(libab_ref_get(&ab->table), name, entry);
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
libab_table_entry_free(entry);
|
||||
free(entry);
|
||||
}
|
||||
} else {
|
||||
result = LIBAB_MALLOC;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_register_function(libab* ab, const char* name,
|
||||
libab_ref* type, libab_function_ptr func) {
|
||||
libab_table_entry* existing_entry;
|
||||
libab_ref function_value;
|
||||
libab_result result =
|
||||
_create_value_function_internal(ab, &function_value, type, func, &ab->table);
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
existing_entry = libab_table_search_filter(
|
||||
libab_ref_get(&ab->table), name, NULL, libab_table_compare_value);
|
||||
if (existing_entry) {
|
||||
result = _libab_register_function_existing(ab, existing_entry,
|
||||
&function_value);
|
||||
} else {
|
||||
result = _libab_register_function_new(ab, name, &function_value);
|
||||
}
|
||||
libab_ref_free(&function_value);
|
||||
libab_overload_function(ab, libab_ref_get(&ab->table), name, &function_value);
|
||||
}
|
||||
libab_ref_free(&function_value);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -406,7 +330,7 @@ void libab_get_bool_value(libab* ab, int val, libab_ref* into) {
|
||||
val ? libab_get_true_value(ab, into) : libab_get_false_value(ab, into);
|
||||
}
|
||||
|
||||
libab_result _create_tree(libab* ab, const char* string, libab_tree** into) {
|
||||
libab_result libab_parse(libab* ab, const char* string, libab_tree** into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
ll tokens;
|
||||
|
||||
@@ -442,7 +366,7 @@ libab_result libab_run(libab* ab, const char* string, libab_ref* value) {
|
||||
libab_tree* root;
|
||||
|
||||
libab_ref_null(value);
|
||||
result = _create_tree(ab, string, &root);
|
||||
result = libab_parse(ab, string, &root);
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
libab_ref_free(value);
|
||||
@@ -453,7 +377,7 @@ 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_result libab_call_function(libab* ab, const char* function,
|
||||
libab_ref* into,
|
||||
size_t param_count, ...) {
|
||||
libab_ref_vec params;
|
||||
@@ -465,7 +389,7 @@ libab_result libab_run_function(libab* ab, const char* function,
|
||||
result = _handle_va_params(ab, ¶ms, param_count, args);
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
libab_ref_free(into);
|
||||
result = libab_interpreter_run_function(&ab->intr, &ab->table, function, ¶ms, into);
|
||||
result = libab_interpreter_call_function(&ab->intr, &ab->table, function, ¶ms, into);
|
||||
|
||||
libab_ref_vec_free(¶ms);
|
||||
}
|
||||
@@ -483,7 +407,7 @@ libab_result libab_run_scoped(libab* ab, const char* string, libab_ref* scope, l
|
||||
libab_tree* root;
|
||||
|
||||
libab_ref_null(into);
|
||||
result = _create_tree(ab, string, &root);
|
||||
result = libab_parse(ab, string, &root);
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
libab_ref_free(into);
|
||||
result = libab_interpreter_run(&ab->intr, root, scope, SCOPE_NONE, into);
|
||||
@@ -493,7 +417,7 @@ libab_result libab_run_scoped(libab* ab, const char* string, libab_ref* scope, l
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_run_function_scoped(libab* ab, const char* function, libab_ref* scope, libab_ref* into,
|
||||
libab_result libab_call_function_scoped(libab* ab, const char* function, libab_ref* scope, libab_ref* into,
|
||||
size_t param_count, ...) {
|
||||
libab_ref_vec params;
|
||||
libab_result result;
|
||||
@@ -504,7 +428,7 @@ libab_result libab_run_function_scoped(libab* ab, const char* function, libab_re
|
||||
result = _handle_va_params(ab, ¶ms, param_count, args);
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
libab_ref_free(into);
|
||||
result = libab_interpreter_run_function(&ab->intr, scope, function, ¶ms, into);
|
||||
result = libab_interpreter_call_function(&ab->intr, scope, function, ¶ms, into);
|
||||
|
||||
libab_ref_vec_free(¶ms);
|
||||
}
|
||||
|
||||
@@ -525,6 +525,7 @@ libab_result _parse_fun(struct parser_state* state, libab_tree** store_into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
int is_parenth, is_comma;
|
||||
libab_tree* temp;
|
||||
*store_into = NULL;
|
||||
result = _parser_consume_type(state, TOKEN_KW_FUN);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
if (_parser_is_type(state, TOKEN_ID)) {
|
||||
|
||||
@@ -45,7 +45,7 @@ libab_result libab_parsetype_init_va(libab_parsetype* type,
|
||||
result = libab_ref_vec_insert(&type->children, ref);
|
||||
}
|
||||
|
||||
if (free_vec) {
|
||||
if (result != LIBAB_SUCCESS && free_vec) {
|
||||
libab_ref_vec_free(&type->children);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,18 +4,6 @@
|
||||
#include "value.h"
|
||||
#include "libabacus.h"
|
||||
|
||||
libab_result _update_entry(libab_table* table, const char* name, libab_ref* value) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_table_entry* value_entry = libab_table_search_entry_value(table, name);
|
||||
if(value_entry) {
|
||||
libab_ref_free(&value_entry->data_u.value);
|
||||
libab_ref_copy(value, &value_entry->data_u.value);
|
||||
} else {
|
||||
result = libab_put_table_value(table, name, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _behavior_assign(libab* ab, libab_ref* scope,
|
||||
libab_tree* left, libab_tree* right,
|
||||
libab_ref* into) {
|
||||
@@ -24,7 +12,7 @@ libab_result _behavior_assign(libab* ab, libab_ref* scope,
|
||||
if(left->variant == TREE_ID) {
|
||||
result = libab_run_tree_scoped(ab, right, scope, into);
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
result = _update_entry(libab_ref_get(scope), left->string_value, into);
|
||||
result = libab_set_variable(libab_ref_get(scope), left->string_value, into);
|
||||
}
|
||||
|
||||
if(result != LIBAB_SUCCESS) {
|
||||
@@ -41,6 +29,61 @@ libab_result _behavior_assign(libab* ab, libab_ref* scope,
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _behavior_method(libab* ab, libab_ref* scope,
|
||||
libab_tree* left, libab_tree* right,
|
||||
libab_ref* into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_ref param;
|
||||
libab_ref callee;
|
||||
libab_ref_vec params;
|
||||
int free_params = 0;
|
||||
size_t index = 0;
|
||||
|
||||
libab_ref_null(&callee);
|
||||
if(right->variant == TREE_CALL) {
|
||||
result = libab_ref_vec_init(¶ms);
|
||||
} else {
|
||||
result = LIBAB_BAD_CALL;
|
||||
}
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
free_params = 1;
|
||||
result = libab_run_tree_scoped(ab, left, scope, ¶m);
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
result = libab_ref_vec_insert(¶ms, ¶m);
|
||||
}
|
||||
libab_ref_free(¶m);
|
||||
}
|
||||
|
||||
for(; index < right->children.size - 1 && result == LIBAB_SUCCESS; index++) {
|
||||
result = libab_run_tree_scoped(ab, vec_index(&right->children, index),
|
||||
scope, ¶m);
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
result = libab_ref_vec_insert(¶ms, ¶m);
|
||||
}
|
||||
libab_ref_free(¶m);
|
||||
}
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
libab_ref_free(&callee);
|
||||
result = libab_run_tree_scoped(ab, vec_index(&right->children, right->children.size - 1),
|
||||
scope, &callee);
|
||||
}
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
result = libab_interpreter_call_value(&ab->intr, scope, &callee, ¶ms, into);
|
||||
} else {
|
||||
libab_ref_null(into);
|
||||
}
|
||||
|
||||
if(free_params) {
|
||||
libab_ref_vec_free(¶ms);
|
||||
}
|
||||
libab_ref_free(&callee);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _expect_boolean(libab* ab, libab_ref* scope,
|
||||
libab_tree* to_run, int* into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
@@ -103,19 +146,25 @@ libab_result _behavior_lor(libab* ab, libab_ref* scope,
|
||||
static const libab_reserved_operator libab_reserved_operators[] = {
|
||||
{
|
||||
"=", /* Assignment */
|
||||
0, /* Lowest precedence */
|
||||
-3, /* Lowest precedence */
|
||||
1, /* Right associative, a = b = 6 should be a = (b = 6) */
|
||||
_behavior_assign
|
||||
},
|
||||
{
|
||||
".",
|
||||
-2,
|
||||
-1,
|
||||
_behavior_method
|
||||
},
|
||||
{
|
||||
"&&", /* Logical and */
|
||||
0, /* Low precedence */
|
||||
-1, /* Low precedence */
|
||||
-1, /* Left associative. */
|
||||
_behavior_land
|
||||
},
|
||||
{
|
||||
"||", /* Logical or */
|
||||
0, /* Low precedence */
|
||||
-1, /* Low precedence */
|
||||
-1, /* Left associative. */
|
||||
_behavior_lor
|
||||
},
|
||||
|
||||
104
src/util.c
104
src/util.c
@@ -290,6 +290,108 @@ libab_result libab_create_value_raw(libab* ab, libab_ref* into,
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _create_value_function_list(libab* ab, libab_ref* into, libab_ref* type) {
|
||||
libab_ref list_ref;
|
||||
libab_result result = libab_create_function_list(ab, &list_ref, type);
|
||||
libab_ref_null(into);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
libab_ref_free(into);
|
||||
result = libab_create_value_ref(ab, into, &list_ref, type);
|
||||
}
|
||||
libab_ref_free(&list_ref);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
libab_result _register_function_existing(libab* ab,
|
||||
libab_table_entry* entry,
|
||||
libab_ref* function_val) {
|
||||
libab_value* old_value;
|
||||
libab_parsetype* old_type;
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
|
||||
old_value = libab_ref_get(&entry->data_u.value);
|
||||
old_type = libab_ref_get(&old_value->type);
|
||||
|
||||
if (old_type->data_u.base == libab_get_basetype_function_list(ab)) {
|
||||
libab_function_list* list = libab_ref_get(&old_value->data);
|
||||
result = libab_function_list_insert(list, function_val);
|
||||
} else if (old_type->data_u.base == libab_get_basetype_function(ab)) {
|
||||
libab_ref new_list;
|
||||
result =
|
||||
_create_value_function_list(ab, &new_list, &ab->type_function_list);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
libab_function_list* list =
|
||||
libab_ref_get(&((libab_value*)libab_ref_get(&new_list))->data);
|
||||
result = libab_function_list_insert(list, &entry->data_u.value);
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
result = libab_function_list_insert(list, function_val);
|
||||
}
|
||||
}
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
libab_ref_swap(&entry->data_u.value, &new_list);
|
||||
}
|
||||
libab_ref_free(&new_list);
|
||||
} else {
|
||||
libab_ref_swap(&entry->data_u.value, function_val);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _register_function_new(libab* ab, const char* name,
|
||||
libab_ref* function_val) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_table_entry* entry;
|
||||
if ((entry = malloc(sizeof(*entry)))) {
|
||||
entry->variant = ENTRY_VALUE;
|
||||
libab_ref_copy(function_val, &entry->data_u.value);
|
||||
result = libab_table_put(libab_ref_get(&ab->table), name, entry);
|
||||
|
||||
if (result != LIBAB_SUCCESS) {
|
||||
libab_table_entry_free(entry);
|
||||
free(entry);
|
||||
}
|
||||
} else {
|
||||
result = LIBAB_MALLOC;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
libab_result libab_overload_function(libab* ab,
|
||||
libab_table* table,
|
||||
const char* name,
|
||||
libab_ref* function) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_table_entry* existing_entry = libab_table_search_filter(
|
||||
table, name, NULL, libab_table_compare_value);
|
||||
|
||||
if (existing_entry) {
|
||||
result = _register_function_existing(ab, existing_entry,
|
||||
function);
|
||||
} else {
|
||||
result = _register_function_new(ab, name, function);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_set_variable(libab_table* table,
|
||||
const char* name,
|
||||
libab_ref* value) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_table_entry* value_entry = libab_table_search_entry_value(table, name);
|
||||
if(value_entry) {
|
||||
libab_ref_free(&value_entry->data_u.value);
|
||||
libab_ref_copy(value, &value_entry->data_u.value);
|
||||
} else {
|
||||
result = libab_put_table_value(table, name, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void _gc_visit_function_children(void* function, libab_visitor_function_ptr visitor, void* data) {
|
||||
size_t index = 0;
|
||||
libab_function* func = function;
|
||||
@@ -484,7 +586,7 @@ void libab_sanitize(char* to, const char* from, size_t buffer_size) {
|
||||
while (*from && index < (buffer_size - 2)) {
|
||||
if (*from == '+' || *from == '*' || *from == '\\' ||
|
||||
*from == '|' || *from == '[' || *from == ']' || *from == '(' ||
|
||||
*from == ')')
|
||||
*from == ')' || *from == '.')
|
||||
to[index++] = '\\';
|
||||
to[index++] = *(from++);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user