Add builtin functions for calc

This commit is contained in:
Robin Jadoul 2017-01-29 12:00:06 +01:00
parent b3cbd2d499
commit 0ebb56eb7c
1 changed files with 41 additions and 2 deletions

View File

@ -1,9 +1,43 @@
#include "AST.h"
#include <cmath>
#include <functional>
#include <map>
#include <string>
namespace calc {
namespace {
using d2dfn = double(*)(double);
std::function<double(const Variables&, const Functions&, FunctionArguments&)> wrap(std::function<double(double)> fn) {
return [fn](const Variables& vars, const Functions& funs, FunctionArguments& args) -> double{
if (args.size() != 1)
return 0;
return fn(args[0]->eval(vars, funs));
};
}
std::map<std::string, std::function<double(const Variables&, const Functions&, FunctionArguments&)>> builtins =
{
{"if", [](const Variables& vars, const Functions& funs, FunctionArguments& args) -> double {
if (args.size() != 3)
return 0;
double test = args[0]->eval(vars, funs);
if (std::fabs(test) < 1e-8)
return args[2]->eval(vars, funs);
else
return args[1]->eval(vars, funs);
}},
{"sin", wrap((d2dfn)(std::sin))},
{"cos", wrap((d2dfn)(std::cos))},
{"tan", wrap((d2dfn)(std::tan))},
{"asin", wrap((d2dfn)(std::asin))},
{"acos", wrap((d2dfn)(std::acos))},
{"atan", wrap((d2dfn)(std::atan))},
{"abs", wrap((d2dfn)(std::fabs))}
};
}
Number::Number(double d) : m_val(d) {}
double Number::eval(const Variables&, const Functions&) const {
return m_val;
@ -74,8 +108,13 @@ std::size_t FunctionArguments::size() const {
FunctionCall::FunctionCall(std::string name, std::unique_ptr<FunctionArguments>&& arguments) : m_name(name), m_arguments(std::move(arguments)) {}
double FunctionCall::eval(const Variables& vars, const Functions& funs) const {
auto fp = funs.find(m_name);
if (fp == funs.end())
return 0;
if (fp == funs.end()) {
if (builtins.count(m_name)) {
return builtins[m_name](vars, funs, *m_arguments);
} else {
return 0;
}
}
Function& fun = *dynamic_cast<Function*>((fp->second.get()));
if (m_arguments->size() != fun.getParams().size()) return 0;