]> git.mxchange.org Git - simgear.git/blobdiff - simgear/structure/SGExpression.cxx
Initial work on CMake support for SimGear.
[simgear.git] / simgear / structure / SGExpression.cxx
index 4c746d885d74a34e5314058ab1706c86c71b7004..78d6daf0f7355072900695826dbc8f9fb7d75313 100644 (file)
@@ -33,6 +33,7 @@
 #include <string>
 #include <sstream>
 #include <boost/bind.hpp>
+#include <cstring> // for strcmp
 
 #include <simgear/props/props.hxx>
 
@@ -292,6 +293,21 @@ SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
         }
         return output;
     }
+
+    if (name == "difference" || name == "dif" ) {
+        if (expression->nChildren() < 1) {
+            SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+            return 0;
+        }
+        SGDifferenceExpression<T>* output = new SGDifferenceExpression<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.");
@@ -332,6 +348,38 @@ SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
         return output;
     }
 
+    if (name == "table") {
+        SGInterpTable* tab = new SGInterpTable(expression);
+        if (!tab) {
+            SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression: malformed table");
+            return 0;
+        }
+        
+        // find input expression - i.e a child not named 'entry'
+        const SGPropertyNode* inputNode = NULL;
+        for (int i=0; (i<expression->nChildren()) && !inputNode; ++i) {
+            if (strcmp(expression->getChild(i)->getName(), "entry") == 0) {
+                continue;
+            }
+            
+            inputNode = expression->getChild(i);
+        }
+        
+        if (!inputNode) {
+            SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression: no input found");
+            return 0;
+        }
+        
+        SGSharedPtr<SGExpression<T> > inputExpression;
+        inputExpression = SGReadIExpression<T>(inputRoot, inputNode);
+        if (!inputExpression) {
+            SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
+            return 0;
+        }
+        
+        return new SGInterpTableExpression<T>(inputExpression, tab);
+    }
+    
     return 0;
 }
 
@@ -585,9 +633,7 @@ SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
         }
         return new SGTanhExpression<T>(inputExpression);
     }
-
-// if (name == "table") {
-// }
+    
 // if (name == "step") {
 // }
 // if (name == "condition") {
@@ -682,44 +728,6 @@ namespace simgear
 namespace expression
 {
 
-class Parser {
-public:
-    void addParser(const std::string& name, exp_parser parser)
-    {
-        _parserTable.insert(std::make_pair(name, parser));
-    }
-    Expression* read(const SGPropertyNode* exp)
-    {
-        ParserMap::iterator itr = _parserTable.find(exp->getName());
-        if (itr == _parserTable.end())
-            throw ParseError(string("unknown expression ") + exp->getName());
-        exp_parser parser = itr->second;
-        return (*parser)(exp, this);
-    }
-    // XXX vector of SGSharedPtr?
-    bool readChildren(const SGPropertyNode* exp,
-                      vector<Expression*>& result);
-protected:
-    typedef std::map<const std::string, exp_parser> ParserMap;
-    ParserMap _parserTable;
-};
-
-class ExpressionParser : public Parser, public Singleton<ExpressionParser>
-{
-};
-
-void addExpParser(const string& token, exp_parser parsefn)
-{
-    ExpressionParser::instance()->addParser(token, parsefn);
-}
-
-Expression* read(const SGPropertyNode* exp, Parser* parser)
-{
-    if (!parser)
-        parser = ExpressionParser::instance();
-    return parser->read(exp);
-}
-
 bool Parser::readChildren(const SGPropertyNode* exp,
                           vector<Expression*>& result)
 {
@@ -728,6 +736,12 @@ bool Parser::readChildren(const SGPropertyNode* exp,
     return true;
 }
 
+void ExpressionParser::addExpParser(const string& token, exp_parser parsefn)
+{
+    ParserMapSingleton::instance()
+        ->_parserTable.insert(std::make_pair(token, parsefn));
+}
+
 Expression* valueParser(const SGPropertyNode* exp, Parser* parser)
 {
     switch (exp->getType()) {
@@ -856,7 +870,7 @@ Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
     parser->readChildren(exp, children);
     vector<Expression*>::iterator notBool =
         find_if(children.begin(), children.end(),
-                bind(&Expression::getType, _1) != BOOL);
+                boost::bind(&Expression::getType, _1) != BOOL);
     if (notBool != children.end())
         throw("non boolean operand to logical expression");
     Logicop *expr = new Logicop;
@@ -867,10 +881,14 @@ Expression* logicopParser(const SGPropertyNode* exp, Parser* parser)
 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(),
+                  boost::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;
@@ -883,7 +901,7 @@ bool BindingLayout::findBinding(const std::string& name,
     using namespace boost;
     vector<VariableBinding>::const_iterator itr
         = find_if(bindings.begin(), bindings.end(),
-                  bind(&VariableBinding::name, _1) == name);
+                  boost::bind(&VariableBinding::name, _1) == name);
     if (itr != bindings.end()) {
         result = *itr;
         return true;