Commit d9c1309c authored by Tobias WEBER's avatar Tobias WEBER
Browse files

added internal functions

parent aef6f213
......@@ -81,7 +81,7 @@ add_executable(in20
${BISON_cliparser_OUTPUT_SOURCE} ${BISON_cliparser_OUTPUT_HEADER}
${FLEX_clilexer_OUTPUTS} ${FLEX_clilexer_OUTPUT_HEADER}
tools/cli/cliparser.cpp tools/cli/cliparser.h tools/cli/cliparser_types.h
tools/cli/ast.cpp
tools/cli/ast.cpp tools/cli/funcs.cpp tools/cli/funcs.h
ext/tlibs/log/log.cpp ext/tlibs/file/loadinstr.cpp
......
......@@ -7,9 +7,13 @@
#include "cliparser.h"
#include "tools/in20/globals.h"
#include "funcs.h"
#include <cmath>
using t_real = t_real_cli;
// ----------------------------------------------------------------------------
// evaluation of symbols
......@@ -231,10 +235,14 @@ std::shared_ptr<Symbol> CliASTString::Eval(CliParserContext& ctx) const
/**
* variable identifier in symbol map
* variable identifier in symbol or constants map
*/
std::shared_ptr<Symbol> CliASTIdent::Eval(CliParserContext& ctx) const
{
// look in constants map
auto iterConst = g_consts_real.find(m_val);
// is workspace available?
auto *workspace = ctx.GetWorkspace();
if(!workspace)
{
......@@ -242,14 +250,24 @@ std::shared_ptr<Symbol> CliASTIdent::Eval(CliParserContext& ctx) const
return nullptr;
}
// look in workspace variables map
auto iter = workspace->find(m_val);
if(iter == workspace->end())
if(iter == workspace->end() && iterConst == g_consts_real.end())
{
ctx.PrintError("Variable \"", m_val, "\" is not in workspace.");
ctx.PrintError("Variable \"", m_val, "\" is neither a constant nor a workspace variable.");
return nullptr;
}
else if(iter != workspace->end() && iterConst != g_consts_real.end())
{
ctx.PrintError("Variable \"", m_val, "\" is both a constant and a workspace variable, using constant.");
return std::make_shared<SymbolReal>(iterConst->second);
}
else if(iter != workspace->end())
return iter->second;
else if(iterConst != g_consts_real.end())
return std::make_shared<SymbolReal>(iterConst->second);
return iter->second;
return nullptr;
}
......@@ -393,6 +411,19 @@ std::shared_ptr<Symbol> CliASTPow::Eval(CliParserContext& ctx) const
*/
std::shared_ptr<Symbol> CliASTCall::Eval(CliParserContext& ctx) const
{
// function name
std::string ident;
if(m_left->GetType() == CliASTType::IDENT)
{
ident = dynamic_cast<CliASTIdent&>(*m_left).GetValue();
}
else
{
ctx.PrintError("Left-hand side of function call has to be an identifier.");
return nullptr;
}
// arguments
std::vector<std::shared_ptr<Symbol>> args;
......@@ -416,6 +447,42 @@ std::shared_ptr<Symbol> CliASTCall::Eval(CliParserContext& ctx) const
}
}
if(args.size() == 1) // function call with one argument requested
{
// real argument
if(args[0]->GetType() == SymbolType::REAL)
{
auto iter = g_funcs_real_1arg.find(ident);
if(iter == g_funcs_real_1arg.end())
{
ctx.PrintError("No real one-argument function \"", ident, "\" was found.");
return nullptr;
}
t_real funcval = (*iter->second)(dynamic_cast<SymbolReal&>(*args[0]).GetValue());
return std::make_shared<SymbolReal>(funcval);
}
}
else if(args.size() == 2) // function call with two arguments requested
{
// real arguments
if(args[0]->GetType() == SymbolType::REAL && args[1]->GetType() == SymbolType::REAL)
{
auto iter = g_funcs_real_2args.find(ident);
if(iter == g_funcs_real_2args.end())
{
ctx.PrintError("No real two-argument function \"", ident, "\" was found.");
return nullptr;
}
t_real arg1 = dynamic_cast<SymbolReal&>(*args[0]).GetValue();
t_real arg2 = dynamic_cast<SymbolReal&>(*args[1]).GetValue();
t_real funcval = (*iter->second)(arg1, arg2);
return std::make_shared<SymbolReal>(funcval);
}
}
return nullptr;
}
......
......@@ -23,9 +23,6 @@
#include "tools/in20/data.h"
using t_real = t_real_cli;
class CliAST;
class CliParserContext;
class Symbol;
......@@ -49,7 +46,7 @@ public:
virtual yy::CliParser::symbol_type yylex(CliParserContext &context);
};
template<class t_real> t_real str_to_real(const std::string& str);
template<class t_real_cli> t_real_cli str_to_real(const std::string& str);
// ----------------------------------------------------------------------------
......@@ -138,15 +135,15 @@ public:
class SymbolReal : public Symbol
{
private:
t_real m_val = 0;
t_real_cli m_val = 0;
public:
SymbolReal() = default;
SymbolReal(t_real val) : m_val(val) {}
SymbolReal(t_real_cli val) : m_val(val) {}
virtual ~SymbolReal() {}
virtual SymbolType GetType() const override { return SymbolType::REAL; }
t_real GetValue() const { return m_val; }
t_real_cli GetValue() const { return m_val; }
virtual std::shared_ptr<Symbol> copy() const override { return std::make_shared<SymbolReal>(m_val); }
};
......
/**
* Built-in functions
* @author Tobias Weber <tweber@ill.fr>
* @date 20-Jun-2018
* @license see 'LICENSE' file
*/
#include "funcs.h"
#include <cmath>
using t_real = t_real_cli;
/**
* real functions with one argument
*/
std::unordered_map<std::string, t_real_cli(*)(t_real)> g_funcs_real_1arg =
{
std::make_pair("sin", static_cast<t_real(*)(t_real)>(&std::sin)),
std::make_pair("cos", static_cast<t_real(*)(t_real)>(&std::cos)),
std::make_pair("tan", static_cast<t_real(*)(t_real)>(&std::tan)),
std::make_pair("asin", static_cast<t_real(*)(t_real)>(&std::asin)),
std::make_pair("acos", static_cast<t_real(*)(t_real)>(&std::acos)),
std::make_pair("atan", static_cast<t_real(*)(t_real)>(&std::atan)),
std::make_pair("sinh", static_cast<t_real(*)(t_real)>(&std::sinh)),
std::make_pair("cosh", static_cast<t_real(*)(t_real)>(&std::cosh)),
std::make_pair("tanh", static_cast<t_real(*)(t_real)>(&std::tanh)),
std::make_pair("asinh", static_cast<t_real(*)(t_real)>(&std::asinh)),
std::make_pair("acosh", static_cast<t_real(*)(t_real)>(&std::acosh)),
std::make_pair("atanh", static_cast<t_real(*)(t_real)>(&std::atanh)),
std::make_pair("sqrt", static_cast<t_real(*)(t_real)>(&std::sqrt)),
std::make_pair("cbrt", static_cast<t_real(*)(t_real)>(&std::cbrt)),
std::make_pair("log", static_cast<t_real(*)(t_real)>(&std::log)),
std::make_pair("log10", static_cast<t_real(*)(t_real)>(&std::log10)),
std::make_pair("log2", static_cast<t_real(*)(t_real)>(&std::log2)),
std::make_pair("exp", static_cast<t_real(*)(t_real)>(&std::exp)),
std::make_pair("exp2", static_cast<t_real(*)(t_real)>(&std::exp2)),
std::make_pair("abs", static_cast<t_real(*)(t_real)>(&std::abs)),
std::make_pair("round", static_cast<t_real(*)(t_real)>(&std::round)),
std::make_pair("nearbyint", static_cast<t_real(*)(t_real)>(&std::nearbyint)),
std::make_pair("trunc", static_cast<t_real(*)(t_real)>(&std::trunc)),
std::make_pair("ceil", static_cast<t_real(*)(t_real)>(&std::ceil)),
std::make_pair("floor", static_cast<t_real(*)(t_real)>(&std::floor)),
std::make_pair("erf", static_cast<t_real(*)(t_real)>(&std::erf)),
std::make_pair("erfc", static_cast<t_real(*)(t_real)>(&std::erfc)),
//std::make_pair("beta", static_cast<t_real(*)(t_real)>(&std::beta)),
std::make_pair("gamma", static_cast<t_real(*)(t_real)>(&std::tgamma)),
std::make_pair("loggamma", static_cast<t_real(*)(t_real)>(&std::lgamma)),
};
/**
* real functions with two arguments
*/
std::unordered_map<std::string, t_real_cli(*)(t_real, t_real)> g_funcs_real_2args =
{
std::make_pair("pow", static_cast<t_real(*)(t_real, t_real)>(&std::pow)),
std::make_pair("atan2", static_cast<t_real(*)(t_real, t_real)>(&std::atan2)),
std::make_pair("hypot", static_cast<t_real(*)(t_real, t_real)>(&std::hypot)),
std::make_pair("max", static_cast<t_real(*)(t_real, t_real)>(&std::fmax)),
std::make_pair("min", static_cast<t_real(*)(t_real, t_real)>(&std::fmin)),
//std::make_pair("diff", static_cast<t_real(*)(t_real, t_real)>(&std::fdim)),
std::make_pair("remainder", static_cast<t_real(*)(t_real, t_real)>(&std::remainder)),
std::make_pair("mod", static_cast<t_real(*)(t_real, t_real)>(&std::fmod)),
std::make_pair("copysign", static_cast<t_real(*)(t_real, t_real)>(&std::copysign)),
};
/**
* real constants
*/
std::unordered_map<std::string, t_real_cli> g_consts_real
{
std::make_pair("pi", t_real(M_PI)),
};
\ No newline at end of file
/**
* Built-in functions
* @author Tobias Weber <tweber@ill.fr>
* @date 20-Jun-2018
* @license see 'LICENSE' file
*/
#ifndef __FUNCS_H__
#define __FUNCS_H__
#include <unordered_map>
#include <string>
#include "cliparser_types.h"
// functions
extern std::unordered_map<std::string, t_real_cli(*)(t_real_cli)> g_funcs_real_1arg;
extern std::unordered_map<std::string, t_real_cli(*)(t_real_cli, t_real_cli)> g_funcs_real_2args;
// constants
extern std::unordered_map<std::string, t_real_cli> g_consts_real;
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment