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"
35 #include <boost/bind.hpp>
36 #include <cstring> // for strcmp
38 #include <simgear/props/props.hxx>
45 const expression::Value evalValue(const Expression* exp,
46 const expression::Binding* b)
49 static_cast<const SGExpression<T>*>(exp)->eval(val, b);
50 return expression::Value(val);
53 const expression::Value eval(const Expression* exp,
54 const expression::Binding* b)
56 using namespace expression;
57 switch (exp->getType()) {
59 return evalValue<bool>(exp, b);
61 return evalValue<int>(exp, b);
63 return evalValue<float>(exp, b);
65 return evalValue<double>(exp, b);
67 throw "invalid type.";
74 SGReadValueFromString(const char* str, T& value)
77 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
81 s.str(std::string(str));
84 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
92 SGReadValueFromString(const char* str, bool& value)
95 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
99 s.str(std::string(str));
105 if (!SGReadValueFromString(str, stdstr))
108 if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
112 if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
121 SGReadValueFromContent(const SGPropertyNode *node, T& value)
125 return SGReadValueFromString(node->getStringValue(), value);
129 static SGExpression<T>*
130 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
134 SGReadNaryOperands(SGNaryExpression<T>* nary,
135 SGPropertyNode *inputRoot, const SGPropertyNode *expression)
137 for (int i = 0; i < expression->nChildren(); ++i) {
138 SGExpression<T>* inputExpression;
139 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
140 if (!inputExpression)
142 nary->addOperand(inputExpression);
147 // template<typename T>
148 // static SGExpression<T>*
149 // SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
154 // std::string name = expression->getName();
155 // if (name == "value") {
157 // if (!SGReadValueFromContent(expression, value)) {
158 // SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
161 // return new SGConstExpression<T>(value);
168 static SGExpression<T>*
169 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
174 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 = SGReadIExpression<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 = SGReadIExpression<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 = SGReadIExpression<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 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
259 SGReadIExpression<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 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
274 SGReadIExpression<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 = SGReadIExpression<T>(inputRoot, inputNode);
375 if (!inputExpression) {
376 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
380 return new SGInterpTableExpression<T>(inputExpression, tab);
388 static SGExpression<T>*
389 SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
391 SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
398 std::string name = expression->getName();
399 if (name == "acos") {
400 if (expression->nChildren() != 1) {
401 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
404 SGSharedPtr<SGExpression<T> > inputExpression;
405 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
406 if (!inputExpression) {
407 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
410 return new SGACosExpression<T>(inputExpression);
413 if (name == "asin") {
414 if (expression->nChildren() != 1) {
415 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
418 SGSharedPtr<SGExpression<T> > inputExpression;
419 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
420 if (!inputExpression) {
421 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
424 return new SGASinExpression<T>(inputExpression);
427 if (name == "atan") {
428 if (expression->nChildren() != 1) {
429 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
432 SGSharedPtr<SGExpression<T> > inputExpression;
433 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
434 if (!inputExpression) {
435 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
438 return new SGATanExpression<T>(inputExpression);
441 if (name == "ceil") {
442 if (expression->nChildren() != 1) {
443 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
446 SGSharedPtr<SGExpression<T> > inputExpression;
447 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
448 if (!inputExpression) {
449 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
452 return new SGCeilExpression<T>(inputExpression);
456 if (expression->nChildren() != 1) {
457 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
460 SGSharedPtr<SGExpression<T> > inputExpression;
461 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
462 if (!inputExpression) {
463 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
466 return new SGCosExpression<T>(inputExpression);
469 if (name == "cosh") {
470 if (expression->nChildren() != 1) {
471 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
474 SGSharedPtr<SGExpression<T> > inputExpression;
475 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
476 if (!inputExpression) {
477 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
480 return new SGCoshExpression<T>(inputExpression);
483 if (name == "deg2rad") {
484 if (expression->nChildren() != 1) {
485 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
488 SGSharedPtr<SGExpression<T> > inputExpression;
489 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
490 if (!inputExpression) {
491 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
494 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
498 if (expression->nChildren() != 1) {
499 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
502 SGSharedPtr<SGExpression<T> > inputExpression;
503 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
504 if (!inputExpression) {
505 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
508 return new SGExpExpression<T>(inputExpression);
511 if (name == "floor") {
512 if (expression->nChildren() != 1) {
513 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
516 SGSharedPtr<SGExpression<T> > inputExpression;
517 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
518 if (!inputExpression) {
519 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
522 return new SGFloorExpression<T>(inputExpression);
526 if (expression->nChildren() != 1) {
527 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
530 SGSharedPtr<SGExpression<T> > inputExpression;
531 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
532 if (!inputExpression) {
533 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
536 return new SGLogExpression<T>(inputExpression);
539 if (name == "log10") {
540 if (expression->nChildren() != 1) {
541 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
544 SGSharedPtr<SGExpression<T> > inputExpression;
545 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
546 if (!inputExpression) {
547 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
550 return new SGLog10Expression<T>(inputExpression);
553 if (name == "rad2deg") {
554 if (expression->nChildren() != 1) {
555 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
558 SGSharedPtr<SGExpression<T> > inputExpression;
559 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
560 if (!inputExpression) {
561 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
564 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
568 if (expression->nChildren() != 1) {
569 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
572 SGSharedPtr<SGExpression<T> > inputExpression;
573 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
574 if (!inputExpression) {
575 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
578 return new SGSinExpression<T>(inputExpression);
581 if (name == "sinh") {
582 if (expression->nChildren() != 1) {
583 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
586 SGSharedPtr<SGExpression<T> > inputExpression;
587 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
588 if (!inputExpression) {
589 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
592 return new SGSinhExpression<T>(inputExpression);
595 if (name == "sqrt") {
596 if (expression->nChildren() != 1) {
597 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
600 SGSharedPtr<SGExpression<T> > inputExpression;
601 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
602 if (!inputExpression) {
603 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
606 return new SGSqrtExpression<T>(inputExpression);
610 if (expression->nChildren() != 1) {
611 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
614 SGSharedPtr<SGExpression<T> > inputExpression;
615 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
616 if (!inputExpression) {
617 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
620 return new SGTanExpression<T>(inputExpression);
623 if (name == "tanh") {
624 if (expression->nChildren() != 1) {
625 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
628 SGSharedPtr<SGExpression<T> > inputExpression;
629 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
630 if (!inputExpression) {
631 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
634 return new SGTanhExpression<T>(inputExpression);
637 // if (name == "step") {
639 // if (name == "condition") {
642 if (name == "atan2") {
643 if (expression->nChildren() != 2) {
644 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
647 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
648 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
649 SGReadFExpression<T>(inputRoot, expression->getChild(1))
651 if (!inputExpressions[0] || !inputExpressions[1]) {
652 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
655 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
658 if (expression->nChildren() != 2) {
659 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
662 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
663 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
664 SGReadFExpression<T>(inputRoot, expression->getChild(1))
666 if (!inputExpressions[0] || !inputExpressions[1]) {
667 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
670 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
673 if (expression->nChildren() != 2) {
674 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
677 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
678 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
679 SGReadFExpression<T>(inputRoot, expression->getChild(1))
681 if (!inputExpressions[0] || !inputExpressions[1]) {
682 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
685 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
688 if (expression->nChildren() != 2) {
689 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
692 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
693 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
694 SGReadIExpression<T>(inputRoot, expression->getChild(1))
696 if (!inputExpressions[0] || !inputExpressions[1]) {
697 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
700 return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
707 SGReadIntExpression(SGPropertyNode *inputRoot,
708 const SGPropertyNode *configNode)
709 { return SGReadIExpression<int>(inputRoot, configNode); }
712 SGReadFloatExpression(SGPropertyNode *inputRoot,
713 const SGPropertyNode *configNode)
714 { return SGReadFExpression<float>(inputRoot, configNode); }
716 SGExpression<double>*
717 SGReadDoubleExpression(SGPropertyNode *inputRoot,
718 const SGPropertyNode *configNode)
719 { return SGReadFExpression<double>(inputRoot, configNode); }
721 // SGExpression<bool>*
722 // SGReadBoolExpression(SGPropertyNode *inputRoot,
723 // const SGPropertyNode *configNode)
724 // { return SGReadBExpression<bool>(inputRoot, configNode); }
731 bool Parser::readChildren(const SGPropertyNode* exp,
732 vector<Expression*>& result)
734 for (int i = 0; i < exp->nChildren(); ++i)
735 result.push_back(read(exp->getChild(i)));
739 void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
741 ParserMapSingleton::instance()
742 ->_parserTable.insert(std::make_pair(token, parsefn));
745 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
747 switch (exp->getType()) {
749 return new SGConstExpression<bool>(getValue<bool>(exp));
751 return new SGConstExpression<int>(getValue<int>(exp));
753 return new SGConstExpression<float>(getValue<float>(exp));
755 return new SGConstExpression<double>(getValue<double>(exp));
761 ExpParserRegistrar valueRegistrar("value", valueParser);
763 template<typename T, typename OpType>
764 inline Expression* makeConvert(Expression* e)
766 return new ConvertExpression<T,
767 OpType>(static_cast<SGExpression<OpType>*>(e));
770 Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
772 vector<Expression*>::iterator maxElem
773 = max_element(exps.begin(), exps.end());
774 Type maxType = (*maxElem)->getType();
775 Type resultType = minType < maxType ? maxType : minType;
776 for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
779 if ((*itr)->getType() != resultType) {
780 switch ((*itr)->getType()) {
782 switch (resultType) {
784 *itr = makeConvert<int, bool>(*itr);
787 *itr = makeConvert<float, bool>(*itr);
790 *itr = makeConvert<double, bool>(*itr);
797 switch (resultType) {
799 *itr = makeConvert<float, int>(*itr);
802 *itr = makeConvert<double, int>(*itr);
809 *itr = makeConvert<double, float>(*itr);
819 template<template<typename OpType> class Expr>
820 Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
822 switch (operandType) {
825 Expr<bool> *expr = new Expr<bool>();
826 expr->addOperands(children.begin(), children.end());
831 Expr<int> *expr = new Expr<int>();
832 expr->addOperands(children.begin(), children.end());
837 Expr<float> *expr = new Expr<float>();
838 expr->addOperands(children.begin(), children.end());
843 Expr<double> *expr = new Expr<double>();
844 expr->addOperands(children.begin(), children.end());
852 template<template<typename OpType> class PredExp>
853 Expression* predParser(const SGPropertyNode* exp, Parser* parser)
855 vector<Expression*> children;
856 parser->readChildren(exp, children);
857 Type operandType = promoteAndConvert(children);
858 return makeTypedOperandExp<PredExp>(operandType, children);
861 ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
862 ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
863 ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
865 template<typename Logicop>
866 Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
868 using namespace boost;
869 vector<Expression*> children;
870 parser->readChildren(exp, children);
871 vector<Expression*>::iterator notBool =
872 find_if(children.begin(), children.end(),
873 boost::bind(&Expression::getType, _1) != BOOL);
874 if (notBool != children.end())
875 throw("non boolean operand to logical expression");
876 Logicop *expr = new Logicop;
877 expr->addOperands(children.begin(), children.end());
881 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
882 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
884 int BindingLayout::addBinding(const string& name, Type type)
887 vector<VariableBinding>::iterator itr
888 = find_if(bindings.begin(), bindings.end(),
889 boost::bind(&VariableBinding::name, _1) == name);
890 if (itr != bindings.end())
891 return itr->location;
892 int result = bindings.size();
893 bindings.push_back(VariableBinding(name, type, bindings.size()));
897 bool BindingLayout::findBinding(const std::string& name,
898 VariableBinding& result) const
901 using namespace boost;
902 vector<VariableBinding>::const_iterator itr
903 = find_if(bindings.begin(), bindings.end(),
904 boost::bind(&VariableBinding::name, _1) == name);
905 if (itr != bindings.end()) {