From 3c949c9ed36a225e08c8f508860e219a2be7b2d1 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Fri, 31 Aug 2018 23:27:20 -0700 Subject: [PATCH] Create a more clear boundary between "library" and "client" Even though "abcs" is technically a front-end for libab, what it does is fill in some blanks left available by it. However, I'm keeping most of this "fill-in-the-blanks" code standalone, so that it may be used in other projects. --- include/abacus.hpp | 1 + include/function_utils.hpp | 32 ++++++++++++++++++++++++ include/functions.hpp | 32 +----------------------- src/abacus.cpp | 49 ++++++++++++++++++++++++++++++++++++ src/main.cpp | 51 +++----------------------------------- 5 files changed, 86 insertions(+), 79 deletions(-) create mode 100644 include/function_utils.hpp diff --git a/include/abacus.hpp b/include/abacus.hpp index 1529b9d..91a4536 100644 --- a/include/abacus.hpp +++ b/include/abacus.hpp @@ -24,6 +24,7 @@ class abacus { void add_operator_infix(const std::string& op, const std::string& func, int assoc, int prec); void add_operator_prefix(const std::string& op, const std::string& func); void add_operator_postfix(const std::string& op, const std::string& func); + void add_standard(); ref run(const std::string& code); template ref call(const std::string& bane, Ts...params); diff --git a/include/function_utils.hpp b/include/function_utils.hpp new file mode 100644 index 0000000..35e9178 --- /dev/null +++ b/include/function_utils.hpp @@ -0,0 +1,32 @@ +#pragma once + +#define FUNCTION(name) libab_result function_##name( \ + libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) + +#define FUNCTION_MPFR(name, func) FUNCTION(name) { \ + number* value = (number*) libab_unwrap_param(params, 0); \ + mpfr_t output; \ + mpfr_init2(output, PRECISION); \ + mpfr_##func(output, value->value, MPFR_RNDN); \ + ref to_return = create_value(ab, new number(std::move(output))); \ + libab_ref_copy(to_return, into); \ + return LIBAB_SUCCESS; \ +} + +#define FUNCTION_MPFR2(name, func) FUNCTION(name) { \ + number* left = (number*) libab_unwrap_param(params, 0); \ + number* right = (number*) libab_unwrap_param(params, 1); \ + mpfr_t output; \ + mpfr_init2(output, PRECISION); \ + mpfr_##func(output, left->value, right->value, MPFR_RNDN); \ + ref to_return = create_value(ab, new number(std::move(output))); \ + libab_ref_copy(to_return, into); \ + return LIBAB_SUCCESS; \ +} + +#define FUNCTION_COMPARE(name, op) FUNCTION(name) { \ + number* left = (number*) libab_unwrap_param(params, 0); \ + number* right = (number*) libab_unwrap_param(params, 1); \ + libab_get_bool_value(ab, mpfr_cmp(left->value, right->value) op 0, into); \ + return LIBAB_SUCCESS; \ +} diff --git a/include/functions.hpp b/include/functions.hpp index 8cef6e4..db6de04 100644 --- a/include/functions.hpp +++ b/include/functions.hpp @@ -2,41 +2,11 @@ #include "ref.hpp" #include "util.hpp" +#include "function_utils.hpp" extern "C" { #include "libabacus.h" } -#define FUNCTION(name) libab_result function_##name( \ - libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) - -#define FUNCTION_MPFR(name, func) FUNCTION(name) { \ - number* value = (number*) libab_unwrap_param(params, 0); \ - mpfr_t output; \ - mpfr_init2(output, PRECISION); \ - mpfr_##func(output, value->value, MPFR_RNDN); \ - ref to_return = create_value(ab, new number(std::move(output))); \ - libab_ref_copy(to_return, into); \ - return LIBAB_SUCCESS; \ -} - -#define FUNCTION_MPFR2(name, func) FUNCTION(name) { \ - number* left = (number*) libab_unwrap_param(params, 0); \ - number* right = (number*) libab_unwrap_param(params, 1); \ - mpfr_t output; \ - mpfr_init2(output, PRECISION); \ - mpfr_##func(output, left->value, right->value, MPFR_RNDN); \ - ref to_return = create_value(ab, new number(std::move(output))); \ - libab_ref_copy(to_return, into); \ - return LIBAB_SUCCESS; \ -} - -#define FUNCTION_COMPARE(name, op) FUNCTION(name) { \ - number* left = (number*) libab_unwrap_param(params, 0); \ - number* right = (number*) libab_unwrap_param(params, 1); \ - libab_get_bool_value(ab, mpfr_cmp(left->value, right->value) op 0, into); \ - return LIBAB_SUCCESS; \ -} - FUNCTION(print_string); FUNCTION(to_string_num); FUNCTION(to_string_bool); diff --git a/src/abacus.cpp b/src/abacus.cpp index 73f012c..761ac5d 100644 --- a/src/abacus.cpp +++ b/src/abacus.cpp @@ -1,4 +1,5 @@ #include "abacus.hpp" +#include "functions.hpp" abacus::abacus() { auto parse_function = [](const char* s) { @@ -42,6 +43,54 @@ void abacus::add_operator_postfix(const std::string& op, const std::string& func libab_register_operator_postfix(&ab, op.c_str(), func.c_str()); } +void abacus::add_standard() { + add_function("quit", function_quit, "()->unit"); + add_function("request_precision", function_request_precision, "(num)->unit"); + + add_function("print", function_print_string, "(str)->unit"); + add_function("to_string", function_to_string_num, "(num)->str"); + add_function("to_string", function_to_string_bool, "(bool)->str"); + add_function("to_string", function_to_string_unit, "(unit)->str"); + + add_function("lt", function_lt, "(num, num)->num"); + add_function("lte", function_lte, "(num, num)->num"); + add_function("equals", function_equals, "(num, num)->num"); + add_function("gt", function_gt, "(num, num)->num"); + add_function("gte", function_gte, "(num, num)->num"); + add_function("plus", function_plus, "(num, num)->num"); + add_function("minus", function_minus, "(num, num)->num"); + add_function("times", function_times, "(num, num)->num"); + add_function("divide", function_divide, "(num, num)->num"); + add_function("pow", function_pow, "(num, num)->num"); + add_function("negate", function_negate, "(num)->num"); + add_function("factorial", function_factorial, "(num)->num"); + + add_function("ln", function_ln, "(num)->num"); + add_function("exp", function_exp, "(num)->num"); + add_function("sqrt", function_sqrt, "(num)->num"); + + add_function("sin", function_sin, "(num)->num"); + add_function("cos", function_cos, "(num)->num"); + add_function("tan", function_tan, "(num)->num"); + + add_function("arcsin", function_arcsin, "(num)->num"); + add_function("arccos", function_arccos, "(num)->num"); + add_function("arctan", function_arctan, "(num)->num"); + + add_operator_infix("<", "lt", -1, 1); + add_operator_infix("<=", "lte", -1, 1); + add_operator_infix("==", "equals", -1, 1); + add_operator_infix(">", "gt", -1, 1); + add_operator_infix(">=", "gte", -1, 1); + add_operator_infix("+", "plus", -1, 2); + add_operator_infix("-", "minus", -1, 2); + add_operator_infix("*", "times", -1, 3); + add_operator_infix("/", "divide", -1, 3); + add_operator_infix("^", "pow", 1, 3); + add_operator_prefix("-", "negate"); + add_operator_postfix("!", "factorial"); +} + ref abacus::run(const std::string& code) { ref value; libab_run_scoped(&ab, code.c_str(), scope, value); diff --git a/src/main.cpp b/src/main.cpp index 6720d3a..2d922fa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,7 @@ #include #include "types.hpp" #include "ref.hpp" -#include "functions.hpp" +#include "function_utils.hpp" #include "abacus.hpp" extern "C" { #include "libabacus.h" @@ -46,53 +46,8 @@ int main() { abacus ab; rl_bind_key('\t', rl_insert); size_t index = 0; - - ab.add_function("quit", function_quit, "()->unit"); - ab.add_function("request_precision", function_request_precision, "(num)->unit"); - - ab.add_function("print", function_print_string, "(str)->unit"); - ab.add_function("to_string", function_to_string_num, "(num)->str"); - ab.add_function("to_string", function_to_string_bool, "(bool)->str"); - ab.add_function("to_string", function_to_string_unit, "(unit)->str"); - - ab.add_function("lt", function_lt, "(num, num)->num"); - ab.add_function("lte", function_lte, "(num, num)->num"); - ab.add_function("equals", function_equals, "(num, num)->num"); - ab.add_function("gt", function_gt, "(num, num)->num"); - ab.add_function("gte", function_gte, "(num, num)->num"); - ab.add_function("plus", function_plus, "(num, num)->num"); - ab.add_function("minus", function_minus, "(num, num)->num"); - ab.add_function("times", function_times, "(num, num)->num"); - ab.add_function("divide", function_divide, "(num, num)->num"); - ab.add_function("pow", function_pow, "(num, num)->num"); - ab.add_function("negate", function_negate, "(num)->num"); - ab.add_function("factorial", function_factorial, "(num)->num"); - - ab.add_function("ln", function_ln, "(num)->num"); - ab.add_function("exp", function_exp, "(num)->num"); - ab.add_function("sqrt", function_sqrt, "(num)->num"); - - ab.add_function("sin", function_sin, "(num)->num"); - ab.add_function("cos", function_cos, "(num)->num"); - ab.add_function("tan", function_tan, "(num)->num"); - - ab.add_function("arcsin", function_arcsin, "(num)->num"); - ab.add_function("arccos", function_arccos, "(num)->num"); - ab.add_function("arctan", function_arctan, "(num)->num"); - - ab.add_operator_infix("<", "lt", -1, 1); - ab.add_operator_infix("<=", "lte", -1, 1); - ab.add_operator_infix("==", "equals", -1, 1); - ab.add_operator_infix(">", "gt", -1, 1); - ab.add_operator_infix(">=", "gte", -1, 1); - ab.add_operator_infix("+", "plus", -1, 2); - ab.add_operator_infix("-", "minus", -1, 2); - ab.add_operator_infix("*", "times", -1, 3); - ab.add_operator_infix("/", "divide", -1, 3); - ab.add_operator_infix("^", "pow", 1, 3); - ab.add_operator_prefix("-", "negate"); - ab.add_operator_postfix("!", "factorial"); - + + ab.add_standard(); run_rc(ab); while(!close_requested) { char* data = readline(" > ");