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
30 #include <simgear/props/condition.hxx>
31 #include <simgear/props/props.hxx>
32 #include <simgear/math/interpolater.hxx>
33 #include <simgear/math/SGMath.hxx>
34 #include <simgear/scene/model/persparam.hxx>
35 #include <simgear/structure/exception.hxx>
36 #include <simgear/structure/Singleton.hxx>
38 /// Expression tree implementation.
50 template<typename T> struct TypeTraits;
51 template<> struct TypeTraits<bool> {
52 static const Type typeTag = BOOL;
54 template<> struct TypeTraits<int> {
55 static const Type typeTag = INT;
57 template<> struct TypeTraits<float> {
58 static const Type typeTag = FLOAT;
60 template<> struct TypeTraits<double> {
61 static const Type typeTag = DOUBLE;
74 Value() : typeTag(DOUBLE)
79 Value(bool val_) : typeTag(BOOL)
84 Value(int val_) : typeTag(INT)
89 Value(float val_) : typeTag(FLOAT)
94 Value(double val_) : typeTag(DOUBLE)
104 class Expression : public SGReferenced
107 virtual ~Expression() {}
108 virtual expression::Type getType() const = 0;
111 const expression::Value eval(const Expression* exp,
112 const expression::Binding* binding = 0);
117 class SGExpression : public simgear::Expression {
119 virtual ~SGExpression() {}
120 typedef T result_type;
121 typedef T operand_type;
122 virtual void eval(T&, const simgear::expression::Binding*) const = 0;
124 T getValue(const simgear::expression::Binding* binding = 0) const
125 { T value; eval(value, binding); return value; }
127 double getDoubleValue(const simgear::expression::Binding* binding = 0) const
128 { T value; eval(value, binding); return value; }
130 virtual bool isConst() const { return false; }
131 virtual SGExpression* simplify();
132 virtual simgear::expression::Type getType() const
134 return simgear::expression::TypeTraits<T>::typeTag;
136 virtual simgear::expression::Type getOperandType() const
138 return simgear::expression::TypeTraits<T>::typeTag;
140 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
144 /// Constant value expression
146 class SGConstExpression : public SGExpression<T> {
148 SGConstExpression(const T& value = T()) : _value(value)
150 void setValue(const T& value)
152 const T& getValue(const simgear::expression::Binding* binding = 0) const
154 virtual void eval(T& value, const simgear::expression::Binding*) const
156 virtual bool isConst() const { return true; }
163 SGExpression<T>::simplify()
166 return new SGConstExpression<T>(getValue());
171 class SGUnaryExpression : public SGExpression<T> {
173 const SGExpression<T>* getOperand() const
174 { return _expression; }
175 SGExpression<T>* getOperand()
176 { return _expression; }
177 void setOperand(SGExpression<T>* expression)
180 expression = new SGConstExpression<T>(T());
181 _expression = expression;
183 virtual bool isConst() const
184 { return getOperand()->isConst(); }
185 virtual SGExpression<T>* simplify()
187 _expression = _expression->simplify();
188 return SGExpression<T>::simplify();
191 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
192 { _expression->collectDependentProperties(props); }
194 SGUnaryExpression(SGExpression<T>* expression = 0)
195 { setOperand(expression); }
198 SGSharedPtr<SGExpression<T> > _expression;
202 class SGBinaryExpression : public SGExpression<T> {
204 const SGExpression<T>* getOperand(size_t i) const
205 { return _expressions[i]; }
206 SGExpression<T>* getOperand(size_t i)
207 { return _expressions[i]; }
208 void setOperand(size_t i, SGExpression<T>* expression)
211 expression = new SGConstExpression<T>(T());
214 _expressions[i] = expression;
217 virtual bool isConst() const
218 { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
219 virtual SGExpression<T>* simplify()
221 _expressions[0] = _expressions[0]->simplify();
222 _expressions[1] = _expressions[1]->simplify();
223 return SGExpression<T>::simplify();
226 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
228 _expressions[0]->collectDependentProperties(props);
229 _expressions[1]->collectDependentProperties(props);
233 SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
234 { setOperand(0, expr0); setOperand(1, expr1); }
237 SGSharedPtr<SGExpression<T> > _expressions[2];
241 class SGNaryExpression : public SGExpression<T> {
243 size_t getNumOperands() const
244 { return _expressions.size(); }
245 const SGExpression<T>* getOperand(size_t i) const
246 { return _expressions[i]; }
247 SGExpression<T>* getOperand(size_t i)
248 { return _expressions[i]; }
249 size_t addOperand(SGExpression<T>* expression)
253 _expressions.push_back(expression);
254 return _expressions.size() - 1;
257 template<typename Iter>
258 void addOperands(Iter begin, Iter end)
260 for (Iter iter = begin; iter != end; ++iter)
262 addOperand(static_cast< ::SGExpression<T>*>(*iter));
266 virtual bool isConst() const
268 for (size_t i = 0; i < _expressions.size(); ++i)
269 if (!_expressions[i]->isConst())
273 virtual SGExpression<T>* simplify()
275 for (size_t i = 0; i < _expressions.size(); ++i)
276 _expressions[i] = _expressions[i]->simplify();
277 return SGExpression<T>::simplify();
280 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
282 for (size_t i = 0; i < _expressions.size(); ++i)
283 _expressions[i]->collectDependentProperties(props);
288 SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
289 { addOperand(expr0); addOperand(expr1); }
292 std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
299 class SGPropertyExpression : public SGExpression<T> {
301 SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
303 void setPropertyNode(const SGPropertyNode* prop)
305 virtual void eval(T& value, const simgear::expression::Binding*) const
308 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
309 { props.insert(_prop.get()); }
311 void doEval(float& value) const
312 { if (_prop) value = _prop->getFloatValue(); }
313 void doEval(double& value) const
314 { if (_prop) value = _prop->getDoubleValue(); }
315 void doEval(int& value) const
316 { if (_prop) value = _prop->getIntValue(); }
317 void doEval(long& value) const
318 { if (_prop) value = _prop->getLongValue(); }
319 void doEval(bool& value) const
320 { if (_prop) value = _prop->getBoolValue(); }
321 SGSharedPtr<const SGPropertyNode> _prop;
325 class SGAbsExpression : public SGUnaryExpression<T> {
327 SGAbsExpression(SGExpression<T>* expr = 0)
328 : SGUnaryExpression<T>(expr)
331 virtual void eval(T& value, const simgear::expression::Binding* b) const
332 { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
334 using SGUnaryExpression<T>::getOperand;
338 class SGACosExpression : public SGUnaryExpression<T> {
340 SGACosExpression(SGExpression<T>* expr = 0)
341 : SGUnaryExpression<T>(expr)
344 virtual void eval(T& value, const simgear::expression::Binding* b) const
345 { value = acos((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
347 using SGUnaryExpression<T>::getOperand;
351 class SGASinExpression : public SGUnaryExpression<T> {
353 SGASinExpression(SGExpression<T>* expr = 0)
354 : SGUnaryExpression<T>(expr)
357 virtual void eval(T& value, const simgear::expression::Binding* b) const
358 { value = asin((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
360 using SGUnaryExpression<T>::getOperand;
364 class SGATanExpression : public SGUnaryExpression<T> {
366 SGATanExpression(SGExpression<T>* expr = 0)
367 : SGUnaryExpression<T>(expr)
370 virtual void eval(T& value, const simgear::expression::Binding* b) const
371 { value = atan(getOperand()->getDoubleValue(b)); }
373 using SGUnaryExpression<T>::getOperand;
377 class SGCeilExpression : public SGUnaryExpression<T> {
379 SGCeilExpression(SGExpression<T>* expr = 0)
380 : SGUnaryExpression<T>(expr)
383 virtual void eval(T& value, const simgear::expression::Binding* b) const
384 { value = ceil(getOperand()->getDoubleValue(b)); }
386 using SGUnaryExpression<T>::getOperand;
390 class SGCosExpression : public SGUnaryExpression<T> {
392 SGCosExpression(SGExpression<T>* expr = 0)
393 : SGUnaryExpression<T>(expr)
396 virtual void eval(T& value, const simgear::expression::Binding* b) const
397 { value = cos(getOperand()->getDoubleValue(b)); }
399 using SGUnaryExpression<T>::getOperand;
403 class SGCoshExpression : public SGUnaryExpression<T> {
405 SGCoshExpression(SGExpression<T>* expr = 0)
406 : SGUnaryExpression<T>(expr)
409 virtual void eval(T& value, const simgear::expression::Binding* b) const
410 { value = cosh(getOperand()->getDoubleValue(b)); }
412 using SGUnaryExpression<T>::getOperand;
416 class SGExpExpression : public SGUnaryExpression<T> {
418 SGExpExpression(SGExpression<T>* expr = 0)
419 : SGUnaryExpression<T>(expr)
422 virtual void eval(T& value, const simgear::expression::Binding* b) const
423 { value = exp(getOperand()->getDoubleValue(b)); }
425 using SGUnaryExpression<T>::getOperand;
429 class SGFloorExpression : public SGUnaryExpression<T> {
431 SGFloorExpression(SGExpression<T>* expr = 0)
432 : SGUnaryExpression<T>(expr)
435 virtual void eval(T& value, const simgear::expression::Binding* b) const
436 { value = floor(getOperand()->getDoubleValue(b)); }
438 using SGUnaryExpression<T>::getOperand;
442 class SGLogExpression : public SGUnaryExpression<T> {
444 SGLogExpression(SGExpression<T>* expr = 0)
445 : SGUnaryExpression<T>(expr)
448 virtual void eval(T& value, const simgear::expression::Binding* b) const
449 { value = log(getOperand()->getDoubleValue(b)); }
451 using SGUnaryExpression<T>::getOperand;
455 class SGLog10Expression : public SGUnaryExpression<T> {
457 SGLog10Expression(SGExpression<T>* expr = 0)
458 : SGUnaryExpression<T>(expr)
461 virtual void eval(T& value, const simgear::expression::Binding* b) const
462 { value = log10(getOperand()->getDoubleValue(b)); }
464 using SGUnaryExpression<T>::getOperand;
468 class SGSinExpression : public SGUnaryExpression<T> {
470 SGSinExpression(SGExpression<T>* expr = 0)
471 : SGUnaryExpression<T>(expr)
474 virtual void eval(T& value, const simgear::expression::Binding* b) const
475 { value = sin(getOperand()->getDoubleValue(b)); }
477 using SGUnaryExpression<T>::getOperand;
481 class SGSinhExpression : public SGUnaryExpression<T> {
483 SGSinhExpression(SGExpression<T>* expr = 0)
484 : SGUnaryExpression<T>(expr)
487 virtual void eval(T& value, const simgear::expression::Binding* b) const
488 { value = sinh(getOperand()->getDoubleValue(b)); }
490 using SGUnaryExpression<T>::getOperand;
494 class SGSqrExpression : public SGUnaryExpression<T> {
496 SGSqrExpression(SGExpression<T>* expr = 0)
497 : SGUnaryExpression<T>(expr)
500 virtual void eval(T& value, const simgear::expression::Binding* b) const
501 { value = getOperand()->getValue(b); value = value*value; }
503 using SGUnaryExpression<T>::getOperand;
507 class SGSqrtExpression : public SGUnaryExpression<T> {
509 SGSqrtExpression(SGExpression<T>* expr = 0)
510 : SGUnaryExpression<T>(expr)
513 virtual void eval(T& value, const simgear::expression::Binding* b) const
514 { value = sqrt(getOperand()->getDoubleValue(b)); }
516 using SGUnaryExpression<T>::getOperand;
520 class SGTanExpression : public SGUnaryExpression<T> {
522 SGTanExpression(SGExpression<T>* expr = 0)
523 : SGUnaryExpression<T>(expr)
526 virtual void eval(T& value, const simgear::expression::Binding* b) const
527 { value = tan(getOperand()->getDoubleValue(b)); }
529 using SGUnaryExpression<T>::getOperand;
533 class SGTanhExpression : public SGUnaryExpression<T> {
535 SGTanhExpression(SGExpression<T>* expr = 0)
536 : SGUnaryExpression<T>(expr)
539 virtual void eval(T& value, const simgear::expression::Binding* b) const
540 { value = tanh(getOperand()->getDoubleValue(b)); }
542 using SGUnaryExpression<T>::getOperand;
546 class SGScaleExpression : public SGUnaryExpression<T> {
548 SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
549 : SGUnaryExpression<T>(expr), _scale(scale)
551 void setScale(const T& scale)
553 const T& getScale() const
556 virtual void eval(T& value, const simgear::expression::Binding* b) const
557 { value = _scale * getOperand()->getValue(b); }
559 virtual SGExpression<T>* simplify()
562 return getOperand()->simplify();
563 return SGUnaryExpression<T>::simplify();
566 using SGUnaryExpression<T>::getOperand;
572 class SGBiasExpression : public SGUnaryExpression<T> {
574 SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
575 : SGUnaryExpression<T>(expr), _bias(bias)
578 void setBias(const T& bias)
580 const T& getBias() const
583 virtual void eval(T& value, const simgear::expression::Binding* b) const
584 { value = _bias + getOperand()->getValue(b); }
586 virtual SGExpression<T>* simplify()
589 return getOperand()->simplify();
590 return SGUnaryExpression<T>::simplify();
593 using SGUnaryExpression<T>::getOperand;
599 class SGInterpTableExpression : public SGUnaryExpression<T> {
601 SGInterpTableExpression(SGExpression<T>* expr,
602 const SGInterpTable* interpTable) :
603 SGUnaryExpression<T>(expr),
604 _interpTable(interpTable)
607 virtual void eval(T& value, const simgear::expression::Binding* b) const
610 value = _interpTable->interpolate(getOperand()->getValue(b));
613 using SGUnaryExpression<T>::getOperand;
615 SGSharedPtr<SGInterpTable const> _interpTable;
619 class SGClipExpression : public SGUnaryExpression<T> {
621 SGClipExpression(SGExpression<T>* expr)
622 : SGUnaryExpression<T>(expr),
623 _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
624 _clipMax(SGLimits<T>::max())
626 SGClipExpression(SGExpression<T>* expr,
627 const T& clipMin, const T& clipMax)
628 : SGUnaryExpression<T>(expr),
633 void setClipMin(const T& clipMin)
634 { _clipMin = clipMin; }
635 const T& getClipMin() const
638 void setClipMax(const T& clipMax)
639 { _clipMax = clipMax; }
640 const T& getClipMax() const
643 virtual void eval(T& value, const simgear::expression::Binding* b) const
645 value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
648 virtual SGExpression<T>* simplify()
650 if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
651 _clipMax >= SGLimits<T>::max())
652 return getOperand()->simplify();
653 return SGUnaryExpression<T>::simplify();
656 using SGUnaryExpression<T>::getOperand;
663 class SGStepExpression : public SGUnaryExpression<T> {
665 SGStepExpression(SGExpression<T>* expr = 0,
666 const T& step = T(1), const T& scroll = T(0))
667 : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
670 void setStep(const T& step)
672 const T& getStep() const
675 void setScroll(const T& scroll)
676 { _scroll = scroll; }
677 const T& getScroll() const
680 virtual void eval(T& value, const simgear::expression::Binding* b) const
681 { value = apply_mods(getOperand()->getValue(b)); }
683 using SGUnaryExpression<T>::getOperand;
686 T apply_mods(T property) const
688 if( _step <= SGLimits<T>::min() ) return property;
690 // apply stepping of input value
691 T modprop = floor(property/_step)*_step;
693 // calculate scroll amount (for odometer like movement)
694 T remainder = property <= SGLimits<T>::min() ? -fmod(property,_step) : (_step - fmod(property,_step));
695 if( remainder > SGLimits<T>::min() && remainder < _scroll )
696 modprop += (_scroll - remainder) / _scroll * _step;
706 class SGEnableExpression : public SGUnaryExpression<T> {
708 SGEnableExpression(SGExpression<T>* expr = 0,
709 SGCondition* enable = 0,
710 const T& disabledValue = T(0))
711 : SGUnaryExpression<T>(expr),
713 _disabledValue(disabledValue)
716 const T& getDisabledValue() const
717 { return _disabledValue; }
718 void setDisabledValue(const T& disabledValue)
719 { _disabledValue = disabledValue; }
721 virtual void eval(T& value, const simgear::expression::Binding* b) const
724 value = getOperand()->getValue(b);
726 value = _disabledValue;
729 virtual SGExpression<T>* simplify()
732 return getOperand()->simplify();
733 return SGUnaryExpression<T>::simplify();
736 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
738 SGUnaryExpression<T>::collectDependentProperties(props);
739 _enable->collectDependentProperties(props);
742 using SGUnaryExpression<T>::getOperand;
744 SGSharedPtr<SGCondition> _enable;
749 class SGAtan2Expression : public SGBinaryExpression<T> {
751 SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
752 : SGBinaryExpression<T>(expr0, expr1)
754 virtual void eval(T& value, const simgear::expression::Binding* b) const
755 { value = atan2(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
756 using SGBinaryExpression<T>::getOperand;
760 class SGDivExpression : public SGBinaryExpression<T> {
762 SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
763 : SGBinaryExpression<T>(expr0, expr1)
765 virtual void eval(T& value, const simgear::expression::Binding* b) const
766 { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
767 using SGBinaryExpression<T>::getOperand;
771 class SGModExpression : public SGBinaryExpression<T> {
773 SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
774 : SGBinaryExpression<T>(expr0, expr1)
776 virtual void eval(T& value, const simgear::expression::Binding* b) const
777 { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
778 using SGBinaryExpression<T>::getOperand;
780 int mod(const int& v0, const int& v1) const
782 float mod(const float& v0, const float& v1) const
783 { return fmod(v0, v1); }
784 double mod(const double& v0, const double& v1) const
785 { return fmod(v0, v1); }
789 class SGPowExpression : public SGBinaryExpression<T> {
791 SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
792 : SGBinaryExpression<T>(expr0, expr1)
794 virtual void eval(T& value, const simgear::expression::Binding* b) const
795 { value = pow(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
796 using SGBinaryExpression<T>::getOperand;
800 class SGSumExpression : public SGNaryExpression<T> {
804 SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
805 : SGNaryExpression<T>(expr0, expr1)
807 virtual void eval(T& value, const simgear::expression::Binding* b) const
810 size_t sz = SGNaryExpression<T>::getNumOperands();
811 for (size_t i = 0; i < sz; ++i)
812 value += getOperand(i)->getValue(b);
814 using SGNaryExpression<T>::getValue;
815 using SGNaryExpression<T>::getOperand;
819 class SGDifferenceExpression : public SGNaryExpression<T> {
821 SGDifferenceExpression()
823 SGDifferenceExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
824 : SGNaryExpression<T>(expr0, expr1)
826 virtual void eval(T& value, const simgear::expression::Binding* b) const
828 value = getOperand(0)->getValue(b);
829 size_t sz = SGNaryExpression<T>::getNumOperands();
830 for (size_t i = 1; i < sz; ++i)
831 value -= getOperand(i)->getValue(b);
833 using SGNaryExpression<T>::getValue;
834 using SGNaryExpression<T>::getOperand;
838 class SGProductExpression : public SGNaryExpression<T> {
840 SGProductExpression()
842 SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
843 : SGNaryExpression<T>(expr0, expr1)
845 virtual void eval(T& value, const simgear::expression::Binding* b) const
848 size_t sz = SGNaryExpression<T>::getNumOperands();
849 for (size_t i = 0; i < sz; ++i)
850 value *= getOperand(i)->getValue(b);
852 using SGNaryExpression<T>::getValue;
853 using SGNaryExpression<T>::getOperand;
857 class SGMinExpression : public SGNaryExpression<T> {
861 SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
862 : SGNaryExpression<T>(expr0, expr1)
864 virtual void eval(T& value, const simgear::expression::Binding* b) const
866 size_t sz = SGNaryExpression<T>::getNumOperands();
870 value = getOperand(0)->getValue(b);
871 for (size_t i = 1; i < sz; ++i)
872 value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
874 using SGNaryExpression<T>::getOperand;
878 class SGMaxExpression : public SGNaryExpression<T> {
882 SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
883 : SGNaryExpression<T>(expr0, expr1)
885 virtual void eval(T& value, const simgear::expression::Binding* b) const
887 size_t sz = SGNaryExpression<T>::getNumOperands();
891 value = getOperand(0)->getValue(b);
892 for (size_t i = 1; i < sz; ++i)
893 value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
895 using SGNaryExpression<T>::getOperand;
898 typedef SGExpression<int> SGExpressioni;
899 typedef SGExpression<float> SGExpressionf;
900 typedef SGExpression<double> SGExpressiond;
901 typedef SGExpression<bool> SGExpressionb;
904 * Global function to make an expression out of properties.
908 <clipMax>79</clipMax>
912 <property>sim/model/whatever-rad</property>
914 <property>sim/model/someother-deg</property>
920 will evaluate to an expression:
922 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
926 SGReadIntExpression(SGPropertyNode *inputRoot,
927 const SGPropertyNode *configNode);
930 SGReadFloatExpression(SGPropertyNode *inputRoot,
931 const SGPropertyNode *configNode);
933 SGExpression<double>*
934 SGReadDoubleExpression(SGPropertyNode *inputRoot,
935 const SGPropertyNode *configNode);
938 SGReadBoolExpression(SGPropertyNode *inputRoot,
939 const SGPropertyNode *configNode);
945 struct ParseError : public sg_exception
947 ParseError(const string& message = std::string())
948 : sg_exception(message) {}
951 // Support for binding variables around an expression.
955 virtual ~Binding() {}
956 const virtual Value* getBindings() const = 0;
957 virtual Value* getBindings() = 0;
960 class VariableLengthBinding : public Binding
963 const Value* getBindings() const
965 if (_bindings.empty())
968 return &_bindings[0];
972 if (_bindings.empty())
975 return &_bindings[0];
977 std::vector<Value> _bindings;
980 template<int Size> class FixedLengthBinding : public Binding
985 return &_bindings[0];
987 const Value* getBindings() const
989 return &_bindings[0];
991 Value _bindings[Size];
994 struct VariableBinding
996 VariableBinding() : type(expression::DOUBLE), location(-1) {}
998 VariableBinding(const std::string& name_, expression::Type type_,
1000 : name(name_), type(type_), location(location_)
1004 expression::Type type;
1011 size_t addBinding(const std::string& name, expression::Type type);
1012 bool findBinding(const string& name, VariableBinding& result) const;
1013 std::vector<VariableBinding> bindings;
1018 typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
1020 void addParser(const std::string& name, exp_parser parser)
1022 getParserMap().insert(std::make_pair(name, parser));
1024 Expression* read(const SGPropertyNode* exp)
1026 ParserMap& map = getParserMap();
1027 ParserMap::iterator itr = map.find(exp->getName());
1028 if (itr == map.end())
1029 throw ParseError(string("unknown expression ") + exp->getName());
1030 exp_parser parser = itr->second;
1031 return (*parser)(exp, this);
1033 // XXX vector of SGSharedPtr?
1034 bool readChildren(const SGPropertyNode* exp,
1035 std::vector<Expression*>& result);
1037 * Function that parses a property tree, producing an expression.
1039 typedef std::map<const std::string, exp_parser> ParserMap;
1040 virtual ParserMap& getParserMap() = 0;
1042 * After an expression is parsed, the binding layout may contain
1043 * references that need to be bound during evaluation.
1045 BindingLayout& getBindingLayout() { return _bindingLayout; }
1047 BindingLayout _bindingLayout;
1050 class ExpressionParser : public Parser
1053 ParserMap& getParserMap()
1055 return ParserMapSingleton::instance()->_parserTable;
1057 static void addExpParser(const std::string&, exp_parser);
1059 struct ParserMapSingleton : public simgear::Singleton<ParserMapSingleton>
1061 ParserMap _parserTable;
1066 * Constructor for registering parser functions.
1068 struct ExpParserRegistrar
1070 ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1072 ExpressionParser::addExpParser(token, parser);
1079 * Access a variable definition. Use a location from a BindingLayout.
1081 template<typename T>
1082 class VariableExpression : public ::SGExpression<T> {
1084 VariableExpression(int location) : _location(location) {}
1085 virtual ~VariableExpression() {}
1086 virtual void eval(T& value, const simgear::expression::Binding* b) const
1088 const expression::Value* values = b->getBindings();
1089 value = *reinterpret_cast<const T *>(&values[_location].val);
1097 * An n-ary expression where the types of the argument aren't the
1098 * same as the return type.
1100 template<typename T, typename OpType>
1101 class GeneralNaryExpression : public ::SGExpression<T> {
1103 typedef OpType operand_type;
1104 size_t getNumOperands() const
1105 { return _expressions.size(); }
1106 const ::SGExpression<OpType>* getOperand(size_t i) const
1107 { return _expressions[i]; }
1108 ::SGExpression<OpType>* getOperand(size_t i)
1109 { return _expressions[i]; }
1110 size_t addOperand(::SGExpression<OpType>* expression)
1114 _expressions.push_back(expression);
1115 return _expressions.size() - 1;
1118 template<typename Iter>
1119 void addOperands(Iter begin, Iter end)
1121 for (Iter iter = begin; iter != end; ++iter)
1123 addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1127 virtual bool isConst() const
1129 for (size_t i = 0; i < _expressions.size(); ++i)
1130 if (!_expressions[i]->isConst())
1134 virtual ::SGExpression<T>* simplify()
1136 for (size_t i = 0; i < _expressions.size(); ++i)
1137 _expressions[i] = _expressions[i]->simplify();
1138 return SGExpression<T>::simplify();
1141 simgear::expression::Type getOperandType() const
1143 return simgear::expression::TypeTraits<OpType>::typeTag;
1147 GeneralNaryExpression()
1149 GeneralNaryExpression(::SGExpression<OpType>* expr0,
1150 ::SGExpression<OpType>* expr1)
1151 { addOperand(expr0); addOperand(expr1); }
1153 std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1157 * A predicate that wraps, for example the STL template predicate
1158 * expressions like std::equal_to.
1160 template<typename OpType, template<typename PredOp> class Pred>
1161 class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1163 PredicateExpression()
1166 PredicateExpression(::SGExpression<OpType>* expr0,
1167 ::SGExpression<OpType>* expr1)
1168 : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1171 virtual void eval(bool& value, const simgear::expression::Binding* b) const
1173 size_t sz = this->getNumOperands();
1176 value = _pred(this->getOperand(0)->getValue(b),
1177 this->getOperand(1)->getValue(b));
1183 template<template<typename OT> class Pred, typename OpType>
1184 PredicateExpression<OpType, Pred>*
1185 makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1187 return new PredicateExpression<OpType, Pred>(op1, op2);
1190 template<typename OpType>
1191 class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1194 EqualToExpression() {}
1195 EqualToExpression(::SGExpression<OpType>* expr0,
1196 ::SGExpression<OpType>* expr1)
1197 : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1202 template<typename OpType>
1203 class LessExpression : public PredicateExpression<OpType, std::less>
1207 LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1208 : PredicateExpression<OpType, std::less>(expr0, expr1)
1213 template<typename OpType>
1214 class LessEqualExpression
1215 : public PredicateExpression<OpType, std::less_equal>
1218 LessEqualExpression() {}
1219 LessEqualExpression(::SGExpression<OpType>* expr0,
1220 ::SGExpression<OpType>* expr1)
1221 : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1226 class NotExpression : public ::SGUnaryExpression<bool>
1229 NotExpression(::SGExpression<bool>* expr = 0)
1230 : ::SGUnaryExpression<bool>(expr)
1233 void eval(bool& value, const expression::Binding* b) const
1235 value = !getOperand()->getValue(b);
1239 class OrExpression : public ::SGNaryExpression<bool>
1242 void eval(bool& value, const expression::Binding* b) const
1245 for (int i = 0; i < (int)getNumOperands(); ++i) {
1246 value = value || getOperand(i)->getValue(b);
1253 class AndExpression : public ::SGNaryExpression<bool>
1256 void eval(bool& value, const expression::Binding* b) const
1259 for (int i = 0; i < (int)getNumOperands(); ++i) {
1260 value = value && getOperand(i)->getValue(b);
1268 * Convert an operand from OpType to T.
1270 template<typename T, typename OpType>
1271 class ConvertExpression : public GeneralNaryExpression<T, OpType>
1274 ConvertExpression() {}
1275 ConvertExpression(::SGExpression<OpType>* expr0)
1277 this->addOperand(expr0);
1279 virtual void eval(T& value, const simgear::expression::Binding* b) const
1281 typename ConvertExpression::operand_type result;
1282 this->_expressions.at(0)->eval(result, b);
1287 #endif // _SG_EXPRESSION_HXX