3 * Copyright (C) 2006-2007 Mathias Froehlich
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 #ifndef _SG_EXPRESSION_HXX
23 #define _SG_EXPRESSION_HXX 1
28 #include <simgear/props/condition.hxx>
29 #include <simgear/props/props.hxx>
30 #include <simgear/math/interpolater.hxx>
31 #include <simgear/math/SGMath.hxx>
32 #include <simgear/scene/model/persparam.hxx>
33 #include <simgear/structure/exception.hxx>
34 #include <simgear/structure/Singleton.hxx>
36 /// Expression tree implementation.
48 template<typename T> struct TypeTraits;
49 template<> struct TypeTraits<bool> {
50 static const Type typeTag = BOOL;
52 template<> struct TypeTraits<int> {
53 static const Type typeTag = INT;
55 template<> struct TypeTraits<float> {
56 static const Type typeTag = FLOAT;
58 template<> struct TypeTraits<double> {
59 static const Type typeTag = DOUBLE;
72 Value() : typeTag(DOUBLE)
77 Value(bool val_) : typeTag(BOOL)
82 Value(int val_) : typeTag(INT)
87 Value(float val_) : typeTag(FLOAT)
92 Value(double val_) : typeTag(DOUBLE)
102 class Expression : public SGReferenced
105 virtual ~Expression() {}
106 virtual expression::Type getType() const = 0;
109 const expression::Value eval(const Expression* exp,
110 const expression::Binding* binding = 0);
115 class SGExpression : public simgear::Expression {
117 virtual ~SGExpression() {}
118 typedef T result_type;
119 typedef T operand_type;
120 virtual void eval(T&, const simgear::expression::Binding*) const = 0;
122 T getValue(const simgear::expression::Binding* binding = 0) const
123 { T value; eval(value, binding); return value; }
125 virtual bool isConst() const { return false; }
126 virtual SGExpression* simplify();
127 virtual simgear::expression::Type getType() const
129 return simgear::expression::TypeTraits<T>::typeTag;
131 virtual simgear::expression::Type getOperandType() const
133 return simgear::expression::TypeTraits<T>::typeTag;
137 /// Constant value expression
139 class SGConstExpression : public SGExpression<T> {
141 SGConstExpression(const T& value = T()) : _value(value)
143 void setValue(const T& value)
145 const T& getValue(const simgear::expression::Binding* binding = 0) const
147 virtual void eval(T& value, const simgear::expression::Binding*) const
149 virtual bool isConst() const { return true; }
156 SGExpression<T>::simplify()
159 return new SGConstExpression<T>(getValue());
164 class SGUnaryExpression : public SGExpression<T> {
166 const SGExpression<T>* getOperand() const
167 { return _expression; }
168 SGExpression<T>* getOperand()
169 { return _expression; }
170 void setOperand(SGExpression<T>* expression)
173 expression = new SGConstExpression<T>(T());
174 _expression = expression;
176 virtual bool isConst() const
177 { return getOperand()->isConst(); }
178 virtual SGExpression<T>* simplify()
180 _expression = _expression->simplify();
181 return SGExpression<T>::simplify();
185 SGUnaryExpression(SGExpression<T>* expression = 0)
186 { setOperand(expression); }
189 SGSharedPtr<SGExpression<T> > _expression;
193 class SGBinaryExpression : public SGExpression<T> {
195 const SGExpression<T>* getOperand(unsigned i) const
196 { return _expressions[i]; }
197 SGExpression<T>* getOperand(unsigned i)
198 { return _expressions[i]; }
199 void setOperand(unsigned i, SGExpression<T>* expression)
202 expression = new SGConstExpression<T>(T());
205 _expressions[i] = expression;
208 virtual bool isConst() const
209 { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
210 virtual SGExpression<T>* simplify()
212 _expressions[0] = _expressions[0]->simplify();
213 _expressions[1] = _expressions[1]->simplify();
214 return SGExpression<T>::simplify();
218 SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
219 { setOperand(0, expr0); setOperand(1, expr1); }
222 SGSharedPtr<SGExpression<T> > _expressions[2];
226 class SGNaryExpression : public SGExpression<T> {
228 unsigned getNumOperands() const
229 { return _expressions.size(); }
230 const SGExpression<T>* getOperand(unsigned i) const
231 { return _expressions[i]; }
232 SGExpression<T>* getOperand(unsigned i)
233 { return _expressions[i]; }
234 unsigned addOperand(SGExpression<T>* expression)
238 _expressions.push_back(expression);
239 return _expressions.size() - 1;
242 template<typename Iter>
243 void addOperands(Iter begin, Iter end)
245 for (Iter iter = begin; iter != end; ++iter)
247 addOperand(static_cast< ::SGExpression<T>*>(*iter));
251 virtual bool isConst() const
253 for (unsigned i = 0; i < _expressions.size(); ++i)
254 if (!_expressions[i]->isConst())
258 virtual SGExpression<T>* simplify()
260 for (unsigned i = 0; i < _expressions.size(); ++i)
261 _expressions[i] = _expressions[i]->simplify();
262 return SGExpression<T>::simplify();
268 SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
269 { addOperand(expr0); addOperand(expr1); }
272 std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
279 class SGPropertyExpression : public SGExpression<T> {
281 SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
283 void setPropertyNode(const SGPropertyNode* prop)
285 virtual void eval(T& value, const simgear::expression::Binding*) const
288 void doEval(float& value) const
289 { if (_prop) value = _prop->getFloatValue(); }
290 void doEval(double& value) const
291 { if (_prop) value = _prop->getDoubleValue(); }
292 void doEval(int& value) const
293 { if (_prop) value = _prop->getIntValue(); }
294 void doEval(long& value) const
295 { if (_prop) value = _prop->getLongValue(); }
296 void doEval(bool& value) const
297 { if (_prop) value = _prop->getBoolValue(); }
298 SGSharedPtr<const SGPropertyNode> _prop;
302 class SGAbsExpression : public SGUnaryExpression<T> {
304 SGAbsExpression(SGExpression<T>* expr = 0)
305 : SGUnaryExpression<T>(expr)
308 virtual void eval(T& value, const simgear::expression::Binding* b) const
309 { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
311 using SGUnaryExpression<T>::getOperand;
315 class SGACosExpression : public SGUnaryExpression<T> {
317 SGACosExpression(SGExpression<T>* expr = 0)
318 : SGUnaryExpression<T>(expr)
321 virtual void eval(T& value, const simgear::expression::Binding* b) const
322 { value = acos(SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
324 using SGUnaryExpression<T>::getOperand;
328 class SGASinExpression : public SGUnaryExpression<T> {
330 SGASinExpression(SGExpression<T>* expr = 0)
331 : SGUnaryExpression<T>(expr)
334 virtual void eval(T& value, const simgear::expression::Binding* b) const
335 { value = asin(SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
337 using SGUnaryExpression<T>::getOperand;
341 class SGATanExpression : public SGUnaryExpression<T> {
343 SGATanExpression(SGExpression<T>* expr = 0)
344 : SGUnaryExpression<T>(expr)
347 virtual void eval(T& value, const simgear::expression::Binding* b) const
348 { value = atan(getOperand()->getValue(b)); }
350 using SGUnaryExpression<T>::getOperand;
354 class SGCeilExpression : public SGUnaryExpression<T> {
356 SGCeilExpression(SGExpression<T>* expr = 0)
357 : SGUnaryExpression<T>(expr)
360 virtual void eval(T& value, const simgear::expression::Binding* b) const
361 { value = ceil(getOperand()->getValue(b)); }
363 using SGUnaryExpression<T>::getOperand;
367 class SGCosExpression : public SGUnaryExpression<T> {
369 SGCosExpression(SGExpression<T>* expr = 0)
370 : SGUnaryExpression<T>(expr)
373 virtual void eval(T& value, const simgear::expression::Binding* b) const
374 { value = cos(getOperand()->getValue(b)); }
376 using SGUnaryExpression<T>::getOperand;
380 class SGCoshExpression : public SGUnaryExpression<T> {
382 SGCoshExpression(SGExpression<T>* expr = 0)
383 : SGUnaryExpression<T>(expr)
386 virtual void eval(T& value, const simgear::expression::Binding* b) const
387 { value = cosh(getOperand()->getValue(b)); }
389 using SGUnaryExpression<T>::getOperand;
393 class SGExpExpression : public SGUnaryExpression<T> {
395 SGExpExpression(SGExpression<T>* expr = 0)
396 : SGUnaryExpression<T>(expr)
399 virtual void eval(T& value, const simgear::expression::Binding* b) const
400 { value = exp(getOperand()->getValue(b)); }
402 using SGUnaryExpression<T>::getOperand;
406 class SGFloorExpression : public SGUnaryExpression<T> {
408 SGFloorExpression(SGExpression<T>* expr = 0)
409 : SGUnaryExpression<T>(expr)
412 virtual void eval(T& value, const simgear::expression::Binding* b) const
413 { value = floor(getOperand()->getValue(b)); }
415 using SGUnaryExpression<T>::getOperand;
419 class SGLogExpression : public SGUnaryExpression<T> {
421 SGLogExpression(SGExpression<T>* expr = 0)
422 : SGUnaryExpression<T>(expr)
425 virtual void eval(T& value, const simgear::expression::Binding* b) const
426 { value = log(getOperand()->getValue(b)); }
428 using SGUnaryExpression<T>::getOperand;
432 class SGLog10Expression : public SGUnaryExpression<T> {
434 SGLog10Expression(SGExpression<T>* expr = 0)
435 : SGUnaryExpression<T>(expr)
438 virtual void eval(T& value, const simgear::expression::Binding* b) const
439 { value = log10(getOperand()->getValue(b)); }
441 using SGUnaryExpression<T>::getOperand;
445 class SGSinExpression : public SGUnaryExpression<T> {
447 SGSinExpression(SGExpression<T>* expr = 0)
448 : SGUnaryExpression<T>(expr)
451 virtual void eval(T& value, const simgear::expression::Binding* b) const
452 { value = sin(getOperand()->getValue(b)); }
454 using SGUnaryExpression<T>::getOperand;
458 class SGSinhExpression : public SGUnaryExpression<T> {
460 SGSinhExpression(SGExpression<T>* expr = 0)
461 : SGUnaryExpression<T>(expr)
464 virtual void eval(T& value, const simgear::expression::Binding* b) const
465 { value = sinh(getOperand()->getValue(b)); }
467 using SGUnaryExpression<T>::getOperand;
471 class SGSqrExpression : public SGUnaryExpression<T> {
473 SGSqrExpression(SGExpression<T>* expr = 0)
474 : SGUnaryExpression<T>(expr)
477 virtual void eval(T& value, const simgear::expression::Binding* b) const
478 { value = getOperand()->getValue(b); value = value*value; }
480 using SGUnaryExpression<T>::getOperand;
484 class SGSqrtExpression : public SGUnaryExpression<T> {
486 SGSqrtExpression(SGExpression<T>* expr = 0)
487 : SGUnaryExpression<T>(expr)
490 virtual void eval(T& value, const simgear::expression::Binding* b) const
491 { value = sqrt(getOperand()->getValue(b)); }
493 using SGUnaryExpression<T>::getOperand;
497 class SGTanExpression : public SGUnaryExpression<T> {
499 SGTanExpression(SGExpression<T>* expr = 0)
500 : SGUnaryExpression<T>(expr)
503 virtual void eval(T& value, const simgear::expression::Binding* b) const
504 { value = tan(getOperand()->getValue(b)); }
506 using SGUnaryExpression<T>::getOperand;
510 class SGTanhExpression : public SGUnaryExpression<T> {
512 SGTanhExpression(SGExpression<T>* expr = 0)
513 : SGUnaryExpression<T>(expr)
516 virtual void eval(T& value, const simgear::expression::Binding* b) const
517 { value = tanh(getOperand()->getValue(b)); }
519 using SGUnaryExpression<T>::getOperand;
523 class SGScaleExpression : public SGUnaryExpression<T> {
525 SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
526 : SGUnaryExpression<T>(expr), _scale(scale)
528 void setScale(const T& scale)
530 const T& getScale() const
533 virtual void eval(T& value, const simgear::expression::Binding* b) const
534 { value = _scale * getOperand()->getValue(b); }
536 virtual SGExpression<T>* simplify()
539 return getOperand()->simplify();
540 return SGUnaryExpression<T>::simplify();
543 using SGUnaryExpression<T>::getOperand;
549 class SGBiasExpression : public SGUnaryExpression<T> {
551 SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
552 : SGUnaryExpression<T>(expr), _bias(bias)
555 void setBias(const T& bias)
557 const T& getBias() const
560 virtual void eval(T& value, const simgear::expression::Binding* b) const
561 { value = _bias + getOperand()->getValue(b); }
563 virtual SGExpression<T>* simplify()
566 return getOperand()->simplify();
567 return SGUnaryExpression<T>::simplify();
570 using SGUnaryExpression<T>::getOperand;
576 class SGInterpTableExpression : public SGUnaryExpression<T> {
578 SGInterpTableExpression(SGExpression<T>* expr,
579 const SGInterpTable* interpTable) :
580 SGUnaryExpression<T>(expr),
581 _interpTable(interpTable)
584 virtual void eval(T& value, const simgear::expression::Binding* b) const
587 value = _interpTable->interpolate(getOperand()->getValue(b));
590 using SGUnaryExpression<T>::getOperand;
592 SGSharedPtr<SGInterpTable const> _interpTable;
596 class SGClipExpression : public SGUnaryExpression<T> {
598 SGClipExpression(SGExpression<T>* expr)
599 : SGUnaryExpression<T>(expr),
600 _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
601 _clipMax(SGLimits<T>::max())
603 SGClipExpression(SGExpression<T>* expr,
604 const T& clipMin, const T& clipMax)
605 : SGUnaryExpression<T>(expr),
610 void setClipMin(const T& clipMin)
611 { _clipMin = clipMin; }
612 const T& getClipMin() const
615 void setClipMax(const T& clipMax)
616 { _clipMax = clipMax; }
617 const T& getClipMax() const
620 virtual void eval(T& value, const simgear::expression::Binding* b) const
622 value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
625 virtual SGExpression<T>* simplify()
627 if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
628 _clipMax >= SGLimits<T>::max())
629 return getOperand()->simplify();
630 return SGUnaryExpression<T>::simplify();
633 using SGUnaryExpression<T>::getOperand;
640 class SGStepExpression : public SGUnaryExpression<T> {
642 SGStepExpression(SGExpression<T>* expr = 0,
643 const T& step = T(1), const T& scroll = T(0))
644 : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
647 void setStep(const T& step)
649 const T& getStep() const
652 void setScroll(const T& scroll)
653 { _scroll = scroll; }
654 const T& getScroll() const
657 virtual void eval(T& value, const simgear::expression::Binding* b) const
658 { value = apply_mods(getOperand()->getValue(b)); }
660 using SGUnaryExpression<T>::getOperand;
663 T apply_mods(T property) const
669 // calculate scroll amount (for odometer like movement)
670 T remainder = _step - fmod(fabs(property), _step);
671 if (remainder < _scroll) {
672 scrollval = (_scroll - remainder) / _scroll * _step;
675 // apply stepping of input value
677 modprop = ((floor(property/_step) * _step) + scrollval);
679 modprop = ((ceil(property/_step) * _step) + scrollval);
691 class SGEnableExpression : public SGUnaryExpression<T> {
693 SGEnableExpression(SGExpression<T>* expr = 0,
694 SGCondition* enable = 0,
695 const T& disabledValue = T(0))
696 : SGUnaryExpression<T>(expr),
698 _disabledValue(disabledValue)
701 const T& getDisabledValue() const
702 { return _disabledValue; }
703 void setDisabledValue(const T& disabledValue)
704 { _disabledValue = disabledValue; }
706 virtual void eval(T& value, const simgear::expression::Binding* b) const
709 value = getOperand()->getValue(b);
711 value = _disabledValue;
714 virtual SGExpression<T>* simplify()
717 return getOperand()->simplify();
718 return SGUnaryExpression<T>::simplify();
721 using SGUnaryExpression<T>::getOperand;
723 SGSharedPtr<SGCondition> _enable;
728 class SGAtan2Expression : public SGBinaryExpression<T> {
730 SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
731 : SGBinaryExpression<T>(expr0, expr1)
733 virtual void eval(T& value, const simgear::expression::Binding* b) const
734 { value = atan2(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
735 using SGBinaryExpression<T>::getOperand;
739 class SGDivExpression : public SGBinaryExpression<T> {
741 SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
742 : SGBinaryExpression<T>(expr0, expr1)
744 virtual void eval(T& value, const simgear::expression::Binding* b) const
745 { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
746 using SGBinaryExpression<T>::getOperand;
750 class SGModExpression : public SGBinaryExpression<T> {
752 SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
753 : SGBinaryExpression<T>(expr0, expr1)
755 virtual void eval(T& value, const simgear::expression::Binding* b) const
756 { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
757 using SGBinaryExpression<T>::getOperand;
759 int mod(const int& v0, const int& v1) const
761 float mod(const float& v0, const float& v1) const
762 { return fmod(v0, v1); }
763 double mod(const double& v0, const double& v1) const
764 { return fmod(v0, v1); }
768 class SGPowExpression : public SGBinaryExpression<T> {
770 SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
771 : SGBinaryExpression<T>(expr0, expr1)
773 virtual void eval(T& value, const simgear::expression::Binding* b) const
774 { value = pow(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
775 using SGBinaryExpression<T>::getOperand;
779 class SGSumExpression : public SGNaryExpression<T> {
783 SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
784 : SGNaryExpression<T>(expr0, expr1)
786 virtual void eval(T& value, const simgear::expression::Binding* b) const
789 unsigned sz = SGNaryExpression<T>::getNumOperands();
790 for (unsigned i = 0; i < sz; ++i)
791 value += getOperand(i)->getValue(b);
793 using SGNaryExpression<T>::getValue;
794 using SGNaryExpression<T>::getOperand;
798 class SGDifferenceExpression : public SGNaryExpression<T> {
800 SGDifferenceExpression()
802 SGDifferenceExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
803 : SGNaryExpression<T>(expr0, expr1)
805 virtual void eval(T& value, const simgear::expression::Binding* b) const
808 unsigned sz = SGNaryExpression<T>::getNumOperands();
809 for (unsigned i = 0; i < sz; ++i)
810 value -= getOperand(i)->getValue(b);
812 using SGNaryExpression<T>::getValue;
813 using SGNaryExpression<T>::getOperand;
817 class SGProductExpression : public SGNaryExpression<T> {
819 SGProductExpression()
821 SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
822 : SGNaryExpression<T>(expr0, expr1)
824 virtual void eval(T& value, const simgear::expression::Binding* b) const
827 unsigned sz = SGNaryExpression<T>::getNumOperands();
828 for (unsigned i = 0; i < sz; ++i)
829 value *= getOperand(i)->getValue(b);
831 using SGNaryExpression<T>::getValue;
832 using SGNaryExpression<T>::getOperand;
836 class SGMinExpression : public SGNaryExpression<T> {
840 SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
841 : SGNaryExpression<T>(expr0, expr1)
843 virtual void eval(T& value, const simgear::expression::Binding* b) const
845 unsigned sz = SGNaryExpression<T>::getNumOperands();
849 value = getOperand(0)->getValue(b);
850 for (unsigned i = 1; i < sz; ++i)
851 value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
853 using SGNaryExpression<T>::getOperand;
857 class SGMaxExpression : public SGNaryExpression<T> {
861 SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
862 : SGNaryExpression<T>(expr0, expr1)
864 virtual void eval(T& value, const simgear::expression::Binding* b) const
866 unsigned sz = SGNaryExpression<T>::getNumOperands();
870 value = getOperand(0)->getValue(b);
871 for (unsigned i = 1; i < sz; ++i)
872 value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
874 using SGNaryExpression<T>::getOperand;
877 typedef SGExpression<int> SGExpressioni;
878 typedef SGExpression<float> SGExpressionf;
879 typedef SGExpression<double> SGExpressiond;
880 typedef SGExpression<bool> SGExpressionb;
883 * Global function to make an expression out of properties.
887 <clipMax>79</clipMax>
891 <property>sim/model/whatever-rad</property>
893 <property>sim/model/someother-deg</property>
899 will evaluate to an expression:
901 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
905 SGReadIntExpression(SGPropertyNode *inputRoot,
906 const SGPropertyNode *configNode);
909 SGReadFloatExpression(SGPropertyNode *inputRoot,
910 const SGPropertyNode *configNode);
912 SGExpression<double>*
913 SGReadDoubleExpression(SGPropertyNode *inputRoot,
914 const SGPropertyNode *configNode);
917 SGReadBoolExpression(SGPropertyNode *inputRoot,
918 const SGPropertyNode *configNode);
924 struct ParseError : public sg_exception
926 ParseError(const string& message = std::string())
927 : sg_exception(message) {}
930 // Support for binding variables around an expression.
934 virtual ~Binding() {}
935 const virtual Value* getBindings() const = 0;
936 virtual Value* getBindings() = 0;
939 class VariableLengthBinding : public Binding
942 const Value* getBindings() const
944 if (_bindings.empty())
947 return &_bindings[0];
951 if (_bindings.empty())
954 return &_bindings[0];
956 std::vector<Value> _bindings;
959 template<int Size> class FixedLengthBinding : public Binding
964 return &_bindings[0];
966 const Value* getBindings() const
968 return &_bindings[0];
970 Value _bindings[Size];
973 struct VariableBinding
975 VariableBinding() : type(expression::DOUBLE), location(-1) {}
977 VariableBinding(const std::string& name_, expression::Type type_,
979 : name(name_), type(type_), location(location_)
983 expression::Type type;
990 int addBinding(const std::string& name, expression::Type type);
991 bool findBinding(const string& name, VariableBinding& result) const;
992 std::vector<VariableBinding> bindings;
997 typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
999 void addParser(const std::string& name, exp_parser parser)
1001 getParserMap().insert(std::make_pair(name, parser));
1003 Expression* read(const SGPropertyNode* exp)
1005 ParserMap& map = getParserMap();
1006 ParserMap::iterator itr = map.find(exp->getName());
1007 if (itr == map.end())
1008 throw ParseError(string("unknown expression ") + exp->getName());
1009 exp_parser parser = itr->second;
1010 return (*parser)(exp, this);
1012 // XXX vector of SGSharedPtr?
1013 bool readChildren(const SGPropertyNode* exp,
1014 std::vector<Expression*>& result);
1016 * Function that parses a property tree, producing an expression.
1018 typedef std::map<const std::string, exp_parser> ParserMap;
1019 virtual ParserMap& getParserMap() = 0;
1021 * After an expression is parsed, the binding layout may contain
1022 * references that need to be bound during evaluation.
1024 BindingLayout& getBindingLayout() { return _bindingLayout; }
1026 BindingLayout _bindingLayout;
1029 class ExpressionParser : public Parser
1032 ParserMap& getParserMap()
1034 return ParserMapSingleton::instance()->_parserTable;
1036 static void addExpParser(const std::string&, exp_parser);
1038 struct ParserMapSingleton : public simgear::Singleton<ParserMapSingleton>
1040 ParserMap _parserTable;
1045 * Constructor for registering parser functions.
1047 struct ExpParserRegistrar
1049 ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1051 ExpressionParser::addExpParser(token, parser);
1058 * Access a variable definition. Use a location from a BindingLayout.
1060 template<typename T>
1061 class VariableExpression : public ::SGExpression<T> {
1063 VariableExpression(int location) : _location(location) {}
1064 virtual ~VariableExpression() {}
1065 virtual void eval(T& value, const simgear::expression::Binding* b) const
1067 const expression::Value* values = b->getBindings();
1068 value = *reinterpret_cast<const T *>(&values[_location].val);
1076 * An n-ary expression where the types of the argument aren't the
1077 * same as the return type.
1079 template<typename T, typename OpType>
1080 class GeneralNaryExpression : public ::SGExpression<T> {
1082 typedef OpType operand_type;
1083 unsigned getNumOperands() const
1084 { return _expressions.size(); }
1085 const ::SGExpression<OpType>* getOperand(unsigned i) const
1086 { return _expressions[i]; }
1087 ::SGExpression<OpType>* getOperand(unsigned i)
1088 { return _expressions[i]; }
1089 unsigned addOperand(::SGExpression<OpType>* expression)
1092 return ~unsigned(0);
1093 _expressions.push_back(expression);
1094 return _expressions.size() - 1;
1097 template<typename Iter>
1098 void addOperands(Iter begin, Iter end)
1100 for (Iter iter = begin; iter != end; ++iter)
1102 addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1106 virtual bool isConst() const
1108 for (unsigned i = 0; i < _expressions.size(); ++i)
1109 if (!_expressions[i]->isConst())
1113 virtual ::SGExpression<T>* simplify()
1115 for (unsigned i = 0; i < _expressions.size(); ++i)
1116 _expressions[i] = _expressions[i]->simplify();
1117 return SGExpression<T>::simplify();
1120 simgear::expression::Type getOperandType() const
1122 return simgear::expression::TypeTraits<OpType>::typeTag;
1126 GeneralNaryExpression()
1128 GeneralNaryExpression(::SGExpression<OpType>* expr0,
1129 ::SGExpression<OpType>* expr1)
1130 { addOperand(expr0); addOperand(expr1); }
1132 std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1136 * A predicate that wraps, for example the STL template predicate
1137 * expressions like std::equal_to.
1139 template<typename OpType, template<typename PredOp> class Pred>
1140 class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1142 PredicateExpression()
1145 PredicateExpression(::SGExpression<OpType>* expr0,
1146 ::SGExpression<OpType>* expr1)
1147 : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1150 virtual void eval(bool& value, const simgear::expression::Binding* b) const
1152 unsigned sz = this->getNumOperands();
1155 value = _pred(this->getOperand(0)->getValue(b),
1156 this->getOperand(1)->getValue(b));
1162 template<template<typename OT> class Pred, typename OpType>
1163 PredicateExpression<OpType, Pred>*
1164 makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1166 return new PredicateExpression<OpType, Pred>(op1, op2);
1169 template<typename OpType>
1170 class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1173 EqualToExpression() {}
1174 EqualToExpression(::SGExpression<OpType>* expr0,
1175 ::SGExpression<OpType>* expr1)
1176 : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1181 template<typename OpType>
1182 class LessExpression : public PredicateExpression<OpType, std::less>
1186 LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1187 : PredicateExpression<OpType, std::less>(expr0, expr1)
1192 template<typename OpType>
1193 class LessEqualExpression
1194 : public PredicateExpression<OpType, std::less_equal>
1197 LessEqualExpression() {}
1198 LessEqualExpression(::SGExpression<OpType>* expr0,
1199 ::SGExpression<OpType>* expr1)
1200 : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1205 class NotExpression : public ::SGUnaryExpression<bool>
1208 NotExpression(::SGExpression<bool>* expr = 0)
1209 : ::SGUnaryExpression<bool>(expr)
1212 void eval(bool& value, const expression::Binding* b) const
1214 value = !getOperand()->getValue(b);
1218 class OrExpression : public ::SGNaryExpression<bool>
1221 void eval(bool& value, const expression::Binding* b) const
1224 for (int i = 0; i < (int)getNumOperands(); ++i) {
1225 value = value || getOperand(i)->getValue(b);
1232 class AndExpression : public ::SGNaryExpression<bool>
1235 void eval(bool& value, const expression::Binding* b) const
1238 for (int i = 0; i < (int)getNumOperands(); ++i) {
1239 value = value && getOperand(i)->getValue(b);
1247 * Convert an operand from OpType to T.
1249 template<typename T, typename OpType>
1250 class ConvertExpression : public GeneralNaryExpression<T, OpType>
1253 ConvertExpression() {}
1254 ConvertExpression(::SGExpression<OpType>* expr0)
1258 virtual void eval(T& value, const simgear::expression::Binding* b) const
1260 typename ConvertExpression::operand_type result;
1261 this->_expressions.at(0)->eval(result, b);
1266 #endif // _SG_EXPRESSION_HXX