]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Implement support for else-if statements in internal solver
authorjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 22 Apr 2015 13:18:01 +0000 (13:18 +0000)
committerjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 22 Apr 2015 13:18:01 +0000 (13:18 +0000)
fixes #5777

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@31195 ac1ea38d-2e2b-0410-8846-a27921b304fc

fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Parser.java

index d8511d728553c176280e85ae66ea0144f9d644a0..c18027b696e071adb038b87b514b0359df55d5ed 100644 (file)
@@ -14,33 +14,50 @@ import java.util.Map;
 \r
 public class IfThenElse implements IExpression {\r
        \r
-    public IExpression exp;\r
-    public IExpression t;\r
-    public IExpression e;\r
+    public IExpression[] condExpr;\r
+    public IExpression[] thenExpr;\r
+    public IExpression elseExpr;\r
     \r
-    public IfThenElse(IExpression exp, IExpression t, IExpression e) {\r
-       this.exp = exp;\r
-       this.t = t;\r
-       this.e = e;\r
+    public IfThenElse(IExpression condExpr, IExpression thenExpr, IExpression elseExpr) {\r
+       this(new IExpression[] { condExpr }, new IExpression[] { thenExpr }, elseExpr);\r
+    }\r
+    \r
+    public IfThenElse(IExpression[] condExpr, IExpression[] thenExpr, IExpression elseExpr) {\r
+       this.condExpr = condExpr;\r
+       this.thenExpr = thenExpr;\r
+       this.elseExpr = elseExpr;\r
     }\r
     \r
     @Override\r
     public String toString() {\r
-       return "if " + exp + " then " + t + " else "+ e;\r
+       StringBuilder str = new StringBuilder();\r
+       str.append("if ").append(condExpr[0]).append(" then ").append(thenExpr[0]);\r
+       for (int i = 1; i < condExpr.length; i++) {\r
+               str.append(" else if ").append(condExpr[i]).append(" then ").append(thenExpr[i]);\r
+       }\r
+       str.append(" else ").append(elseExpr);\r
+       return str.toString();\r
     }\r
     \r
        @Override\r
        public Object evaluate(IEnvironment environment) {\r
-               if((Boolean)exp.evaluate(environment)) {\r
-                       return t.evaluate(environment);\r
-               } else {\r
-                       return e.evaluate(environment);\r
+               for (int i = 0; i < condExpr.length; i++) {\r
+                       if ((Boolean)condExpr[i].evaluate(environment)) {\r
+                               return thenExpr[i].evaluate(environment);\r
+                       }\r
                }\r
+               return elseExpr.evaluate(environment);\r
        }\r
     \r
        @Override\r
        public IExpression withBase(IFrame frame, String prefix) {\r
-               return new IfThenElse(exp.withBase(frame, prefix), t.withBase(frame, prefix), e.withBase(frame, prefix));\r
+               IExpression[] newConds = new IExpression[condExpr.length];\r
+               IExpression[] newThens = new IExpression[thenExpr.length];\r
+               for (int i = 0; i < condExpr.length; i++) {\r
+                       newConds[i] = condExpr[i].withBase(frame, prefix);\r
+                       newThens[i] = thenExpr[i].withBase(frame, prefix);\r
+               }\r
+               return new IfThenElse(newConds, newThens, elseExpr.withBase(frame, prefix));\r
        }\r
     \r
        @Override\r
@@ -50,18 +67,26 @@ public class IfThenElse implements IExpression {
        \r
        @Override\r
        public IExpression rewrite(IFrame frame, Map<String, VariableBase> copies) {\r
-               exp = exp.rewrite(frame, copies);\r
-               t = t.rewrite(frame, copies);\r
-               e = e.rewrite(frame, copies);\r
+               IExpression[] newConds = new IExpression[condExpr.length];\r
+               IExpression[] newThens = new IExpression[thenExpr.length];\r
+               for (int i = 0; i < condExpr.length; i++) {\r
+                       newConds[i] = condExpr[i].rewrite(frame, copies);\r
+                       newThens[i] = thenExpr[i].rewrite(frame, copies);\r
+               }\r
+               condExpr = newConds;\r
+               thenExpr = newThens;\r
+               elseExpr = elseExpr.rewrite(frame, copies);\r
                return this;\r
        }\r
        \r
        @Override\r
        public void accept(ExpressionVisitor visitor) {\r
                visitor.visit(this);\r
-               exp.accept(visitor);\r
-               t.accept(visitor);\r
-               e.accept(visitor);\r
+               for (int i = 0; i < condExpr.length; i++) {\r
+                       condExpr[i].accept(visitor);\r
+                       thenExpr[i].accept(visitor);\r
+               }\r
+               elseExpr.accept(visitor);\r
        }\r
 \r
 }\r
index 3fe43ba4ec2baee554c745d0709de73f1b9dcc35..fff4923a46fad6c7d680489f7da33d85c3fe023b 100644 (file)
@@ -52,7 +52,7 @@ public class Parser {
        }\r
        \r
        public Object walk_(SimpleNode n, int indent, IFrame frame) {\r
-\r
+               \r
                Model model = frame instanceof Model ? (Model)frame : null;\r
                \r
                // TODO: most of this should probably be implemented in the parser\r
@@ -588,11 +588,29 @@ public class Parser {
                                return walk((SimpleNode)n.jjtGetChild(0), indent+2, frame);\r
                        }                       \r
                case if_expression:\r
-                       if(n.jjtGetNumChildren() == 3) {\r
-                               IExpression exp1 = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, frame);\r
-                               IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, frame);\r
-                               IExpression exp3 = (IExpression)walk((SimpleNode)n.jjtGetChild(2), indent+2, frame);\r
-                               return new IfThenElse(exp1, exp2, exp3);\r
+                       int children = n.jjtGetNumChildren();\r
+                       if (children >= 3 && children % 2 == 1) {\r
+                               // a Modelica if-expression contains at least three clauses:\r
+                               // a condition, a then-expression and an else-expression. The\r
+                               // expression can also contain one or more elseif-expressions\r
+                               // which contain a condition and a then-expression of their own.\r
+                               int branches = (children - 1) / 2;\r
+                               \r
+                               IExpression[] condExpr = new IExpression[branches];\r
+                               IExpression[] thenExpr = new IExpression[branches];\r
+                               \r
+                               for (int i = 0; i < branches; i++) {\r
+                                       condExpr[i] = (IExpression)walk((SimpleNode)n.jjtGetChild(2*i), indent+2, frame);\r
+                                       thenExpr[i] = (IExpression)walk((SimpleNode)n.jjtGetChild(2*i+1), indent+2, frame);\r
+                               }\r
+                               \r
+                               IExpression elseExpr = (IExpression)walk((SimpleNode)n.jjtGetChild(children-1), indent+2, frame);\r
+                               \r
+                               return new IfThenElse(condExpr, thenExpr, elseExpr);\r
+                       }\r
+                       else {\r
+                               // should definitely return something here as well, an error at the very least\r
+                               throw new UnsupportedOperationException();\r
                        }\r
                case add_op:\r
                        return n.op;\r