/******************************************************************************* * 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 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 p = (Triple)o2; stack.push(Triple.make(p.first, p.second + (Double)o1, p.third)); } else if (o2 instanceof Double && o1 instanceof Triple) { Triple p = (Triple)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) { // o2 - double o1 Triple p = (Triple)o2; stack.push(Triple.make(p.first, p.second - (Double)o1, p.third)); } else if (o2 instanceof Double && o1 instanceof Triple) { // double o2 - o1 Triple p = (Triple)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 p = (Triple)o2; stack.push(Triple.make(p.first * (Double)o1, p.second * (Double)o1, p.third)); } else if (o2 instanceof Double && o1 instanceof Triple) { Triple p = (Triple)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) { // o2 / double o1 Triple p = (Triple)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 / o1 stack.push(Double.NaN); } else if (o2 instanceof Double && o1 instanceof Double) { stack.push((Double)o2 / (Double)o1); } else { stack.push(Double.NaN); } } }