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,
23 # include <simgear_config.h>
26 #include "SGExpression.hxx"
27 #include "Singleton.hxx"
34 #include <boost/bind.hpp>
35 #include <cstring> // for strcmp
37 #include <simgear/props/props.hxx>
44 const expression::Value evalValue(const Expression* exp,
45 const expression::Binding* b)
48 static_cast<const SGExpression<T>*>(exp)->eval(val, b);
49 return expression::Value(val);
52 const expression::Value eval(const Expression* exp,
53 const expression::Binding* b)
55 using namespace expression;
56 switch (exp->getType()) {
58 return evalValue<bool>(exp, b);
60 return evalValue<int>(exp, b);
62 return evalValue<float>(exp, b);
64 return evalValue<double>(exp, b);
66 throw "invalid type.";
73 SGReadValueFromString(const char* str, T& value)
76 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
80 s.str(std::string(str));
83 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
91 SGReadValueFromString(const char* str, bool& value)
94 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
98 s.str(std::string(str));
104 if (!SGReadValueFromString(str, stdstr))
107 if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
111 if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
120 SGReadValueFromContent(const SGPropertyNode *node, T& value)
124 return SGReadValueFromString(node->getStringValue(), value);
128 static SGExpression<T>*
129 SGReadExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
133 SGReadNaryOperands(SGNaryExpression<T>* nary,
134 SGPropertyNode *inputRoot, const SGPropertyNode *expression)
136 for (int i = 0; i < expression->nChildren(); ++i) {
137 SGExpression<T>* inputExpression;
138 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(i));
139 if (!inputExpression)
141 nary->addOperand(inputExpression);
146 // template<typename T>
147 // static SGExpression<T>*
148 // SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
153 // std::string name = expression->getName();
154 // if (name == "value") {
156 // if (!SGReadValueFromContent(expression, value)) {
157 // SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
160 // return new SGConstExpression<T>(value);
167 static SGExpression<T>*
168 SGReadExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
173 std::string name = expression->getName();
175 if (name == "value") {
177 if (!SGReadValueFromContent(expression, value)) {
178 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
181 return new SGConstExpression<T>(value);
184 if (name == "property") {
186 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
187 "No inputRoot argument given!");
190 if (!expression->getStringValue()) {
191 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
194 SGPropertyNode* inputNode;
195 inputNode = inputRoot->getNode(expression->getStringValue(), true);
196 return new SGPropertyExpression<T>(inputNode);
199 if (name == "abs" || name == "fabs") {
200 if (expression->nChildren() != 1) {
201 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
204 SGSharedPtr<SGExpression<T> > inputExpression;
205 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
206 if (!inputExpression) {
207 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
210 return new SGAbsExpression<T>(inputExpression);
214 if (expression->nChildren() != 1) {
215 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
218 SGSharedPtr<SGExpression<T> > inputExpression;
219 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
220 if (!inputExpression) {
221 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
224 return new SGSqrExpression<T>(inputExpression);
227 if (name == "clip") {
228 if (expression->nChildren() != 3) {
229 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
232 const SGPropertyNode* minProperty = expression->getChild("clipMin");
234 if (!SGReadValueFromContent(minProperty, clipMin))
235 clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
237 const SGPropertyNode* maxProperty = expression->getChild("clipMax");
239 if (!SGReadValueFromContent(maxProperty, clipMax))
240 clipMin = SGLimits<T>::max();
242 SGSharedPtr<SGExpression<T> > inputExpression;
243 for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
244 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(i));
245 if (!inputExpression) {
246 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
249 return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
253 if (expression->nChildren() != 2) {
254 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
257 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
258 SGReadExpression<T>(inputRoot, expression->getChild(0)),
259 SGReadExpression<T>(inputRoot, expression->getChild(1))
261 if (!inputExpressions[0] || !inputExpressions[1]) {
262 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
265 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
268 if (expression->nChildren() != 2) {
269 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
272 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
273 SGReadExpression<T>(inputRoot, expression->getChild(0)),
274 SGReadExpression<T>(inputRoot, expression->getChild(1))
276 if (!inputExpressions[0] || !inputExpressions[1]) {
277 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
280 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
284 if (expression->nChildren() < 1) {
285 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
288 SGSumExpression<T>* output = new SGSumExpression<T>;
289 if (!SGReadNaryOperands(output, inputRoot, expression)) {
291 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
297 if (name == "difference" || name == "dif" ) {
298 if (expression->nChildren() < 1) {
299 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
302 SGDifferenceExpression<T>* output = new SGDifferenceExpression<T>;
303 if (!SGReadNaryOperands(output, inputRoot, expression)) {
305 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
311 if (name == "prod" || name == "product") {
312 if (expression->nChildren() < 1) {
313 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
316 SGProductExpression<T>* output = new SGProductExpression<T>;
317 if (!SGReadNaryOperands(output, inputRoot, expression)) {
319 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
325 if (expression->nChildren() < 1) {
326 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
329 SGMinExpression<T>* output = new SGMinExpression<T>;
330 if (!SGReadNaryOperands(output, inputRoot, expression)) {
332 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
338 if (expression->nChildren() < 1) {
339 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
342 SGMaxExpression<T>* output = new SGMaxExpression<T>;
343 if (!SGReadNaryOperands(output, inputRoot, expression)) {
345 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
351 if (name == "table") {
352 SGInterpTable* tab = new SGInterpTable(expression);
354 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression: malformed table");
358 // find input expression - i.e a child not named 'entry'
359 const SGPropertyNode* inputNode = NULL;
360 for (int i=0; (i<expression->nChildren()) && !inputNode; ++i) {
361 if (strcmp(expression->getChild(i)->getName(), "entry") == 0) {
365 inputNode = expression->getChild(i);
369 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression: no input found");
373 SGSharedPtr<SGExpression<T> > inputExpression;
374 inputExpression = SGReadExpression<T>(inputRoot, inputNode);
375 if (!inputExpression) {
376 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
380 return new SGInterpTableExpression<T>(inputExpression, tab);
383 if (name == "acos") {
384 if (expression->nChildren() != 1) {
385 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
388 SGSharedPtr<SGExpression<T> > inputExpression;
389 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
390 if (!inputExpression) {
391 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
394 return new SGACosExpression<T>(inputExpression);
397 if (name == "asin") {
398 if (expression->nChildren() != 1) {
399 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
402 SGSharedPtr<SGExpression<T> > inputExpression;
403 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
404 if (!inputExpression) {
405 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
408 return new SGASinExpression<T>(inputExpression);
411 if (name == "atan") {
412 if (expression->nChildren() != 1) {
413 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
416 SGSharedPtr<SGExpression<T> > inputExpression;
417 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
418 if (!inputExpression) {
419 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
422 return new SGATanExpression<T>(inputExpression);
425 if (name == "ceil") {
426 if (expression->nChildren() != 1) {
427 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
430 SGSharedPtr<SGExpression<T> > inputExpression;
431 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
432 if (!inputExpression) {
433 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
436 return new SGCeilExpression<T>(inputExpression);
440 if (expression->nChildren() != 1) {
441 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
444 SGSharedPtr<SGExpression<T> > inputExpression;
445 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
446 if (!inputExpression) {
447 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
450 return new SGCosExpression<T>(inputExpression);
453 if (name == "cosh") {
454 if (expression->nChildren() != 1) {
455 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
458 SGSharedPtr<SGExpression<T> > inputExpression;
459 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
460 if (!inputExpression) {
461 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
464 return new SGCoshExpression<T>(inputExpression);
467 if (name == "deg2rad") {
468 if (expression->nChildren() != 1) {
469 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
472 SGSharedPtr<SGExpression<T> > inputExpression;
473 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
474 if (!inputExpression) {
475 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
478 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
482 if (expression->nChildren() != 1) {
483 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
486 SGSharedPtr<SGExpression<T> > inputExpression;
487 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
488 if (!inputExpression) {
489 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
492 return new SGExpExpression<T>(inputExpression);
495 if (name == "floor") {
496 if (expression->nChildren() != 1) {
497 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
500 SGSharedPtr<SGExpression<T> > inputExpression;
501 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
502 if (!inputExpression) {
503 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
506 return new SGFloorExpression<T>(inputExpression);
510 if (expression->nChildren() != 1) {
511 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
514 SGSharedPtr<SGExpression<T> > inputExpression;
515 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
516 if (!inputExpression) {
517 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
520 return new SGLogExpression<T>(inputExpression);
523 if (name == "log10") {
524 if (expression->nChildren() != 1) {
525 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
528 SGSharedPtr<SGExpression<T> > inputExpression;
529 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
530 if (!inputExpression) {
531 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
534 return new SGLog10Expression<T>(inputExpression);
537 if (name == "rad2deg") {
538 if (expression->nChildren() != 1) {
539 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
542 SGSharedPtr<SGExpression<T> > inputExpression;
543 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
544 if (!inputExpression) {
545 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
548 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
552 if (expression->nChildren() != 1) {
553 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
556 SGSharedPtr<SGExpression<T> > inputExpression;
557 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
558 if (!inputExpression) {
559 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
562 return new SGSinExpression<T>(inputExpression);
565 if (name == "sinh") {
566 if (expression->nChildren() != 1) {
567 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
570 SGSharedPtr<SGExpression<T> > inputExpression;
571 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
572 if (!inputExpression) {
573 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
576 return new SGSinhExpression<T>(inputExpression);
579 if (name == "sqrt") {
580 if (expression->nChildren() != 1) {
581 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
584 SGSharedPtr<SGExpression<T> > inputExpression;
585 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
586 if (!inputExpression) {
587 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
590 return new SGSqrtExpression<T>(inputExpression);
594 if (expression->nChildren() != 1) {
595 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
598 SGSharedPtr<SGExpression<T> > inputExpression;
599 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
600 if (!inputExpression) {
601 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
604 return new SGTanExpression<T>(inputExpression);
607 if (name == "tanh") {
608 if (expression->nChildren() != 1) {
609 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
612 SGSharedPtr<SGExpression<T> > inputExpression;
613 inputExpression = SGReadExpression<T>(inputRoot, expression->getChild(0));
614 if (!inputExpression) {
615 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
618 return new SGTanhExpression<T>(inputExpression);
621 // if (name == "step") {
623 // if (name == "condition") {
626 if (name == "atan2") {
627 if (expression->nChildren() != 2) {
628 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
631 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
632 SGReadExpression<T>(inputRoot, expression->getChild(0)),
633 SGReadExpression<T>(inputRoot, expression->getChild(1))
635 if (!inputExpressions[0] || !inputExpressions[1]) {
636 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
639 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
642 if (expression->nChildren() != 2) {
643 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
646 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
647 SGReadExpression<T>(inputRoot, expression->getChild(0)),
648 SGReadExpression<T>(inputRoot, expression->getChild(1))
650 if (!inputExpressions[0] || !inputExpressions[1]) {
651 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
654 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
657 if (expression->nChildren() != 2) {
658 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
661 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
662 SGReadExpression<T>(inputRoot, expression->getChild(0)),
663 SGReadExpression<T>(inputRoot, expression->getChild(1))
665 if (!inputExpressions[0] || !inputExpressions[1]) {
666 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
669 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
672 if (expression->nChildren() != 2) {
673 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
676 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
677 SGReadExpression<T>(inputRoot, expression->getChild(0)),
678 SGReadExpression<T>(inputRoot, expression->getChild(1))
680 if (!inputExpressions[0] || !inputExpressions[1]) {
681 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
684 return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
691 SGReadIntExpression(SGPropertyNode *inputRoot,
692 const SGPropertyNode *configNode)
693 { return SGReadExpression<int>(inputRoot, configNode); }
696 SGReadFloatExpression(SGPropertyNode *inputRoot,
697 const SGPropertyNode *configNode)
698 { return SGReadExpression<float>(inputRoot, configNode); }
700 SGExpression<double>*
701 SGReadDoubleExpression(SGPropertyNode *inputRoot,
702 const SGPropertyNode *configNode)
703 { return SGReadExpression<double>(inputRoot, configNode); }
705 // SGExpression<bool>*
706 // SGReadBoolExpression(SGPropertyNode *inputRoot,
707 // const SGPropertyNode *configNode)
708 // { return SGReadBExpression<bool>(inputRoot, configNode); }
715 bool Parser::readChildren(const SGPropertyNode* exp,
716 vector<Expression*>& result)
718 for (int i = 0; i < exp->nChildren(); ++i)
719 result.push_back(read(exp->getChild(i)));
723 void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
725 ParserMapSingleton::instance()
726 ->_parserTable.insert(std::make_pair(token, parsefn));
729 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
731 switch (exp->getType()) {
733 return new SGConstExpression<bool>(getValue<bool>(exp));
735 return new SGConstExpression<int>(getValue<int>(exp));
737 return new SGConstExpression<float>(getValue<float>(exp));
739 return new SGConstExpression<double>(getValue<double>(exp));
745 ExpParserRegistrar valueRegistrar("value", valueParser);
747 template<typename T, typename OpType>
748 inline Expression* makeConvert(Expression* e)
750 return new ConvertExpression<T,
751 OpType>(static_cast<SGExpression<OpType>*>(e));
754 Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
756 vector<Expression*>::iterator maxElem
757 = max_element(exps.begin(), exps.end());
758 Type maxType = (*maxElem)->getType();
759 Type resultType = minType < maxType ? maxType : minType;
760 for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
763 if ((*itr)->getType() != resultType) {
764 switch ((*itr)->getType()) {
766 switch (resultType) {
768 *itr = makeConvert<int, bool>(*itr);
771 *itr = makeConvert<float, bool>(*itr);
774 *itr = makeConvert<double, bool>(*itr);
781 switch (resultType) {
783 *itr = makeConvert<float, int>(*itr);
786 *itr = makeConvert<double, int>(*itr);
793 *itr = makeConvert<double, float>(*itr);
803 template<template<typename OpType> class Expr>
804 Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
806 switch (operandType) {
809 Expr<bool> *expr = new Expr<bool>();
810 expr->addOperands(children.begin(), children.end());
815 Expr<int> *expr = new Expr<int>();
816 expr->addOperands(children.begin(), children.end());
821 Expr<float> *expr = new Expr<float>();
822 expr->addOperands(children.begin(), children.end());
827 Expr<double> *expr = new Expr<double>();
828 expr->addOperands(children.begin(), children.end());
836 template<template<typename OpType> class PredExp>
837 Expression* predParser(const SGPropertyNode* exp, Parser* parser)
839 vector<Expression*> children;
840 parser->readChildren(exp, children);
841 Type operandType = promoteAndConvert(children);
842 return makeTypedOperandExp<PredExp>(operandType, children);
845 ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
846 ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
847 ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
849 template<typename Logicop>
850 Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
852 using namespace boost;
853 vector<Expression*> children;
854 parser->readChildren(exp, children);
855 vector<Expression*>::iterator notBool =
856 find_if(children.begin(), children.end(),
857 boost::bind(&Expression::getType, _1) != BOOL);
858 if (notBool != children.end())
859 throw("non boolean operand to logical expression");
860 Logicop *expr = new Logicop;
861 expr->addOperands(children.begin(), children.end());
865 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
866 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
868 int BindingLayout::addBinding(const string& name, Type type)
871 vector<VariableBinding>::iterator itr
872 = find_if(bindings.begin(), bindings.end(),
873 boost::bind(&VariableBinding::name, _1) == name);
874 if (itr != bindings.end())
875 return itr->location;
876 int result = bindings.size();
877 bindings.push_back(VariableBinding(name, type, bindings.size()));
881 bool BindingLayout::findBinding(const std::string& name,
882 VariableBinding& result) const
885 using namespace boost;
886 vector<VariableBinding>::const_iterator itr
887 = find_if(bindings.begin(), bindings.end(),
888 boost::bind(&VariableBinding::name, _1) == name);
889 if (itr != bindings.end()) {