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>
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 SGReadIExpression(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 = SGReadIExpression<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 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
173 std::string name = expression->getName();
174 if (name == "value") {
176 if (!SGReadValueFromContent(expression, value)) {
177 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
180 return new SGConstExpression<T>(value);
183 if (name == "property") {
185 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
186 "No inputRoot argument given!");
189 if (!expression->getStringValue()) {
190 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
193 SGPropertyNode* inputNode;
194 inputNode = inputRoot->getNode(expression->getStringValue(), true);
195 return new SGPropertyExpression<T>(inputNode);
198 if (name == "abs" || name == "fabs") {
199 if (expression->nChildren() != 1) {
200 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
203 SGSharedPtr<SGExpression<T> > inputExpression;
204 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
205 if (!inputExpression) {
206 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
209 return new SGAbsExpression<T>(inputExpression);
213 if (expression->nChildren() != 1) {
214 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
217 SGSharedPtr<SGExpression<T> > inputExpression;
218 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
219 if (!inputExpression) {
220 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
223 return new SGSqrExpression<T>(inputExpression);
226 if (name == "clip") {
227 if (expression->nChildren() != 3) {
228 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
231 const SGPropertyNode* minProperty = expression->getChild("clipMin");
233 if (!SGReadValueFromContent(minProperty, clipMin))
234 clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
236 const SGPropertyNode* maxProperty = expression->getChild("clipMax");
238 if (!SGReadValueFromContent(maxProperty, clipMax))
239 clipMin = SGLimits<T>::max();
241 SGSharedPtr<SGExpression<T> > inputExpression;
242 for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
243 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
244 if (!inputExpression) {
245 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
248 return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
252 if (expression->nChildren() != 2) {
253 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
256 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
257 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
258 SGReadIExpression<T>(inputRoot, expression->getChild(1))
260 if (!inputExpressions[0] || !inputExpressions[1]) {
261 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
264 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
267 if (expression->nChildren() != 2) {
268 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
271 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
272 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
273 SGReadIExpression<T>(inputRoot, expression->getChild(1))
275 if (!inputExpressions[0] || !inputExpressions[1]) {
276 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
279 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
283 if (expression->nChildren() < 1) {
284 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
287 SGSumExpression<T>* output = new SGSumExpression<T>;
288 if (!SGReadNaryOperands(output, inputRoot, expression)) {
290 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
295 if (name == "prod" || name == "product") {
296 if (expression->nChildren() < 1) {
297 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
300 SGProductExpression<T>* output = new SGProductExpression<T>;
301 if (!SGReadNaryOperands(output, inputRoot, expression)) {
303 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
309 if (expression->nChildren() < 1) {
310 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
313 SGMinExpression<T>* output = new SGMinExpression<T>;
314 if (!SGReadNaryOperands(output, inputRoot, expression)) {
316 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
322 if (expression->nChildren() < 1) {
323 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
326 SGMaxExpression<T>* output = new SGMaxExpression<T>;
327 if (!SGReadNaryOperands(output, inputRoot, expression)) {
329 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
340 static SGExpression<T>*
341 SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
343 SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
350 std::string name = expression->getName();
351 if (name == "acos") {
352 if (expression->nChildren() != 1) {
353 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
356 SGSharedPtr<SGExpression<T> > inputExpression;
357 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
358 if (!inputExpression) {
359 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
362 return new SGACosExpression<T>(inputExpression);
365 if (name == "asin") {
366 if (expression->nChildren() != 1) {
367 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
370 SGSharedPtr<SGExpression<T> > inputExpression;
371 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
372 if (!inputExpression) {
373 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
376 return new SGASinExpression<T>(inputExpression);
379 if (name == "atan") {
380 if (expression->nChildren() != 1) {
381 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
384 SGSharedPtr<SGExpression<T> > inputExpression;
385 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
386 if (!inputExpression) {
387 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
390 return new SGATanExpression<T>(inputExpression);
393 if (name == "ceil") {
394 if (expression->nChildren() != 1) {
395 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
398 SGSharedPtr<SGExpression<T> > inputExpression;
399 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
400 if (!inputExpression) {
401 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
404 return new SGCeilExpression<T>(inputExpression);
408 if (expression->nChildren() != 1) {
409 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
412 SGSharedPtr<SGExpression<T> > inputExpression;
413 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
414 if (!inputExpression) {
415 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
418 return new SGCosExpression<T>(inputExpression);
421 if (name == "cosh") {
422 if (expression->nChildren() != 1) {
423 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
426 SGSharedPtr<SGExpression<T> > inputExpression;
427 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
428 if (!inputExpression) {
429 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
432 return new SGCoshExpression<T>(inputExpression);
435 if (name == "deg2rad") {
436 if (expression->nChildren() != 1) {
437 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
440 SGSharedPtr<SGExpression<T> > inputExpression;
441 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
442 if (!inputExpression) {
443 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
446 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
450 if (expression->nChildren() != 1) {
451 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
454 SGSharedPtr<SGExpression<T> > inputExpression;
455 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
456 if (!inputExpression) {
457 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
460 return new SGExpExpression<T>(inputExpression);
463 if (name == "floor") {
464 if (expression->nChildren() != 1) {
465 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
468 SGSharedPtr<SGExpression<T> > inputExpression;
469 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
470 if (!inputExpression) {
471 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
474 return new SGFloorExpression<T>(inputExpression);
478 if (expression->nChildren() != 1) {
479 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
482 SGSharedPtr<SGExpression<T> > inputExpression;
483 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
484 if (!inputExpression) {
485 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
488 return new SGLogExpression<T>(inputExpression);
491 if (name == "log10") {
492 if (expression->nChildren() != 1) {
493 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
496 SGSharedPtr<SGExpression<T> > inputExpression;
497 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
498 if (!inputExpression) {
499 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
502 return new SGLog10Expression<T>(inputExpression);
505 if (name == "rad2deg") {
506 if (expression->nChildren() != 1) {
507 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
510 SGSharedPtr<SGExpression<T> > inputExpression;
511 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
512 if (!inputExpression) {
513 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
516 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
520 if (expression->nChildren() != 1) {
521 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
524 SGSharedPtr<SGExpression<T> > inputExpression;
525 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
526 if (!inputExpression) {
527 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
530 return new SGSinExpression<T>(inputExpression);
533 if (name == "sinh") {
534 if (expression->nChildren() != 1) {
535 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
538 SGSharedPtr<SGExpression<T> > inputExpression;
539 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
540 if (!inputExpression) {
541 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
544 return new SGSinhExpression<T>(inputExpression);
547 if (name == "sqrt") {
548 if (expression->nChildren() != 1) {
549 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
552 SGSharedPtr<SGExpression<T> > inputExpression;
553 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
554 if (!inputExpression) {
555 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
558 return new SGSqrtExpression<T>(inputExpression);
562 if (expression->nChildren() != 1) {
563 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
566 SGSharedPtr<SGExpression<T> > inputExpression;
567 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
568 if (!inputExpression) {
569 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
572 return new SGTanExpression<T>(inputExpression);
575 if (name == "tanh") {
576 if (expression->nChildren() != 1) {
577 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
580 SGSharedPtr<SGExpression<T> > inputExpression;
581 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
582 if (!inputExpression) {
583 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
586 return new SGTanhExpression<T>(inputExpression);
589 // if (name == "table") {
591 // if (name == "step") {
593 // if (name == "condition") {
596 if (name == "atan2") {
597 if (expression->nChildren() != 2) {
598 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
601 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
602 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
603 SGReadFExpression<T>(inputRoot, expression->getChild(1))
605 if (!inputExpressions[0] || !inputExpressions[1]) {
606 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
609 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
612 if (expression->nChildren() != 2) {
613 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
616 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
617 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
618 SGReadFExpression<T>(inputRoot, expression->getChild(1))
620 if (!inputExpressions[0] || !inputExpressions[1]) {
621 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
624 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
627 if (expression->nChildren() != 2) {
628 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
631 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
632 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
633 SGReadFExpression<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 SGModExpression<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 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
648 SGReadIExpression<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 SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
661 SGReadIntExpression(SGPropertyNode *inputRoot,
662 const SGPropertyNode *configNode)
663 { return SGReadIExpression<int>(inputRoot, configNode); }
666 SGReadFloatExpression(SGPropertyNode *inputRoot,
667 const SGPropertyNode *configNode)
668 { return SGReadFExpression<float>(inputRoot, configNode); }
670 SGExpression<double>*
671 SGReadDoubleExpression(SGPropertyNode *inputRoot,
672 const SGPropertyNode *configNode)
673 { return SGReadFExpression<double>(inputRoot, configNode); }
675 // SGExpression<bool>*
676 // SGReadBoolExpression(SGPropertyNode *inputRoot,
677 // const SGPropertyNode *configNode)
678 // { return SGReadBExpression<bool>(inputRoot, configNode); }
685 bool Parser::readChildren(const SGPropertyNode* exp,
686 vector<Expression*>& result)
688 for (int i = 0; i < exp->nChildren(); ++i)
689 result.push_back(read(exp->getChild(i)));
693 void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
695 ParserMapSingleton::instance()
696 ->_parserTable.insert(std::make_pair(token, parsefn));
699 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
701 switch (exp->getType()) {
703 return new SGConstExpression<bool>(getValue<bool>(exp));
705 return new SGConstExpression<int>(getValue<int>(exp));
707 return new SGConstExpression<float>(getValue<float>(exp));
709 return new SGConstExpression<double>(getValue<double>(exp));
715 ExpParserRegistrar valueRegistrar("value", valueParser);
717 template<typename T, typename OpType>
718 inline Expression* makeConvert(Expression* e)
720 return new ConvertExpression<T,
721 OpType>(static_cast<SGExpression<OpType>*>(e));
724 Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
726 vector<Expression*>::iterator maxElem
727 = max_element(exps.begin(), exps.end());
728 Type maxType = (*maxElem)->getType();
729 Type resultType = minType < maxType ? maxType : minType;
730 for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
733 if ((*itr)->getType() != resultType) {
734 switch ((*itr)->getType()) {
736 switch (resultType) {
738 *itr = makeConvert<int, bool>(*itr);
741 *itr = makeConvert<float, bool>(*itr);
744 *itr = makeConvert<double, bool>(*itr);
751 switch (resultType) {
753 *itr = makeConvert<float, int>(*itr);
756 *itr = makeConvert<double, int>(*itr);
763 *itr = makeConvert<double, float>(*itr);
773 template<template<typename OpType> class Expr>
774 Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
776 switch (operandType) {
779 Expr<bool> *expr = new Expr<bool>();
780 expr->addOperands(children.begin(), children.end());
785 Expr<int> *expr = new Expr<int>();
786 expr->addOperands(children.begin(), children.end());
791 Expr<float> *expr = new Expr<float>();
792 expr->addOperands(children.begin(), children.end());
797 Expr<double> *expr = new Expr<double>();
798 expr->addOperands(children.begin(), children.end());
806 template<template<typename OpType> class PredExp>
807 Expression* predParser(const SGPropertyNode* exp, Parser* parser)
809 vector<Expression*> children;
810 parser->readChildren(exp, children);
811 Type operandType = promoteAndConvert(children);
812 return makeTypedOperandExp<PredExp>(operandType, children);
815 ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
816 ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
817 ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
819 template<typename Logicop>
820 Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
822 using namespace boost;
823 vector<Expression*> children;
824 parser->readChildren(exp, children);
825 vector<Expression*>::iterator notBool =
826 find_if(children.begin(), children.end(),
827 bind(&Expression::getType, _1) != BOOL);
828 if (notBool != children.end())
829 throw("non boolean operand to logical expression");
830 Logicop *expr = new Logicop;
831 expr->addOperands(children.begin(), children.end());
835 ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
836 ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
838 int BindingLayout::addBinding(const string& name, Type type)
841 vector<VariableBinding>::iterator itr
842 = find_if(bindings.begin(), bindings.end(),
843 bind(&VariableBinding::name, _1) == name);
844 if (itr != bindings.end())
845 return itr->location;
846 int result = bindings.size();
847 bindings.push_back(VariableBinding(name, type, bindings.size()));
851 bool BindingLayout::findBinding(const std::string& name,
852 VariableBinding& result) const
855 using namespace boost;
856 vector<VariableBinding>::const_iterator itr
857 = find_if(bindings.begin(), bindings.end(),
858 bind(&VariableBinding::name, _1) == name);
859 if (itr != bindings.end()) {