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"
30 #include <simgear/props/props.hxx>
34 SGReadValueFromString(const char* str, T& value)
37 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
41 s.str(std::string(str));
44 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
52 SGReadValueFromString(const char* str, bool& value)
55 SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
59 s.str(std::string(str));
65 if (!SGReadValueFromString(str, stdstr))
68 if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
72 if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
81 SGReadValueFromContent(const SGPropertyNode *node, T& value)
85 return SGReadValueFromString(node->getStringValue(), value);
89 static SGExpression<T>*
90 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
94 SGReadNaryOperands(SGNaryExpression<T>* nary,
95 SGPropertyNode *inputRoot, const SGPropertyNode *expression)
97 for (int i = 0; i < expression->nChildren(); ++i) {
98 SGExpression<T>* inputExpression;
99 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
100 if (!inputExpression)
102 nary->addOperand(inputExpression);
107 // template<typename T>
108 // static SGExpression<T>*
109 // SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
114 // std::string name = expression->getName();
115 // if (name == "value") {
117 // if (!SGReadValueFromContent(expression, value)) {
118 // SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
121 // return new SGConstExpression<T>(value);
128 static SGExpression<T>*
129 SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
134 std::string name = expression->getName();
135 if (name == "value") {
137 if (!SGReadValueFromContent(expression, value)) {
138 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
141 return new SGConstExpression<T>(value);
144 if (name == "property") {
146 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
147 "No inputRoot argument given!");
150 if (!expression->getStringValue()) {
151 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
154 SGPropertyNode* inputNode;
155 inputNode = inputRoot->getNode(expression->getStringValue(), true);
156 return new SGPropertyExpression<T>(inputNode);
159 if (name == "abs" || name == "fabs") {
160 if (expression->nChildren() != 1) {
161 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
164 SGSharedPtr<SGExpression<T> > inputExpression;
165 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
166 if (!inputExpression) {
167 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
170 return new SGAbsExpression<T>(inputExpression);
174 if (expression->nChildren() != 1) {
175 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
178 SGSharedPtr<SGExpression<T> > inputExpression;
179 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
180 if (!inputExpression) {
181 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
184 return new SGSqrExpression<T>(inputExpression);
187 if (name == "clip") {
188 if (expression->nChildren() != 3) {
189 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
192 const SGPropertyNode* minProperty = expression->getChild("clipMin");
194 if (!SGReadValueFromContent(minProperty, clipMin))
195 clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
197 const SGPropertyNode* maxProperty = expression->getChild("clipMax");
199 if (!SGReadValueFromContent(maxProperty, clipMax))
200 clipMin = SGLimits<T>::max();
202 SGSharedPtr<SGExpression<T> > inputExpression;
203 for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
204 inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
205 if (!inputExpression) {
206 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
209 return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
213 if (expression->nChildren() != 2) {
214 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
217 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
218 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
219 SGReadIExpression<T>(inputRoot, expression->getChild(1))
221 if (!inputExpressions[0] || !inputExpressions[1]) {
222 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
225 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
228 if (expression->nChildren() != 2) {
229 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
232 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
233 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
234 SGReadIExpression<T>(inputRoot, expression->getChild(1))
236 if (!inputExpressions[0] || !inputExpressions[1]) {
237 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
240 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
244 if (expression->nChildren() < 1) {
245 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
248 SGSumExpression<T>* output = new SGSumExpression<T>;
249 if (!SGReadNaryOperands(output, inputRoot, expression)) {
251 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
256 if (name == "prod" || name == "product") {
257 if (expression->nChildren() < 1) {
258 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
261 SGProductExpression<T>* output = new SGProductExpression<T>;
262 if (!SGReadNaryOperands(output, inputRoot, expression)) {
264 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
270 if (expression->nChildren() < 1) {
271 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
274 SGMinExpression<T>* output = new SGMinExpression<T>;
275 if (!SGReadNaryOperands(output, inputRoot, expression)) {
277 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
283 if (expression->nChildren() < 1) {
284 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
287 SGMaxExpression<T>* output = new SGMaxExpression<T>;
288 if (!SGReadNaryOperands(output, inputRoot, expression)) {
290 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
301 static SGExpression<T>*
302 SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
304 SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
311 std::string name = expression->getName();
312 if (name == "acos") {
313 if (expression->nChildren() != 1) {
314 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
317 SGSharedPtr<SGExpression<T> > inputExpression;
318 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
319 if (!inputExpression) {
320 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
323 return new SGACosExpression<T>(inputExpression);
326 if (name == "asin") {
327 if (expression->nChildren() != 1) {
328 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
331 SGSharedPtr<SGExpression<T> > inputExpression;
332 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
333 if (!inputExpression) {
334 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
337 return new SGASinExpression<T>(inputExpression);
340 if (name == "atan") {
341 if (expression->nChildren() != 1) {
342 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
345 SGSharedPtr<SGExpression<T> > inputExpression;
346 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
347 if (!inputExpression) {
348 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
351 return new SGATanExpression<T>(inputExpression);
354 if (name == "ceil") {
355 if (expression->nChildren() != 1) {
356 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
359 SGSharedPtr<SGExpression<T> > inputExpression;
360 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
361 if (!inputExpression) {
362 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
365 return new SGCeilExpression<T>(inputExpression);
369 if (expression->nChildren() != 1) {
370 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
373 SGSharedPtr<SGExpression<T> > inputExpression;
374 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
375 if (!inputExpression) {
376 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
379 return new SGCosExpression<T>(inputExpression);
382 if (name == "cosh") {
383 if (expression->nChildren() != 1) {
384 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
387 SGSharedPtr<SGExpression<T> > inputExpression;
388 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
389 if (!inputExpression) {
390 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
393 return new SGCoshExpression<T>(inputExpression);
396 if (name == "deg2rad") {
397 if (expression->nChildren() != 1) {
398 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
401 SGSharedPtr<SGExpression<T> > inputExpression;
402 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
403 if (!inputExpression) {
404 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
407 return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
411 if (expression->nChildren() != 1) {
412 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
415 SGSharedPtr<SGExpression<T> > inputExpression;
416 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
417 if (!inputExpression) {
418 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
421 return new SGExpExpression<T>(inputExpression);
424 if (name == "floor") {
425 if (expression->nChildren() != 1) {
426 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
429 SGSharedPtr<SGExpression<T> > inputExpression;
430 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
431 if (!inputExpression) {
432 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
435 return new SGFloorExpression<T>(inputExpression);
439 if (expression->nChildren() != 1) {
440 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
443 SGSharedPtr<SGExpression<T> > inputExpression;
444 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
445 if (!inputExpression) {
446 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
449 return new SGLogExpression<T>(inputExpression);
452 if (name == "log10") {
453 if (expression->nChildren() != 1) {
454 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
457 SGSharedPtr<SGExpression<T> > inputExpression;
458 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
459 if (!inputExpression) {
460 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
463 return new SGLog10Expression<T>(inputExpression);
466 if (name == "rad2deg") {
467 if (expression->nChildren() != 1) {
468 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
471 SGSharedPtr<SGExpression<T> > inputExpression;
472 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
473 if (!inputExpression) {
474 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
477 return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
481 if (expression->nChildren() != 1) {
482 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
485 SGSharedPtr<SGExpression<T> > inputExpression;
486 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
487 if (!inputExpression) {
488 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
491 return new SGSinExpression<T>(inputExpression);
494 if (name == "sinh") {
495 if (expression->nChildren() != 1) {
496 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
499 SGSharedPtr<SGExpression<T> > inputExpression;
500 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
501 if (!inputExpression) {
502 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
505 return new SGSinhExpression<T>(inputExpression);
508 if (name == "sqrt") {
509 if (expression->nChildren() != 1) {
510 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
513 SGSharedPtr<SGExpression<T> > inputExpression;
514 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
515 if (!inputExpression) {
516 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
519 return new SGSqrtExpression<T>(inputExpression);
523 if (expression->nChildren() != 1) {
524 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
527 SGSharedPtr<SGExpression<T> > inputExpression;
528 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
529 if (!inputExpression) {
530 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
533 return new SGTanExpression<T>(inputExpression);
536 if (name == "tanh") {
537 if (expression->nChildren() != 1) {
538 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
541 SGSharedPtr<SGExpression<T> > inputExpression;
542 inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
543 if (!inputExpression) {
544 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
547 return new SGTanhExpression<T>(inputExpression);
550 // if (name == "table") {
552 // if (name == "step") {
554 // if (name == "condition") {
557 if (name == "atan2") {
558 if (expression->nChildren() != 2) {
559 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
562 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
563 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
564 SGReadFExpression<T>(inputRoot, expression->getChild(1))
566 if (!inputExpressions[0] || !inputExpressions[1]) {
567 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
570 return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
573 if (expression->nChildren() != 2) {
574 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
577 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
578 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
579 SGReadFExpression<T>(inputRoot, expression->getChild(1))
581 if (!inputExpressions[0] || !inputExpressions[1]) {
582 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
585 return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
588 if (expression->nChildren() != 2) {
589 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
592 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
593 SGReadFExpression<T>(inputRoot, expression->getChild(0)),
594 SGReadFExpression<T>(inputRoot, expression->getChild(1))
596 if (!inputExpressions[0] || !inputExpressions[1]) {
597 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
600 return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
603 if (expression->nChildren() != 2) {
604 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
607 SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
608 SGReadIExpression<T>(inputRoot, expression->getChild(0)),
609 SGReadIExpression<T>(inputRoot, expression->getChild(1))
611 if (!inputExpressions[0] || !inputExpressions[1]) {
612 SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
615 return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
622 SGReadIntExpression(SGPropertyNode *inputRoot,
623 const SGPropertyNode *configNode)
624 { return SGReadIExpression<int>(inputRoot, configNode); }
627 SGReadFloatExpression(SGPropertyNode *inputRoot,
628 const SGPropertyNode *configNode)
629 { return SGReadFExpression<float>(inputRoot, configNode); }
631 SGExpression<double>*
632 SGReadDoubleExpression(SGPropertyNode *inputRoot,
633 const SGPropertyNode *configNode)
634 { return SGReadFExpression<double>(inputRoot, configNode); }
636 // SGExpression<bool>*
637 // SGReadBoolExpression(SGPropertyNode *inputRoot,
638 // const SGPropertyNode *configNode)
639 // { return SGReadBExpression<bool>(inputRoot, configNode); }