1 /*******************************************************************************
2 * Copyright (c) 2020 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Semantum Oy - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.modeling;
14 import java.util.Stack;
16 import org.simantics.basicexpression.analysis.DepthFirstAdapter;
17 import org.simantics.basicexpression.node.AConstantValue;
18 import org.simantics.basicexpression.node.ADivMultiplicative;
19 import org.simantics.basicexpression.node.AMinusExpression;
20 import org.simantics.basicexpression.node.AMultMultiplicative;
21 import org.simantics.basicexpression.node.APlusExpression;
22 import org.simantics.basicexpression.node.AVariablePrimary;
23 import org.simantics.utils.datastructures.Triple;
26 * @author Tuukka Lehtonen
28 public class InvertBasicExpressionVisitorBase extends DepthFirstAdapter {
30 protected Stack<Object> stack = new Stack<>();
32 public InvertBasicExpressionVisitorBase() {
36 public Object getResult() {
37 if(stack.size() != 1) return null;
42 public void outAConstantValue(AConstantValue node) {
43 stack.push(Double.valueOf(node.toString()));
47 public void outAVariablePrimary(AVariablePrimary node) {
48 String value = node.toString().trim();
49 stack.push(Triple.make(1.0, 0.0, value));
52 @SuppressWarnings("unchecked")
54 public void outAPlusExpression(APlusExpression node) {
56 final Object o1 = stack.pop();
57 final Object o2 = stack.pop();
59 if(o1 instanceof Double && o2 instanceof Triple) {
60 Triple<Double, Double, String> p = (Triple<Double, Double, String>)o2;
61 stack.push(Triple.make(p.first, p.second + (Double)o1, p.third));
62 } else if (o2 instanceof Double && o1 instanceof Triple) {
63 Triple<Double, Double, String> p = (Triple<Double, Double, String>)o1;
64 stack.push(Triple.make(p.first, p.second + (Double)o2, p.third));
65 } else if (o2 instanceof Double && o1 instanceof Double) {
66 stack.push((Double)o1 + (Double)o2);
68 stack.push(Double.NaN);
73 @SuppressWarnings("unchecked")
75 public void outAMinusExpression(AMinusExpression node) {
77 final Object o1 = stack.pop();
78 final Object o2 = stack.pop();
81 if(o1 instanceof Double && o2 instanceof Triple) {
82 // <triple> o2 - double o1
83 Triple<Double, Double, String> p = (Triple<Double, Double, String>)o2;
84 stack.push(Triple.make(p.first, p.second - (Double)o1, p.third));
85 } else if (o2 instanceof Double && o1 instanceof Triple) {
86 // double o2 - <triple> o1
87 Triple<Double, Double, String> p = (Triple<Double, Double, String>)o1;
88 stack.push(Triple.make(-p.first, (Double)o2 - p.second, p.third));
89 } else if (o2 instanceof Double && o1 instanceof Double) {
90 stack.push((Double)o2 - (Double)o1);
92 stack.push(Double.NaN);
97 @SuppressWarnings("unchecked")
99 public void outAMultMultiplicative(AMultMultiplicative node) {
101 final Object o1 = stack.pop();
102 final Object o2 = stack.pop();
104 if(o1 instanceof Double && o2 instanceof Triple) {
105 Triple<Double, Double, String> p = (Triple<Double, Double, String>)o2;
106 stack.push(Triple.make(p.first * (Double)o1, p.second * (Double)o1, p.third));
107 } else if (o2 instanceof Double && o1 instanceof Triple) {
108 Triple<Double, Double, String> p = (Triple<Double, Double, String>)o1;
109 stack.push(Triple.make(p.first * (Double)o2, p.second * (Double)o2, p.third));
110 } else if (o2 instanceof Double && o1 instanceof Double) {
111 stack.push((Double)o1 * (Double)o2);
113 stack.push(Double.NaN);
118 @SuppressWarnings("unchecked")
120 public void outADivMultiplicative(ADivMultiplicative node) {
122 final Object o1 = stack.pop();
123 final Object o2 = stack.pop();
126 if(o1 instanceof Double && o2 instanceof Triple) {
127 // <triple> o2 / double o1
128 Triple<Double, Double, String> p = (Triple<Double,Double, String>)o2;
129 stack.push(Triple.make(p.first / (Double)o1, p.second / (Double)o1, p.third));
130 } else if (o2 instanceof Double && o1 instanceof Triple) {
131 // double o2 / <triple> o1
132 stack.push(Double.NaN);
133 } else if (o2 instanceof Double && o1 instanceof Double) {
134 stack.push((Double)o2 / (Double)o1);
136 stack.push(Double.NaN);