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
29 #include <simgear/props/condition.hxx>
30 #include <simgear/props/props.hxx>
31 #include <simgear/math/interpolater.hxx>
32 #include <simgear/math/SGMath.hxx>
33 #include <simgear/scene/model/persparam.hxx>
34 #include <simgear/structure/exception.hxx>
35 #include <simgear/structure/Singleton.hxx>
37 /// Expression tree implementation.
49 template<typename T> struct TypeTraits;
50 template<> struct TypeTraits<bool> {
51 static const Type typeTag = BOOL;
53 template<> struct TypeTraits<int> {
54 static const Type typeTag = INT;
56 template<> struct TypeTraits<float> {
57 static const Type typeTag = FLOAT;
59 template<> struct TypeTraits<double> {
60 static const Type typeTag = DOUBLE;
73 Value() : typeTag(DOUBLE)
78 Value(bool val_) : typeTag(BOOL)
83 Value(int val_) : typeTag(INT)
88 Value(float val_) : typeTag(FLOAT)
93 Value(double val_) : typeTag(DOUBLE)
103 class Expression : public SGReferenced
106 virtual ~Expression() {}
107 virtual expression::Type getType() const = 0;
110 const expression::Value eval(const Expression* exp,
111 const expression::Binding* binding = 0);
116 class SGExpression : public simgear::Expression {
118 virtual ~SGExpression() {}
119 typedef T result_type;
120 typedef T operand_type;
121 virtual void eval(T&, const simgear::expression::Binding*) const = 0;
123 T getValue(const simgear::expression::Binding* binding = 0) const
124 { T value; eval(value, binding); return value; }
126 double getDoubleValue(const simgear::expression::Binding* binding = 0) const
127 { T value; eval(value, binding); return value; }
129 virtual bool isConst() const { return false; }
130 virtual SGExpression* simplify();
131 virtual simgear::expression::Type getType() const
133 return simgear::expression::TypeTraits<T>::typeTag;
135 virtual simgear::expression::Type getOperandType() const
137 return simgear::expression::TypeTraits<T>::typeTag;
141 /// Constant value expression
143 class SGConstExpression : public SGExpression<T> {
145 SGConstExpression(const T& value = T()) : _value(value)
147 void setValue(const T& value)
149 const T& getValue(const simgear::expression::Binding* binding = 0) const
151 virtual void eval(T& value, const simgear::expression::Binding*) const
153 virtual bool isConst() const { return true; }
160 SGExpression<T>::simplify()
163 return new SGConstExpression<T>(getValue());
168 class SGUnaryExpression : public SGExpression<T> {
170 const SGExpression<T>* getOperand() const
171 { return _expression; }
172 SGExpression<T>* getOperand()
173 { return _expression; }
174 void setOperand(SGExpression<T>* expression)
177 expression = new SGConstExpression<T>(T());
178 _expression = expression;
180 virtual bool isConst() const
181 { return getOperand()->isConst(); }
182 virtual SGExpression<T>* simplify()
184 _expression = _expression->simplify();
185 return SGExpression<T>::simplify();
189 SGUnaryExpression(SGExpression<T>* expression = 0)
190 { setOperand(expression); }
193 SGSharedPtr<SGExpression<T> > _expression;
197 class SGBinaryExpression : public SGExpression<T> {
199 const SGExpression<T>* getOperand(unsigned i) const
200 { return _expressions[i]; }
201 SGExpression<T>* getOperand(unsigned i)
202 { return _expressions[i]; }
203 void setOperand(unsigned i, SGExpression<T>* expression)
206 expression = new SGConstExpression<T>(T());
209 _expressions[i] = expression;
212 virtual bool isConst() const
213 { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
214 virtual SGExpression<T>* simplify()
216 _expressions[0] = _expressions[0]->simplify();
217 _expressions[1] = _expressions[1]->simplify();
218 return SGExpression<T>::simplify();
222 SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
223 { setOperand(0, expr0); setOperand(1, expr1); }
226 SGSharedPtr<SGExpression<T> > _expressions[2];
230 class SGNaryExpression : public SGExpression<T> {
232 unsigned getNumOperands() const
233 { return _expressions.size(); }
234 const SGExpression<T>* getOperand(unsigned i) const
235 { return _expressions[i]; }
236 SGExpression<T>* getOperand(unsigned i)
237 { return _expressions[i]; }
238 unsigned addOperand(SGExpression<T>* expression)
242 _expressions.push_back(expression);
243 return _expressions.size() - 1;
246 template<typename Iter>
247 void addOperands(Iter begin, Iter end)
249 for (Iter iter = begin; iter != end; ++iter)
251 addOperand(static_cast< ::SGExpression<T>*>(*iter));
255 virtual bool isConst() const
257 for (unsigned i = 0; i < _expressions.size(); ++i)
258 if (!_expressions[i]->isConst())
262 virtual SGExpression<T>* simplify()
264 for (unsigned i = 0; i < _expressions.size(); ++i)
265 _expressions[i] = _expressions[i]->simplify();
266 return SGExpression<T>::simplify();
272 SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
273 { addOperand(expr0); addOperand(expr1); }
276 std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
283 class SGPropertyExpression : public SGExpression<T> {
285 SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
287 void setPropertyNode(const SGPropertyNode* prop)
289 virtual void eval(T& value, const simgear::expression::Binding*) const
292 void doEval(float& value) const
293 { if (_prop) value = _prop->getFloatValue(); }
294 void doEval(double& value) const
295 { if (_prop) value = _prop->getDoubleValue(); }
296 void doEval(int& value) const
297 { if (_prop) value = _prop->getIntValue(); }
298 void doEval(long& value) const
299 { if (_prop) value = _prop->getLongValue(); }
300 void doEval(bool& value) const
301 { if (_prop) value = _prop->getBoolValue(); }
302 SGSharedPtr<const SGPropertyNode> _prop;
306 class SGAbsExpression : public SGUnaryExpression<T> {
308 SGAbsExpression(SGExpression<T>* expr = 0)
309 : SGUnaryExpression<T>(expr)
312 virtual void eval(T& value, const simgear::expression::Binding* b) const
313 { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
315 using SGUnaryExpression<T>::getOperand;
319 class SGACosExpression : public SGUnaryExpression<T> {
321 SGACosExpression(SGExpression<T>* expr = 0)
322 : SGUnaryExpression<T>(expr)
325 virtual void eval(T& value, const simgear::expression::Binding* b) const
326 { value = acos((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
328 using SGUnaryExpression<T>::getOperand;
332 class SGASinExpression : public SGUnaryExpression<T> {
334 SGASinExpression(SGExpression<T>* expr = 0)
335 : SGUnaryExpression<T>(expr)
338 virtual void eval(T& value, const simgear::expression::Binding* b) const
339 { value = asin((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
341 using SGUnaryExpression<T>::getOperand;
345 class SGATanExpression : public SGUnaryExpression<T> {
347 SGATanExpression(SGExpression<T>* expr = 0)
348 : SGUnaryExpression<T>(expr)
351 virtual void eval(T& value, const simgear::expression::Binding* b) const
352 { value = atan(getOperand()->getDoubleValue(b)); }
354 using SGUnaryExpression<T>::getOperand;
358 class SGCeilExpression : public SGUnaryExpression<T> {
360 SGCeilExpression(SGExpression<T>* expr = 0)
361 : SGUnaryExpression<T>(expr)
364 virtual void eval(T& value, const simgear::expression::Binding* b) const
365 { value = ceil(getOperand()->getDoubleValue(b)); }
367 using SGUnaryExpression<T>::getOperand;
371 class SGCosExpression : public SGUnaryExpression<T> {
373 SGCosExpression(SGExpression<T>* expr = 0)
374 : SGUnaryExpression<T>(expr)
377 virtual void eval(T& value, const simgear::expression::Binding* b) const
378 { value = cos(getOperand()->getDoubleValue(b)); }
380 using SGUnaryExpression<T>::getOperand;
384 class SGCoshExpression : public SGUnaryExpression<T> {
386 SGCoshExpression(SGExpression<T>* expr = 0)
387 : SGUnaryExpression<T>(expr)
390 virtual void eval(T& value, const simgear::expression::Binding* b) const
391 { value = cosh(getOperand()->getDoubleValue(b)); }
393 using SGUnaryExpression<T>::getOperand;
397 class SGExpExpression : public SGUnaryExpression<T> {
399 SGExpExpression(SGExpression<T>* expr = 0)
400 : SGUnaryExpression<T>(expr)
403 virtual void eval(T& value, const simgear::expression::Binding* b) const
404 { value = exp(getOperand()->getDoubleValue(b)); }
406 using SGUnaryExpression<T>::getOperand;
410 class SGFloorExpression : public SGUnaryExpression<T> {
412 SGFloorExpression(SGExpression<T>* expr = 0)
413 : SGUnaryExpression<T>(expr)
416 virtual void eval(T& value, const simgear::expression::Binding* b) const
417 { value = floor(getOperand()->getDoubleValue(b)); }
419 using SGUnaryExpression<T>::getOperand;
423 class SGLogExpression : public SGUnaryExpression<T> {
425 SGLogExpression(SGExpression<T>* expr = 0)
426 : SGUnaryExpression<T>(expr)
429 virtual void eval(T& value, const simgear::expression::Binding* b) const
430 { value = log(getOperand()->getDoubleValue(b)); }
432 using SGUnaryExpression<T>::getOperand;
436 class SGLog10Expression : public SGUnaryExpression<T> {
438 SGLog10Expression(SGExpression<T>* expr = 0)
439 : SGUnaryExpression<T>(expr)
442 virtual void eval(T& value, const simgear::expression::Binding* b) const
443 { value = log10(getOperand()->getDoubleValue(b)); }
445 using SGUnaryExpression<T>::getOperand;
449 class SGSinExpression : public SGUnaryExpression<T> {
451 SGSinExpression(SGExpression<T>* expr = 0)
452 : SGUnaryExpression<T>(expr)
455 virtual void eval(T& value, const simgear::expression::Binding* b) const
456 { value = sin(getOperand()->getDoubleValue(b)); }
458 using SGUnaryExpression<T>::getOperand;
462 class SGSinhExpression : public SGUnaryExpression<T> {
464 SGSinhExpression(SGExpression<T>* expr = 0)
465 : SGUnaryExpression<T>(expr)
468 virtual void eval(T& value, const simgear::expression::Binding* b) const
469 { value = sinh(getOperand()->getDoubleValue(b)); }
471 using SGUnaryExpression<T>::getOperand;
475 class SGSqrExpression : public SGUnaryExpression<T> {
477 SGSqrExpression(SGExpression<T>* expr = 0)
478 : SGUnaryExpression<T>(expr)
481 virtual void eval(T& value, const simgear::expression::Binding* b) const
482 { value = getOperand()->getValue(b); value = value*value; }
484 using SGUnaryExpression<T>::getOperand;
488 class SGSqrtExpression : public SGUnaryExpression<T> {
490 SGSqrtExpression(SGExpression<T>* expr = 0)
491 : SGUnaryExpression<T>(expr)
494 virtual void eval(T& value, const simgear::expression::Binding* b) const
495 { value = sqrt(getOperand()->getDoubleValue(b)); }
497 using SGUnaryExpression<T>::getOperand;
501 class SGTanExpression : public SGUnaryExpression<T> {
503 SGTanExpression(SGExpression<T>* expr = 0)
504 : SGUnaryExpression<T>(expr)
507 virtual void eval(T& value, const simgear::expression::Binding* b) const
508 { value = tan(getOperand()->getDoubleValue(b)); }
510 using SGUnaryExpression<T>::getOperand;
514 class SGTanhExpression : public SGUnaryExpression<T> {
516 SGTanhExpression(SGExpression<T>* expr = 0)
517 : SGUnaryExpression<T>(expr)
520 virtual void eval(T& value, const simgear::expression::Binding* b) const
521 { value = tanh(getOperand()->getDoubleValue(b)); }
523 using SGUnaryExpression<T>::getOperand;
527 class SGScaleExpression : public SGUnaryExpression<T> {
529 SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
530 : SGUnaryExpression<T>(expr), _scale(scale)
532 void setScale(const T& scale)
534 const T& getScale() const
537 virtual void eval(T& value, const simgear::expression::Binding* b) const
538 { value = _scale * getOperand()->getValue(b); }
540 virtual SGExpression<T>* simplify()
543 return getOperand()->simplify();
544 return SGUnaryExpression<T>::simplify();
547 using SGUnaryExpression<T>::getOperand;
553 class SGBiasExpression : public SGUnaryExpression<T> {
555 SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
556 : SGUnaryExpression<T>(expr), _bias(bias)
559 void setBias(const T& bias)
561 const T& getBias() const
564 virtual void eval(T& value, const simgear::expression::Binding* b) const
565 { value = _bias + getOperand()->getValue(b); }
567 virtual SGExpression<T>* simplify()
570 return getOperand()->simplify();
571 return SGUnaryExpression<T>::simplify();
574 using SGUnaryExpression<T>::getOperand;
580 class SGInterpTableExpression : public SGUnaryExpression<T> {
582 SGInterpTableExpression(SGExpression<T>* expr,
583 const SGInterpTable* interpTable) :
584 SGUnaryExpression<T>(expr),
585 _interpTable(interpTable)
588 virtual void eval(T& value, const simgear::expression::Binding* b) const
591 value = _interpTable->interpolate(getOperand()->getValue(b));
594 using SGUnaryExpression<T>::getOperand;
596 SGSharedPtr<SGInterpTable const> _interpTable;
600 class SGClipExpression : public SGUnaryExpression<T> {
602 SGClipExpression(SGExpression<T>* expr)
603 : SGUnaryExpression<T>(expr),
604 _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
605 _clipMax(SGLimits<T>::max())
607 SGClipExpression(SGExpression<T>* expr,
608 const T& clipMin, const T& clipMax)
609 : SGUnaryExpression<T>(expr),
614 void setClipMin(const T& clipMin)
615 { _clipMin = clipMin; }
616 const T& getClipMin() const
619 void setClipMax(const T& clipMax)
620 { _clipMax = clipMax; }
621 const T& getClipMax() const
624 virtual void eval(T& value, const simgear::expression::Binding* b) const
626 value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
629 virtual SGExpression<T>* simplify()
631 if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
632 _clipMax >= SGLimits<T>::max())
633 return getOperand()->simplify();
634 return SGUnaryExpression<T>::simplify();
637 using SGUnaryExpression<T>::getOperand;
644 class SGStepExpression : public SGUnaryExpression<T> {
646 SGStepExpression(SGExpression<T>* expr = 0,
647 const T& step = T(1), const T& scroll = T(0))
648 : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
651 void setStep(const T& step)
653 const T& getStep() const
656 void setScroll(const T& scroll)
657 { _scroll = scroll; }
658 const T& getScroll() const
661 virtual void eval(T& value, const simgear::expression::Binding* b) const
662 { value = apply_mods(getOperand()->getValue(b)); }
664 using SGUnaryExpression<T>::getOperand;
667 T apply_mods(T property) const
669 if( _step <= SGLimits<T>::min() ) return property;
671 // apply stepping of input value
672 T modprop = floor(property/_step)*_step;
674 // calculate scroll amount (for odometer like movement)
675 T remainder = property <= SGLimits<T>::min() ? -fmod(property,_step) : (_step - fmod(property,_step));
676 if( remainder > SGLimits<T>::min() && remainder < _scroll )
677 modprop += (_scroll - remainder) / _scroll * _step;
687 class SGEnableExpression : public SGUnaryExpression<T> {
689 SGEnableExpression(SGExpression<T>* expr = 0,
690 SGCondition* enable = 0,
691 const T& disabledValue = T(0))
692 : SGUnaryExpression<T>(expr),
694 _disabledValue(disabledValue)
697 const T& getDisabledValue() const
698 { return _disabledValue; }
699 void setDisabledValue(const T& disabledValue)
700 { _disabledValue = disabledValue; }
702 virtual void eval(T& value, const simgear::expression::Binding* b) const
705 value = getOperand()->getValue(b);
707 value = _disabledValue;
710 virtual SGExpression<T>* simplify()
713 return getOperand()->simplify();
714 return SGUnaryExpression<T>::simplify();
717 using SGUnaryExpression<T>::getOperand;
719 SGSharedPtr<SGCondition> _enable;
724 class SGAtan2Expression : public SGBinaryExpression<T> {
726 SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
727 : SGBinaryExpression<T>(expr0, expr1)
729 virtual void eval(T& value, const simgear::expression::Binding* b) const
730 { value = atan2(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
731 using SGBinaryExpression<T>::getOperand;
735 class SGDivExpression : public SGBinaryExpression<T> {
737 SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
738 : SGBinaryExpression<T>(expr0, expr1)
740 virtual void eval(T& value, const simgear::expression::Binding* b) const
741 { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
742 using SGBinaryExpression<T>::getOperand;
746 class SGModExpression : public SGBinaryExpression<T> {
748 SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
749 : SGBinaryExpression<T>(expr0, expr1)
751 virtual void eval(T& value, const simgear::expression::Binding* b) const
752 { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
753 using SGBinaryExpression<T>::getOperand;
755 int mod(const int& v0, const int& v1) const
757 float mod(const float& v0, const float& v1) const
758 { return fmod(v0, v1); }
759 double mod(const double& v0, const double& v1) const
760 { return fmod(v0, v1); }
764 class SGPowExpression : public SGBinaryExpression<T> {
766 SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
767 : SGBinaryExpression<T>(expr0, expr1)
769 virtual void eval(T& value, const simgear::expression::Binding* b) const
770 { value = pow(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
771 using SGBinaryExpression<T>::getOperand;
775 class SGSumExpression : public SGNaryExpression<T> {
779 SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
780 : SGNaryExpression<T>(expr0, expr1)
782 virtual void eval(T& value, const simgear::expression::Binding* b) const
785 unsigned sz = SGNaryExpression<T>::getNumOperands();
786 for (unsigned i = 0; i < sz; ++i)
787 value += getOperand(i)->getValue(b);
789 using SGNaryExpression<T>::getValue;
790 using SGNaryExpression<T>::getOperand;
794 class SGDifferenceExpression : public SGNaryExpression<T> {
796 SGDifferenceExpression()
798 SGDifferenceExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
799 : SGNaryExpression<T>(expr0, expr1)
801 virtual void eval(T& value, const simgear::expression::Binding* b) const
803 value = getOperand(0)->getValue(b);
804 unsigned sz = SGNaryExpression<T>::getNumOperands();
805 for (unsigned i = 1; i < sz; ++i)
806 value -= getOperand(i)->getValue(b);
808 using SGNaryExpression<T>::getValue;
809 using SGNaryExpression<T>::getOperand;
813 class SGProductExpression : public SGNaryExpression<T> {
815 SGProductExpression()
817 SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
818 : SGNaryExpression<T>(expr0, expr1)
820 virtual void eval(T& value, const simgear::expression::Binding* b) const
823 unsigned sz = SGNaryExpression<T>::getNumOperands();
824 for (unsigned i = 0; i < sz; ++i)
825 value *= getOperand(i)->getValue(b);
827 using SGNaryExpression<T>::getValue;
828 using SGNaryExpression<T>::getOperand;
832 class SGMinExpression : public SGNaryExpression<T> {
836 SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
837 : SGNaryExpression<T>(expr0, expr1)
839 virtual void eval(T& value, const simgear::expression::Binding* b) const
841 unsigned sz = SGNaryExpression<T>::getNumOperands();
845 value = getOperand(0)->getValue(b);
846 for (unsigned i = 1; i < sz; ++i)
847 value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
849 using SGNaryExpression<T>::getOperand;
853 class SGMaxExpression : public SGNaryExpression<T> {
857 SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
858 : SGNaryExpression<T>(expr0, expr1)
860 virtual void eval(T& value, const simgear::expression::Binding* b) const
862 unsigned sz = SGNaryExpression<T>::getNumOperands();
866 value = getOperand(0)->getValue(b);
867 for (unsigned i = 1; i < sz; ++i)
868 value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
870 using SGNaryExpression<T>::getOperand;
873 typedef SGExpression<int> SGExpressioni;
874 typedef SGExpression<float> SGExpressionf;
875 typedef SGExpression<double> SGExpressiond;
876 typedef SGExpression<bool> SGExpressionb;
879 * Global function to make an expression out of properties.
883 <clipMax>79</clipMax>
887 <property>sim/model/whatever-rad</property>
889 <property>sim/model/someother-deg</property>
895 will evaluate to an expression:
897 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
901 SGReadIntExpression(SGPropertyNode *inputRoot,
902 const SGPropertyNode *configNode);
905 SGReadFloatExpression(SGPropertyNode *inputRoot,
906 const SGPropertyNode *configNode);
908 SGExpression<double>*
909 SGReadDoubleExpression(SGPropertyNode *inputRoot,
910 const SGPropertyNode *configNode);
913 SGReadBoolExpression(SGPropertyNode *inputRoot,
914 const SGPropertyNode *configNode);
920 struct ParseError : public sg_exception
922 ParseError(const string& message = std::string())
923 : sg_exception(message) {}
926 // Support for binding variables around an expression.
930 virtual ~Binding() {}
931 const virtual Value* getBindings() const = 0;
932 virtual Value* getBindings() = 0;
935 class VariableLengthBinding : public Binding
938 const Value* getBindings() const
940 if (_bindings.empty())
943 return &_bindings[0];
947 if (_bindings.empty())
950 return &_bindings[0];
952 std::vector<Value> _bindings;
955 template<int Size> class FixedLengthBinding : public Binding
960 return &_bindings[0];
962 const Value* getBindings() const
964 return &_bindings[0];
966 Value _bindings[Size];
969 struct VariableBinding
971 VariableBinding() : type(expression::DOUBLE), location(-1) {}
973 VariableBinding(const std::string& name_, expression::Type type_,
975 : name(name_), type(type_), location(location_)
979 expression::Type type;
986 int addBinding(const std::string& name, expression::Type type);
987 bool findBinding(const string& name, VariableBinding& result) const;
988 std::vector<VariableBinding> bindings;
993 typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
995 void addParser(const std::string& name, exp_parser parser)
997 getParserMap().insert(std::make_pair(name, parser));
999 Expression* read(const SGPropertyNode* exp)
1001 ParserMap& map = getParserMap();
1002 ParserMap::iterator itr = map.find(exp->getName());
1003 if (itr == map.end())
1004 throw ParseError(string("unknown expression ") + exp->getName());
1005 exp_parser parser = itr->second;
1006 return (*parser)(exp, this);
1008 // XXX vector of SGSharedPtr?
1009 bool readChildren(const SGPropertyNode* exp,
1010 std::vector<Expression*>& result);
1012 * Function that parses a property tree, producing an expression.
1014 typedef std::map<const std::string, exp_parser> ParserMap;
1015 virtual ParserMap& getParserMap() = 0;
1017 * After an expression is parsed, the binding layout may contain
1018 * references that need to be bound during evaluation.
1020 BindingLayout& getBindingLayout() { return _bindingLayout; }
1022 BindingLayout _bindingLayout;
1025 class ExpressionParser : public Parser
1028 ParserMap& getParserMap()
1030 return ParserMapSingleton::instance()->_parserTable;
1032 static void addExpParser(const std::string&, exp_parser);
1034 struct ParserMapSingleton : public simgear::Singleton<ParserMapSingleton>
1036 ParserMap _parserTable;
1041 * Constructor for registering parser functions.
1043 struct ExpParserRegistrar
1045 ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1047 ExpressionParser::addExpParser(token, parser);
1054 * Access a variable definition. Use a location from a BindingLayout.
1056 template<typename T>
1057 class VariableExpression : public ::SGExpression<T> {
1059 VariableExpression(int location) : _location(location) {}
1060 virtual ~VariableExpression() {}
1061 virtual void eval(T& value, const simgear::expression::Binding* b) const
1063 const expression::Value* values = b->getBindings();
1064 value = *reinterpret_cast<const T *>(&values[_location].val);
1072 * An n-ary expression where the types of the argument aren't the
1073 * same as the return type.
1075 template<typename T, typename OpType>
1076 class GeneralNaryExpression : public ::SGExpression<T> {
1078 typedef OpType operand_type;
1079 unsigned getNumOperands() const
1080 { return _expressions.size(); }
1081 const ::SGExpression<OpType>* getOperand(unsigned i) const
1082 { return _expressions[i]; }
1083 ::SGExpression<OpType>* getOperand(unsigned i)
1084 { return _expressions[i]; }
1085 unsigned addOperand(::SGExpression<OpType>* expression)
1088 return ~unsigned(0);
1089 _expressions.push_back(expression);
1090 return _expressions.size() - 1;
1093 template<typename Iter>
1094 void addOperands(Iter begin, Iter end)
1096 for (Iter iter = begin; iter != end; ++iter)
1098 addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1102 virtual bool isConst() const
1104 for (unsigned i = 0; i < _expressions.size(); ++i)
1105 if (!_expressions[i]->isConst())
1109 virtual ::SGExpression<T>* simplify()
1111 for (unsigned i = 0; i < _expressions.size(); ++i)
1112 _expressions[i] = _expressions[i]->simplify();
1113 return SGExpression<T>::simplify();
1116 simgear::expression::Type getOperandType() const
1118 return simgear::expression::TypeTraits<OpType>::typeTag;
1122 GeneralNaryExpression()
1124 GeneralNaryExpression(::SGExpression<OpType>* expr0,
1125 ::SGExpression<OpType>* expr1)
1126 { addOperand(expr0); addOperand(expr1); }
1128 std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1132 * A predicate that wraps, for example the STL template predicate
1133 * expressions like std::equal_to.
1135 template<typename OpType, template<typename PredOp> class Pred>
1136 class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1138 PredicateExpression()
1141 PredicateExpression(::SGExpression<OpType>* expr0,
1142 ::SGExpression<OpType>* expr1)
1143 : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1146 virtual void eval(bool& value, const simgear::expression::Binding* b) const
1148 unsigned sz = this->getNumOperands();
1151 value = _pred(this->getOperand(0)->getValue(b),
1152 this->getOperand(1)->getValue(b));
1158 template<template<typename OT> class Pred, typename OpType>
1159 PredicateExpression<OpType, Pred>*
1160 makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1162 return new PredicateExpression<OpType, Pred>(op1, op2);
1165 template<typename OpType>
1166 class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1169 EqualToExpression() {}
1170 EqualToExpression(::SGExpression<OpType>* expr0,
1171 ::SGExpression<OpType>* expr1)
1172 : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1177 template<typename OpType>
1178 class LessExpression : public PredicateExpression<OpType, std::less>
1182 LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1183 : PredicateExpression<OpType, std::less>(expr0, expr1)
1188 template<typename OpType>
1189 class LessEqualExpression
1190 : public PredicateExpression<OpType, std::less_equal>
1193 LessEqualExpression() {}
1194 LessEqualExpression(::SGExpression<OpType>* expr0,
1195 ::SGExpression<OpType>* expr1)
1196 : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1201 class NotExpression : public ::SGUnaryExpression<bool>
1204 NotExpression(::SGExpression<bool>* expr = 0)
1205 : ::SGUnaryExpression<bool>(expr)
1208 void eval(bool& value, const expression::Binding* b) const
1210 value = !getOperand()->getValue(b);
1214 class OrExpression : public ::SGNaryExpression<bool>
1217 void eval(bool& value, const expression::Binding* b) const
1220 for (int i = 0; i < (int)getNumOperands(); ++i) {
1221 value = value || getOperand(i)->getValue(b);
1228 class AndExpression : public ::SGNaryExpression<bool>
1231 void eval(bool& value, const expression::Binding* b) const
1234 for (int i = 0; i < (int)getNumOperands(); ++i) {
1235 value = value && getOperand(i)->getValue(b);
1243 * Convert an operand from OpType to T.
1245 template<typename T, typename OpType>
1246 class ConvertExpression : public GeneralNaryExpression<T, OpType>
1249 ConvertExpression() {}
1250 ConvertExpression(::SGExpression<OpType>* expr0)
1252 this->addOperand(expr0);
1254 virtual void eval(T& value, const simgear::expression::Binding* b) const
1256 typename ConvertExpression::operand_type result;
1257 this->_expressions.at(0)->eval(result, b);
1262 #endif // _SG_EXPRESSION_HXX