package models.dataFlowModel; import models.algebra.Symbol; import models.algebra.Type; import models.dataConstraintModel.DataConstraintModel; public class ModelExtension { private static Symbol.Memento floorMem; private static Symbol.Memento sumMem; private static Symbol.Memento mergeMem; public static void extendModel(DataFlowModel model) { Symbol floor = model.getSymbol("floor"); floorMem = null; if (floor != null) { floorMem = floor.createMemento(); floor.setImplName("(int)Math.floor"); floor.setImplOperatorType(Symbol.Type.PREFIX); } Symbol sum = model.getSymbol("sum"); sumMem = null; if (sum != null) { sumMem = sum.createMemento(); final int[] count = new int[] {0}; sum.setGenerator(new Symbol.IImplGenerator() { @Override public String generate(Type type, String[] children, String[] sideEffects) { String compType = "Integer"; if (type != null) { String interfaceType = type.getInterfaceTypeName(); if (interfaceType.contains("<")) { compType = interfaceType.substring(interfaceType.indexOf("<") + 1, interfaceType.lastIndexOf(">")); } } count[0]++; String impl = compType + " " + "temp_sum" + count[0] + " = 0;\n"; impl += "for (" + compType + " x: " + children[0] + ") {\n"; impl += "\t" + "temp_sum" + count[0] + " += x;\n"; impl += "}\n"; sideEffects[0] = sideEffects[0] + impl; return "temp_sum" + count[0]; } }); sum.setImplOperatorType(Symbol.Type.GENERATIVE); sum.setSignature(new Type[] {DataConstraintModel.typeInt, DataConstraintModel.typeList}); // sum.setImplName("stream().mapToInt(x->x).sum"); // sum.setImplOperatorType(Symbol.Type.METHOD); } Symbol merge = model.getSymbol("merge"); mergeMem = null; if (merge != null) { mergeMem = merge.createMemento(); merge.setArity(2); final int[] count = new int[] {0}; merge.setGenerator(new Symbol.IImplGenerator() { @Override public String generate(Type type, String[] childrenImpl, String[] sideEffects) { String implType = "Arrayist<>"; String interfaceType = "List<Integer>"; String compType = "Integer"; if (type != null) { implType = type.getImplementationTypeName(); interfaceType = type.getInterfaceTypeName(); if (interfaceType.contains("<")) { compType = interfaceType.substring(interfaceType.indexOf("<") + 1, interfaceType.lastIndexOf(">")); } } String idxGetter = ""; if (compType.startsWith("Map.Entry")) { idxGetter = ".getKey()"; } count[0]++; String impl = ""; impl += "" + interfaceType + " temp_l" + count[0] + " = new " + implType + "();\n"; impl += "{\n"; impl += "\tIterator<" + compType + "> i1 = " + childrenImpl[0] + ".iterator();\n"; impl += "\tIterator<" + compType + "> i2 = " + childrenImpl[1] + ".iterator();\n"; impl += "\t" + compType + " t1 = null;\n"; impl += "\t" + compType + " t2 = null;\n"; impl += "\twhile (i1.hasNext() || i2.hasNext() || t1 != null || t2 != null) {\n"; impl += "\t\tif (t1 == null && i1.hasNext()) {\n"; impl += "\t\t\tt1 = i1.next();\n"; impl += "\t\t}\n"; impl += "\t\tif (t2 == null && i2.hasNext()) {\n"; impl += "\t\t\tt2 = i2.next();\n"; impl += "\t\t}\n"; impl += "\t\tif (t1 == null || (t2 != null && t1" + idxGetter + " < t2" + idxGetter + ")) {\n"; impl += "\t\t\ttemp_l" + count[0] +".add(t2);\n"; impl += "\t\t\tt2 = null;\n"; impl += "\t\t} else {\n"; impl += "\t\t\ttemp_l" + count[0] + ".add(t1);\n"; impl += "\t\t\tt1 = null;\n"; impl += "\t\t}\n"; impl += "\t}\n"; impl += "}\n"; sideEffects[0] = sideEffects[0] + impl; return "temp_l" + count[0]; } }); merge.setImplOperatorType(Symbol.Type.GENERATIVE); merge.setSignature(new Type[] {DataConstraintModel.typeList, DataConstraintModel.typeList, DataConstraintModel.typeList}); } } public static void recoverModel(DataFlowModel model) { Symbol floor = model.getSymbol("floor"); if (floor != null) floor.setMemento(floorMem); Symbol sum = model.getSymbol("sum"); if (sum != null) sum.setMemento(sumMem); Symbol merge = model.getSymbol("merge"); if (merge != null) merge.setMemento(mergeMem); } }