X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.spreadsheet.graph%2Fsrc%2Forg%2Fsimantics%2Fspreadsheet%2Fgraph%2Frequest%2FSpreadsheetExpressionVisitor.java;h=71466070ef099d03bbfc947570d43980b98f117a;hp=e7c413a96d4c5645252cf33ed5a238a9c1e1bc9d;hb=5c67a96d34fe904b8c4b0375cd08ff1d543bf369;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/request/SpreadsheetExpressionVisitor.java b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/request/SpreadsheetExpressionVisitor.java index e7c413a96..71466070e 100644 --- a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/request/SpreadsheetExpressionVisitor.java +++ b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/request/SpreadsheetExpressionVisitor.java @@ -1,401 +1,401 @@ -package org.simantics.spreadsheet.graph.request; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -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.AFunctionPrimary; -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.ASingleRange; -import org.simantics.basicexpression.node.AStringValue; -import org.simantics.basicexpression.node.AVariablePrimary; -import org.simantics.basicexpression.node.PArgList; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.adapter.Function; -import org.simantics.db.layer0.adapter.Instances; -import org.simantics.db.layer0.variable.Variable; -import org.simantics.db.layer0.variable.Variables; -import org.simantics.layer0.Layer0; -import org.simantics.spreadsheet.Range; -import org.simantics.spreadsheet.util.SpreadsheetUtils; - -public class SpreadsheetExpressionVisitor extends DepthFirstAdapter { - - public static final boolean DEBUG_APPLICATION = false; - public static final boolean DEBUG = false; - - public static class ApplicationException extends Exception { - - private static final long serialVersionUID = 1L; - - public ApplicationException(String message) { - super(message); - } - - } - - final ReadGraph graph; - final Variable cellVariable; - final Resource model; - final Resource sheet; - final int row; - final int column; - // final EvaluationEnvironmentImpl env; - Stack stack = new Stack(); - - HashMap builtins = new HashMap(); - - // class EvaluationEnvironmentImpl implements EvaluationEnvironment { - // - // private boolean ready = false; - // private boolean valid = true; - // public HashSet deps = new HashSet(); - // - // - // @Override - // public int getColumn() { - // return column; - // } - // - // @Override - // public Model getModel() { - // return model; - // } - // - // @Override - // public int getRow() { - // return row; - // } - // - // public void depend(Range range) { - // deps.add(range); - // } - // - // public void listen() { - // ready = true; - // } - // - // @Override - // public void invalidate() { - // // DependencyHandler handler = model.getAdapter(DependencyHandler.class); - // // handler.invalidate(row, column); - // if(!ready) return; - // valid = false; - // ThreadUtils.getNonBlockingWorkExecutor().execute(new Runnable() { - // - // @Override - // public void run() { - // - // Cell cell = model.get(row, column); - // UpdateHandler handler = cell.getAdapter(UpdateHandler.class); - // if(handler != null) handler.update(); - // - // } - // - // }); - // - // } - // - // @Override - // public boolean isDisposed() { - // return !valid; - // } - // - // } - - public SpreadsheetExpressionVisitor(ReadGraph graph, Variable cellVariable, int row, int column) throws DatabaseException { - - // assert(model != null); - // // assert(graph != null); - // // assert(sheet != null); - this.graph = graph; - this.cellVariable = cellVariable; - this.model = Variables.getModel(graph, cellVariable); - Resource cell = cellVariable.getPossiblePropertyValue(graph, Variables.RESOURCE); - this.sheet = graph.getPossibleObject(cell, Layer0.getInstance(graph).PartOf); -// this.sheet = sheet; -// this.model = model; - this.row = row; - this.column = column; - // - // builtins.put("Sequence", new Sequence()); - // builtins.put("Set", new Set()); - // builtins.put("SetBlock", new SetBlock()); - // builtins.put("Sum", new Sum()); - // builtins.put("Naturals", new Naturals()); - // - // env = new EvaluationEnvironmentImpl(); - // - - // SpreadsheetResource sr = SpreadsheetResource.getInstance(graph); - // - // builtins.put("SUBSCRIPT", new Runnable() { - // - // @Override - // public void run() { - // - // try { - // - // int column = ((Double)stack.pop()).intValue(); - // int row = ((Double)stack.pop()).intValue(); - // Object value = stack.pop(); - // - // //System.out.println("subscript(value=" + value + " row=" + row + - // " column=" + column + ")"); - // - // if(value instanceof Collection) { - // stack.push(((Collection)value).toArray()[row]); - // } - // - // } catch (Throwable t) { - // t.printStackTrace(); - // } - // - // } - // - // }); - - } - - public Object getResult() { - return stack.pop(); - } - - public void outAConstantValue(AConstantValue node) { - if(DEBUG) System.out.println("outAConstantValue " + node); - stack.push(Double.valueOf(node.toString())); - } - - public void outAStringValue(AStringValue node) { - if(DEBUG) System.out.println("outAStringValue " + node); - String value = node.toString(); - stack.push(value.substring(1, value.length() - 2).trim()); - } - - public void outAAddressValue(AAddressValue node) { - if(DEBUG) System.out.println("outAAddressValue " + node); - stack.push('&' + node.getRange().toString()); - } - - @Override - public void outASingleRange(ASingleRange node) { - - if(DEBUG) System.out.println("outASingleRange " + node); - - } - - @Override - public void outARviValue(ARviValue node) { - - if(DEBUG) System.out.println("outARviValue " + node); - - String rvi = node.toString().trim(); - - try { - System.out.println("browsing at " + cellVariable.getURI(graph)); - Variable var = cellVariable.browse(graph, rvi); - stack.push(var); - } catch (DatabaseException e) { - e.printStackTrace(); - } - - } - - @Override - public void outAVariablePrimary(AVariablePrimary node) { - - if(DEBUG) System.out.println("outAVariablePrimary " + node); - - String identifier = node.toString().trim(); - - Range range = SpreadsheetUtils.decodeRange(identifier, row, column); - if (range.size() != 1) { - ArrayList value = new ArrayList(); - for (int c = range.startColumn; c <= range.endColumn; c++) { - for (int r = range.startRow; r <= range.endRow; r++) { - try { - String location = SpreadsheetUtils.cellName(r, c); - Variable cell = cellVariable.getChild(graph, location); - System.out.println("cell=" + cell.getURI(graph)); - String label = cell.getPossiblePropertyValue(graph, "Label"); - System.out.println("lavel=" + label); - value.add(label); - } catch (DatabaseException e) { - value.add(null); - } - } - } - stack.push(value); - // System.out.println("pushing " + value); - return; - } - -// try { -// String location = SpreadsheetUtils.cellName(range.startRow, -// range.startColumn); -// stack.push(graph.syncRequest(new CellResult(sheet, model, location))); -// } catch (DatabaseException e) { -// stack.push(null); -// } - - } - - public void outARangeValue(ARangeValue node) { - - if(DEBUG) System.out.println("outARangeValue " + node); - - String identifier = node.getRange().toString().trim(); - // try { - -// Range range = SpreadsheetUtils.decodeRange(identifier, row, column); -// // env.depend(range); -// if (range.size() != 1) { -// ArrayList value = new ArrayList(); -// for (int c = range.startColumn; c <= range.endColumn; c++) { -// for (int r = range.startRow; r <= range.endRow; r++) { -// try { -// String location = SpreadsheetUtils.cellName(r, c); -// -// value.add(graph -// .syncRequest(new CellResult(sheet, model, location))); -// } catch (DatabaseException e) { -// value.add(null); -// } -// } -// } -// stack.push(value); -// // System.out.println("pushing " + value); -// return; -// } -// -// try { -// String location = SpreadsheetUtils.cellName(range.startRow, -// range.startColumn); -// stack.push(graph.syncRequest(new CellResult(sheet, model, location))); -// } catch (DatabaseException e) { -// stack.push(null); -// } - - } - - 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) { - - if(DEBUG) System.out.println("outAPlusExpression " + 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 outAMultMultiplicative(AMultMultiplicative node) { - - if(DEBUG) System.out.println("outAMultiplicative " + 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); - } - - 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) { - - if(DEBUG) System.out.println("outAFunctionPrimary " + node); - - try { - - String functionName = node.getFunc().getText().replace("(", ""); - - if (DEBUG_APPLICATION) - System.out.println("function apply " + functionName); - - Function function = builtins.get(functionName); - if (function != null) { - - LinkedList args = new LinkedList(); - int argc = countArguments(node.getArgList()); - for (int i = 0; i < argc; i++) { - args.addFirst(stack.pop()); - } - args.addFirst(sheet); - args.addFirst(model); - - Object result = function.apply(graph, args); - stack.push(result); - - } else { - - Layer0 L0 = Layer0.getInstance(graph); - Instances instances = graph.adapt(L0.Function, Instances.class); - Collection functions = instances.find(graph, model, - "Name:" + functionName); - if (DEBUG_APPLICATION) - System.out.println("Found " + functions.size() + " matches."); - if (functions != null && functions.size() == 1) { - - Resource functionResource = functions.iterator().next(); - function = graph.adapt(functionResource, Function.class); - LinkedList args = new LinkedList(); - int argc = countArguments(node.getArgList()); - for (int i = 0; i < argc; i++) { - args.addFirst(stack.pop()); - } - args.addFirst(cellVariable); - //args.addFirst(model); - // System.out.println("args=" + - // Arrays.toString(args.toArray())); - Object result = function.apply(graph, args.toArray()); - stack.push(result); - - } else { - - stack.push(null); - - } - - } - - } catch (DatabaseException e) { - - stack.push(null); - - } - - } - -} +package org.simantics.spreadsheet.graph.request; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +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.AFunctionPrimary; +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.ASingleRange; +import org.simantics.basicexpression.node.AStringValue; +import org.simantics.basicexpression.node.AVariablePrimary; +import org.simantics.basicexpression.node.PArgList; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.Function; +import org.simantics.db.layer0.adapter.Instances; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.spreadsheet.Range; +import org.simantics.spreadsheet.Spreadsheets; + +public class SpreadsheetExpressionVisitor extends DepthFirstAdapter { + + public static final boolean DEBUG_APPLICATION = false; + public static final boolean DEBUG = false; + + public static class ApplicationException extends Exception { + + private static final long serialVersionUID = 1L; + + public ApplicationException(String message) { + super(message); + } + + } + + final ReadGraph graph; + final Variable cellVariable; + final Resource model; + final Resource sheet; + final int row; + final int column; + // final EvaluationEnvironmentImpl env; + Stack stack = new Stack(); + + HashMap builtins = new HashMap(); + + // class EvaluationEnvironmentImpl implements EvaluationEnvironment { + // + // private boolean ready = false; + // private boolean valid = true; + // public HashSet deps = new HashSet(); + // + // + // @Override + // public int getColumn() { + // return column; + // } + // + // @Override + // public Model getModel() { + // return model; + // } + // + // @Override + // public int getRow() { + // return row; + // } + // + // public void depend(Range range) { + // deps.add(range); + // } + // + // public void listen() { + // ready = true; + // } + // + // @Override + // public void invalidate() { + // // DependencyHandler handler = model.getAdapter(DependencyHandler.class); + // // handler.invalidate(row, column); + // if(!ready) return; + // valid = false; + // ThreadUtils.getNonBlockingWorkExecutor().execute(new Runnable() { + // + // @Override + // public void run() { + // + // Cell cell = model.get(row, column); + // UpdateHandler handler = cell.getAdapter(UpdateHandler.class); + // if(handler != null) handler.update(); + // + // } + // + // }); + // + // } + // + // @Override + // public boolean isDisposed() { + // return !valid; + // } + // + // } + + public SpreadsheetExpressionVisitor(ReadGraph graph, Variable cellVariable, int row, int column) throws DatabaseException { + + // assert(model != null); + // // assert(graph != null); + // // assert(sheet != null); + this.graph = graph; + this.cellVariable = cellVariable; + this.model = Variables.getModel(graph, cellVariable); + Resource cell = cellVariable.getPossiblePropertyValue(graph, Variables.RESOURCE); + this.sheet = graph.getPossibleObject(cell, Layer0.getInstance(graph).PartOf); +// this.sheet = sheet; +// this.model = model; + this.row = row; + this.column = column; + // + // builtins.put("Sequence", new Sequence()); + // builtins.put("Set", new Set()); + // builtins.put("SetBlock", new SetBlock()); + // builtins.put("Sum", new Sum()); + // builtins.put("Naturals", new Naturals()); + // + // env = new EvaluationEnvironmentImpl(); + // + + // SpreadsheetResource sr = SpreadsheetResource.getInstance(graph); + // + // builtins.put("SUBSCRIPT", new Runnable() { + // + // @Override + // public void run() { + // + // try { + // + // int column = ((Double)stack.pop()).intValue(); + // int row = ((Double)stack.pop()).intValue(); + // Object value = stack.pop(); + // + // //System.out.println("subscript(value=" + value + " row=" + row + + // " column=" + column + ")"); + // + // if(value instanceof Collection) { + // stack.push(((Collection)value).toArray()[row]); + // } + // + // } catch (Throwable t) { + // t.printStackTrace(); + // } + // + // } + // + // }); + + } + + public Object getResult() { + return stack.pop(); + } + + public void outAConstantValue(AConstantValue node) { + if(DEBUG) System.out.println("outAConstantValue " + node); + stack.push(Double.valueOf(node.toString())); + } + + public void outAStringValue(AStringValue node) { + if(DEBUG) System.out.println("outAStringValue " + node); + String value = node.toString(); + stack.push(value.substring(1, value.length() - 2).trim()); + } + + public void outAAddressValue(AAddressValue node) { + if(DEBUG) System.out.println("outAAddressValue " + node); + stack.push('&' + node.getRange().toString()); + } + + @Override + public void outASingleRange(ASingleRange node) { + + if(DEBUG) System.out.println("outASingleRange " + node); + + } + + @Override + public void outARviValue(ARviValue node) { + + if(DEBUG) System.out.println("outARviValue " + node); + + String rvi = node.toString().trim(); + + try { + System.out.println("browsing at " + cellVariable.getURI(graph)); + Variable var = cellVariable.browse(graph, rvi); + stack.push(var); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + @Override + public void outAVariablePrimary(AVariablePrimary node) { + + if(DEBUG) System.out.println("outAVariablePrimary " + node); + + String identifier = node.toString().trim(); + + Range range = Spreadsheets.decodeRange(identifier, row, column); + if (range.size() != 1) { + ArrayList value = new ArrayList(); + for (int c = range.startColumn; c <= range.endColumn; c++) { + for (int r = range.startRow; r <= range.endRow; r++) { + try { + String location = Spreadsheets.cellName(r, c); + Variable cell = cellVariable.getChild(graph, location); + System.out.println("cell=" + cell.getURI(graph)); + String label = cell.getPossiblePropertyValue(graph, "Label"); + System.out.println("lavel=" + label); + value.add(label); + } catch (DatabaseException e) { + value.add(null); + } + } + } + stack.push(value); + // System.out.println("pushing " + value); + return; + } + +// try { +// String location = SpreadsheetUtils.cellName(range.startRow, +// range.startColumn); +// stack.push(graph.syncRequest(new CellResult(sheet, model, location))); +// } catch (DatabaseException e) { +// stack.push(null); +// } + + } + + public void outARangeValue(ARangeValue node) { + + if(DEBUG) System.out.println("outARangeValue " + node); + + String identifier = node.getRange().toString().trim(); + // try { + +// Range range = SpreadsheetUtils.decodeRange(identifier, row, column); +// // env.depend(range); +// if (range.size() != 1) { +// ArrayList value = new ArrayList(); +// for (int c = range.startColumn; c <= range.endColumn; c++) { +// for (int r = range.startRow; r <= range.endRow; r++) { +// try { +// String location = SpreadsheetUtils.cellName(r, c); +// +// value.add(graph +// .syncRequest(new CellResult(sheet, model, location))); +// } catch (DatabaseException e) { +// value.add(null); +// } +// } +// } +// stack.push(value); +// // System.out.println("pushing " + value); +// return; +// } +// +// try { +// String location = SpreadsheetUtils.cellName(range.startRow, +// range.startColumn); +// stack.push(graph.syncRequest(new CellResult(sheet, model, location))); +// } catch (DatabaseException e) { +// stack.push(null); +// } + + } + + 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) { + + if(DEBUG) System.out.println("outAPlusExpression " + 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 outAMultMultiplicative(AMultMultiplicative node) { + + if(DEBUG) System.out.println("outAMultiplicative " + 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); + } + + 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) { + + if(DEBUG) System.out.println("outAFunctionPrimary " + node); + + try { + + String functionName = node.getFunc().getText().replace("(", ""); + + if (DEBUG_APPLICATION) + System.out.println("function apply " + functionName); + + Function function = builtins.get(functionName); + if (function != null) { + + LinkedList args = new LinkedList(); + int argc = countArguments(node.getArgList()); + for (int i = 0; i < argc; i++) { + args.addFirst(stack.pop()); + } + args.addFirst(sheet); + args.addFirst(model); + + Object result = function.apply(graph, args); + stack.push(result); + + } else { + + Layer0 L0 = Layer0.getInstance(graph); + Instances instances = graph.adapt(L0.Function, Instances.class); + Collection functions = instances.find(graph, model, + "Name:" + functionName); + if (DEBUG_APPLICATION) + System.out.println("Found " + functions.size() + " matches."); + if (functions != null && functions.size() == 1) { + + Resource functionResource = functions.iterator().next(); + function = graph.adapt(functionResource, Function.class); + LinkedList args = new LinkedList(); + int argc = countArguments(node.getArgList()); + for (int i = 0; i < argc; i++) { + args.addFirst(stack.pop()); + } + args.addFirst(cellVariable); + //args.addFirst(model); + // System.out.println("args=" + + // Arrays.toString(args.toArray())); + Object result = function.apply(graph, args.toArray()); + stack.push(result); + + } else { + + stack.push(null); + + } + + } + + } catch (DatabaseException e) { + + stack.push(null); + + } + + } + +}