- if (!expression)
- return 0;
+ if (!expression)
+ return 0;
+
+ std::string name = expression->getName();
+ if (name == "value") {
+ T value;
+ if (!SGReadValueFromContent(expression, value)) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
+ return 0;
+ }
+ return new SGConstExpression<T>(value);
+ }
+
+ if (name == "property") {
+ if (!inputRoot) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
+ "No inputRoot argument given!");
+ return 0;
+ }
+ if (!expression->getStringValue()) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGPropertyNode* inputNode;
+ inputNode = inputRoot->getNode(expression->getStringValue(), true);
+ return new SGPropertyExpression<T>(inputNode);
+ }
+
+ if (name == "abs" || name == "fabs") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGAbsExpression<T>(inputExpression);
+ }
+
+ if (name == "sqr") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGSqrExpression<T>(inputExpression);
+ }
+
+ if (name == "clip") {
+ if (expression->nChildren() != 3) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ const SGPropertyNode* minProperty = expression->getChild("clipMin");
+ T clipMin;
+ if (!SGReadValueFromContent(minProperty, clipMin))
+ clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
+
+ const SGPropertyNode* maxProperty = expression->getChild("clipMax");
+ T clipMax;
+ if (!SGReadValueFromContent(maxProperty, clipMax))
+ clipMin = SGLimits<T>::max();
+
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
+ inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
+ }
+
+ if (name == "div") {
+ if (expression->nChildren() != 2) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
+ SGReadIExpression<T>(inputRoot, expression->getChild(0)),
+ SGReadIExpression<T>(inputRoot, expression->getChild(1))
+ };
+ if (!inputExpressions[0] || !inputExpressions[1]) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
+ }
+ if (name == "mod") {
+ if (expression->nChildren() != 2) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
+ SGReadIExpression<T>(inputRoot, expression->getChild(0)),
+ SGReadIExpression<T>(inputRoot, expression->getChild(1))
+ };
+ if (!inputExpressions[0] || !inputExpressions[1]) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
+ }
+
+ if (name == "sum") {
+ if (expression->nChildren() < 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSumExpression<T>* output = new SGSumExpression<T>;
+ if (!SGReadNaryOperands(output, inputRoot, expression)) {
+ delete output;
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return output;
+ }
+ if (name == "prod" || name == "product") {
+ if (expression->nChildren() < 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGProductExpression<T>* output = new SGProductExpression<T>;
+ if (!SGReadNaryOperands(output, inputRoot, expression)) {
+ delete output;
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return output;
+ }
+ if (name == "min") {
+ if (expression->nChildren() < 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGMinExpression<T>* output = new SGMinExpression<T>;
+ if (!SGReadNaryOperands(output, inputRoot, expression)) {
+ delete output;
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return output;
+ }
+ if (name == "max") {
+ if (expression->nChildren() < 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGMaxExpression<T>* output = new SGMaxExpression<T>;
+ if (!SGReadNaryOperands(output, inputRoot, expression)) {
+ delete output;
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return output;
+ }
- std::string name = expression->getName();
- if (name == "value") {
- T value;
- if (!SGReadValueFromContent(expression, value)) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
- return 0;
- }
- return new SGConstExpression<T>(value);
- }
-
- if (name == "property") {
- if (!inputRoot) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
- "No inputRoot argument given!");
- return 0;
- }
- if (!expression->getStringValue()) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGPropertyNode* inputNode;
- inputNode = inputRoot->getNode(expression->getStringValue(), true);
- return new SGPropertyExpression<T>(inputNode);
- }
-
- if (name == "abs" || name == "fabs") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGAbsExpression<T>(inputExpression);
- }
-
- if (name == "sqr") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGSqrExpression<T>(inputExpression);
- }
-
- if (name == "clip") {
- if (expression->nChildren() != 3) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- const SGPropertyNode* minProperty = expression->getChild("clipMin");
- T clipMin;
- if (!SGReadValueFromContent(minProperty, clipMin))
- clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
-
- const SGPropertyNode* maxProperty = expression->getChild("clipMax");
- T clipMax;
- if (!SGReadValueFromContent(maxProperty, clipMax))
- clipMin = SGLimits<T>::max();
-
- SGSharedPtr<SGExpression<T> > inputExpression;
- for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
- inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
- }
-
- if (name == "div") {
- if (expression->nChildren() != 2) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
- SGReadIExpression<T>(inputRoot, expression->getChild(0)),
- SGReadIExpression<T>(inputRoot, expression->getChild(1))
- };
- if (!inputExpressions[0] || !inputExpressions[1]) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
- }
- if (name == "mod") {
- if (expression->nChildren() != 2) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
- SGReadIExpression<T>(inputRoot, expression->getChild(0)),
- SGReadIExpression<T>(inputRoot, expression->getChild(1))
- };
- if (!inputExpressions[0] || !inputExpressions[1]) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
- }
-
- if (name == "sum") {
- if (expression->nChildren() < 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSumExpression<T>* output = new SGSumExpression<T>;
- if (!SGReadNaryOperands(output, inputRoot, expression)) {
- delete output;
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return output;
- }
- if (name == "prod" || name == "product") {
- if (expression->nChildren() < 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGProductExpression<T>* output = new SGProductExpression<T>;
- if (!SGReadNaryOperands(output, inputRoot, expression)) {
- delete output;
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return output;
- }
- if (name == "min") {
- if (expression->nChildren() < 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGMinExpression<T>* output = new SGMinExpression<T>;
- if (!SGReadNaryOperands(output, inputRoot, expression)) {
- delete output;
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return output;
- }
- if (name == "max") {
- if (expression->nChildren() < 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGMaxExpression<T>* output = new SGMaxExpression<T>;
- if (!SGReadNaryOperands(output, inputRoot, expression)) {
- delete output;
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return output;
- }
-
- return 0;
- SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
- if (r)
- return r;
-
- if (!expression)
- return 0;
-
- std::string name = expression->getName();
- if (name == "acos") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGACosExpression<T>(inputExpression);
- }
-
- if (name == "asin") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGASinExpression<T>(inputExpression);
- }
-
- if (name == "atan") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGATanExpression<T>(inputExpression);
- }
-
- if (name == "ceil") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGCeilExpression<T>(inputExpression);
- }
-
- if (name == "cos") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGCosExpression<T>(inputExpression);
- }
-
- if (name == "cosh") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGCoshExpression<T>(inputExpression);
- }
-
- if (name == "deg2rad") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
- }
-
- if (name == "exp") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGExpExpression<T>(inputExpression);
- }
-
- if (name == "floor") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGFloorExpression<T>(inputExpression);
- }
-
- if (name == "log") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGLogExpression<T>(inputExpression);
- }
-
- if (name == "log10") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGLog10Expression<T>(inputExpression);
- }
-
- if (name == "rad2deg") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
- }
-
- if (name == "sin") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGSinExpression<T>(inputExpression);
- }
-
- if (name == "sinh") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGSinhExpression<T>(inputExpression);
- }
-
- if (name == "sqrt") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGSqrtExpression<T>(inputExpression);
- }
-
- if (name == "tan") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGTanExpression<T>(inputExpression);
- }
-
- if (name == "tanh") {
- if (expression->nChildren() != 1) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpression;
- inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
- if (!inputExpression) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGTanhExpression<T>(inputExpression);
- }
+ SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
+ if (r)
+ return r;
+
+ if (!expression)
+ return 0;
+
+ std::string name = expression->getName();
+ if (name == "acos") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGACosExpression<T>(inputExpression);
+ }
+
+ if (name == "asin") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGASinExpression<T>(inputExpression);
+ }
+
+ if (name == "atan") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGATanExpression<T>(inputExpression);
+ }
+
+ if (name == "ceil") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGCeilExpression<T>(inputExpression);
+ }
+
+ if (name == "cos") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGCosExpression<T>(inputExpression);
+ }
+
+ if (name == "cosh") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGCoshExpression<T>(inputExpression);
+ }
+
+ if (name == "deg2rad") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
+ }
+
+ if (name == "exp") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGExpExpression<T>(inputExpression);
+ }
+
+ if (name == "floor") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGFloorExpression<T>(inputExpression);
+ }
+
+ if (name == "log") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGLogExpression<T>(inputExpression);
+ }
+
+ if (name == "log10") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGLog10Expression<T>(inputExpression);
+ }
+
+ if (name == "rad2deg") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
+ }
+
+ if (name == "sin") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGSinExpression<T>(inputExpression);
+ }
+
+ if (name == "sinh") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGSinhExpression<T>(inputExpression);
+ }
+
+ if (name == "sqrt") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGSqrtExpression<T>(inputExpression);
+ }
+
+ if (name == "tan") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGTanExpression<T>(inputExpression);
+ }
+
+ if (name == "tanh") {
+ if (expression->nChildren() != 1) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpression;
+ inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
+ if (!inputExpression) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGTanhExpression<T>(inputExpression);
+ }
- if (name == "atan2") {
- if (expression->nChildren() != 2) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
- SGReadFExpression<T>(inputRoot, expression->getChild(0)),
- SGReadFExpression<T>(inputRoot, expression->getChild(1))
- };
- if (!inputExpressions[0] || !inputExpressions[1]) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
- }
- if (name == "div") {
- if (expression->nChildren() != 2) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
- SGReadFExpression<T>(inputRoot, expression->getChild(0)),
- SGReadFExpression<T>(inputRoot, expression->getChild(1))
- };
- if (!inputExpressions[0] || !inputExpressions[1]) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
- }
- if (name == "mod") {
- if (expression->nChildren() != 2) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
- SGReadFExpression<T>(inputRoot, expression->getChild(0)),
- SGReadFExpression<T>(inputRoot, expression->getChild(1))
- };
- if (!inputExpressions[0] || !inputExpressions[1]) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
- }
- if (name == "pow") {
- if (expression->nChildren() != 2) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
- SGReadIExpression<T>(inputRoot, expression->getChild(0)),
- SGReadIExpression<T>(inputRoot, expression->getChild(1))
- };
- if (!inputExpressions[0] || !inputExpressions[1]) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
- return 0;
- }
- return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
- }
-
- return 0;
+ if (name == "atan2") {
+ if (expression->nChildren() != 2) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
+ SGReadFExpression<T>(inputRoot, expression->getChild(0)),
+ SGReadFExpression<T>(inputRoot, expression->getChild(1))
+ };
+ if (!inputExpressions[0] || !inputExpressions[1]) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
+ }
+ if (name == "div") {
+ if (expression->nChildren() != 2) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
+ SGReadFExpression<T>(inputRoot, expression->getChild(0)),
+ SGReadFExpression<T>(inputRoot, expression->getChild(1))
+ };
+ if (!inputExpressions[0] || !inputExpressions[1]) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
+ }
+ if (name == "mod") {
+ if (expression->nChildren() != 2) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
+ SGReadFExpression<T>(inputRoot, expression->getChild(0)),
+ SGReadFExpression<T>(inputRoot, expression->getChild(1))
+ };
+ if (!inputExpressions[0] || !inputExpressions[1]) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
+ }
+ if (name == "pow") {
+ if (expression->nChildren() != 2) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
+ SGReadIExpression<T>(inputRoot, expression->getChild(0)),
+ SGReadIExpression<T>(inputRoot, expression->getChild(1))
+ };
+ if (!inputExpressions[0] || !inputExpressions[1]) {
+ SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+ return 0;
+ }
+ return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
+ }
+
+ return 0;
+
+namespace simgear
+{
+namespace expression
+{
+
+bool Parser::readChildren(const SGPropertyNode* exp,
+ vector<Expression*>& result)
+{
+ for (int i = 0; i < exp->nChildren(); ++i)
+ result.push_back(read(exp->getChild(i)));
+ return true;
+}
+
+Parser::ParserMap ExpressionParser::_parserTable;
+
+void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
+{
+ _parserTable.insert(std::make_pair(token, parsefn));
+}
+
+Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
+{
+ switch (exp->getType()) {
+ case props::BOOL:
+ return new SGConstExpression<bool>(getValue<bool>(exp));
+ case props::INT:
+ return new SGConstExpression<int>(getValue<int>(exp));
+ case props::FLOAT:
+ return new SGConstExpression<float>(getValue<float>(exp));
+ case props::DOUBLE:
+ return new SGConstExpression<double>(getValue<double>(exp));
+ default:
+ return 0;
+ }
+}
+
+ExpParserRegistrar valueRegistrar("value", valueParser);
+
+template<typename T, typename OpType>
+inline Expression* makeConvert(Expression* e)
+{
+ return new ConvertExpression<T,
+ OpType>(static_cast<SGExpression<OpType>*>(e));
+}
+
+Type promoteAndConvert(vector<Expression*>& exps, Type minType = BOOL)
+{
+ vector<Expression*>::iterator maxElem
+ = max_element(exps.begin(), exps.end());
+ Type maxType = (*maxElem)->getType();
+ Type resultType = minType < maxType ? maxType : minType;
+ for (vector<Expression*>::iterator itr = exps.begin(), end = exps.end();
+ itr != end;
+ ++itr) {
+ if ((*itr)->getType() != resultType) {
+ switch ((*itr)->getType()) {
+ case BOOL:
+ switch (resultType) {
+ case INT:
+ *itr = makeConvert<int, bool>(*itr);
+ break;
+ case FLOAT:
+ *itr = makeConvert<float, bool>(*itr);
+ break;
+ case DOUBLE:
+ *itr = makeConvert<double, bool>(*itr);
+ break;
+ default:
+ break;
+ }
+ break;
+ case INT:
+ switch (resultType) {
+ case FLOAT:
+ *itr = makeConvert<float, int>(*itr);
+ break;
+ case DOUBLE:
+ *itr = makeConvert<double, int>(*itr);
+ break;
+ default:
+ break;
+ }
+ break;
+ case FLOAT:
+ *itr = makeConvert<double, float>(*itr);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return resultType;
+}
+
+template<template<typename OpType> class Expr>
+Expression* makeTypedOperandExp(Type operandType, vector<Expression*> children)
+{
+ switch (operandType) {
+ case BOOL:
+ {
+ Expr<bool> *expr = new Expr<bool>();
+ expr->addOperands(children.begin(), children.end());
+ return expr;
+ }
+ case INT:
+ {
+ Expr<int> *expr = new Expr<int>();
+ expr->addOperands(children.begin(), children.end());
+ return expr;
+ }
+ case FLOAT:
+ {
+ Expr<float> *expr = new Expr<float>();
+ expr->addOperands(children.begin(), children.end());
+ return expr;
+ }
+ case DOUBLE:
+ {
+ Expr<double> *expr = new Expr<double>();
+ expr->addOperands(children.begin(), children.end());
+ return expr;
+ }
+ default:
+ return 0;
+ }
+}
+
+template<template<typename OpType> class PredExp>
+Expression* predParser(const SGPropertyNode* exp, Parser* parser)
+{
+ vector<Expression*> children;
+ parser->readChildren(exp, children);
+ Type operandType = promoteAndConvert(children);
+ return makeTypedOperandExp<PredExp>(operandType, children);
+}
+
+ExpParserRegistrar equalRegistrar("equal", predParser<EqualToExpression>);
+ExpParserRegistrar lessRegistrar("less", predParser<LessExpression>);
+ExpParserRegistrar leRegistrar("less-equal", predParser<LessEqualExpression>);
+
+template<typename Logicop>
+Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
+{
+ using namespace boost;
+ vector<Expression*> children;
+ parser->readChildren(exp, children);
+ vector<Expression*>::iterator notBool =
+ find_if(children.begin(), children.end(),
+ bind(&Expression::getType, _1) != BOOL);
+ if (notBool != children.end())
+ throw("non boolean operand to logical expression");
+ Logicop *expr = new Logicop;
+ expr->addOperands(children.begin(), children.end());
+ return expr;
+}
+
+ExpParserRegistrar andRegistrar("and", logicopParser<AndExpression>);
+ExpParserRegistrar orRegistrar("or", logicopParser<OrExpression>);
+
+int BindingLayout::addBinding(const string& name, Type type)
+{
+ //XXX error checkint
+ vector<VariableBinding>::iterator itr
+ = find_if(bindings.begin(), bindings.end(),
+ bind(&VariableBinding::name, _1) == name);
+ if (itr != bindings.end())
+ return itr->location;
+ int result = bindings.size();
+ bindings.push_back(VariableBinding(name, type, bindings.size()));
+ return result;
+}
+
+bool BindingLayout::findBinding(const std::string& name,
+ VariableBinding& result) const
+{
+ using namespace std;
+ using namespace boost;
+ vector<VariableBinding>::const_iterator itr
+ = find_if(bindings.begin(), bindings.end(),
+ bind(&VariableBinding::name, _1) == name);
+ if (itr != bindings.end()) {
+ result = *itr;
+ return true;
+ } else {
+ return false;
+ }
+}
+}
+}