1 package org.simantics.modeling.ui.diagram.monitor;
3 import java.util.HashMap;
4 import java.util.LinkedList;
6 import java.util.Stack;
8 import org.simantics.basicexpression.analysis.DepthFirstAdapter;
9 import org.simantics.basicexpression.analysis.EvaluationException;
10 import org.simantics.basicexpression.node.AAddressValue;
11 import org.simantics.basicexpression.node.AConstantValue;
12 import org.simantics.basicexpression.node.AFunctionPrimary;
13 import org.simantics.basicexpression.node.AMultMultiplicative;
14 import org.simantics.basicexpression.node.APlusExpression;
15 import org.simantics.basicexpression.node.ARangeValue;
16 import org.simantics.basicexpression.node.ARviValue;
17 import org.simantics.basicexpression.node.ASequenceArgList;
18 import org.simantics.basicexpression.node.ASingleArgList;
19 import org.simantics.basicexpression.node.ASingleRange;
20 import org.simantics.basicexpression.node.AStringValue;
21 import org.simantics.basicexpression.node.AVariablePrimary;
22 import org.simantics.basicexpression.node.PArgList;
23 import org.simantics.common.format.Formatter;
24 import org.simantics.db.ReadGraph;
25 import org.simantics.db.Resource;
26 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
27 import org.simantics.db.common.utils.Logger;
28 import org.simantics.db.exception.DatabaseException;
29 import org.simantics.db.layer0.request.ModelInstances;
30 import org.simantics.db.layer0.request.VariableIndexRoot;
31 import org.simantics.db.layer0.variable.Variable;
32 import org.simantics.layer0.Layer0;
33 import org.simantics.scl.runtime.function.Function;
35 public class MonitorExpressionVisitor extends DepthFirstAdapter {
37 public static final boolean DEBUG_APPLICATION = false;
38 public static final boolean DEBUG = false;
40 public static class ApplicationException extends Exception {
42 private static final long serialVersionUID = 1L;
44 public ApplicationException(String message) {
50 final ReadGraph graph;
51 final Variable variable;
52 final Formatter formatter;
54 Stack<Object> stack = new Stack<Object>();
56 HashMap<String, Function> builtins = new HashMap<String, Function>();
58 public MonitorExpressionVisitor(ReadGraph graph, Formatter formatter, Variable variable) {
61 this.formatter = formatter;
62 this.variable = variable;
66 public Object getResult() {
67 if(exception != null) return exception;
71 public void outAConstantValue(AConstantValue node) {
72 if(DEBUG) System.out.println("outAConstantValue " + node);
73 stack.push(Double.valueOf(node.toString()));
76 public void outAStringValue(AStringValue node) {
77 if(DEBUG) System.out.println("outAStringValue " + node);
78 String value = node.toString();
79 stack.push(value.substring(1, value.length() - 2));
82 public void outAAddressValue(AAddressValue node) {
83 if(DEBUG) System.out.println("outAAddressValue " + node);
84 stack.push('&' + node.getRange().toString());
88 public void outASingleRange(ASingleRange node) {
90 if(DEBUG) System.out.println("outASingleRange " + node);
95 public void outARviValue(ARviValue node) {
97 if(DEBUG) System.out.println("outARviValue " + node);
99 String rvi = node.toString().trim();
102 Variable var = variable.browse(graph, rvi);
103 stack.push(format(var.getValue(graph)));
104 } catch (DatabaseException e) {
105 Logger.defaultLogError(e);
106 stack.push("<No value for '" + rvi + "'>");
112 public void outAVariablePrimary(AVariablePrimary node) {
114 if(DEBUG) System.out.println("outAVariablePrimary " + node);
116 String identifier = node.toString().trim();
117 if("value".equals(identifier)) {
119 stack.push(format(variable.getValue(graph)));
120 } catch (DatabaseException e) {
124 stack.push(identifier);
129 public void outARangeValue(ARangeValue node) {
131 if(DEBUG) System.out.println("outARangeValue " + node);
133 String identifier = node.getRange().toString().trim();
134 stack.push(identifier);
138 private String format(Object o) {
139 if(formatter != null)
140 return formatter.format(o);
141 else return o != null ? o.toString() : "";
144 private double extractValue(Object o) {
145 if (o instanceof Number) {
146 return ((Number) o).doubleValue();
147 } else if (o instanceof String) {
148 String s = (String) o;
151 return Double.valueOf((String) o);
157 private Object extractSum(Object o1, Object o2) {
159 if(o1 instanceof String) {
160 return o1.toString() + o2;
161 } else if (o2 instanceof String) {
162 return o1.toString() + o2.toString();
163 } else if (o1 instanceof Number && o2 instanceof Number) {
164 return ((Number) o1).doubleValue() + ((Number) o2).doubleValue();
166 return o1.toString() + o2.toString();
171 public void outAPlusExpression(APlusExpression node) {
173 if(DEBUG) System.out.println("outAPlusExpression " + node);
175 Object o2 = stack.pop();
176 Object o1 = stack.pop();
178 Object out = extractSum(o1, o2);
183 public void outAMultMultiplicative(AMultMultiplicative node) {
185 if(DEBUG) System.out.println("outAMultiplicative " + node);
187 Object o1 = stack.pop();
188 Object o2 = stack.pop();
189 double d1 = extractValue(o1);
190 double d2 = extractValue(o2);
195 int countArguments(PArgList args) {
198 if (args instanceof ASingleArgList)
200 ASequenceArgList seq = (ASequenceArgList) args;
201 return 1 + countArguments(seq.getArgList());
204 public void outAFunctionPrimary(AFunctionPrimary node) {
206 if(DEBUG) System.out.println("outAFunctionPrimary " + node);
210 String functionName = node.getFunc().getText().replace("(", "");
212 if (DEBUG_APPLICATION)
213 System.out.println("function apply " + functionName);
215 Function function = builtins.get(functionName);
216 if (function != null) {
218 LinkedList<Object> args = new LinkedList<Object>();
219 int argc = countArguments(node.getArgList());
220 for (int i = 0; i < argc; i++) {
221 args.addFirst(stack.pop());
223 args.addFirst(formatter);
224 args.addFirst(variable);
225 args.addFirst(graph);
227 Object result = function.applyArray(args);
228 stack.push(format(result));
232 // Instances instances = graph.adapt(L0.Function, Instances.class);
233 // Collection<Resource> functions = instances.find(graph, Variables.getModel(graph, variable),
234 // "Name:" + functionName);
235 // if (DEBUG_APPLICATION)
236 // System.out.println("Found " + functions.size() + " matches.");
237 // if (functions != null && functions.size() == 1) {
238 Layer0 L0 = Layer0.getInstance(graph);
239 Resource functionResource = null;
240 Resource indexRoot = graph.sync(new VariableIndexRoot(variable));
241 if (indexRoot != null) {
242 Map<String, Resource> functions = graph.syncRequest(
243 new ModelInstances(indexRoot, L0.Function),
244 TransientCacheListener.<Map<String, Resource>> instance());
245 functionResource = functions.get(functionName);
247 if(functionResource != null) {
248 // Resource functionResource = functions.iterator().next();
249 function = graph.adapt(functionResource, Function.class);
250 LinkedList<Object> args = new LinkedList<Object>();
251 int argc = countArguments(node.getArgList());
252 for (int i = 0; i < argc; i++) {
253 args.addFirst(stack.pop());
255 args.addFirst(formatter);
256 args.addFirst(variable);
257 args.addFirst(graph);
258 Object result = function.applyArray(args.toArray());
259 stack.push(format(result));
264 throw new EvaluationException("Function not found in dependencies: '" + functionName + "'");
270 } catch (DatabaseException e) {