25 #include "userFunction.rcd" 51 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) 55 # ifndef WIN32_LEAN_AND_MEAN 56 # define WIN32_LEAN_AND_MEAN 62 # include <sys/time.h> 63 # include <sys/types.h> 76 UserFunction::UserFunction(
const string&,
const string&) {}
77 vector<string> UserFunction::symbolNames()
const {
return {};}
78 void UserFunction::compile() {}
79 double UserFunction::evaluate(
double,
double) {
return {};}
80 double UserFunction::operator()(
const vector<double>& p) {}
81 Units UserFunction::units(
bool check)
const {
return {};}
82 string UserFunction::description(
const string&) {
return {};}
83 string UserFunction::name()
const {
return {};}
87 #include <exprtk/exprtk.hpp> 102 table.add_variable(
"time",
minsky().t);
103 table.add_variable(
"timeStep",
minsky().stepMax);
104 table.add_variable(
"initialTime",
minsky().t0);
105 table.add_variable(
"finalTime",
minsky().tmax);
107 table.add_function(
"isfinite",
isfinite);
108 table.add_function(
"isinf",
isinf);
109 table.add_function(
"isnan",
isnan);
116 std::weak_ptr<CallableFunction>
f;
119 if (
auto sf=
f.lock())
143 bool inWord=
false, inString=
false, quoted=
false;
148 case '\'':
if (!quoted) inString=!inString;
break;
149 case '\\': quoted=
true;
break;
150 default: quoted=
false;
break;
153 if (!inWord && !inString)
158 if (isalnum(c) || c==
'_' || c==
'.')
163 if (word.back()==
'.') word.erase(word.end()-1);
177 impl->compiledExpression=exprtk::expression<double>();
180 impl->symbols.clear();
181 impl->functions.clear();
187 if (v!=
minsky().variableValues.end())
189 impl->symbols.add_variable(i, (*v->second)[0]);
193 if (
f!=
minsky().userFunctions.end())
195 impl->functions.emplace_back(
f->second);
196 impl->symbols.add_function(i,
impl->functions.back());
202 for (
size_t i=0; i<
argNames.size(); ++i)
204 impl->compiledExpression.register_symbol_table(
impl->symbols);
209 for (
size_t i=0; i<
parser.error_count(); ++i)
210 errorInfo+=
parser.get_error(i).diagnostic+
'\n';
211 throw_error(
"Invalid function expression:\n"+errorInfo);
220 return impl->compiledExpression.value();
228 return impl->compiledExpression.value();
234 static const regex extractArgList(R
"([^(]*\(([^)]*)\))"); 237 if (regex_match(nm,match,extractArgList))
241 auto end=argList.find(
',');
242 decltype(end) begin=0;
243 for (; end!=string::npos; begin=end+1, end=argList.find(
',',begin))
244 argNames.push_back(argList.substr(begin,end-begin));
245 argNames.push_back(argList.substr(begin));
251 static const regex extractName(R
"(([^(]*).*)"); 254 regex_match(d, match, extractName);
255 assert (match.size()>1);
std::vector< double > argVals
std::vector< std::string > argNames
double operator()(const std::vector< double > &p) override
evaluate function on arbitrary number of arguments (exprtk support)
VariableValues variableValues
std::weak_ptr< CallableFunction > f
exprtk::symbol_table< double > symbols
exprtk::expression< double > compiledExpression
double operator()(const std::vector< double > &x)
std::vector< ExprTkCallableFunction > functions
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky's state cha...
CLASSDESC_ACCESS_EXPLICIT_INSTANTIATION(minsky::UserFunction)
double isfinite(double x)
std::vector< std::string > symbolNames() const
virtual std::string description() const
name of the associated data operation
void addTimeVariables(exprtk::symbol_table< double > &table)
void throw_error(const std::string &) const
mark item on canvas, then throw
exprtk::parser< double > parser
double evaluate(double x, double y)
string canonicalName(const string &name)
convert a raw name into a canonical name - this is not idempotent.
std::shared_ptr< Impl > impl
std::string name() const override
function name, shorn of argument decorators
Exclude< std::map< std::string, std::shared_ptr< CallableFunction > > > userFunctions
string valueIdFromScope(const GroupPtr &scope, const std::string &name)
value Id from scope and canonical name name
ExprTkCallableFunction(const std::weak_ptr< CallableFunction > &f)
Minsky & minsky()
global minsky object
void iconDraw(cairo_t *) const override
visual representation of operation on the canvas