44#ifndef NIMBLE_EXPRESSION_PARSER_H
45#define NIMBLE_EXPRESSION_PARSER_H
53#ifdef NIMBLE_HAVE_DARMA
84 template <
typename T,
typename... In>
88 T* pointer =
new T(inputs...);
89 unsigned long insert_location =
first->count;
91 first->count = insert_location + 1;
92 first->Pointers[insert_location] = pointer;
96 first->Pointers[0] = pointer;
105 unsigned int count = current->
count;
106 for (
unsigned int i = 0; i < count; ++i) {
delete *scan++; }
111 next = current->
next;
112 for (
unsigned int i = 0; i <
BlockSize; ++i) {
delete *scan++; }
122 virtual operator T()
const = 0;
136 operator T()
const {
return value; }
145 operator T()
const {
return *
value; }
152#define MakeGenericFunction(GenericFunction, f) \
153 template <typename Out, typename In> \
154 struct GenericFunction : Evaluatable<Out> \
156 struct ReferenceCase : Evaluatable<Out> \
159 operator Out() const { return f(*input1); } \
160 ReferenceCase(In* in1) : input1(in1) {} \
162 Evaluatable<In>* input1; \
163 operator Out() const { return f(*input1); } \
164 GenericFunction(Evaluatable<In>* in1) : input1(in1) {} \
166 optimize(MemoryManager& m) \
168 Evaluatable<In>* in1 = this->input1->optimize(m); \
169 if (GenericConstant<In>* constant = dynamic_cast<GenericConstant<In>*>(in1)) { \
170 return m.New<GenericConstant<Out>>(f(*in1)); \
171 } else if (GenericReference<In>* reference = dynamic_cast<GenericReference<In>*>(in1)) { \
172 return m.New<ReferenceCase>(reference->value); \
174 this->input1 = in1; \
179#define MakeGenericOperator(name, operation) \
180 template <typename Out, typename In1, typename In2> \
181 struct name : Evaluatable<Out> \
183 template <typename In1_t, typename In2_t> \
184 struct ReferenceCase : Evaluatable<Out> \
188 operator Out() const { return (*input1)operation(*input2); } \
189 ReferenceCase(In1_t* in1, In2_t* in2) : input1(in1), input2(in2) {} \
191 template <typename In2_type> \
192 struct ConstCase1 : Evaluatable<Out> \
196 operator Out() const { return input1 operation(*input2); } \
197 ConstCase1(In1 in1, In2_type* in2) : input1(in1), input2(in2) {} \
199 template <typename In1_type> \
200 struct ConstCase2 : Evaluatable<Out> \
204 operator Out() const { return (*input1)operation input2; } \
205 ConstCase2(In1_type* in1, In2 in2) : input1(in1), input2(in2) {} \
207 Evaluatable<In1>* input1; \
208 Evaluatable<In2>* input2; \
209 operator Out() const { return (*input1)operation(*input2); } \
210 name(Evaluatable<In1>* in1, Evaluatable<In2>* in2) : input1(in1), input2(in2) {} \
212 optimize(MemoryManager& m) \
214 Evaluatable<In1>* input1 = this->input1->optimize(m); \
215 Evaluatable<In2>* input2 = this->input2->optimize(m); \
216 if (auto const1 = dynamic_cast<GenericConstant<In1>*>(input1)) { \
217 if (auto const2 = dynamic_cast<GenericConstant<In2>*>(input2)) \
218 return m.New<GenericConstant<Out>>((*input1)operation(*input2)); \
219 else if (auto ref2 = dynamic_cast<GenericReference<In2>*>(input2)) \
220 return m.New<ConstCase1<In2>>(const1->value, ref2->value); \
222 return m.New<ConstCase1<Evaluatable<In2>>>(const1->value, input2); \
223 } else if (auto ref1 = dynamic_cast<GenericReference<In1>*>(input1)) { \
224 if (auto const2 = dynamic_cast<GenericConstant<In2>*>(input2)) \
225 return m.New<ConstCase2<In1>>(ref1->value, const2->value); \
226 else if (auto ref2 = dynamic_cast<GenericReference<In2>*>(input2)) \
227 return m.New<ReferenceCase<In1, In2>>(ref1->value, ref2->value); \
229 return m.New<ReferenceCase<In1, Evaluatable<In2>>>(ref1->value, input2); \
230 } else if (auto const2 = dynamic_cast<GenericConstant<In2>*>(input2)) \
231 return m.New<ConstCase2<Evaluatable<In1>>>(input1, const2->value); \
232 else if (auto ref2 = dynamic_cast<GenericReference<In2>*>(input2)) \
233 return m.New<ReferenceCase<Evaluatable<In1>, In2>>(input1, ref2->value); \
234 this->input1 = input1; \
235 this->input2 = input2; \
240#define MakeGenericTwoInputFunc(name, f) \
241 template <typename Out, typename In1, typename In2> \
242 struct name : Evaluatable<Out> \
244 template <typename In1_t, typename In2_t> \
245 struct ReferenceCase : Evaluatable<Out> \
249 operator Out() const { return f(*input1, *input2); } \
250 ReferenceCase(In1_t* in1, In2_t* in2) : input1(in1), input2(in2) {} \
252 template <typename In2_type> \
253 struct ConstCase1 : Evaluatable<Out> \
257 operator Out() const { return f(input1, *input2); } \
258 ConstCase1(In1 in1, In2_type* in2) : input1(in1), input2(in2) {} \
260 template <typename In1_type> \
261 struct ConstCase2 : Evaluatable<Out> \
265 operator Out() const { return f(*input1, input2); } \
266 ConstCase2(In1_type* in1, In2 in2) : input1(in1), input2(in2) {} \
268 Evaluatable<In1>* input1; \
269 Evaluatable<In2>* input2; \
270 operator Out() const { return f(*input1, *input2); } \
271 name(Evaluatable<In1>* in1, Evaluatable<In2>* in2) : input1(in1), input2(in2) {} \
273 optimize(MemoryManager& m) \
275 Evaluatable<In1>* input1 = this->input1->optimize(m); \
276 Evaluatable<In2>* input2 = this->input2->optimize(m); \
277 if (auto const1 = dynamic_cast<GenericConstant<In1>*>(input1)) { \
278 if (auto const2 = dynamic_cast<GenericConstant<In2>*>(input2)) \
279 return m.New<GenericConstant<Out>>(f(*input1, *input2)); \
280 else if (auto ref2 = dynamic_cast<GenericReference<In2>*>(input2)) \
281 return m.New<ConstCase1<In2>>(const1->value, ref2->value); \
283 return m.New<ConstCase1<Evaluatable<In2>>>(const1->value, input2); \
284 } else if (auto ref1 = dynamic_cast<GenericReference<In1>*>(input1)) { \
285 if (auto const2 = dynamic_cast<GenericConstant<In2>*>(input2)) \
286 return m.New<ConstCase2<In1>>(ref1->value, const2->value); \
287 else if (auto ref2 = dynamic_cast<GenericReference<In2>*>(input2)) \
288 return m.New<ReferenceCase<In1, In2>>(ref1->value, ref2->value); \
290 return m.New<ReferenceCase<In1, Evaluatable<In2>>>(ref1->value, input2); \
291 } else if (auto const2 = dynamic_cast<GenericConstant<In2>*>(input2)) \
292 return m.New<ConstCase2<Evaluatable<In1>>>(input1, const2->value); \
293 else if (auto ref2 = dynamic_cast<GenericReference<In2>*>(input2)) \
294 return m.New<ReferenceCase<Evaluatable<In1>, In2>>(input1, ref2->value); \
295 this->input1 = input1; \
296 this->input2 = input2; \
315 GenericGreaterOrEqual,
326 template <typename Out>
332 operator Out()
const {
return (*
condition) ? (*IfTrue) : (*IfFalse); }
344 if (ConstCondition->value) {
381 sub(
const char* start,
const char* end)
383 return Reader(start, end - start);
387 sub(
unsigned int start,
unsigned int end)
393 sub(
const char* start,
unsigned int len)
395 return Reader(start, len);
401 const char* f = this->first;
402 if (f[
pos] == open) {
419 const char* f = this->first;
420 if (f[
pos] == close) {
422 while (depth != 0 &&
pos > 0) {
439 const char* f =
first;
441 while (
pos < max_pos && f[
pos] != c)
Next(
'(',
')');
452 const char* f =
first;
453 while (
pos > 0 && f[
pos] != c)
Prev(
'(',
')');
454 if (f[
pos] == c)
return true;
466 const char* scan =
first;
467 const char* last = scan +
length;
468 while (scan < last && *lit !=
'\0') {
475 return scan == last && *lit ==
'\0';
546 ParseDoubleConstant(
Reader r)
555 double floating_point_value = std::stod(temp_string);
561 ParseFunction(Reader r)
564 if (
IsDigit(c) || c ==
'(' || c ==
'-' || r.length < 3)
return 0;
565 while (c = r.first[r.pos], c !=
'(' && c !=
' ' && r.pos < r.length) {
566 if (c !=
'*' && c !=
'/' && c !=
'^' && c !=
'+' && c !=
'=' && c !=
'<' && c !=
'~' && c !=
'>')
573 int depth = r.Next(
'(',
')');
574 if (depth > 0)
throw std::invalid_argument(
"Mismatched parethesis in " + r.MakeString());
575 if (r.pos < r.length - 1)
return 0;
576 Reader func_name = r.sub(r.first, p);
585 ParseOperation(Reader r)
589 int depth = r.Next(
'?',
':');
590 if (depth > 0)
throw std::invalid_argument(
"Couldn't find matching : for ternary operator in " + r.MakeString());
591 if (r.pos != r.length) {
593 ParseBooleanExpression(r.sub(r.first, p1)),
606 while (r.pos > 0 && (r.first[r.pos] ==
'-' || r.first[r.pos] ==
' ')) r.pos--;
607 if (r.pos > 0 || r.first[r.pos] !=
'-') {
608 char c = r.first[r.pos];
609 if (c !=
'*' && c !=
'/' && c !=
'^' && c !=
'e' && c !=
'=' && c !=
'<' && c !=
'~' && c !=
'>') {
610 while (r.first[r.pos] !=
'-') r.pos++;
625 Reader power_text = r.sub(r.pos + 1, r.length);
633 if (*r.first ==
'-') {
return mem.New<GenericNeg<double, double>>(
ParseEquation(r.sub(1, r.length))); }
639 ParseBooleanExpression(Reader r)
646 return mem.New<GenericOr<bool, bool, bool>>(
647 ParseBooleanExpression(r.sub(r.first, r.pos)), ParseBooleanExpression(r.sub(r.pos + 1, r.length)));
650 return mem.New<GenericXor<bool, bool, bool>>(
651 ParseBooleanExpression(r.sub(r.first, r.pos)), ParseBooleanExpression(r.sub(r.pos + 1, r.length)));
654 return mem.New<GenericAnd<bool, bool, bool>>(
655 ParseBooleanExpression(r.sub(r.first, r.pos)), ParseBooleanExpression(r.sub(r.pos + 1, r.length)));
657 if (r <<
'!')
return mem.New<GenericNot<bool, bool>>(ParseBooleanExpression(r.sub(r.first + 1, r.length)));
660 if (r.first[r.pos + 1] ==
'=')
661 return mem.New<GenericGreaterOrEqual<bool, double, double>>(
664 return mem.New<GenericGreater<bool, double, double>>(
669 if (r.first[r.pos + 1] ==
'=')
670 return mem.New<GenericLessOrEqual<bool, double, double>>(
673 return mem.New<GenericLess<bool, double, double>>(
686 if (r.first[r.pos - 1] ==
'=')
687 return mem.New<GenericEqual<bool, double, double>>(
690 throw std::invalid_argument(
"Unable to parse \"" + r.MakeString() +
"\" as boolean");
699 double x = 0,
y = 0,
z = 0,
t = 0;
724 }
catch (std::invalid_argument arg) {
749 if (old_context)
delete old_context;
751 }
catch (std::invalid_argument arg) {
761 throw std::invalid_argument(
762 "Error in BoundaryConditionFunctor::eva(), expression pointer is "
775 throw std::invalid_argument(
776 "Error in BoundaryConditionFunctor::eva(), expression pointer is "
789 throw std::invalid_argument(
790 "Error in BoundaryConditionFunctor::eva(), expression pointer is "
Definition nimble_expression_parser.h:523
RealValuedExpression * ParseEquation(std::string s)
Definition nimble_expression_parser.h:535
std::map< std::string, RealValuedExpression * > variables
Definition nimble_expression_parser.h:528
void AddVarible(std::string name, double &ref)
Definition nimble_expression_parser.h:530
MemoryManager mem
Definition nimble_expression_parser.h:527
Definition nimble_expression_parser.h:69
~MemoryManager()
Definition nimble_expression_parser.h:100
T * New(In... inputs)
Definition nimble_expression_parser.h:86
MemoryManager()
Definition nimble_expression_parser.h:83
MemoryBlock * first
Definition nimble_expression_parser.h:82
static const unsigned int BlockSize
Definition nimble_expression_parser.h:73
Definition nimble_expression_parser.h:61
GenericMod< double, double, double > DoubleMod
Definition nimble_expression_parser.h:363
RealValuedExpression * GetCMathFunc(Reader r, RealValuedExpression *input, MemoryManager &m)
Definition nimble_expression_parser.cc:57
Conditional< double > RealValuedConditional
Definition nimble_expression_parser.h:367
this condition
Definition nimble_expression_parser.h:349
GenericPow< double, double, double > DoublePow
Definition nimble_expression_parser.h:362
GenericSubtract< double, double, double > DoubleSubtract
Definition nimble_expression_parser.h:359
void ApplyNecessaryFormatting(Reader &text)
Definition nimble_expression_parser.cc:166
bool IsDigit(char c)
Definition nimble_expression_parser.cc:83
void RemoveWhitespace(Reader &text)
Definition nimble_expression_parser.cc:136
GenericMultiply< double, double, double > DoubleMultiply
Definition nimble_expression_parser.h:360
GenericPow< double, double, int > DoubleToIntegerPow
Definition nimble_expression_parser.h:364
std::cos std::erf std::log std::asin std::atan std::cbrt std::ceil std::floor MakeGenericOperator(GenericMultiply, *) MakeGenericOperator(GenericDivide
bool IsCMathFunc(Reader r)
Definition nimble_expression_parser.cc:47
std::cos std::erf std::log std::asin std::atan std::cbrt std::ceil std::floor<) MakeGenericOperator(GenericLessOrEqual,<=) MakeGenericOperator(GenericEqual,==) MakeGenericOperator(GenericInequal, !=) MakeGenericOperator(GenericAnd, &&) MakeGenericOperator(GenericXor, xor) MakeGenericOperator(GenericOr,||) MakeGenericTwoInputFunc(GenericPow, std::pow) MakeGenericTwoInputFunc(GenericMod, std::fmod) template< typename Out > struct Conditional :Evaluatable< Out > { Evaluatable< bool > *condition;Evaluatable< Out > *IfTrue;Evaluatable< Out > *IfFalse;operator Out() const { return(*condition) ?(*IfTrue) :(*IfFalse);} Conditional(Evaluatable< bool > *condition, Evaluatable< Out > *WhenTrue, Evaluatable< Out > *WhenFalse) :condition(condition), IfTrue(WhenTrue), IfFalse(WhenFalse) { } Evaluatable< Out > *optimize(MemoryManager &m) { Evaluatable< bool > *condition=this-> condition optimize(m)
void RemoveRedundantParenthesis(Reader &text)
Definition nimble_expression_parser.cc:149
void ConvertStringToLowercase(std::string &s)
Definition nimble_expression_parser.cc:126
GenericAdd< double, double, double > DoubleAdd
Definition nimble_expression_parser.h:358
Evaluatable< Out > * IfFalse
Definition nimble_expression_parser.h:342
Evaluatable< Out > * IfTrue
Definition nimble_expression_parser.h:341
GenericConstant< double > DoubleConstant
Definition nimble_expression_parser.h:357
MakeGenericFunction(GenericSin, std::sin) MakeGenericFunction(GenericCos
Evaluatable< double > RealValuedExpression
Definition nimble_expression_parser.h:356
bool IsNumber(Reader r)
Definition nimble_expression_parser.cc:101
GenericDivide< double, double, double > DoubleDivide
Definition nimble_expression_parser.h:361
bool IsInteger(Reader r)
Definition nimble_expression_parser.cc:89
Evaluatable< bool > BooleanExpression
Definition nimble_expression_parser.h:365
GenericConstant< bool > BooleanConstant
Definition nimble_expression_parser.h:366
#define MakeGenericFunction(GenericFunction, f)
Definition nimble_expression_parser.h:152
#define MakeGenericTwoInputFunc(name, f)
Definition nimble_expression_parser.h:240
Definition nimble_expression_parser.h:698
EquationContext * context
Definition nimble_expression_parser.h:700
BoundaryConditionFunctor & operator=(const BoundaryConditionFunctor &other)
Definition nimble_expression_parser.h:732
double operator()(double x, double y, double z, double t)
Definition nimble_expression_parser.h:782
double eval()
Definition nimble_expression_parser.h:758
~BoundaryConditionFunctor()
Definition nimble_expression_parser.h:795
RealValuedExpression * expression
Definition nimble_expression_parser.h:702
BoundaryConditionFunctor & operator=(const std::string &equation)
Definition nimble_expression_parser.h:737
BoundaryConditionFunctor()
Definition nimble_expression_parser.h:704
BoundaryConditionFunctor(const BoundaryConditionFunctor &other)
Definition nimble_expression_parser.h:730
std::string equation
Definition nimble_expression_parser.h:703
double eval(double x, double y, double z, double t)
Definition nimble_expression_parser.h:768
double t
Definition nimble_expression_parser.h:699
double x
Definition nimble_expression_parser.h:699
BoundaryConditionFunctor(const std::string &equation)
Definition nimble_expression_parser.h:705
double y
Definition nimble_expression_parser.h:699
double z
Definition nimble_expression_parser.h:699
Definition nimble_expression_parser.h:64
virtual ~DeletableObjectBaseClass()
Definition nimble_expression_parser.h:65
Definition nimble_expression_parser.h:121
virtual Evaluatable * optimize(MemoryManager &m)
Definition nimble_expression_parser.h:126
Definition nimble_expression_parser.h:134
double value
Definition nimble_expression_parser.h:135
GenericConstant()
Definition nimble_expression_parser.h:137
GenericConstant(T value)
Definition nimble_expression_parser.h:138
Definition nimble_expression_parser.h:143
GenericReference(T *value)
Definition nimble_expression_parser.h:147
GenericReference()
Definition nimble_expression_parser.h:146
T * value
Definition nimble_expression_parser.h:144
Definition nimble_expression_parser.h:75
DeletableObjectBaseClass * Pointers[BlockSize]
Definition nimble_expression_parser.h:76
MemoryBlock()
Definition nimble_expression_parser.h:79
MemoryBlock * next
Definition nimble_expression_parser.h:78
size_t count
Definition nimble_expression_parser.h:77
MemoryBlock(MemoryBlock *next)
Definition nimble_expression_parser.h:80
Definition nimble_expression_parser.h:370
const char * first
Definition nimble_expression_parser.h:371
char operator[](unsigned int i)
Definition nimble_expression_parser.h:479
bool IsEmpty()
Definition nimble_expression_parser.h:489
bool operator==(std::string &s)
Definition nimble_expression_parser.h:459
Reader(const Reader &r)
Definition nimble_expression_parser.h:378
std::string MakeString()
Definition nimble_expression_parser.h:484
Reader(const char *lit)
Definition nimble_expression_parser.h:376
Reader sub(const char *start, const char *end)
Definition nimble_expression_parser.h:381
bool operator>>(char c)
Definition nimble_expression_parser.h:436
Reader(const char *start, const char *end)
Definition nimble_expression_parser.h:377
Reader sub(unsigned int start, unsigned int end)
Definition nimble_expression_parser.h:387
Reader(const char *lit, unsigned int len)
Definition nimble_expression_parser.h:374
int Next(char open, char close)
Definition nimble_expression_parser.h:399
Reader sub(const char *start, unsigned int len)
Definition nimble_expression_parser.h:393
Reader(const std::string &s)
Definition nimble_expression_parser.h:375
bool operator==(const char *lit)
Definition nimble_expression_parser.h:464
int Prev(char open, char close)
Definition nimble_expression_parser.h:417
bool operator<<(char c)
Definition nimble_expression_parser.h:449
unsigned int length
Definition nimble_expression_parser.h:372
unsigned int pos
Definition nimble_expression_parser.h:373