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 double getDoubleValue(const simgear::expression::Binding* binding = 0) const
126 { T value; eval(value, binding); return value; }
128 virtual bool isConst() const { return false; }
129 virtual SGExpression* simplify();
130 virtual simgear::expression::Type getType() const
132 return simgear::expression::TypeTraits<T>::typeTag;
134 virtual simgear::expression::Type getOperandType() const
136 return simgear::expression::TypeTraits<T>::typeTag;
140 /// Constant value expression
142 class SGConstExpression : public SGExpression<T> {
144 SGConstExpression(const T& value = T()) : _value(value)
146 void setValue(const T& value)
148 const T& getValue(const simgear::expression::Binding* binding = 0) const
150 virtual void eval(T& value, const simgear::expression::Binding*) const
152 virtual bool isConst() const { return true; }
159 SGExpression<T>::simplify()
162 return new SGConstExpression<T>(getValue());
167 class SGUnaryExpression : public SGExpression<T> {
169 const SGExpression<T>* getOperand() const
170 { return _expression; }
171 SGExpression<T>* getOperand()
172 { return _expression; }
173 void setOperand(SGExpression<T>* expression)
176 expression = new SGConstExpression<T>(T());
177 _expression = expression;
179 virtual bool isConst() const
180 { return getOperand()->isConst(); }
181 virtual SGExpression<T>* simplify()
183 _expression = _expression->simplify();
184 return SGExpression<T>::simplify();
188 SGUnaryExpression(SGExpression<T>* expression = 0)
189 { setOperand(expression); }
192 SGSharedPtr<SGExpression<T> > _expression;
196 class SGBinaryExpression : public SGExpression<T> {
198 const SGExpression<T>* getOperand(unsigned i) const
199 { return _expressions[i]; }
200 SGExpression<T>* getOperand(unsigned i)
201 { return _expressions[i]; }
202 void setOperand(unsigned i, SGExpression<T>* expression)
205 expression = new SGConstExpression<T>(T());
208 _expressions[i] = expression;
211 virtual bool isConst() const
212 { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
213 virtual SGExpression<T>* simplify()
215 _expressions[0] = _expressions[0]->simplify();
216 _expressions[1] = _expressions[1]->simplify();
217 return SGExpression<T>::simplify();
221 SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
222 { setOperand(0, expr0); setOperand(1, expr1); }
225 SGSharedPtr<SGExpression<T> > _expressions[2];
229 class SGNaryExpression : public SGExpression<T> {
231 unsigned getNumOperands() const
232 { return _expressions.size(); }
233 const SGExpression<T>* getOperand(unsigned i) const
234 { return _expressions[i]; }
235 SGExpression<T>* getOperand(unsigned i)
236 { return _expressions[i]; }
237 unsigned addOperand(SGExpression<T>* expression)
241 _expressions.push_back(expression);
242 return _expressions.size() - 1;
245 template<typename Iter>
246 void addOperands(Iter begin, Iter end)
248 for (Iter iter = begin; iter != end; ++iter)
250 addOperand(static_cast< ::SGExpression<T>*>(*iter));
254 virtual bool isConst() const
256 for (unsigned i = 0; i < _expressions.size(); ++i)
257 if (!_expressions[i]->isConst())
261 virtual SGExpression<T>* simplify()
263 for (unsigned i = 0; i < _expressions.size(); ++i)
264 _expressions[i] = _expressions[i]->simplify();
265 return SGExpression<T>::simplify();
271 SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
272 { addOperand(expr0); addOperand(expr1); }
275 std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
282 class SGPropertyExpression : public SGExpression<T> {
284 SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
286 void setPropertyNode(const SGPropertyNode* prop)
288 virtual void eval(T& value, const simgear::expression::Binding*) const
291 void doEval(float& value) const
292 { if (_prop) value = _prop->getFloatValue(); }
293 void doEval(double& value) const
294 { if (_prop) value = _prop->getDoubleValue(); }
295 void doEval(int& value) const
296 { if (_prop) value = _prop->getIntValue(); }
297 void doEval(long& value) const
298 { if (_prop) value = _prop->getLongValue(); }
299 void doEval(bool& value) const
300 { if (_prop) value = _prop->getBoolValue(); }
301 SGSharedPtr<const SGPropertyNode> _prop;
305 class SGAbsExpression : public SGUnaryExpression<T> {
307 SGAbsExpression(SGExpression<T>* expr = 0)
308 : SGUnaryExpression<T>(expr)
311 virtual void eval(T& value, const simgear::expression::Binding* b) const
312 { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
314 using SGUnaryExpression<T>::getOperand;
318 class SGACosExpression : public SGUnaryExpression<T> {
320 SGACosExpression(SGExpression<T>* expr = 0)
321 : SGUnaryExpression<T>(expr)
324 virtual void eval(T& value, const simgear::expression::Binding* b) const
325 { value = acos((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
327 using SGUnaryExpression<T>::getOperand;
331 class SGASinExpression : public SGUnaryExpression<T> {
333 SGASinExpression(SGExpression<T>* expr = 0)
334 : SGUnaryExpression<T>(expr)
337 virtual void eval(T& value, const simgear::expression::Binding* b) const
338 { value = asin((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
340 using SGUnaryExpression<T>::getOperand;
344 class SGATanExpression : public SGUnaryExpression<T> {
346 SGATanExpression(SGExpression<T>* expr = 0)
347 : SGUnaryExpression<T>(expr)
350 virtual void eval(T& value, const simgear::expression::Binding* b) const
351 { value = atan(getOperand()->getDoubleValue(b)); }
353 using SGUnaryExpression<T>::getOperand;
357 class SGCeilExpression : public SGUnaryExpression<T> {
359 SGCeilExpression(SGExpression<T>* expr = 0)
360 : SGUnaryExpression<T>(expr)
363 virtual void eval(T& value, const simgear::expression::Binding* b) const
364 { value = ceil(getOperand()->getDoubleValue(b)); }
366 using SGUnaryExpression<T>::getOperand;
370 class SGCosExpression : public SGUnaryExpression<T> {
372 SGCosExpression(SGExpression<T>* expr = 0)
373 : SGUnaryExpression<T>(expr)
376 virtual void eval(T& value, const simgear::expression::Binding* b) const
377 { value = cos(getOperand()->getDoubleValue(b)); }
379 using SGUnaryExpression<T>::getOperand;
383 class SGCoshExpression : public SGUnaryExpression<T> {
385 SGCoshExpression(SGExpression<T>* expr = 0)
386 : SGUnaryExpression<T>(expr)
389 virtual void eval(T& value, const simgear::expression::Binding* b) const
390 { value = cosh(getOperand()->getDoubleValue(b)); }
392 using SGUnaryExpression<T>::getOperand;
396 class SGExpExpression : public SGUnaryExpression<T> {
398 SGExpExpression(SGExpression<T>* expr = 0)
399 : SGUnaryExpression<T>(expr)
402 virtual void eval(T& value, const simgear::expression::Binding* b) const
403 { value = exp(getOperand()->getDoubleValue(b)); }
405 using SGUnaryExpression<T>::getOperand;
409 class SGFloorExpression : public SGUnaryExpression<T> {
411 SGFloorExpression(SGExpression<T>* expr = 0)
412 : SGUnaryExpression<T>(expr)
415 virtual void eval(T& value, const simgear::expression::Binding* b) const
416 { value = floor(getOperand()->getDoubleValue(b)); }
418 using SGUnaryExpression<T>::getOperand;
422 class SGLogExpression : public SGUnaryExpression<T> {
424 SGLogExpression(SGExpression<T>* expr = 0)
425 : SGUnaryExpression<T>(expr)
428 virtual void eval(T& value, const simgear::expression::Binding* b) const
429 { value = log(getOperand()->getDoubleValue(b)); }
431 using SGUnaryExpression<T>::getOperand;
435 class SGLog10Expression : public SGUnaryExpression<T> {
437 SGLog10Expression(SGExpression<T>* expr = 0)
438 : SGUnaryExpression<T>(expr)
441 virtual void eval(T& value, const simgear::expression::Binding* b) const
442 { value = log10(getOperand()->getDoubleValue(b)); }
444 using SGUnaryExpression<T>::getOperand;
448 class SGSinExpression : public SGUnaryExpression<T> {
450 SGSinExpression(SGExpression<T>* expr = 0)
451 : SGUnaryExpression<T>(expr)
454 virtual void eval(T& value, const simgear::expression::Binding* b) const
455 { value = sin(getOperand()->getDoubleValue(b)); }
457 using SGUnaryExpression<T>::getOperand;
461 class SGSinhExpression : public SGUnaryExpression<T> {
463 SGSinhExpression(SGExpression<T>* expr = 0)
464 : SGUnaryExpression<T>(expr)
467 virtual void eval(T& value, const simgear::expression::Binding* b) const
468 { value = sinh(getOperand()->getDoubleValue(b)); }
470 using SGUnaryExpression<T>::getOperand;
474 class SGSqrExpression : public SGUnaryExpression<T> {
476 SGSqrExpression(SGExpression<T>* expr = 0)
477 : SGUnaryExpression<T>(expr)
480 virtual void eval(T& value, const simgear::expression::Binding* b) const
481 { value = getOperand()->getValue(b); value = value*value; }
483 using SGUnaryExpression<T>::getOperand;
487 class SGSqrtExpression : public SGUnaryExpression<T> {
489 SGSqrtExpression(SGExpression<T>* expr = 0)
490 : SGUnaryExpression<T>(expr)
493 virtual void eval(T& value, const simgear::expression::Binding* b) const
494 { value = sqrt(getOperand()->getDoubleValue(b)); }
496 using SGUnaryExpression<T>::getOperand;
500 class SGTanExpression : public SGUnaryExpression<T> {
502 SGTanExpression(SGExpression<T>* expr = 0)
503 : SGUnaryExpression<T>(expr)
506 virtual void eval(T& value, const simgear::expression::Binding* b) const
507 { value = tan(getOperand()->getDoubleValue(b)); }
509 using SGUnaryExpression<T>::getOperand;
513 class SGTanhExpression : public SGUnaryExpression<T> {
515 SGTanhExpression(SGExpression<T>* expr = 0)
516 : SGUnaryExpression<T>(expr)
519 virtual void eval(T& value, const simgear::expression::Binding* b) const
520 { value = tanh(getOperand()->getDoubleValue(b)); }
522 using SGUnaryExpression<T>::getOperand;
526 class SGScaleExpression : public SGUnaryExpression<T> {
528 SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
529 : SGUnaryExpression<T>(expr), _scale(scale)
531 void setScale(const T& scale)
533 const T& getScale() const
536 virtual void eval(T& value, const simgear::expression::Binding* b) const
537 { value = _scale * getOperand()->getValue(b); }
539 virtual SGExpression<T>* simplify()
542 return getOperand()->simplify();
543 return SGUnaryExpression<T>::simplify();
546 using SGUnaryExpression<T>::getOperand;
552 class SGBiasExpression : public SGUnaryExpression<T> {
554 SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
555 : SGUnaryExpression<T>(expr), _bias(bias)
558 void setBias(const T& bias)
560 const T& getBias() const
563 virtual void eval(T& value, const simgear::expression::Binding* b) const
564 { value = _bias + getOperand()->getValue(b); }
566 virtual SGExpression<T>* simplify()
569 return getOperand()->simplify();
570 return SGUnaryExpression<T>::simplify();
573 using SGUnaryExpression<T>::getOperand;
579 class SGInterpTableExpression : public SGUnaryExpression<T> {
581 SGInterpTableExpression(SGExpression<T>* expr,
582 const SGInterpTable* interpTable) :
583 SGUnaryExpression<T>(expr),
584 _interpTable(interpTable)
587 virtual void eval(T& value, const simgear::expression::Binding* b) const
590 value = _interpTable->interpolate(getOperand()->getValue(b));
593 using SGUnaryExpression<T>::getOperand;
595 SGSharedPtr<SGInterpTable const> _interpTable;
599 class SGClipExpression : public SGUnaryExpression<T> {
601 SGClipExpression(SGExpression<T>* expr)
602 : SGUnaryExpression<T>(expr),
603 _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
604 _clipMax(SGLimits<T>::max())
606 SGClipExpression(SGExpression<T>* expr,
607 const T& clipMin, const T& clipMax)
608 : SGUnaryExpression<T>(expr),
613 void setClipMin(const T& clipMin)
614 { _clipMin = clipMin; }
615 const T& getClipMin() const
618 void setClipMax(const T& clipMax)
619 { _clipMax = clipMax; }
620 const T& getClipMax() const
623 virtual void eval(T& value, const simgear::expression::Binding* b) const
625 value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
628 virtual SGExpression<T>* simplify()
630 if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
631 _clipMax >= SGLimits<T>::max())
632 return getOperand()->simplify();
633 return SGUnaryExpression<T>::simplify();
636 using SGUnaryExpression<T>::getOperand;
643 class SGStepExpression : public SGUnaryExpression<T> {
645 SGStepExpression(SGExpression<T>* expr = 0,
646 const T& step = T(1), const T& scroll = T(0))
647 : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
650 void setStep(const T& step)
652 const T& getStep() const
655 void setScroll(const T& scroll)
656 { _scroll = scroll; }
657 const T& getScroll() const
660 virtual void eval(T& value, const simgear::expression::Binding* b) const
661 { value = apply_mods(getOperand()->getValue(b)); }
663 using SGUnaryExpression<T>::getOperand;
666 T apply_mods(T property) const
668 if( _step <= SGLimits<T>::min() ) return property;
670 // apply stepping of input value
671 T modprop = floor(property/_step)*_step;
673 // calculate scroll amount (for odometer like movement)
674 T remainder = property <= SGLimits<T>::min() ? -fmod(property,_step) : (_step - fmod(property,_step));
675 if( remainder > SGLimits<T>::min() && remainder < _scroll )
676 modprop += (_scroll - remainder) / _scroll * _step;
686 class SGEnableExpression : public SGUnaryExpression<T> {
688 SGEnableExpression(SGExpression<T>* expr = 0,
689 SGCondition* enable = 0,
690 const T& disabledValue = T(0))
691 : SGUnaryExpression<T>(expr),
693 _disabledValue(disabledValue)
696 const T& getDisabledValue() const
697 { return _disabledValue; }
698 void setDisabledValue(const T& disabledValue)
699 { _disabledValue = disabledValue; }
701 virtual void eval(T& value, const simgear::expression::Binding* b) const
704 value = getOperand()->getValue(b);
706 value = _disabledValue;
709 virtual SGExpression<T>* simplify()
712 return getOperand()->simplify();
713 return SGUnaryExpression<T>::simplify();
716 using SGUnaryExpression<T>::getOperand;
718 SGSharedPtr<SGCondition> _enable;
723 class SGAtan2Expression : public SGBinaryExpression<T> {
725 SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
726 : SGBinaryExpression<T>(expr0, expr1)
728 virtual void eval(T& value, const simgear::expression::Binding* b) const
729 { value = atan2(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
730 using SGBinaryExpression<T>::getOperand;
734 class SGDivExpression : public SGBinaryExpression<T> {
736 SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
737 : SGBinaryExpression<T>(expr0, expr1)
739 virtual void eval(T& value, const simgear::expression::Binding* b) const
740 { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
741 using SGBinaryExpression<T>::getOperand;
745 class SGModExpression : public SGBinaryExpression<T> {
747 SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
748 : SGBinaryExpression<T>(expr0, expr1)
750 virtual void eval(T& value, const simgear::expression::Binding* b) const
751 { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
752 using SGBinaryExpression<T>::getOperand;
754 int mod(const int& v0, const int& v1) const
756 float mod(const float& v0, const float& v1) const
757 { return fmod(v0, v1); }
758 double mod(const double& v0, const double& v1) const
759 { return fmod(v0, v1); }
763 class SGPowExpression : public SGBinaryExpression<T> {
765 SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
766 : SGBinaryExpression<T>(expr0, expr1)
768 virtual void eval(T& value, const simgear::expression::Binding* b) const
769 { value = pow(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
770 using SGBinaryExpression<T>::getOperand;
774 class SGSumExpression : public SGNaryExpression<T> {
778 SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
779 : SGNaryExpression<T>(expr0, expr1)
781 virtual void eval(T& value, const simgear::expression::Binding* b) const
784 unsigned sz = SGNaryExpression<T>::getNumOperands();
785 for (unsigned i = 0; i < sz; ++i)
786 value += getOperand(i)->getValue(b);
788 using SGNaryExpression<T>::getValue;
789 using SGNaryExpression<T>::getOperand;
793 class SGDifferenceExpression : public SGNaryExpression<T> {
795 SGDifferenceExpression()
797 SGDifferenceExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
798 : SGNaryExpression<T>(expr0, expr1)
800 virtual void eval(T& value, const simgear::expression::Binding* b) const
802 value = getOperand(0)->getValue(b);
803 unsigned sz = SGNaryExpression<T>::getNumOperands();
804 for (unsigned i = 1; i < sz; ++i)
805 value -= getOperand(i)->getValue(b);
807 using SGNaryExpression<T>::getValue;
808 using SGNaryExpression<T>::getOperand;
812 class SGProductExpression : public SGNaryExpression<T> {
814 SGProductExpression()
816 SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
817 : SGNaryExpression<T>(expr0, expr1)
819 virtual void eval(T& value, const simgear::expression::Binding* b) const
822 unsigned sz = SGNaryExpression<T>::getNumOperands();
823 for (unsigned i = 0; i < sz; ++i)
824 value *= getOperand(i)->getValue(b);
826 using SGNaryExpression<T>::getValue;
827 using SGNaryExpression<T>::getOperand;
831 class SGMinExpression : public SGNaryExpression<T> {
835 SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
836 : SGNaryExpression<T>(expr0, expr1)
838 virtual void eval(T& value, const simgear::expression::Binding* b) const
840 unsigned sz = SGNaryExpression<T>::getNumOperands();
844 value = getOperand(0)->getValue(b);
845 for (unsigned i = 1; i < sz; ++i)
846 value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
848 using SGNaryExpression<T>::getOperand;
852 class SGMaxExpression : public SGNaryExpression<T> {
856 SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
857 : SGNaryExpression<T>(expr0, expr1)
859 virtual void eval(T& value, const simgear::expression::Binding* b) const
861 unsigned sz = SGNaryExpression<T>::getNumOperands();
865 value = getOperand(0)->getValue(b);
866 for (unsigned i = 1; i < sz; ++i)
867 value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
869 using SGNaryExpression<T>::getOperand;
872 typedef SGExpression<int> SGExpressioni;
873 typedef SGExpression<float> SGExpressionf;
874 typedef SGExpression<double> SGExpressiond;
875 typedef SGExpression<bool> SGExpressionb;
878 * Global function to make an expression out of properties.
882 <clipMax>79</clipMax>
886 <property>sim/model/whatever-rad</property>
888 <property>sim/model/someother-deg</property>
894 will evaluate to an expression:
896 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
900 SGReadIntExpression(SGPropertyNode *inputRoot,
901 const SGPropertyNode *configNode);
904 SGReadFloatExpression(SGPropertyNode *inputRoot,
905 const SGPropertyNode *configNode);
907 SGExpression<double>*
908 SGReadDoubleExpression(SGPropertyNode *inputRoot,
909 const SGPropertyNode *configNode);
912 SGReadBoolExpression(SGPropertyNode *inputRoot,
913 const SGPropertyNode *configNode);
919 struct ParseError : public sg_exception
921 ParseError(const string& message = std::string())
922 : sg_exception(message) {}
925 // Support for binding variables around an expression.
929 virtual ~Binding() {}
930 const virtual Value* getBindings() const = 0;
931 virtual Value* getBindings() = 0;
934 class VariableLengthBinding : public Binding
937 const Value* getBindings() const
939 if (_bindings.empty())
942 return &_bindings[0];
946 if (_bindings.empty())
949 return &_bindings[0];
951 std::vector<Value> _bindings;
954 template<int Size> class FixedLengthBinding : public Binding
959 return &_bindings[0];
961 const Value* getBindings() const
963 return &_bindings[0];
965 Value _bindings[Size];
968 struct VariableBinding
970 VariableBinding() : type(expression::DOUBLE), location(-1) {}
972 VariableBinding(const std::string& name_, expression::Type type_,
974 : name(name_), type(type_), location(location_)
978 expression::Type type;
985 int addBinding(const std::string& name, expression::Type type);
986 bool findBinding(const string& name, VariableBinding& result) const;
987 std::vector<VariableBinding> bindings;
992 typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
994 void addParser(const std::string& name, exp_parser parser)
996 getParserMap().insert(std::make_pair(name, parser));
998 Expression* read(const SGPropertyNode* exp)
1000 ParserMap& map = getParserMap();
1001 ParserMap::iterator itr = map.find(exp->getName());
1002 if (itr == map.end())
1003 throw ParseError(string("unknown expression ") + exp->getName());
1004 exp_parser parser = itr->second;
1005 return (*parser)(exp, this);
1007 // XXX vector of SGSharedPtr?
1008 bool readChildren(const SGPropertyNode* exp,
1009 std::vector<Expression*>& result);
1011 * Function that parses a property tree, producing an expression.
1013 typedef std::map<const std::string, exp_parser> ParserMap;
1014 virtual ParserMap& getParserMap() = 0;
1016 * After an expression is parsed, the binding layout may contain
1017 * references that need to be bound during evaluation.
1019 BindingLayout& getBindingLayout() { return _bindingLayout; }
1021 BindingLayout _bindingLayout;
1024 class ExpressionParser : public Parser
1027 ParserMap& getParserMap()
1029 return ParserMapSingleton::instance()->_parserTable;
1031 static void addExpParser(const std::string&, exp_parser);
1033 struct ParserMapSingleton : public simgear::Singleton<ParserMapSingleton>
1035 ParserMap _parserTable;
1040 * Constructor for registering parser functions.
1042 struct ExpParserRegistrar
1044 ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1046 ExpressionParser::addExpParser(token, parser);
1053 * Access a variable definition. Use a location from a BindingLayout.
1055 template<typename T>
1056 class VariableExpression : public ::SGExpression<T> {
1058 VariableExpression(int location) : _location(location) {}
1059 virtual ~VariableExpression() {}
1060 virtual void eval(T& value, const simgear::expression::Binding* b) const
1062 const expression::Value* values = b->getBindings();
1063 value = *reinterpret_cast<const T *>(&values[_location].val);
1071 * An n-ary expression where the types of the argument aren't the
1072 * same as the return type.
1074 template<typename T, typename OpType>
1075 class GeneralNaryExpression : public ::SGExpression<T> {
1077 typedef OpType operand_type;
1078 unsigned getNumOperands() const
1079 { return _expressions.size(); }
1080 const ::SGExpression<OpType>* getOperand(unsigned i) const
1081 { return _expressions[i]; }
1082 ::SGExpression<OpType>* getOperand(unsigned i)
1083 { return _expressions[i]; }
1084 unsigned addOperand(::SGExpression<OpType>* expression)
1087 return ~unsigned(0);
1088 _expressions.push_back(expression);
1089 return _expressions.size() - 1;
1092 template<typename Iter>
1093 void addOperands(Iter begin, Iter end)
1095 for (Iter iter = begin; iter != end; ++iter)
1097 addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1101 virtual bool isConst() const
1103 for (unsigned i = 0; i < _expressions.size(); ++i)
1104 if (!_expressions[i]->isConst())
1108 virtual ::SGExpression<T>* simplify()
1110 for (unsigned i = 0; i < _expressions.size(); ++i)
1111 _expressions[i] = _expressions[i]->simplify();
1112 return SGExpression<T>::simplify();
1115 simgear::expression::Type getOperandType() const
1117 return simgear::expression::TypeTraits<OpType>::typeTag;
1121 GeneralNaryExpression()
1123 GeneralNaryExpression(::SGExpression<OpType>* expr0,
1124 ::SGExpression<OpType>* expr1)
1125 { addOperand(expr0); addOperand(expr1); }
1127 std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1131 * A predicate that wraps, for example the STL template predicate
1132 * expressions like std::equal_to.
1134 template<typename OpType, template<typename PredOp> class Pred>
1135 class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1137 PredicateExpression()
1140 PredicateExpression(::SGExpression<OpType>* expr0,
1141 ::SGExpression<OpType>* expr1)
1142 : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1145 virtual void eval(bool& value, const simgear::expression::Binding* b) const
1147 unsigned sz = this->getNumOperands();
1150 value = _pred(this->getOperand(0)->getValue(b),
1151 this->getOperand(1)->getValue(b));
1157 template<template<typename OT> class Pred, typename OpType>
1158 PredicateExpression<OpType, Pred>*
1159 makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1161 return new PredicateExpression<OpType, Pred>(op1, op2);
1164 template<typename OpType>
1165 class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1168 EqualToExpression() {}
1169 EqualToExpression(::SGExpression<OpType>* expr0,
1170 ::SGExpression<OpType>* expr1)
1171 : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1176 template<typename OpType>
1177 class LessExpression : public PredicateExpression<OpType, std::less>
1181 LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1182 : PredicateExpression<OpType, std::less>(expr0, expr1)
1187 template<typename OpType>
1188 class LessEqualExpression
1189 : public PredicateExpression<OpType, std::less_equal>
1192 LessEqualExpression() {}
1193 LessEqualExpression(::SGExpression<OpType>* expr0,
1194 ::SGExpression<OpType>* expr1)
1195 : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1200 class NotExpression : public ::SGUnaryExpression<bool>
1203 NotExpression(::SGExpression<bool>* expr = 0)
1204 : ::SGUnaryExpression<bool>(expr)
1207 void eval(bool& value, const expression::Binding* b) const
1209 value = !getOperand()->getValue(b);
1213 class OrExpression : public ::SGNaryExpression<bool>
1216 void eval(bool& value, const expression::Binding* b) const
1219 for (int i = 0; i < (int)getNumOperands(); ++i) {
1220 value = value || getOperand(i)->getValue(b);
1227 class AndExpression : public ::SGNaryExpression<bool>
1230 void eval(bool& value, const expression::Binding* b) const
1233 for (int i = 0; i < (int)getNumOperands(); ++i) {
1234 value = value && getOperand(i)->getValue(b);
1242 * Convert an operand from OpType to T.
1244 template<typename T, typename OpType>
1245 class ConvertExpression : public GeneralNaryExpression<T, OpType>
1248 ConvertExpression() {}
1249 ConvertExpression(::SGExpression<OpType>* expr0)
1251 this->addOperand(expr0);
1253 virtual void eval(T& value, const simgear::expression::Binding* b) const
1255 typename ConvertExpression::operand_type result;
1256 this->_expressions.at(0)->eval(result, b);
1261 #endif // _SG_EXPRESSION_HXX