From 8cd1d23120f7c3b1f37b0d675ce2ff8d23e26e9f Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sat, 17 Feb 2018 14:00:37 -0800 Subject: [PATCH] Add functions to separately register different types of operators. --- include/libabacus.h | 21 ++++++++++++++++++++- include/table.h | 4 ++-- src/libabacus.c | 24 +++++++++++++++++++++--- src/table.c | 4 ++-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/include/libabacus.h b/include/libabacus.h index 5880b76..e1fe1a8 100644 --- a/include/libabacus.h +++ b/include/libabacus.h @@ -48,7 +48,26 @@ libab_result libab_init(libab* ab); * @param func the function that describes the functionality of the operator. * @return the result of the initialization. */ -libab_result libab_register_operator(libab* ab, const char* op, int precedence, libab_function_ptr func); +libab_result libab_register_operator_infix(libab* ab, const char* op, int precedence, libab_function_ptr func); +/** + * Registers an operation with libabacus that appears + * before its operand. + * @param ab the libabacus instance to register the operator with. + * @param op the operator string to register. + * @param func the function that describes the functionality of the operator. + * @return the result of the registration. + */ +libab_result libab_register_operator_prefix(libab* ab, const char* op, libab_function_ptr func); +/** + * Registers an operation with libabacus that appears + * after its operand. + * @param ab the libabacus instance to register the operator with. + * @param op the operator string to register. + * @param func the function that describes the functionality of the operator. + * @return the result of the registration. + */ +libab_result libab_register_operator_postfix(libab* ab, const char* op, libab_function_ptr func); + /** * Registers a function with libabacus. * @param ab the libabacus instance used to keep state. diff --git a/include/table.h b/include/table.h index 780c0d3..2862cc2 100644 --- a/include/table.h +++ b/include/table.h @@ -30,8 +30,8 @@ struct libab_table_s { enum libab_table_entry_variant_e { ENTRY_VALUE, ENTRY_TYPE, - ENTRY_OPERATOR, - ENTRY_FUNCTION + ENTRY_OP, + ENTRY_FUN }; /** diff --git a/src/libabacus.c b/src/libabacus.c index 778a52e..b0dba88 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -1,5 +1,6 @@ #include "libabacus.h" #include +#include "util.h" libab_result libab_init(libab* ab) { libab_table_init(&ab->table); @@ -7,33 +8,50 @@ libab_result libab_init(libab* ab) { return libab_lexer_init(&ab->lexer); } -libab_result libab_register_operator(libab* ab, const char* op, int precedence, libab_function_ptr func) { +libab_result _register_operator(libab* ab, const char* op, int token_type, int precedence, libab_function_ptr func) { libab_result result = LIBAB_SUCCESS; libab_table_entry* new_entry; if((new_entry = malloc(sizeof(*new_entry)))) { - new_entry->variant = ENTRY_OPERATOR; + new_entry->variant = ENTRY_OP; new_entry->data_u.op.function = func; new_entry->data_u.op.precedence = precedence; } else { result = LIBAB_MALLOC; } + if(result == LIBAB_SUCCESS) { + result = libab_convert_lex_result(eval_config_add(&ab->lexer.config, op, token_type)); + } + if(result == LIBAB_SUCCESS) { result = libab_table_put(&ab->table, op, new_entry); } if(result != LIBAB_SUCCESS) { + eval_config_remove(&ab->lexer.config, op, token_type); free(new_entry); } return result; } +libab_result libab_register_operator_infix(libab* ab, const char* op, int precedence, libab_function_ptr func) { + return _register_operator(ab, op, TOKEN_OP_INFIX, precedence, func); +} + +libab_result libab_register_operator_prefix(libab* ab, const char* op, libab_function_ptr func) { + return _register_operator(ab, op, TOKEN_OP_PREFIX, 0, func); +} + +libab_result libab_register_operator_postfix(libab* ab, const char* op, libab_function_ptr func) { + return _register_operator(ab, op, TOKEN_OP_POSTFIX, 0, func); +} + libab_result libab_register_function(libab* ab, const char* name, libab_function_ptr func) { libab_result result = LIBAB_SUCCESS; libab_table_entry* new_entry; if((new_entry = malloc(sizeof(*new_entry)))) { - new_entry->variant = ENTRY_FUNCTION; + new_entry->variant = ENTRY_FUN; new_entry->data_u.function.function = func; } else { result = LIBAB_MALLOC; diff --git a/src/table.c b/src/table.c index 23af601..e14918d 100644 --- a/src/table.c +++ b/src/table.c @@ -17,7 +17,7 @@ libab_table_entry* table_search(libab_table* table, const char* string) { libab_operator* libab_table_search_operator(libab_table* table, const char* string) { libab_table_entry* entry = table_search(table, string); libab_operator* to_return = NULL; - if(entry && entry->variant == ENTRY_OPERATOR) { + if(entry && entry->variant == ENTRY_OP) { to_return = &entry->data_u.op; } return to_return; @@ -25,7 +25,7 @@ libab_operator* libab_table_search_operator(libab_table* table, const char* stri libab_function* libab_table_search_function(libab_table* table, const char* string) { libab_table_entry* entry = table_search(table, string); libab_function* to_return = NULL; - if(entry && entry->variant == ENTRY_FUNCTION) { + if(entry && entry->variant == ENTRY_FUN) { to_return = &entry->data_u.function; } return to_return;