Newer
Older
AlgebraicDataflowArchitectureModel / AlgebraicDataflowArchitectureModel / src / models / dataFlowModel / ModelExtension.java
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);		
	}
}