diff --git a/include/custom.h b/include/custom.h index ac41239..0079ce4 100644 --- a/include/custom.h +++ b/include/custom.h @@ -61,10 +61,6 @@ struct libab_operator_s { * each operator. */ enum libab_operator_variant_e variant; - /** - * The type of this operator. - */ - libab_ref type; /** * The precedence of the operator. */ @@ -74,9 +70,9 @@ struct libab_operator_s { */ int associativity; /** - * The behavior of this operator. + * The function called by this operator. */ - struct libab_behavior_s behavior; + const char* function; }; /** @@ -132,12 +128,10 @@ void libab_behavior_free(libab_behavior* behavior); * @param precedence the precedence of the operator. * @param associativity the associativity (left = -1, right = 1) of the * operator. - * @param type the type of the operator. - * @param func the function used to implement the operator. + * @param function the function this operator represents. */ void libab_operator_init(libab_operator* op, libab_operator_variant variant, - int precedence, int associativity, libab_ref* type, - libab_function_ptr func); + int precedence, int associativity, const char* function); /** * Frees the given operator. * @param op the operator to free. diff --git a/include/libabacus.h b/include/libabacus.h index e76335d..8dc1460 100644 --- a/include/libabacus.h +++ b/include/libabacus.h @@ -78,38 +78,32 @@ libab_result libab_init(libab* ab, void* (*parse_function)(const char*), * @param op the operator string to register. * @param precedence the precedence of the operator. * @param associativity the associativity of the operator. - * @param type the type of this operator. - * @param func the function that describes the functionality of the operator. + * @param function the function this operator calls. * @return the result of the initialization. */ libab_result libab_register_operator_infix(libab* ab, const char* op, int precedence, int associativity, - libab_ref* type, - libab_function_ptr func); + const char* function); /** * 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 type the type of this operator. - * @param func the function that describes the functionality of the operator. + * @param function the function this operator calls. * @return the result of the registration. */ libab_result libab_register_operator_prefix(libab* ab, const char* op, - libab_ref* type, - libab_function_ptr func); + const char* function); /** * 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 type the type of this operator. - * @param func the function that describes the functionality of the operator. + * @param function the function this operator calls. * @return the result of the registration. */ libab_result libab_register_operator_postfix(libab* ab, const char* op, - libab_ref* type, - libab_function_ptr func); + const char* function); /** * Registers a function with libabacus. diff --git a/src/custom.c b/src/custom.c index 3da4a9c..8bd5e88 100644 --- a/src/custom.c +++ b/src/custom.c @@ -18,18 +18,15 @@ void libab_behavior_free(libab_behavior* behavior) { } void libab_operator_init(libab_operator* op, libab_operator_variant variant, - int precedence, int associativity, libab_ref* type, - libab_function_ptr func) { + int precedence, int associativity, const char* function) { op->variant = variant; op->precedence = precedence; op->associativity = associativity; - libab_ref_copy(type, &op->type); - libab_behavior_init_internal(&op->behavior, func); + op->function = function; } void libab_operator_free(libab_operator* op) { - libab_ref_free(&op->type); - libab_behavior_free(&op->behavior); + } libab_result _function_init(libab_function* function, libab_ref* scope) { diff --git a/src/interactive.c b/src/interactive.c index 649419b..4c42ca2 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -75,14 +75,14 @@ libab_result register_functions(libab* ab) { TRY(libab_register_function(ab, "atan", &trig_type, function_atan)); TRY(libab_register_function(ab, "atan2", &atan2_type, function_atan2)); - TRY(libab_register_operator_infix(ab, "+", 0, -1, &atan2_type, - function_operator)); - TRY(libab_register_operator_infix(ab, "-", 0, -1, &atan2_type, - function_operator)); - TRY(libab_register_operator_infix(ab, "*", 1, -1, &atan2_type, - function_operator)); - TRY(libab_register_operator_infix(ab, "/", 1, -1, &atan2_type, - function_operator)); + TRY(libab_register_function(ab, "plus", &atan2_type, function_operator)); + TRY(libab_register_function(ab, "minus", &atan2_type, function_operator)); + TRY(libab_register_function(ab, "times", &atan2_type, function_operator)); + TRY(libab_register_function(ab, "divide", &atan2_type, function_operator)); + 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")); + TRY(libab_register_operator_infix(ab, "/", 1, -1, "divide")); libab_ref_free(&trig_type); libab_ref_free(&atan2_type); diff --git a/src/interpreter.c b/src/interpreter.c index 0edfa15..e66f1be 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -636,66 +636,36 @@ libab_result _interpreter_try_call(struct interpreter_state* state, return result; } -/** - * Casts the paramters of an operator, and calls it. - * @param state the state in which to perform the call on the operator. - * @param to_call the operator to call. - * @param params the parameters to give to the operator. - * @param new_types the types to which to cast the parameters. - * @param into the reference into which to store the result of the cold. - * @return the result of the call. - */ -libab_result _interpreter_cast_and_perform_operator_call( - struct interpreter_state* state, - libab_operator* to_call, libab_ref_vec* params, libab_ref_vec* new_types, - libab_ref* into) { - libab_result result = LIBAB_SUCCESS; - libab_ref_vec new_params; - libab_ref_null(into); - - result = libab_ref_vec_init(&new_params); - if (result == LIBAB_SUCCESS) { - result = _interpreter_cast_params(params, new_types, &new_params); - - if (result == LIBAB_SUCCESS) { - libab_ref_free(into); - result = - _interpreter_call_behavior(state, &to_call->behavior, params, into); - } - - libab_ref_vec_free(&new_params); - } - - return result; -} - libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree, libab_ref* into, libab_ref* scope, int force_scope); +libab_result _interpreter_require_value(libab_ref* scope, const char* name, + libab_ref* into) { + libab_result result = LIBAB_SUCCESS; + libab_table_search_value(libab_ref_get(scope), name, into); + if(libab_ref_get(into) == NULL) { + result = LIBAB_UNEXPECTED; + } + return result; +} + libab_result _interpreter_call_operator(struct interpreter_state* state, libab_operator* to_call, libab_ref* into, libab_ref* scope, ...) { va_list args; libab_result result = LIBAB_SUCCESS; + libab_ref function_value; libab_ref_vec params; - libab_ref_vec new_types; libab_ref temp; - libab_parsetype* operator_type; + libab_ref_null(&function_value); va_start(args, scope); - operator_type = libab_ref_get(&to_call->type); result = libab_ref_vec_init(¶ms); if (result == LIBAB_SUCCESS) { - result = libab_ref_vec_init(&new_types); - if (result != LIBAB_SUCCESS) { - libab_ref_vec_free(¶ms); - } - } - - if (result == LIBAB_SUCCESS) { + /* Get first parameter. */ result = _interpreter_run(state, va_arg(args, libab_tree*), &temp, scope, 0); @@ -705,6 +675,7 @@ libab_result _interpreter_call_operator(struct interpreter_state* state, libab_ref_free(&temp); + /* If infix, get second parameter. */ if (result == LIBAB_SUCCESS && to_call->variant == OPERATOR_INFIX) { result = _interpreter_run(state, va_arg(args, libab_tree*), &temp, scope, 0); @@ -716,20 +687,19 @@ libab_result _interpreter_call_operator(struct interpreter_state* state, libab_ref_free(&temp); } - if (result == LIBAB_SUCCESS) { - result = _interpreter_check_types(&operator_type->children, - ¶ms, &new_types); + if(result == LIBAB_SUCCESS) { + libab_ref_free(&function_value); + result = _interpreter_require_value(scope, to_call->function, &function_value); } - if (result == LIBAB_SUCCESS) { - result = _interpreter_cast_and_perform_operator_call( - state, to_call, ¶ms, &new_types, into); + if(result == LIBAB_SUCCESS) { + result = _interpreter_try_call(state, &function_value, ¶ms, into); } libab_ref_vec_free(¶ms); - libab_ref_vec_free(&new_types); } va_end(args); + libab_ref_free(&function_value); return result; } @@ -810,11 +780,7 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree, } else if (tree->variant == TREE_VOID) { libab_ref_null(into); } else if (tree->variant == TREE_ID) { - libab_table_search_value(libab_ref_get(scope), tree->string_value, - into); - if (libab_ref_get(into) == NULL) { - result = LIBAB_UNEXPECTED; - } + result = _interpreter_require_value(scope, tree->string_value, into); } else if (tree->variant == TREE_CALL) { result = _interpreter_run_function_node(state, tree, into, scope); } else if (tree->variant == TREE_OP) { diff --git a/src/libabacus.c b/src/libabacus.c index 2d971ad..dad412d 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -92,7 +92,7 @@ void _initialize_behavior(libab_behavior* behavior, libab_ref* type, libab_result _register_operator(libab* ab, const char* op, libab_operator_variant token_type, int precedence, int associativity, - libab_ref* type, libab_function_ptr func) { + const char* function) { char op_buffer[8]; libab_result result = LIBAB_SUCCESS; libab_table_entry* new_entry; @@ -101,7 +101,7 @@ libab_result _register_operator(libab* ab, const char* op, new_entry->variant = ENTRY_OP; new_operator = &(new_entry->data_u.op); libab_operator_init(new_operator, token_type, precedence, associativity, - type, func); + function); } else { result = LIBAB_MALLOC; } @@ -128,22 +128,19 @@ libab_result _register_operator(libab* ab, const char* op, libab_result libab_register_operator_infix(libab* ab, const char* op, int precedence, int associativity, - libab_ref* type, - libab_function_ptr func) { + const char* function) { return _register_operator(ab, op, OPERATOR_INFIX, precedence, associativity, - type, func); + function); } libab_result libab_register_operator_prefix(libab* ab, const char* op, - libab_ref* type, - libab_function_ptr func) { - return _register_operator(ab, op, OPERATOR_PREFIX, 0, 0, type, func); + const char* function) { + return _register_operator(ab, op, OPERATOR_PREFIX, 0, 0, function); } libab_result libab_register_operator_postfix(libab* ab, const char* op, - libab_ref* type, - libab_function_ptr func) { - return _register_operator(ab, op, OPERATOR_POSTFIX, 0, 0, type, func); + const char* function) { + return _register_operator(ab, op, OPERATOR_POSTFIX, 0, 0, function); } libab_result _create_value_function_internal(libab_ref* into, libab_ref* type,