]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitorBase.java
Fixed InvertBasicExpressionVisitor bugs with subtractions and divisions
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / InvertBasicExpressionVisitorBase.java
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitorBase.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitorBase.java
new file mode 100644 (file)
index 0000000..8ccf5c2
--- /dev/null
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling;
+
+import java.util.Stack;
+
+import org.simantics.basicexpression.analysis.DepthFirstAdapter;
+import org.simantics.basicexpression.node.AConstantValue;
+import org.simantics.basicexpression.node.ADivMultiplicative;
+import org.simantics.basicexpression.node.AMinusExpression;
+import org.simantics.basicexpression.node.AMultMultiplicative;
+import org.simantics.basicexpression.node.APlusExpression;
+import org.simantics.basicexpression.node.AVariablePrimary;
+import org.simantics.utils.datastructures.Triple;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class InvertBasicExpressionVisitorBase extends DepthFirstAdapter {
+
+       protected Stack<Object> stack = new Stack<>();
+
+       public InvertBasicExpressionVisitorBase() {
+               super();
+       }
+
+       public Object getResult() {
+               if(stack.size() != 1) return null; 
+               return stack.pop();
+       }
+
+       @Override
+       public void outAConstantValue(AConstantValue node) {
+               stack.push(Double.valueOf(node.toString()));
+       }
+
+       @Override
+       public void outAVariablePrimary(AVariablePrimary node) {
+               String value = node.toString().trim();
+               stack.push(Triple.make(1.0, 0.0, value));
+       }
+
+       @SuppressWarnings("unchecked")
+       @Override
+       public void outAPlusExpression(APlusExpression node) {
+
+               final Object o1 = stack.pop();
+               final Object o2 = stack.pop();
+
+               if(o1 instanceof Double && o2 instanceof Triple) {
+                       Triple<Double, Double, String> p = (Triple<Double, Double, String>)o2;
+                       stack.push(Triple.make(p.first, p.second + (Double)o1, p.third));
+               } else if (o2 instanceof Double && o1 instanceof Triple) {
+                       Triple<Double, Double, String> p = (Triple<Double, Double, String>)o1;
+                       stack.push(Triple.make(p.first, p.second + (Double)o2, p.third));
+               } else if (o2 instanceof Double && o1 instanceof Double) {
+                       stack.push((Double)o1 + (Double)o2);
+               } else {
+                       stack.push(Double.NaN);
+               }
+
+       }
+
+       @SuppressWarnings("unchecked")
+       @Override
+       public void outAMinusExpression(AMinusExpression node) {
+
+               final Object o1 = stack.pop();
+               final Object o2 = stack.pop();
+
+               // o2 - o1
+               if(o1 instanceof Double && o2 instanceof Triple) {
+                       // <triple> o2 - double o1
+                       Triple<Double, Double, String> p = (Triple<Double, Double, String>)o2;
+                       stack.push(Triple.make(p.first, p.second - (Double)o1, p.third));
+               } else if (o2 instanceof Double && o1 instanceof Triple) {
+                       // double o2 - <triple> o1
+                       Triple<Double, Double, String> p = (Triple<Double, Double, String>)o1;
+                       stack.push(Triple.make(-p.first, (Double)o2 - p.second, p.third));
+               } else if (o2 instanceof Double && o1 instanceof Double) {
+                       stack.push((Double)o2 - (Double)o1);
+               } else {
+                       stack.push(Double.NaN);
+               }
+
+       }
+
+       @SuppressWarnings("unchecked")
+       @Override
+       public void outAMultMultiplicative(AMultMultiplicative node) {
+
+               final Object o1 = stack.pop();
+               final Object o2 = stack.pop();
+
+               if(o1 instanceof Double && o2 instanceof Triple) {
+                       Triple<Double, Double, String> p = (Triple<Double, Double, String>)o2;
+                       stack.push(Triple.make(p.first * (Double)o1, p.second * (Double)o1, p.third));
+               } else if (o2 instanceof Double && o1 instanceof Triple) {
+                       Triple<Double, Double, String> p = (Triple<Double, Double, String>)o1;
+                       stack.push(Triple.make(p.first * (Double)o2, p.second * (Double)o2, p.third));
+               } else if (o2 instanceof Double && o1 instanceof Double) {
+                       stack.push((Double)o1 * (Double)o2);
+               } else {
+                       stack.push(Double.NaN);
+               }
+
+       }
+
+       @SuppressWarnings("unchecked")
+       @Override
+       public void outADivMultiplicative(ADivMultiplicative node) {
+
+               final Object o1 = stack.pop();
+               final Object o2 = stack.pop();
+
+               // o2 / o1
+               if(o1 instanceof Double && o2 instanceof Triple) {
+                       // <triple> o2 / double o1 
+                       Triple<Double, Double, String> p = (Triple<Double,Double, String>)o2;
+                       stack.push(Triple.make(p.first / (Double)o1, p.second / (Double)o1, p.third));
+               } else if (o2 instanceof Double && o1 instanceof Triple) {
+                       // double o2 / <triple> o1 
+                       stack.push(Double.NaN);
+               } else if (o2 instanceof Double && o1 instanceof Double) {
+                       stack.push((Double)o2 / (Double)o1);
+               } else {
+                       stack.push(Double.NaN);
+               }
+
+       }
+
+}
\ No newline at end of file