diff --git a/CMakeLists.txt b/CMakeLists.txt index 5aff539..9718608 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ add_compile_options(-pedantic -Wall) add_library(abacus STATIC src/lexer.c src/util.c src/table.c src/parser.c src/libabacus.c src/tree.c src/debug.c src/parsetype.c src/reserved.c src/trie.c src/refcount.c src/ref_vec.c src/ref_trie.c src/basetype.c src/value.c src/custom.c src/interpreter.c src/function_list.c) add_executable(libabacus src/main.c) +add_executable(interactive src/interactive.c) add_subdirectory(external/liblex) set_property(TARGET abacus PROPERTY C_STANDARD 90) @@ -19,3 +20,4 @@ target_include_directories(libabacus PUBLIC include) target_link_libraries(abacus lex) target_link_libraries(libabacus abacus) +target_link_libraries(interactive abacus) diff --git a/src/interactive.c b/src/interactive.c new file mode 100644 index 0000000..10cfcd5 --- /dev/null +++ b/src/interactive.c @@ -0,0 +1,87 @@ +#include "libabacus.h" +#include + +#define TRY(expression) if(result == LIBAB_SUCCESS) result = expression; +#define INTERACTIONS 5 + +void* impl_parse(const char* string) { + double* data = malloc(sizeof(*data)); + if(data) { + *data = strtod(string, NULL); + } + return data; +} + +void impl_free(void* data) { + free(data); +} + +libab_result function_atan(libab_ref_vec* params, libab_ref* into) { + printf("atan called\n"); + libab_ref_null(into); + return LIBAB_SUCCESS; +} + +libab_result function_atan2(libab_ref_vec* params, libab_ref* into) { + printf("atan2 called\n"); + libab_ref_null(into); + return LIBAB_SUCCESS; +} + +libab_result function_operator(libab_ref_vec* params, libab_ref* into) { + printf("operator called\n"); + libab_ref_null(into); + return LIBAB_SUCCESS; +} + +libab_result register_functions(libab* ab) { + libab_result result = LIBAB_SUCCESS; + libab_ref trig_type; + libab_ref atan2_type; + libab_ref difficult_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_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)); + + libab_ref_free(&trig_type); + libab_ref_free(&atan2_type); + libab_ref_free(&difficult_type); + + return result; +} + +int main() { + char input_buffer[2048]; + int interaction_count = INTERACTIONS; + libab_ref eval_into; + libab_result result; + libab_result eval_result; + libab ab; + + if(libab_init(&ab, impl_parse, impl_free) != LIBAB_SUCCESS) { + fprintf(stderr, "Failed to initialize libab.\n"); + exit(1); + } + + result = register_functions(&ab); + while(interaction_count-- && result == LIBAB_SUCCESS) { + printf("(%d) > ", INTERACTIONS - interaction_count); + fgets(input_buffer, 2048, stdin); + eval_result = libab_run(&ab, input_buffer, &eval_into); + + if(eval_result != LIBAB_SUCCESS) { + printf("Invalid input.\n"); + } + libab_ref_free(&eval_into); + } + + libab_free(&ab); +}