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.
This commit is contained in:
parent
4e138d67dd
commit
3c949c9ed3
|
@ -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_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_prefix(const std::string& op, const std::string& func);
|
||||||
void add_operator_postfix(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);
|
ref run(const std::string& code);
|
||||||
template <typename ... Ts>
|
template <typename ... Ts>
|
||||||
ref call(const std::string& bane, Ts...params);
|
ref call(const std::string& bane, Ts...params);
|
||||||
|
|
32
include/function_utils.hpp
Normal file
32
include/function_utils.hpp
Normal file
|
@ -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<number>(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<number>(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; \
|
||||||
|
}
|
|
@ -2,41 +2,11 @@
|
||||||
|
|
||||||
#include "ref.hpp"
|
#include "ref.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
#include "function_utils.hpp"
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "libabacus.h"
|
#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<number>(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<number>(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(print_string);
|
||||||
FUNCTION(to_string_num);
|
FUNCTION(to_string_num);
|
||||||
FUNCTION(to_string_bool);
|
FUNCTION(to_string_bool);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "abacus.hpp"
|
#include "abacus.hpp"
|
||||||
|
#include "functions.hpp"
|
||||||
|
|
||||||
abacus::abacus() {
|
abacus::abacus() {
|
||||||
auto parse_function = [](const char* s) {
|
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());
|
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 abacus::run(const std::string& code) {
|
||||||
ref value;
|
ref value;
|
||||||
libab_run_scoped(&ab, code.c_str(), scope, value);
|
libab_run_scoped(&ab, code.c_str(), scope, value);
|
||||||
|
|
49
src/main.cpp
49
src/main.cpp
|
@ -7,7 +7,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "ref.hpp"
|
#include "ref.hpp"
|
||||||
#include "functions.hpp"
|
#include "function_utils.hpp"
|
||||||
#include "abacus.hpp"
|
#include "abacus.hpp"
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "libabacus.h"
|
#include "libabacus.h"
|
||||||
|
@ -47,52 +47,7 @@ int main() {
|
||||||
rl_bind_key('\t', rl_insert);
|
rl_bind_key('\t', rl_insert);
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
|
||||||
ab.add_function("quit", function_quit, "()->unit");
|
ab.add_standard();
|
||||||
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");
|
|
||||||
|
|
||||||
run_rc(ab);
|
run_rc(ab);
|
||||||
while(!close_requested) {
|
while(!close_requested) {
|
||||||
char* data = readline(" > ");
|
char* data = readline(" > ");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user