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
31 #include <simgear/props/condition.hxx>
32 #include <simgear/props/props.hxx>
33 #include <simgear/math/interpolater.hxx>
34 #include <simgear/math/SGMath.hxx>
35 #include <simgear/scene/model/persparam.hxx>
36 #include <simgear/structure/exception.hxx>
37 #include <simgear/structure/Singleton.hxx>
39 /// Expression tree implementation.
51 template<typename T> struct TypeTraits;
52 template<> struct TypeTraits<bool> {
53 static const Type typeTag = BOOL;
55 template<> struct TypeTraits<int> {
56 static const Type typeTag = INT;
58 template<> struct TypeTraits<float> {
59 static const Type typeTag = FLOAT;
61 template<> struct TypeTraits<double> {
62 static const Type typeTag = DOUBLE;
75 Value() : typeTag(DOUBLE)
80 Value(bool val_) : typeTag(BOOL)
85 Value(int val_) : typeTag(INT)
90 Value(float val_) : typeTag(FLOAT)
95 Value(double val_) : typeTag(DOUBLE)
105 class Expression : public SGReferenced
108 virtual ~Expression() {}
109 virtual expression::Type getType() const = 0;
112 const expression::Value eval(const Expression* exp,
113 const expression::Binding* binding = 0);
118 class SGExpression : public simgear::Expression {
120 virtual ~SGExpression() {}
121 typedef T result_type;
122 typedef T operand_type;
123 virtual void eval(T&, const simgear::expression::Binding*) const = 0;
125 T getValue(const simgear::expression::Binding* binding = 0) const
126 { T value; eval(value, binding); return value; }
128 double getDoubleValue(const simgear::expression::Binding* binding = 0) const
129 { T value; eval(value, binding); return value; }
131 virtual bool isConst() const { return false; }
132 virtual SGExpression* simplify();
133 virtual simgear::expression::Type getType() const
135 return simgear::expression::TypeTraits<T>::typeTag;
137 virtual simgear::expression::Type getOperandType() const
139 return simgear::expression::TypeTraits<T>::typeTag;
141 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
145 /// Constant value expression
147 class SGConstExpression : public SGExpression<T> {
149 SGConstExpression(const T& value = T()) : _value(value)
151 void setValue(const T& value)
153 const T& getValue(const simgear::expression::Binding* binding = 0) const
155 virtual void eval(T& value, const simgear::expression::Binding*) const
157 virtual bool isConst() const { return true; }
164 SGExpression<T>::simplify()
167 return new SGConstExpression<T>(getValue());
172 class SGUnaryExpression : public SGExpression<T> {
174 const SGExpression<T>* getOperand() const
175 { return _expression; }
176 SGExpression<T>* getOperand()
177 { return _expression; }
178 void setOperand(SGExpression<T>* expression)
181 expression = new SGConstExpression<T>(T());
182 _expression = expression;
184 virtual bool isConst() const
185 { return getOperand()->isConst(); }
186 virtual SGExpression<T>* simplify()
188 _expression = _expression->simplify();
189 return SGExpression<T>::simplify();
192 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
193 { _expression->collectDependentProperties(props); }
195 SGUnaryExpression(SGExpression<T>* expression = 0)
196 { setOperand(expression); }
199 SGSharedPtr<SGExpression<T> > _expression;
203 class SGBinaryExpression : public SGExpression<T> {
205 const SGExpression<T>* getOperand(size_t i) const
206 { return _expressions[i]; }
207 SGExpression<T>* getOperand(size_t i)
208 { return _expressions[i]; }
209 void setOperand(size_t i, SGExpression<T>* expression)
212 expression = new SGConstExpression<T>(T());
215 _expressions[i] = expression;
218 virtual bool isConst() const
219 { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
220 virtual SGExpression<T>* simplify()
222 _expressions[0] = _expressions[0]->simplify();
223 _expressions[1] = _expressions[1]->simplify();
224 return SGExpression<T>::simplify();
227 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
229 _expressions[0]->collectDependentProperties(props);
230 _expressions[1]->collectDependentProperties(props);
234 SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
235 { setOperand(0, expr0); setOperand(1, expr1); }
238 SGSharedPtr<SGExpression<T> > _expressions[2];
242 class SGNaryExpression : public SGExpression<T> {
244 size_t getNumOperands() const
245 { return _expressions.size(); }
246 const SGExpression<T>* getOperand(size_t i) const
247 { return _expressions[i]; }
248 SGExpression<T>* getOperand(size_t i)
249 { return _expressions[i]; }
250 size_t addOperand(SGExpression<T>* expression)
254 _expressions.push_back(expression);
255 return _expressions.size() - 1;
258 template<typename Iter>
259 void addOperands(Iter begin, Iter end)
261 for (Iter iter = begin; iter != end; ++iter)
263 addOperand(static_cast< ::SGExpression<T>*>(*iter));
267 virtual bool isConst() const
269 for (size_t i = 0; i < _expressions.size(); ++i)
270 if (!_expressions[i]->isConst())
274 virtual SGExpression<T>* simplify()
276 for (size_t i = 0; i < _expressions.size(); ++i)
277 _expressions[i] = _expressions[i]->simplify();
278 return SGExpression<T>::simplify();
281 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
283 for (size_t i = 0; i < _expressions.size(); ++i)
284 _expressions[i]->collectDependentProperties(props);
289 SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
290 { addOperand(expr0); addOperand(expr1); }
293 std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
300 class SGPropertyExpression : public SGExpression<T> {
302 SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
304 void setPropertyNode(const SGPropertyNode* prop)
306 virtual void eval(T& value, const simgear::expression::Binding*) const
309 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
310 { props.insert(_prop.get()); }
312 void doEval(float& value) const
313 { if (_prop) value = _prop->getFloatValue(); }
314 void doEval(double& value) const
315 { if (_prop) value = _prop->getDoubleValue(); }
316 void doEval(int& value) const
317 { if (_prop) value = _prop->getIntValue(); }
318 void doEval(long& value) const
319 { if (_prop) value = _prop->getLongValue(); }
320 void doEval(bool& value) const
321 { if (_prop) value = _prop->getBoolValue(); }
322 SGSharedPtr<const SGPropertyNode> _prop;
326 class SGAbsExpression : public SGUnaryExpression<T> {
328 SGAbsExpression(SGExpression<T>* expr = 0)
329 : SGUnaryExpression<T>(expr)
332 virtual void eval(T& value, const simgear::expression::Binding* b) const
333 { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
335 using SGUnaryExpression<T>::getOperand;
339 class SGACosExpression : public SGUnaryExpression<T> {
341 SGACosExpression(SGExpression<T>* expr = 0)
342 : SGUnaryExpression<T>(expr)
345 virtual void eval(T& value, const simgear::expression::Binding* b) const
346 { value = acos((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
348 using SGUnaryExpression<T>::getOperand;
352 class SGASinExpression : public SGUnaryExpression<T> {
354 SGASinExpression(SGExpression<T>* expr = 0)
355 : SGUnaryExpression<T>(expr)
358 virtual void eval(T& value, const simgear::expression::Binding* b) const
359 { value = asin((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
361 using SGUnaryExpression<T>::getOperand;
365 class SGATanExpression : public SGUnaryExpression<T> {
367 SGATanExpression(SGExpression<T>* expr = 0)
368 : SGUnaryExpression<T>(expr)
371 virtual void eval(T& value, const simgear::expression::Binding* b) const
372 { value = atan(getOperand()->getDoubleValue(b)); }
374 using SGUnaryExpression<T>::getOperand;
378 class SGCeilExpression : public SGUnaryExpression<T> {
380 SGCeilExpression(SGExpression<T>* expr = 0)
381 : SGUnaryExpression<T>(expr)
384 virtual void eval(T& value, const simgear::expression::Binding* b) const
385 { value = ceil(getOperand()->getDoubleValue(b)); }
387 using SGUnaryExpression<T>::getOperand;
391 class SGCosExpression : public SGUnaryExpression<T> {
393 SGCosExpression(SGExpression<T>* expr = 0)
394 : SGUnaryExpression<T>(expr)
397 virtual void eval(T& value, const simgear::expression::Binding* b) const
398 { value = cos(getOperand()->getDoubleValue(b)); }
400 using SGUnaryExpression<T>::getOperand;
404 class SGCoshExpression : public SGUnaryExpression<T> {
406 SGCoshExpression(SGExpression<T>* expr = 0)
407 : SGUnaryExpression<T>(expr)
410 virtual void eval(T& value, const simgear::expression::Binding* b) const
411 { value = cosh(getOperand()->getDoubleValue(b)); }
413 using SGUnaryExpression<T>::getOperand;
417 class SGExpExpression : public SGUnaryExpression<T> {
419 SGExpExpression(SGExpression<T>* expr = 0)
420 : SGUnaryExpression<T>(expr)
423 virtual void eval(T& value, const simgear::expression::Binding* b) const
424 { value = exp(getOperand()->getDoubleValue(b)); }
426 using SGUnaryExpression<T>::getOperand;
430 class SGFloorExpression : public SGUnaryExpression<T> {
432 SGFloorExpression(SGExpression<T>* expr = 0)
433 : SGUnaryExpression<T>(expr)
436 virtual void eval(T& value, const simgear::expression::Binding* b) const
437 { value = floor(getOperand()->getDoubleValue(b)); }
439 using SGUnaryExpression<T>::getOperand;
443 class SGLogExpression : public SGUnaryExpression<T> {
445 SGLogExpression(SGExpression<T>* expr = 0)
446 : SGUnaryExpression<T>(expr)
449 virtual void eval(T& value, const simgear::expression::Binding* b) const
450 { value = log(getOperand()->getDoubleValue(b)); }
452 using SGUnaryExpression<T>::getOperand;
456 class SGLog10Expression : public SGUnaryExpression<T> {
458 SGLog10Expression(SGExpression<T>* expr = 0)
459 : SGUnaryExpression<T>(expr)
462 virtual void eval(T& value, const simgear::expression::Binding* b) const
463 { value = log10(getOperand()->getDoubleValue(b)); }
465 using SGUnaryExpression<T>::getOperand;
469 class SGSinExpression : public SGUnaryExpression<T> {
471 SGSinExpression(SGExpression<T>* expr = 0)
472 : SGUnaryExpression<T>(expr)
475 virtual void eval(T& value, const simgear::expression::Binding* b) const
476 { value = sin(getOperand()->getDoubleValue(b)); }
478 using SGUnaryExpression<T>::getOperand;
482 class SGSinhExpression : public SGUnaryExpression<T> {
484 SGSinhExpression(SGExpression<T>* expr = 0)
485 : SGUnaryExpression<T>(expr)
488 virtual void eval(T& value, const simgear::expression::Binding* b) const
489 { value = sinh(getOperand()->getDoubleValue(b)); }
491 using SGUnaryExpression<T>::getOperand;
495 class SGSqrExpression : public SGUnaryExpression<T> {
497 SGSqrExpression(SGExpression<T>* expr = 0)
498 : SGUnaryExpression<T>(expr)
501 virtual void eval(T& value, const simgear::expression::Binding* b) const
502 { value = getOperand()->getValue(b); value = value*value; }
504 using SGUnaryExpression<T>::getOperand;
508 class SGSqrtExpression : public SGUnaryExpression<T> {
510 SGSqrtExpression(SGExpression<T>* expr = 0)
511 : SGUnaryExpression<T>(expr)
514 virtual void eval(T& value, const simgear::expression::Binding* b) const
515 { value = sqrt(getOperand()->getDoubleValue(b)); }
517 using SGUnaryExpression<T>::getOperand;
521 class SGTanExpression : public SGUnaryExpression<T> {
523 SGTanExpression(SGExpression<T>* expr = 0)
524 : SGUnaryExpression<T>(expr)
527 virtual void eval(T& value, const simgear::expression::Binding* b) const
528 { value = tan(getOperand()->getDoubleValue(b)); }
530 using SGUnaryExpression<T>::getOperand;
534 class SGTanhExpression : public SGUnaryExpression<T> {
536 SGTanhExpression(SGExpression<T>* expr = 0)
537 : SGUnaryExpression<T>(expr)
540 virtual void eval(T& value, const simgear::expression::Binding* b) const
541 { value = tanh(getOperand()->getDoubleValue(b)); }
543 using SGUnaryExpression<T>::getOperand;
547 class SGScaleExpression : public SGUnaryExpression<T> {
549 SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
550 : SGUnaryExpression<T>(expr), _scale(scale)
552 void setScale(const T& scale)
554 const T& getScale() const
557 virtual void eval(T& value, const simgear::expression::Binding* b) const
558 { value = _scale * getOperand()->getValue(b); }
560 virtual SGExpression<T>* simplify()
563 return getOperand()->simplify();
564 return SGUnaryExpression<T>::simplify();
567 using SGUnaryExpression<T>::getOperand;
573 class SGBiasExpression : public SGUnaryExpression<T> {
575 SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
576 : SGUnaryExpression<T>(expr), _bias(bias)
579 void setBias(const T& bias)
581 const T& getBias() const
584 virtual void eval(T& value, const simgear::expression::Binding* b) const
585 { value = _bias + getOperand()->getValue(b); }
587 virtual SGExpression<T>* simplify()
590 return getOperand()->simplify();
591 return SGUnaryExpression<T>::simplify();
594 using SGUnaryExpression<T>::getOperand;
600 class SGInterpTableExpression : public SGUnaryExpression<T> {
602 SGInterpTableExpression(SGExpression<T>* expr,
603 const SGInterpTable* interpTable) :
604 SGUnaryExpression<T>(expr),
605 _interpTable(interpTable)
608 virtual void eval(T& value, const simgear::expression::Binding* b) const
611 value = _interpTable->interpolate(getOperand()->getValue(b));
614 using SGUnaryExpression<T>::getOperand;
616 SGSharedPtr<SGInterpTable const> _interpTable;
620 class SGClipExpression : public SGUnaryExpression<T> {
622 SGClipExpression(SGExpression<T>* expr)
623 : SGUnaryExpression<T>(expr),
624 _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
625 _clipMax(SGLimits<T>::max())
627 SGClipExpression(SGExpression<T>* expr,
628 const T& clipMin, const T& clipMax)
629 : SGUnaryExpression<T>(expr),
634 void setClipMin(const T& clipMin)
635 { _clipMin = clipMin; }
636 const T& getClipMin() const
639 void setClipMax(const T& clipMax)
640 { _clipMax = clipMax; }
641 const T& getClipMax() const
644 virtual void eval(T& value, const simgear::expression::Binding* b) const
646 value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
649 virtual SGExpression<T>* simplify()
651 if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
652 _clipMax >= SGLimits<T>::max())
653 return getOperand()->simplify();
654 return SGUnaryExpression<T>::simplify();
657 using SGUnaryExpression<T>::getOperand;
664 class SGStepExpression : public SGUnaryExpression<T> {
666 SGStepExpression(SGExpression<T>* expr = 0,
667 const T& step = T(1), const T& scroll = T(0))
668 : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
671 void setStep(const T& step)
673 const T& getStep() const
676 void setScroll(const T& scroll)
677 { _scroll = scroll; }
678 const T& getScroll() const
681 virtual void eval(T& value, const simgear::expression::Binding* b) const
682 { value = apply_mods(getOperand()->getValue(b)); }
684 using SGUnaryExpression<T>::getOperand;
687 T apply_mods(T property) const
689 if( _step <= SGLimits<T>::min() ) return property;
691 // apply stepping of input value
692 T modprop = floor(property/_step)*_step;
694 // calculate scroll amount (for odometer like movement)
695 T remainder = property <= SGLimits<T>::min() ? -fmod(property,_step) : (_step - fmod(property,_step));
696 if( remainder > SGLimits<T>::min() && remainder < _scroll )
697 modprop += (_scroll - remainder) / _scroll * _step;
707 class SGEnableExpression : public SGUnaryExpression<T> {
709 SGEnableExpression(SGExpression<T>* expr = 0,
710 SGCondition* enable = 0,
711 const T& disabledValue = T(0))
712 : SGUnaryExpression<T>(expr),
714 _disabledValue(disabledValue)
717 const T& getDisabledValue() const
718 { return _disabledValue; }
719 void setDisabledValue(const T& disabledValue)
720 { _disabledValue = disabledValue; }
722 virtual void eval(T& value, const simgear::expression::Binding* b) const
725 value = getOperand()->getValue(b);
727 value = _disabledValue;
730 virtual SGExpression<T>* simplify()
733 return getOperand()->simplify();
734 return SGUnaryExpression<T>::simplify();
737 virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
739 SGUnaryExpression<T>::collectDependentProperties(props);
740 _enable->collectDependentProperties(props);
743 using SGUnaryExpression<T>::getOperand;
745 SGSharedPtr<SGCondition> _enable;
750 class SGAtan2Expression : public SGBinaryExpression<T> {
752 SGAtan2Expression(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 = atan2(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
757 using SGBinaryExpression<T>::getOperand;
761 class SGDivExpression : public SGBinaryExpression<T> {
763 SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
764 : SGBinaryExpression<T>(expr0, expr1)
766 virtual void eval(T& value, const simgear::expression::Binding* b) const
767 { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
768 using SGBinaryExpression<T>::getOperand;
772 class SGModExpression : public SGBinaryExpression<T> {
774 SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
775 : SGBinaryExpression<T>(expr0, expr1)
777 virtual void eval(T& value, const simgear::expression::Binding* b) const
778 { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
779 using SGBinaryExpression<T>::getOperand;
781 int mod(const int& v0, const int& v1) const
783 float mod(const float& v0, const float& v1) const
784 { return fmod(v0, v1); }
785 double mod(const double& v0, const double& v1) const
786 { return fmod(v0, v1); }
790 class SGPowExpression : public SGBinaryExpression<T> {
792 SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
793 : SGBinaryExpression<T>(expr0, expr1)
795 virtual void eval(T& value, const simgear::expression::Binding* b) const
796 { value = pow(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
797 using SGBinaryExpression<T>::getOperand;
801 class SGSumExpression : public SGNaryExpression<T> {
805 SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
806 : SGNaryExpression<T>(expr0, expr1)
808 virtual void eval(T& value, const simgear::expression::Binding* b) const
811 size_t sz = SGNaryExpression<T>::getNumOperands();
812 for (size_t i = 0; i < sz; ++i)
813 value += getOperand(i)->getValue(b);
815 using SGNaryExpression<T>::getValue;
816 using SGNaryExpression<T>::getOperand;
820 class SGDifferenceExpression : public SGNaryExpression<T> {
822 SGDifferenceExpression()
824 SGDifferenceExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
825 : SGNaryExpression<T>(expr0, expr1)
827 virtual void eval(T& value, const simgear::expression::Binding* b) const
829 value = getOperand(0)->getValue(b);
830 size_t sz = SGNaryExpression<T>::getNumOperands();
831 for (size_t i = 1; i < sz; ++i)
832 value -= getOperand(i)->getValue(b);
834 using SGNaryExpression<T>::getValue;
835 using SGNaryExpression<T>::getOperand;
839 class SGProductExpression : public SGNaryExpression<T> {
841 SGProductExpression()
843 SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
844 : SGNaryExpression<T>(expr0, expr1)
846 virtual void eval(T& value, const simgear::expression::Binding* b) const
849 size_t sz = SGNaryExpression<T>::getNumOperands();
850 for (size_t i = 0; i < sz; ++i)
851 value *= getOperand(i)->getValue(b);
853 using SGNaryExpression<T>::getValue;
854 using SGNaryExpression<T>::getOperand;
858 class SGMinExpression : public SGNaryExpression<T> {
862 SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
863 : SGNaryExpression<T>(expr0, expr1)
865 virtual void eval(T& value, const simgear::expression::Binding* b) const
867 size_t sz = SGNaryExpression<T>::getNumOperands();
871 value = getOperand(0)->getValue(b);
872 for (size_t i = 1; i < sz; ++i)
873 value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
875 using SGNaryExpression<T>::getOperand;
879 class SGMaxExpression : public SGNaryExpression<T> {
883 SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
884 : SGNaryExpression<T>(expr0, expr1)
886 virtual void eval(T& value, const simgear::expression::Binding* b) const
888 size_t sz = SGNaryExpression<T>::getNumOperands();
892 value = getOperand(0)->getValue(b);
893 for (size_t i = 1; i < sz; ++i)
894 value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
896 using SGNaryExpression<T>::getOperand;
899 typedef SGExpression<int> SGExpressioni;
900 typedef SGExpression<float> SGExpressionf;
901 typedef SGExpression<double> SGExpressiond;
902 typedef SGExpression<bool> SGExpressionb;
904 typedef SGSharedPtr<SGExpressioni> SGExpressioni_ref;
905 typedef SGSharedPtr<SGExpressionf> SGExpressionf_ref;
906 typedef SGSharedPtr<SGExpressiond> SGExpressiond_ref;
907 typedef SGSharedPtr<SGExpressionb> SGExpressionb_ref;
910 * Global function to make an expression out of properties.
914 <clipMax>79</clipMax>
918 <property>sim/model/whatever-rad</property>
920 <property>sim/model/someother-deg</property>
926 will evaluate to an expression:
928 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
932 SGReadIntExpression(SGPropertyNode *inputRoot,
933 const SGPropertyNode *configNode);
936 SGReadFloatExpression(SGPropertyNode *inputRoot,
937 const SGPropertyNode *configNode);
939 SGExpression<double>*
940 SGReadDoubleExpression(SGPropertyNode *inputRoot,
941 const SGPropertyNode *configNode);
944 SGReadBoolExpression(SGPropertyNode *inputRoot,
945 const SGPropertyNode *configNode);
951 struct ParseError : public sg_exception
953 ParseError(const std::string& message = std::string())
954 : sg_exception(message) {}
957 // Support for binding variables around an expression.
961 virtual ~Binding() {}
962 const virtual Value* getBindings() const = 0;
963 virtual Value* getBindings() = 0;
966 class VariableLengthBinding : public Binding
969 const Value* getBindings() const
971 if (_bindings.empty())
974 return &_bindings[0];
978 if (_bindings.empty())
981 return &_bindings[0];
983 std::vector<Value> _bindings;
986 template<int Size> class FixedLengthBinding : public Binding
991 return &_bindings[0];
993 const Value* getBindings() const
995 return &_bindings[0];
997 Value _bindings[Size];
1000 struct VariableBinding
1002 VariableBinding() : type(expression::DOUBLE), location(-1) {}
1004 VariableBinding(const std::string& name_, expression::Type type_,
1006 : name(name_), type(type_), location(location_)
1010 expression::Type type;
1017 size_t addBinding(const std::string& name, expression::Type type);
1018 bool findBinding(const std::string& name, VariableBinding& result) const;
1019 std::vector<VariableBinding> bindings;
1024 typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
1026 void addParser(const std::string& name, exp_parser parser)
1028 getParserMap().insert(std::make_pair(name, parser));
1030 Expression* read(const SGPropertyNode* exp)
1032 ParserMap& map = getParserMap();
1033 ParserMap::iterator itr = map.find(exp->getName());
1034 if (itr == map.end())
1035 throw ParseError(std::string("unknown expression ") + exp->getName());
1036 exp_parser parser = itr->second;
1037 return (*parser)(exp, this);
1039 // XXX vector of SGSharedPtr?
1040 bool readChildren(const SGPropertyNode* exp,
1041 std::vector<Expression*>& result);
1043 * Function that parses a property tree, producing an expression.
1045 typedef std::map<const std::string, exp_parser> ParserMap;
1046 virtual ParserMap& getParserMap() = 0;
1048 * After an expression is parsed, the binding layout may contain
1049 * references that need to be bound during evaluation.
1051 BindingLayout& getBindingLayout() { return _bindingLayout; }
1053 BindingLayout _bindingLayout;
1056 class ExpressionParser : public Parser
1059 ParserMap& getParserMap()
1061 return ParserMapSingleton::instance()->_parserTable;
1063 static void addExpParser(const std::string&, exp_parser);
1065 struct ParserMapSingleton : public simgear::Singleton<ParserMapSingleton>
1067 ParserMap _parserTable;
1072 * Constructor for registering parser functions.
1074 struct ExpParserRegistrar
1076 ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1078 ExpressionParser::addExpParser(token, parser);
1085 * Access a variable definition. Use a location from a BindingLayout.
1087 template<typename T>
1088 class VariableExpression : public ::SGExpression<T> {
1090 VariableExpression(int location) : _location(location) {}
1091 virtual ~VariableExpression() {}
1092 virtual void eval(T& value, const simgear::expression::Binding* b) const
1094 const expression::Value* values = b->getBindings();
1095 value = *reinterpret_cast<const T *>(&values[_location].val);
1103 * An n-ary expression where the types of the argument aren't the
1104 * same as the return type.
1106 template<typename T, typename OpType>
1107 class GeneralNaryExpression : public ::SGExpression<T> {
1109 typedef OpType operand_type;
1110 size_t getNumOperands() const
1111 { return _expressions.size(); }
1112 const ::SGExpression<OpType>* getOperand(size_t i) const
1113 { return _expressions[i]; }
1114 ::SGExpression<OpType>* getOperand(size_t i)
1115 { return _expressions[i]; }
1116 size_t addOperand(::SGExpression<OpType>* expression)
1120 _expressions.push_back(expression);
1121 return _expressions.size() - 1;
1124 template<typename Iter>
1125 void addOperands(Iter begin, Iter end)
1127 for (Iter iter = begin; iter != end; ++iter)
1129 addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1133 virtual bool isConst() const
1135 for (size_t i = 0; i < _expressions.size(); ++i)
1136 if (!_expressions[i]->isConst())
1140 virtual ::SGExpression<T>* simplify()
1142 for (size_t i = 0; i < _expressions.size(); ++i)
1143 _expressions[i] = _expressions[i]->simplify();
1144 return SGExpression<T>::simplify();
1147 simgear::expression::Type getOperandType() const
1149 return simgear::expression::TypeTraits<OpType>::typeTag;
1153 GeneralNaryExpression()
1155 GeneralNaryExpression(::SGExpression<OpType>* expr0,
1156 ::SGExpression<OpType>* expr1)
1157 { addOperand(expr0); addOperand(expr1); }
1159 std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1163 * A predicate that wraps, for example the STL template predicate
1164 * expressions like std::equal_to.
1166 template<typename OpType, template<typename PredOp> class Pred>
1167 class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1169 PredicateExpression()
1172 PredicateExpression(::SGExpression<OpType>* expr0,
1173 ::SGExpression<OpType>* expr1)
1174 : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1177 virtual void eval(bool& value, const simgear::expression::Binding* b) const
1179 size_t sz = this->getNumOperands();
1182 value = _pred(this->getOperand(0)->getValue(b),
1183 this->getOperand(1)->getValue(b));
1189 template<template<typename OT> class Pred, typename OpType>
1190 PredicateExpression<OpType, Pred>*
1191 makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1193 return new PredicateExpression<OpType, Pred>(op1, op2);
1196 template<typename OpType>
1197 class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1200 EqualToExpression() {}
1201 EqualToExpression(::SGExpression<OpType>* expr0,
1202 ::SGExpression<OpType>* expr1)
1203 : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1208 template<typename OpType>
1209 class LessExpression : public PredicateExpression<OpType, std::less>
1213 LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1214 : PredicateExpression<OpType, std::less>(expr0, expr1)
1219 template<typename OpType>
1220 class LessEqualExpression
1221 : public PredicateExpression<OpType, std::less_equal>
1224 LessEqualExpression() {}
1225 LessEqualExpression(::SGExpression<OpType>* expr0,
1226 ::SGExpression<OpType>* expr1)
1227 : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1232 class NotExpression : public ::SGUnaryExpression<bool>
1235 NotExpression(::SGExpression<bool>* expr = 0)
1236 : ::SGUnaryExpression<bool>(expr)
1239 void eval(bool& value, const expression::Binding* b) const
1241 value = !getOperand()->getValue(b);
1245 class OrExpression : public ::SGNaryExpression<bool>
1248 void eval(bool& value, const expression::Binding* b) const
1251 for (int i = 0; i < (int)getNumOperands(); ++i) {
1252 value = value || getOperand(i)->getValue(b);
1259 class AndExpression : public ::SGNaryExpression<bool>
1262 void eval(bool& value, const expression::Binding* b) const
1265 for (int i = 0; i < (int)getNumOperands(); ++i) {
1266 value = value && getOperand(i)->getValue(b);
1274 * Convert an operand from OpType to T.
1276 template<typename T, typename OpType>
1277 class ConvertExpression : public GeneralNaryExpression<T, OpType>
1280 ConvertExpression() {}
1281 ConvertExpression(::SGExpression<OpType>* expr0)
1283 this->addOperand(expr0);
1285 virtual void eval(T& value, const simgear::expression::Binding* b) const
1287 typename ConvertExpression::operand_type result;
1288 this->_expressions.at(0)->eval(result, b);
1293 #endif // _SG_EXPRESSION_HXX