abcs/src/main.cpp

117 lines
3.8 KiB
C++
Raw Normal View History

2018-08-14 01:03:34 -07:00
#include <iostream>
#include <map>
#include <mpfr.h>
2018-08-16 23:24:22 -07:00
#include <readline/readline.h>
#include <readline/history.h>
2018-08-19 22:19:56 -07:00
#include <fstream>
#include <sstream>
#include "types.hpp"
#include "ref.hpp"
#include "functions.hpp"
#include "abacus.hpp"
2018-08-14 01:03:34 -07:00
extern "C" {
#include "libabacus.h"
#include "table.h"
#include "value.h"
2018-08-14 01:03:34 -07:00
#include "util.h"
}
2018-08-14 16:34:17 -07:00
// == Global State (uh-oh)
bool close_requested = false;
long requested_precision = 3;
2018-08-14 16:34:17 -07:00
FUNCTION(quit) {
close_requested = true;
libab_get_unit_value(ab, into);
return LIBAB_SUCCESS;
}
FUNCTION(request_precision) {
number* value = (number*) libab_unwrap_param(params, 0);
requested_precision = std::min(PRECISION / 4, std::max(2, value->to_int()));
libab_get_unit_value(ab, into);
return LIBAB_SUCCESS;
}
2018-08-19 22:19:56 -07:00
void run_rc(abacus& ab) {
std::ifstream rcfile("./.abcsrc");
std::ostringstream str;
if(rcfile.good()) {
str << rcfile.rdbuf();
ab.run(str.str());
}
}
2018-08-14 01:03:34 -07:00
int main() {
abacus ab;
2018-08-16 23:24:22 -07:00
rl_bind_key('\t', rl_insert);
size_t index = 0;
2018-08-14 16:34:17 -07:00
ab.add_function("quit", function_quit, "()->unit");
ab.add_function("request_precision", function_request_precision, "(num)->unit");
2018-08-14 16:34:17 -07:00
2018-08-14 01:03:34 -07:00
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");
2018-08-14 16:34:17 -07:00
2018-08-17 00:55:24 -07:00
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");
2018-08-14 01:03:34 -07:00
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");
2018-08-16 23:47:20 -07:00
ab.add_function("pow", function_pow, "(num, num)->num");
2018-08-14 19:05:14 -07:00
ab.add_function("negate", function_negate, "(num)->num");
ab.add_function("factorial", function_factorial, "(num)->num");
2018-08-14 16:34:17 -07:00
ab.add_function("ln", function_ln, "(num)->num");
ab.add_function("exp", function_exp, "(num)->num");
2018-08-18 17:41:32 -07:00
ab.add_function("sqrt", function_sqrt, "(num)->num");
2018-08-16 23:47:20 -07:00
ab.add_function("sin", function_sin, "(num)->num");
ab.add_function("cos", function_cos, "(num)->num");
ab.add_function("tan", function_tan, "(num)->num");
2018-08-16 23:47:20 -07:00
ab.add_function("arcsin", function_arcsin, "(num)->num");
ab.add_function("arccos", function_arccos, "(num)->num");
ab.add_function("arctan", function_arctan, "(num)->num");
2018-08-17 00:55:24 -07:00
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);
2018-08-15 00:44:43 -07:00
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);
2018-08-16 23:47:20 -07:00
ab.add_operator_infix("^", "pow", 1, 3);
2018-08-14 19:12:35 -07:00
ab.add_operator_prefix("-", "negate");
ab.add_operator_postfix("!", "factorial");
2018-08-14 19:12:35 -07:00
2018-08-19 22:19:56 -07:00
run_rc(ab);
2018-08-14 16:34:17 -07:00
while(!close_requested) {
2018-08-16 23:24:22 -07:00
char* data = readline(" > ");
std::string buffer(data);
add_history(data);
free(data);
ref value = ab.run(buffer);
2018-08-14 16:34:17 -07:00
if(value == nullptr) {
std::cout << "Invalid expression." << std::endl;
} else {
std::string name = "r" + std::to_string(index);
std::string ans = "ans";
ab.add_variable(name, value);
ab.add_variable(ans, value);
index++;
std::cout << name << " = " << ab.to_string(value) << std::endl;
2018-08-14 16:34:17 -07:00
}
}
2018-08-14 01:03:34 -07:00
}