diff --git a/include/custom.h b/include/custom.h index d719da9..92ed12c 100644 --- a/include/custom.h +++ b/include/custom.h @@ -9,6 +9,16 @@ */ typedef void(*libab_function_ptr)(); +/** + * The variant of the operator that + * has been registered with libabacus. + */ +enum libab_operator_variant_e { + OPERATOR_PREFIX, + OPERATOR_INFIX, + OPERATOR_POSTFIX +}; + /** * The common information * that both operators and functions shared. @@ -34,7 +44,7 @@ struct libab_operator_s { * Corresponds to token types associated with * each operator. */ - int type; + enum libab_operator_variant_e type; /** * The precedence of the operator. */ @@ -61,6 +71,7 @@ struct libab_function_s { struct libab_behavior_s behavior; }; +typedef enum libab_operator_variant_e libab_operator_variant; typedef struct libab_behavior_s libab_behavior; typedef struct libab_operator_s libab_operator; typedef struct libab_function_s libab_function; diff --git a/include/lexer.h b/include/lexer.h index 15c208f..8969563 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -55,6 +55,7 @@ enum libab_lexer_token_e { TOKEN_CHAR = 0, TOKEN_ID, TOKEN_NUM, + TOKEN_OP, TOKEN_OP_INFIX, TOKEN_OP_PREFIX, TOKEN_OP_POSTFIX, diff --git a/src/libabacus.c b/src/libabacus.c index 8431b0a..a857d92 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -49,7 +49,7 @@ libab_result _initialize_behavior(libab* ab, libab_behavior* behavior, return result; } -libab_result _register_operator(libab* ab, const char* op, int token_type, int precedence, int associativity, const char* type, libab_function_ptr func) { +libab_result _register_operator(libab* ab, const char* op, libab_operator_variant token_type, int precedence, int associativity, const char* type, libab_function_ptr func) { char op_buffer[8]; libab_result result = LIBAB_SUCCESS; libab_table_entry* new_entry; @@ -69,7 +69,7 @@ libab_result _register_operator(libab* ab, const char* op, int token_type, int p if(result == LIBAB_SUCCESS) { _sanitize(op_buffer, op, 8); - result = libab_convert_lex_result(eval_config_add(&ab->lexer.config, op_buffer, token_type)); + result = libab_convert_lex_result(eval_config_add(&ab->lexer.config, op_buffer, TOKEN_OP)); } if(result == LIBAB_SUCCESS) { @@ -79,7 +79,7 @@ libab_result _register_operator(libab* ab, const char* op, int token_type, int p if(result != LIBAB_SUCCESS) { if(new_entry && new_entry->data_u.op.behavior.type) libab_parsetype_free_recursive(new_entry->data_u.op.behavior.type); - eval_config_remove(&ab->lexer.config, op, token_type); + eval_config_remove(&ab->lexer.config, op, TOKEN_OP); free(new_entry); } @@ -87,15 +87,15 @@ libab_result _register_operator(libab* ab, const char* op, int token_type, int p } libab_result libab_register_operator_infix(libab* ab, const char* op, int precedence, int associativity, const char* type, libab_function_ptr func) { - return _register_operator(ab, op, TOKEN_OP_INFIX, precedence, associativity, type, func); + return _register_operator(ab, op, OPERATOR_INFIX, precedence, associativity, type, func); } libab_result libab_register_operator_prefix(libab* ab, const char* op, const char* type, libab_function_ptr func) { - return _register_operator(ab, op, TOKEN_OP_PREFIX, 0, 0, type, func); + return _register_operator(ab, op, OPERATOR_PREFIX, 0, 0, type, func); } libab_result libab_register_operator_postfix(libab* ab, const char* op, const char* type, libab_function_ptr func) { - return _register_operator(ab, op, TOKEN_OP_POSTFIX, 0, 0, type, func); + return _register_operator(ab, op, OPERATOR_POSTFIX, 0, 0, type, func); } libab_result libab_register_function(libab* ab, const char* name, const char* type, libab_function_ptr func) { diff --git a/src/parser.c b/src/parser.c index ea74bcf..570d1cb 100644 --- a/src/parser.c +++ b/src/parser.c @@ -748,7 +748,8 @@ libab_result _parser_append_op_node(struct parser_state* state, libab_lexer_matc // Expression-specific utility functions int _parser_match_is_op(libab_lexer_match* match) { - return match->type == TOKEN_OP_INFIX || + return match->type == TOKEN_OP || + match->type == TOKEN_OP_INFIX || match->type == TOKEN_OP_PREFIX || match->type == TOKEN_OP_POSTFIX || match->type == TOKEN_OP_RESERVED; @@ -792,7 +793,7 @@ void _parser_find_operator_infix(struct parser_state* state, libab_lexer_match* char op_buffer[8]; _parser_extract_token_buffer(state, op_buffer, 8, match); if(match->type != TOKEN_OP_RESERVED) { - libab_operator* operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_INFIX); + libab_operator* operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_INFIX); data->associativity = operator->associativity; data->precedence = operator->precedence; } else { @@ -856,41 +857,33 @@ libab_result _parser_expression_tree(struct parser_state* state, ll* source, lib int _parser_match_is_postfix_op(struct parser_state* state, libab_lexer_match* match) { int is_postfix = 0; - if(match->type == TOKEN_OP_POSTFIX) { - is_postfix = 1; - } else { - libab_operator* operator; - char op_buffer[8]; - _parser_extract_token_buffer(state, op_buffer, 8, match); - operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_POSTFIX); - if(operator) is_postfix = 1; - } + libab_operator* operator; + char op_buffer[8]; + _parser_extract_token_buffer(state, op_buffer, 8, match); + operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_POSTFIX); + if(operator) is_postfix = 1; return is_postfix; } int _parser_match_is_prefix_op(struct parser_state* state, libab_lexer_match* match) { int is_prefix = 0; - if(match->type == TOKEN_OP_PREFIX) { - is_prefix = 1; - } else { - libab_operator* operator; - char op_buffer[8]; - _parser_extract_token_buffer(state, op_buffer, 8, match); - operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_PREFIX); - if(operator) is_prefix = 1; - } + libab_operator* operator; + char op_buffer[8]; + _parser_extract_token_buffer(state, op_buffer, 8, match); + operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_PREFIX); + if(operator) is_prefix = 1; return is_prefix; } int _parser_match_is_infix_op(struct parser_state* state, libab_lexer_match* match) { int is_infix = 0; - if(match->type == TOKEN_OP_INFIX || match->type == TOKEN_OP_RESERVED) { + if(match->type == TOKEN_OP_RESERVED) { is_infix = 1; } else { libab_operator* operator; char op_buffer[8]; _parser_extract_token_buffer(state, op_buffer, 8, match); - operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_INFIX); + operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_INFIX); if(operator) is_infix = 1; } return is_infix; @@ -946,7 +939,8 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in _parser_state_step(state); new_type = EXPR_OP_POSTFIX; } else if(_parser_match_is_infix_op(state, new_token)) { - new_token->type = TOKEN_OP_INFIX; + if(new_token->type == TOKEN_OP) + new_token->type = TOKEN_OP_INFIX; _parser_find_operator_infix(state, new_token, &operator); _parser_state_step(state); diff --git a/src/table.c b/src/table.c index c81812d..c64f728 100644 --- a/src/table.c +++ b/src/table.c @@ -29,17 +29,17 @@ libab_table_entry* libab_table_search(libab_table* table, const char* string) { return entry->variant == ENTRY_OP && entry->data_u.op.type == TYPE;\ } -OP_TYPE_COMPARATOR(_table_compare_prefix, TOKEN_OP_PREFIX) -OP_TYPE_COMPARATOR(_table_compare_infix, TOKEN_OP_INFIX) -OP_TYPE_COMPARATOR(_table_compare_postfix, TOKEN_OP_POSTFIX) +OP_TYPE_COMPARATOR(_table_compare_prefix, OPERATOR_PREFIX) +OP_TYPE_COMPARATOR(_table_compare_infix, OPERATOR_INFIX) +OP_TYPE_COMPARATOR(_table_compare_postfix, OPERATOR_POSTFIX) libab_operator* libab_table_search_operator(libab_table* table, const char* string, int type) { libab_table_entry* entry = NULL; - if(type == TOKEN_OP_PREFIX) { + if(type == OPERATOR_PREFIX) { entry = libab_table_search_filter(table, string, NULL, _table_compare_prefix); - } else if(type == TOKEN_OP_INFIX) { + } else if(type == OPERATOR_INFIX) { entry = libab_table_search_filter(table, string, NULL, _table_compare_infix); - } else if(type == TOKEN_OP_POSTFIX) { + } else if(type == OPERATOR_PREFIX) { entry = libab_table_search_filter(table, string, NULL, _table_compare_postfix); } return entry ? &entry->data_u.op : NULL;