package org.simantics.modeling.ui.expression; 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.AMultMultiplicative; import org.simantics.basicexpression.node.APlusExpression; import org.simantics.basicexpression.node.AStringValue; import org.simantics.utils.datastructures.Triple; public class InvertBasicExpressionVisitor extends DepthFirstAdapter { Stack stack = new Stack(); public Object getResult() { return stack.pop(); } public void outAConstantValue(AConstantValue node) { stack.push(Double.valueOf(node.toString())); } public void outAStringValue(AStringValue node) { String value = node.toString(); stack.push(Triple.make(1.0, 0.0, value.substring(1, value.length() - 2).trim())); } @SuppressWarnings("unchecked") 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") public void outAMinusExpression(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, (Double)o1 - p.second, 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") 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") public void outADivMultiplicative(ADivMultiplicative node) { final Object o1 = stack.pop(); final Object o2 = stack.pop(); if(o1 instanceof Double && o2 instanceof Triple) { stack.push(Double.NaN); } 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); } } }