diff --git a/include/libabacus.h b/include/libabacus.h index 3382ad0..3ff8665 100644 --- a/include/libabacus.h +++ b/include/libabacus.h @@ -182,6 +182,13 @@ void libab_get_type_function_list(libab* ab, libab_ref* into); */ void libab_get_type_unit(libab* ab, libab_ref* into); +/** + * Gets the unit value form this libab instance. + * @param ab the instance to get the unit value from. + * @param into the reference into which to store the unit value. + */ +void libab_get_unit_value(libab* ab, libab_ref* into); + /** * Executes the given string of code. * @param ab the libabacus instance to use for executing code. diff --git a/src/interactive.c b/src/interactive.c index 5f1f8f7..5639313 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -2,6 +2,7 @@ #include "util.h" #include "value.h" #include +#include #define TRY(expression) \ if (result == LIBAB_SUCCESS) \ @@ -18,25 +19,6 @@ void* impl_parse(const char* string) { void impl_free(void* data) { free(data); } -libab_result function_atan(libab* ab, libab_ref_vec* params, libab_ref* into) { - printf("atan called\n"); - libab_ref_null(into); - return LIBAB_SUCCESS; -} - -libab_result function_atan2(libab* ab, libab_ref_vec* params, libab_ref* into) { - printf("atan2 called\n"); - libab_ref_null(into); - return LIBAB_SUCCESS; -} - -libab_result function_print_num(libab* ab, libab_ref_vec* params, libab_ref* into) { - double* param = libab_unwrap_param(params, 0); - printf("%f\n", *param); - libab_ref_null(into); - return LIBAB_SUCCESS; -} - libab_result create_double_value(libab* ab, double val, libab_ref* into) { libab_ref type_num; libab_result result = LIBAB_SUCCESS; @@ -56,6 +38,32 @@ libab_result create_double_value(libab* ab, double val, libab_ref* into) { return result; } +libab_result function_atan(libab* ab, libab_ref_vec* params, libab_ref* into) { + printf("atan called\n"); + double* val = libab_unwrap_param(params, 0); + return create_double_value(ab, atan(*val), into); +} + +libab_result function_atan2(libab* ab, libab_ref_vec* params, libab_ref* into) { + printf("atan2 called\n"); + double* left = libab_unwrap_param(params, 0); + double* right = libab_unwrap_param(params, 1); + return create_double_value(ab, atan2(*left, *right), into); +} + +libab_result function_print_num(libab* ab, libab_ref_vec* params, libab_ref* into) { + double* param = libab_unwrap_param(params, 0); + printf("%f\n", *param); + libab_get_unit_value(ab, into); + return LIBAB_SUCCESS; +} + +libab_result function_print_unit(libab* ab, libab_ref_vec* params, libab_ref* into) { + printf("()\n"); + libab_get_unit_value(ab, into); + return LIBAB_SUCCESS; +} + #define OP_FUNCTION(name, expression) \ libab_result name(libab* ab, libab_ref_vec* params, libab_ref* into) { \ libab_result result = LIBAB_SUCCESS; \ @@ -79,11 +87,13 @@ libab_result register_functions(libab* ab) { libab_ref atan2_type; libab_ref difficult_type; libab_ref print_num_type; + libab_ref print_unit_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, &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_register_function(ab, "atan", &trig_type, function_atan)); TRY(libab_register_function(ab, "atan2", &atan2_type, function_atan2)); @@ -92,6 +102,7 @@ libab_result register_functions(libab* ab) { TRY(libab_register_function(ab, "times", &atan2_type, function_times)); TRY(libab_register_function(ab, "divide", &atan2_type, function_divide)); 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_operator_infix(ab, "+", 0, -1, "plus")); TRY(libab_register_operator_infix(ab, "-", 0, -1, "minus")); TRY(libab_register_operator_infix(ab, "*", 1, -1, "times")); @@ -101,6 +112,7 @@ libab_result register_functions(libab* ab) { libab_ref_free(&atan2_type); libab_ref_free(&difficult_type); libab_ref_free(&print_num_type); + libab_ref_free(&print_unit_type); return result; } diff --git a/src/interpreter.c b/src/interpreter.c index 40891b8..c60bcc4 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -31,8 +31,10 @@ libab_result _interpreter_create_num_val(struct interpreter_state* state, libab_ref* into, const char* from) { void* data; libab_result result = LIBAB_SUCCESS; + libab_ref_null(into); if ((data = state->ab->impl.parse_num(from))) { + libab_ref_free(into); result = libab_create_value_raw(into, data, &state->ab->type_num); if (result != LIBAB_SUCCESS) { @@ -380,8 +382,6 @@ libab_result _interpreter_find_match(libab_function_list* function_values, if (result == LIBAB_SUCCESS) { libab_ref_vec_free(&temp_new_types); - if (!found_match) - libab_ref_null(match); } else { libab_ref_free(match); libab_ref_null(match); @@ -776,7 +776,7 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree, } else if (tree->variant == TREE_BASE || tree->variant == TREE_BLOCK) { size_t index = 0; - libab_ref_null(into); + libab_get_unit_value(state->ab, into); while (result == LIBAB_SUCCESS && index < tree->children.size) { libab_ref_free(into); result = _interpreter_run(state, vec_index(&tree->children, index), @@ -786,7 +786,7 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree, } else if (tree->variant == TREE_NUM) { result = _interpreter_create_num_val(state, into, tree->string_value); } else if (tree->variant == TREE_VOID) { - libab_ref_null(into); + libab_get_unit_value(state->ab, into); } else if (tree->variant == TREE_ID) { result = _interpreter_require_value(scope, tree->string_value, into); } else if (tree->variant == TREE_CALL) { diff --git a/src/libabacus.c b/src/libabacus.c index 1a4d8ae..9c58913 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -387,6 +387,10 @@ void libab_get_type_unit(libab* ab, libab_ref* into) { libab_ref_copy(&ab->type_unit, into); } +void libab_get_unit_value(libab* ab, libab_ref* into) { + libab_interpreter_unit_value(&ab->intr, into); +} + libab_result libab_run(libab* ab, const char* string, libab_ref* value) { libab_result result = LIBAB_SUCCESS; ll tokens;