Compare commits
8 Commits
b0c2eb5a5e
...
71b6092654
Author | SHA1 | Date |
---|---|---|
Danila Fedorin | 71b6092654 | |
Danila Fedorin | 20fb078ad2 | |
Danila Fedorin | d7ef8e236d | |
Danila Fedorin | 450d12dc43 | |
Danila Fedorin | 0824dee594 | |
Danila Fedorin | 0a21c7fdf7 | |
Danila Fedorin | aebba42196 | |
Danila Fedorin | 4a058384c1 |
|
@ -216,6 +216,14 @@ void libab_get_true_value(libab* ab, libab_ref* into);
|
|||
* @param into the reference into which to store the false value.
|
||||
*/
|
||||
void libab_get_false_value(libab* ab, libab_ref* into);
|
||||
/**
|
||||
* Get the boolean value corresponding to val from this
|
||||
* libab instance.
|
||||
* @param ab the instance to get the value from.
|
||||
* @param val the true or false value to represent.
|
||||
* @param into the reference into which to store the value.
|
||||
*/
|
||||
void libab_get_bool_value(libab* ab, int val, libab_ref* into);
|
||||
|
||||
/**
|
||||
* Executes the given string of code.
|
||||
|
|
|
@ -94,6 +94,17 @@ libab_table_entry* libab_table_search(libab_table* table, const char* string);
|
|||
*/
|
||||
libab_operator* libab_table_search_operator(libab_table* table,
|
||||
const char* string, int type);
|
||||
/**
|
||||
* Searches for a given string in the table,
|
||||
* returning the entry that holds it only if it is an operator.
|
||||
* @param table the table to search.
|
||||
* @param string the string to search for.
|
||||
* @param type the type of operator to search for (infix, prefix, postfix)
|
||||
* @return the entry, or NULL if it was not found.
|
||||
*/
|
||||
libab_table_entry* libab_table_search_entry_operator(libab_table* table,
|
||||
const char* string,
|
||||
int type);
|
||||
/**
|
||||
* Searches for the given basetype in the table, returning a value
|
||||
* only if it's a basetype.
|
||||
|
@ -103,6 +114,15 @@ libab_operator* libab_table_search_operator(libab_table* table,
|
|||
*/
|
||||
libab_basetype* libab_table_search_basetype(libab_table* table,
|
||||
const char* string);
|
||||
/**
|
||||
* Searches for the given basetype in the table, returning a table
|
||||
* entry only if it holds a basetype.
|
||||
* @param table to table to search.
|
||||
* @param string the string to search for.
|
||||
* @return the entry holding the basetype, or NULL if it was not found.
|
||||
*/
|
||||
libab_table_entry* libab_table_search_entry_basetype(libab_table* table,
|
||||
const char* string);
|
||||
/**
|
||||
* Searches for the given value in the table.
|
||||
* @param table the table to search.
|
||||
|
@ -112,13 +132,30 @@ libab_basetype* libab_table_search_basetype(libab_table* table,
|
|||
void libab_table_search_value(libab_table* table, const char* string,
|
||||
libab_ref* ref);
|
||||
/**
|
||||
* Searches for the given type parameter in the talb.e
|
||||
* Searches for a value with the given name in the table,
|
||||
* and returns an entry that holds it.
|
||||
* @param table the table to search.
|
||||
* @param string the tabe entry key.
|
||||
* @return the table entry holding the value, or NULL if it was not found.
|
||||
*/
|
||||
libab_table_entry* libab_table_search_entry_value(libab_table* table,
|
||||
const char* string);
|
||||
/**
|
||||
* Searches for the given type parameter in the table.
|
||||
* @param table the table to search in.
|
||||
* @param string the key ot search for.
|
||||
* @param string the key to search for.
|
||||
* @param ref the reference to store the type into.
|
||||
*/
|
||||
void libab_table_search_type_param(libab_table* table, const char* string,
|
||||
libab_ref* ref);
|
||||
/**
|
||||
* Searches for the given type parameter in the table.
|
||||
* @param table the table to search in.
|
||||
* @param string the key to search for.
|
||||
* @return the table entry holding the type parameter, or NULL.
|
||||
*/
|
||||
libab_table_entry* libab_table_search_entry_type_param(libab_table* table,
|
||||
const char* string);
|
||||
/**
|
||||
* Stores the given entry in the table under the given key.
|
||||
* @param table the table to store the entry into.
|
||||
|
|
|
@ -178,5 +178,12 @@ void* libab_unwrap_value(libab_ref* ref);
|
|||
* @return the value at the given index.
|
||||
*/
|
||||
void* libab_unwrap_param(libab_ref_vec* vec, size_t index);
|
||||
/**
|
||||
* Sanitizes a string to avoid liblex compilation errors.
|
||||
* @param to the buffer to store the sanitized string to.
|
||||
* @param from the string to sanitize.
|
||||
* @param buffer_size the size of the to buffer.
|
||||
*/
|
||||
void libab_sanitize(char* to, const char* from, size_t buffer_size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,28 +42,31 @@ libab_result create_double_value(libab* ab, double val, libab_ref* into) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void get_boolean_value(libab* ab, int val, libab_ref* into) {
|
||||
val ? libab_get_true_value(ab, into) : libab_get_false_value(ab, into);
|
||||
|
||||
FUNCTION(not) {
|
||||
int* left = libab_unwrap_param(params, 0);
|
||||
libab_get_bool_value(ab, !(*left), into);
|
||||
return LIBAB_SUCCESS;
|
||||
}
|
||||
|
||||
FUNCTION(and) {
|
||||
int* left = libab_unwrap_param(params, 0);
|
||||
int* right = libab_unwrap_param(params, 1);
|
||||
get_boolean_value(ab, *left & *right, into);
|
||||
libab_get_bool_value(ab, *left & *right, into);
|
||||
return LIBAB_SUCCESS;
|
||||
}
|
||||
|
||||
FUNCTION(or) {
|
||||
int* left = libab_unwrap_param(params, 0);
|
||||
int* right = libab_unwrap_param(params, 1);
|
||||
get_boolean_value(ab, *left | *right, into);
|
||||
libab_get_bool_value(ab, *left | *right, into);
|
||||
return LIBAB_SUCCESS;
|
||||
}
|
||||
|
||||
FUNCTION(xor) {
|
||||
int* left = libab_unwrap_param(params, 0);
|
||||
int* right = libab_unwrap_param(params, 1);
|
||||
get_boolean_value(ab, *left ^ *right, into);
|
||||
libab_get_bool_value(ab, *left ^ *right, into);
|
||||
return LIBAB_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -80,6 +83,13 @@ FUNCTION(atan2) {
|
|||
return create_double_value(ab, atan2(*left, *right), into);
|
||||
}
|
||||
|
||||
FUNCTION(equals_num) {
|
||||
double* left = libab_unwrap_param(params, 0);
|
||||
double* right = libab_unwrap_param(params, 1);
|
||||
libab_get_bool_value(ab, *left == *right, into);
|
||||
return LIBAB_SUCCESS;
|
||||
}
|
||||
|
||||
FUNCTION(print_num) {
|
||||
double* param = libab_unwrap_param(params, 0);
|
||||
printf("%f\n", *param);
|
||||
|
@ -126,14 +136,18 @@ libab_result register_functions(libab* ab) {
|
|||
libab_ref print_unit_type;
|
||||
libab_ref print_bool_type;
|
||||
libab_ref bool_logic_type;
|
||||
libab_ref bool_not_type;
|
||||
libab_ref equals_num_type;
|
||||
|
||||
result = libab_create_type(ab, &trig_type, "(num)->num");
|
||||
TRY(libab_create_type(ab, &atan2_type, "(num, num)->num"));
|
||||
TRY(libab_create_type(ab, &equals_num_type, "(num, num)->bool"));
|
||||
TRY(libab_create_type(ab, &difficult_type, "((num)->num)->num"));
|
||||
TRY(libab_create_type(ab, &print_num_type, "(num)->unit"));
|
||||
TRY(libab_create_type(ab, &print_unit_type, "(unit)->unit"));
|
||||
TRY(libab_create_type(ab, &print_bool_type, "(bool)->unit"));
|
||||
TRY(libab_create_type(ab, &bool_logic_type, "(bool,bool)->bool"));
|
||||
TRY(libab_create_type(ab, &bool_not_type, "(bool)->bool"));
|
||||
|
||||
TRY(libab_register_function(ab, "atan", &trig_type, function_atan));
|
||||
TRY(libab_register_function(ab, "atan2", &atan2_type, function_atan2));
|
||||
|
@ -144,9 +158,12 @@ libab_result register_functions(libab* ab) {
|
|||
TRY(libab_register_function(ab, "and", &bool_logic_type, function_and));
|
||||
TRY(libab_register_function(ab, "or", &bool_logic_type, function_or));
|
||||
TRY(libab_register_function(ab, "xor", &bool_logic_type, function_xor));
|
||||
TRY(libab_register_function(ab, "not", &bool_not_type, function_not));
|
||||
TRY(libab_register_function(ab, "equals", &equals_num_type, function_equals_num));
|
||||
TRY(libab_register_function(ab, "print", &print_num_type, function_print_num));
|
||||
TRY(libab_register_function(ab, "print", &print_unit_type, function_print_unit));
|
||||
TRY(libab_register_function(ab, "print", &print_bool_type, function_print_bool));
|
||||
TRY(libab_register_operator_infix(ab, "==", 0, -1, "equals"));
|
||||
TRY(libab_register_operator_infix(ab, "+", 0, -1, "plus"));
|
||||
TRY(libab_register_operator_infix(ab, "-", 0, -1, "minus"));
|
||||
TRY(libab_register_operator_infix(ab, "*", 1, -1, "times"));
|
||||
|
@ -154,6 +171,7 @@ libab_result register_functions(libab* ab) {
|
|||
TRY(libab_register_operator_infix(ab, "&", 1, -1, "and"));
|
||||
TRY(libab_register_operator_infix(ab, "|", 1, -1, "or"));
|
||||
TRY(libab_register_operator_infix(ab, "^", 1, -1, "xor"));
|
||||
TRY(libab_register_operator_prefix(ab, "!", "not"));
|
||||
|
||||
libab_ref_free(&trig_type);
|
||||
libab_ref_free(&atan2_type);
|
||||
|
@ -161,6 +179,8 @@ libab_result register_functions(libab* ab) {
|
|||
libab_ref_free(&print_num_type);
|
||||
libab_ref_free(&print_unit_type);
|
||||
libab_ref_free(&print_bool_type);
|
||||
libab_ref_free(&bool_logic_type);
|
||||
libab_ref_free(&bool_not_type);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1139,9 +1139,36 @@ libab_result _interpreter_create_function_value(
|
|||
return result;
|
||||
}
|
||||
|
||||
libab_result _interpreter_expect_boolean(struct interpreter_state* state,
|
||||
libab_tree* tree, int* into,
|
||||
libab_ref* scope,
|
||||
libab_interpreter_scope_mode mode) {
|
||||
libab_ref output;
|
||||
libab_result result = _interpreter_run(state, tree, &output, scope, mode);
|
||||
libab_value* value;
|
||||
libab_parsetype* type;
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
value = libab_ref_get(&output);
|
||||
type = libab_ref_get(&value->type);
|
||||
|
||||
if(type->data_u.base != libab_get_basetype_bool(state->ab)) {
|
||||
result = LIBAB_BAD_CALL;
|
||||
}
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
*into = *((int*) libab_ref_get(&value->data));
|
||||
}
|
||||
}
|
||||
libab_ref_free(&output);
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree,
|
||||
libab_ref* into, libab_ref* scope,
|
||||
libab_interpreter_scope_mode mode) {
|
||||
#define RUN_CHECK(i) _interpreter_expect_boolean(state, \
|
||||
vec_index(&tree->children, i), &value, scope, SCOPE_NORMAL)
|
||||
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_ref new_scope;
|
||||
int needs_scope = (mode == SCOPE_FORCE) ||
|
||||
|
@ -1215,29 +1242,32 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree,
|
|||
} else if(tree->variant == TREE_FALSE) {
|
||||
libab_get_false_value(state->ab, into);
|
||||
} else if (tree->variant == TREE_IF) {
|
||||
libab_ref condition;
|
||||
libab_value* condition_value;
|
||||
libab_parsetype* condition_type;
|
||||
result = _interpreter_run(state, vec_index(&tree->children, 0),
|
||||
&condition, scope, SCOPE_NORMAL);
|
||||
int value;
|
||||
result = _interpreter_expect_boolean(state,
|
||||
vec_index(&tree->children, 0), &value, scope, SCOPE_NORMAL);
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
condition_value = libab_ref_get(&condition);
|
||||
condition_type = libab_ref_get(&condition_value->type);
|
||||
if(condition_type->data_u.base != libab_get_basetype_bool(state->ab)) {
|
||||
result = LIBAB_MISMATCHED_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
int* boolean = libab_ref_get(&condition_value->data);
|
||||
result = _interpreter_run(state, vec_index(&tree->children,
|
||||
*boolean ? 1 : 2), into, scope, SCOPE_NORMAL);
|
||||
value ? 1 : 2), into, scope, SCOPE_FORCE);
|
||||
} else {
|
||||
libab_ref_null(into);
|
||||
}
|
||||
|
||||
libab_ref_free(&condition);
|
||||
} else if(tree->variant == TREE_WHILE) {
|
||||
int value;
|
||||
libab_get_unit_value(state->ab, into);
|
||||
while(result == LIBAB_SUCCESS && (result = RUN_CHECK(0)) == LIBAB_SUCCESS && value) {
|
||||
libab_ref_free(into);
|
||||
result = _interpreter_run(state, vec_index(&tree->children, 1),
|
||||
into, scope, SCOPE_FORCE);
|
||||
}
|
||||
} else if(tree->variant == TREE_DOWHILE) {
|
||||
int value;
|
||||
libab_get_unit_value(state->ab, into);
|
||||
do {
|
||||
libab_ref_free(into);
|
||||
result = _interpreter_run(state, vec_index(&tree->children, 0),
|
||||
into, scope, SCOPE_FORCE);
|
||||
} while(result == LIBAB_SUCCESS && (result = RUN_CHECK(1)) == LIBAB_SUCCESS && value);
|
||||
} else {
|
||||
libab_get_unit_value(state->ab, into);
|
||||
}
|
||||
|
|
|
@ -84,18 +84,6 @@ libab_result libab_init(libab* ab, void* (*parse_function)(const char*),
|
|||
return result;
|
||||
}
|
||||
|
||||
void _sanitize(char* to, const char* from, size_t buffer_size) {
|
||||
size_t index = 0;
|
||||
while (*from && index < (buffer_size - 2)) {
|
||||
if (*from == '+' || *from == '*' || *from == '\\' ||
|
||||
*from == '|' || *from == '[' || *from == ']' || *from == '(' ||
|
||||
*from == ')')
|
||||
to[index++] = '\\';
|
||||
to[index++] = *(from++);
|
||||
}
|
||||
to[index] = '\0';
|
||||
}
|
||||
|
||||
void _initialize_behavior(libab_behavior* behavior, libab_ref* type,
|
||||
libab_function_ptr func) {
|
||||
behavior->variant = BIMPL_INTERNAL;
|
||||
|
@ -120,7 +108,7 @@ libab_result _register_operator(libab* ab, const char* op,
|
|||
}
|
||||
|
||||
if (result == LIBAB_SUCCESS) {
|
||||
_sanitize(op_buffer, op, 8);
|
||||
libab_sanitize(op_buffer, op, 8);
|
||||
result = libab_convert_lex_result(
|
||||
eval_config_add(&ab->lexer.config, op_buffer, TOKEN_OP));
|
||||
}
|
||||
|
@ -412,6 +400,10 @@ void libab_get_false_value(libab* ab, libab_ref* into) {
|
|||
libab_interpreter_false_value(&ab->intr, into);
|
||||
}
|
||||
|
||||
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 result = LIBAB_SUCCESS;
|
||||
ll tokens;
|
||||
|
|
109
src/reserved.c
109
src/reserved.c
|
@ -1,6 +1,20 @@
|
|||
#include "reserved.h"
|
||||
#include "string.h"
|
||||
#include "util.h"
|
||||
#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,
|
||||
|
@ -10,7 +24,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 = libab_put_table_value(libab_ref_get(scope), left->string_value, into);
|
||||
result = _update_entry(libab_ref_get(scope), left->string_value, into);
|
||||
}
|
||||
|
||||
if(result != LIBAB_SUCCESS) {
|
||||
|
@ -27,12 +41,85 @@ libab_result _behavior_assign(libab* ab, libab_ref* scope,
|
|||
return result;
|
||||
}
|
||||
|
||||
static const libab_reserved_operator libab_reserved_operators[] = {{
|
||||
"=", /* Assignment */
|
||||
0, /* Lowest precedence */
|
||||
1, /* Right associative, a = b = 6 should be a = (b = 6) */
|
||||
_behavior_assign
|
||||
}};
|
||||
libab_result _expect_boolean(libab* ab, libab_ref* scope,
|
||||
libab_tree* to_run, int* into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
libab_ref output;
|
||||
libab_value* value;
|
||||
libab_parsetype* type;
|
||||
|
||||
result = libab_run_tree_scoped(ab, to_run, scope, &output);
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
value = libab_ref_get(&output);
|
||||
type = libab_ref_get(&value->type);
|
||||
if(type->data_u.base != libab_get_basetype_bool(ab)) {
|
||||
result = LIBAB_BAD_CALL;
|
||||
} else {
|
||||
*into = *((int*) libab_ref_get(&value->data));
|
||||
}
|
||||
}
|
||||
libab_ref_free(&output);
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _behavior_land(libab* ab, libab_ref* scope,
|
||||
libab_tree* left, libab_tree* right,
|
||||
libab_ref* into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
int temp;
|
||||
result = _expect_boolean(ab, scope, left, &temp);
|
||||
if(result == LIBAB_SUCCESS && temp) {
|
||||
result = _expect_boolean(ab, scope, right, &temp);
|
||||
}
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
libab_get_bool_value(ab, temp, into);
|
||||
} else {
|
||||
libab_ref_null(into);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result _behavior_lor(libab* ab, libab_ref* scope,
|
||||
libab_tree* left, libab_tree* right,
|
||||
libab_ref* into) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
int temp = 0;
|
||||
result = _expect_boolean(ab, scope, left, &temp);
|
||||
if(result == LIBAB_SUCCESS && !temp) {
|
||||
result = _expect_boolean(ab, scope, right, &temp);
|
||||
}
|
||||
|
||||
if(result == LIBAB_SUCCESS) {
|
||||
libab_get_bool_value(ab, temp, into);
|
||||
} else {
|
||||
libab_ref_null(into);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const libab_reserved_operator libab_reserved_operators[] = {
|
||||
{
|
||||
"=", /* Assignment */
|
||||
0, /* Lowest precedence */
|
||||
1, /* Right associative, a = b = 6 should be a = (b = 6) */
|
||||
_behavior_assign
|
||||
},
|
||||
{
|
||||
"&&", /* Logical and */
|
||||
0, /* Low precedence */
|
||||
-1, /* Left associative. */
|
||||
_behavior_land
|
||||
},
|
||||
{
|
||||
"||", /* Logical or */
|
||||
0, /* Low precedence */
|
||||
-1, /* Left associative. */
|
||||
_behavior_lor
|
||||
},
|
||||
};
|
||||
|
||||
static const size_t element_count =
|
||||
sizeof(libab_reserved_operators) / sizeof(libab_reserved_operator);
|
||||
|
@ -48,20 +135,24 @@ const libab_reserved_operator* libab_find_reserved_operator(const char* name) {
|
|||
|
||||
libab_result libab_register_reserved_operators(libab_lexer* lexer) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
char buffer[16];
|
||||
size_t i;
|
||||
for (i = 0; i < element_count && result == LIBAB_SUCCESS; i++) {
|
||||
libab_sanitize(buffer, libab_reserved_operators[i].op, 16);
|
||||
result = libab_convert_lex_result(eval_config_add(
|
||||
&lexer->config, libab_reserved_operators[i].op, TOKEN_OP_RESERVED));
|
||||
&lexer->config, buffer, TOKEN_OP_RESERVED));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
libab_result libab_remove_reserved_operators(libab_lexer* lexer) {
|
||||
libab_result result = LIBAB_SUCCESS;
|
||||
char buffer[16];
|
||||
size_t i;
|
||||
for (i = 0; i < element_count && result == LIBAB_SUCCESS; i++) {
|
||||
libab_sanitize(buffer, libab_reserved_operators[i].op, 16);
|
||||
result = libab_convert_lex_result(eval_config_remove(
|
||||
&lexer->config, libab_reserved_operators[i].op, TOKEN_OP_RESERVED));
|
||||
&lexer->config, buffer, TOKEN_OP_RESERVED));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
35
src/table.c
35
src/table.c
|
@ -54,6 +54,12 @@ int libab_table_compare_type_param(const void* left, const void* right) {
|
|||
|
||||
libab_operator* libab_table_search_operator(libab_table* table,
|
||||
const char* string, int type) {
|
||||
libab_table_entry* entry =
|
||||
libab_table_search_entry_operator(table, string, type);
|
||||
return entry ? &entry->data_u.op : NULL;
|
||||
}
|
||||
libab_table_entry* libab_table_search_entry_operator(libab_table* table,
|
||||
const char* string, int type) {
|
||||
libab_table_entry* entry = NULL;
|
||||
if (type == OPERATOR_PREFIX) {
|
||||
entry = libab_table_search_filter(table, string, NULL,
|
||||
|
@ -65,37 +71,52 @@ libab_operator* libab_table_search_operator(libab_table* table,
|
|||
entry = libab_table_search_filter(table, string, NULL,
|
||||
libab_table_compare_op_postfix);
|
||||
}
|
||||
return entry ? &entry->data_u.op : NULL;
|
||||
return entry;
|
||||
}
|
||||
|
||||
libab_basetype* libab_table_search_basetype(libab_table* table,
|
||||
const char* string) {
|
||||
libab_table_entry* entry = libab_table_search_filter(
|
||||
table, string, NULL, libab_table_compare_basetype);
|
||||
libab_table_entry* entry =
|
||||
libab_table_search_entry_basetype(table, string);
|
||||
return entry ? entry->data_u.basetype : NULL;
|
||||
}
|
||||
libab_table_entry* libab_table_search_entry_basetype(libab_table* table,
|
||||
const char* string) {
|
||||
return libab_table_search_filter(table, string, NULL,
|
||||
libab_table_compare_basetype);
|
||||
}
|
||||
|
||||
void libab_table_search_value(libab_table* table, const char* string,
|
||||
libab_ref* ref) {
|
||||
libab_table_entry* entry = libab_table_search_filter(
|
||||
table, string, NULL, libab_table_compare_value);
|
||||
libab_table_entry* entry =
|
||||
libab_table_search_entry_value(table, string);
|
||||
if (entry) {
|
||||
libab_ref_copy(&entry->data_u.value, ref);
|
||||
} else {
|
||||
libab_ref_null(ref);
|
||||
}
|
||||
}
|
||||
libab_table_entry* libab_table_search_entry_value(libab_table* table,
|
||||
const char* string) {
|
||||
return libab_table_search_filter(table, string, NULL,
|
||||
libab_table_compare_value);
|
||||
}
|
||||
|
||||
void libab_table_search_type_param(libab_table* table, const char* string,
|
||||
libab_ref* ref) {
|
||||
libab_table_entry* entry = libab_table_search_filter(
|
||||
table, string, NULL, libab_table_compare_type_param);
|
||||
libab_table_entry* entry =
|
||||
libab_table_search_entry_type_param(table, string);
|
||||
if (entry) {
|
||||
libab_ref_copy(&entry->data_u.type_param, ref);
|
||||
} else {
|
||||
libab_ref_null(ref);
|
||||
}
|
||||
}
|
||||
libab_table_entry* libab_table_search_entry_type_param(libab_table* table,
|
||||
const char* string) {
|
||||
return libab_table_search_filter(
|
||||
table, string, NULL, libab_table_compare_type_param);
|
||||
}
|
||||
|
||||
libab_result libab_table_put(libab_table* table, const char* string,
|
||||
libab_table_entry* entry) {
|
||||
|
|
12
src/util.c
12
src/util.c
|
@ -416,3 +416,15 @@ void* libab_unwrap_param(libab_ref_vec* vec, size_t index) {
|
|||
libab_ref_free(&temp);
|
||||
return data;
|
||||
}
|
||||
|
||||
void libab_sanitize(char* to, const char* from, size_t buffer_size) {
|
||||
size_t index = 0;
|
||||
while (*from && index < (buffer_size - 2)) {
|
||||
if (*from == '+' || *from == '*' || *from == '\\' ||
|
||||
*from == '|' || *from == '[' || *from == ']' || *from == '(' ||
|
||||
*from == ')')
|
||||
to[index++] = '\\';
|
||||
to[index++] = *(from++);
|
||||
}
|
||||
to[index] = '\0';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue