package org.simantics.modeling.ui.expression; import java.util.HashMap; import java.util.Stack; import org.simantics.basicexpression.analysis.DepthFirstAdapter; import org.simantics.basicexpression.node.AAddressValue; import org.simantics.basicexpression.node.AConstantValue; import org.simantics.basicexpression.node.ADivMultiplicative; import org.simantics.basicexpression.node.AFunctionPrimary; import org.simantics.basicexpression.node.AMinusExpression; import org.simantics.basicexpression.node.AMultMultiplicative; import org.simantics.basicexpression.node.APlusExpression; import org.simantics.basicexpression.node.ARangeValue; import org.simantics.basicexpression.node.ARviValue; import org.simantics.basicexpression.node.ASequenceArgList; import org.simantics.basicexpression.node.ASingleArgList; import org.simantics.basicexpression.node.AStringValue; import org.simantics.basicexpression.node.PArgList; import org.simantics.db.ReadGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.Function; import org.simantics.db.layer0.variable.Variable; public class BasicExpressionVisitor extends DepthFirstAdapter { public static final boolean DEBUG_APPLICATION = false; public static class ApplicationException extends Exception { private static final long serialVersionUID = 1L; public ApplicationException(String message) { super(message); } } final ReadGraph graph; final Variable property; Stack stack = new Stack(); HashMap builtins = new HashMap(); public BasicExpressionVisitor(ReadGraph graph, Variable property) { this.graph = graph; this.property = property; } public Object getResult() { return stack.pop(); } public void outAConstantValue(AConstantValue node) { // System.out.println("eval constant " + node); stack.push(Double.valueOf(node.toString())); } public void outAStringValue(AStringValue node) { try { String value = node.toString(); String rvi = value.substring(1, value.length() - 2).trim(); Variable relative = property.browse(graph, rvi); stack.push(relative.getValue(graph)); } catch (DatabaseException e) { stack.push(e); } } @Override public void outARviValue(ARviValue node) { try { String value = node.toString(); String rvi = value.trim(); // System.out.println("property=" + property.getURI(graph) + " " + property); // System.out.println("rvi=" + rvi); Variable relative = property.browse(graph, rvi); // System.out.println("relative=" + relative.getURI(graph)); Object valueObject = relative.getValue(graph); // System.out.println("relative2=" + relative.getURI(graph) + " -> " + valueObject); stack.push(valueObject); } catch (DatabaseException e) { stack.push(e); } } public void outAAddressValue(AAddressValue node) { stack.push('&' + node.getRange().toString()); } public void outARangeValue(ARangeValue node) { } private double extractValue(Object o) { if (o instanceof Number) { return ((Number) o).doubleValue(); } else if (o instanceof String) { return Double.valueOf((String) o); } else { return Double.NaN; } } public void outAPlusExpression(APlusExpression node) { Object o1 = stack.pop(); Object o2 = stack.pop(); double d1 = extractValue(o1); double d2 = extractValue(o2); stack.push(d1 + d2); // System.out.println("plus " + d1 + " " + d2); } public void outAMinusExpression(AMinusExpression node) { Object o2 = stack.pop(); Object o1 = stack.pop(); double d1 = extractValue(o1); double d2 = extractValue(o2); // System.out.println("minus " + d1 + " " + d2); stack.push(d1 - d2); } public void outAMultMultiplicative(AMultMultiplicative node) { Object o1 = stack.pop(); Object o2 = stack.pop(); double d1 = extractValue(o1); double d2 = extractValue(o2); stack.push(d1 * d2); // System.out.println("mult " + d1 + " " + d2); } @Override public void outADivMultiplicative(ADivMultiplicative node) { Object o1 = stack.pop(); Object o2 = stack.pop(); double d1 = extractValue(o1); double d2 = extractValue(o2); stack.push(d2 / d1); } int countArguments(PArgList args) { if (args == null) return 0; if (args instanceof ASingleArgList) return 1; ASequenceArgList seq = (ASequenceArgList) args; return 1 + countArguments(seq.getArgList()); } public void outAFunctionPrimary(AFunctionPrimary node) { } }