diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java index 93f04d5..8b4c569 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaCodeGenerator.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.HashSet; +import java.util.Set; import code.ast.Block; import code.ast.CompilationUnit; @@ -57,13 +58,15 @@ static public ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model) { ArrayList codes = new ArrayList<>(); - ArrayList resources = StoreResourceCheck(graph); +// ArrayList resources = StoreResourceCheck(graph); + Set resources = graph.getNodes(); TypeDeclaration mainType = new TypeDeclaration(mainTypeName); CompilationUnit mainCU = new CompilationUnit(mainType); mainCU.addImport(new ImportDeclaration("java.util.*")); codes.add(mainCU); - for (ResourceNode rn : resources) { + for (Node n : resources) { + ResourceNode rn = (ResourceNode) n; boolean f = false; String resourceName = rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() + rn.getIdentifierTemplate().getResourceName().substring(1); diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java index 00df97c..d8a8d9c 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java @@ -14,15 +14,12 @@ import models.algebra.Expression; import models.algebra.InvalidMessage; import models.algebra.ParameterizedIdentifierIsFutureWork; -import models.algebra.Symbol; import models.algebra.Term; -import models.algebra.Type; import models.algebra.UnificationFailed; import models.algebra.ValueUndefined; import models.algebra.Variable; import models.dataConstraintModel.ChannelGenerator; import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.DataConstraintModel; import models.dataConstraintModel.IdentifierTemplate; import models.dataFlowModel.DataFlowModel; import models.dataFlowModel.DataflowChannelGenerator; @@ -37,95 +34,6 @@ public class JavaMethodBodyGenerator { public static ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model, ArrayList codes) { - Symbol floor = model.getSymbol("floor"); - Symbol.Memento floorMem = null; - if (floor != null) { - floorMem = floor.createMemento(); - floor.setImplName("(int)Math.floor"); - floor.setImplOperatorType(Symbol.Type.PREFIX); - } - Symbol sum = model.getSymbol("sum"); - Symbol.Memento 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"); - Symbol.Memento 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"; - 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 += "Iterator<" + compType + "> i1 = " + childrenImpl[0] + ".iterator();\n"; - impl += "Iterator<" + compType + "> i2 = " + childrenImpl[1] + ".iterator();\n"; - impl += compType + " t1 = null;\n"; - impl += compType + " t2 = null;\n"; - impl += "while (i1.hasNext() || i2.hasNext()) {\n"; - impl += "\tif (t1 == null && i1.hasNext()) {\n"; - impl += "\t\tt1 = i1.next();\n"; - impl += "\t}\n"; - impl += "\tif (t2 == null && i2.hasNext()) {\n"; - impl += "\t\tt2 = i2.next();\n"; - impl += "\t}\n"; - impl += "\tif (t1 == null || (t2 != null && t1" + idxGetter + " > t2" + idxGetter + ")) {\n"; - impl += "\t\ttemp_l" + count[0] +".add(t2);\n"; - impl += "\t\tt2 = null;\n"; - impl += "\t} else {\n"; - impl += "\t\ttemp_l" + count[0] + ".add(t1);\n"; - impl += "\t\tt1 = null;\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}); - } - // Create a map from type names (lower case) to their types. Map typeMap = new HashMap<>(); for (CompilationUnit code: codes) { @@ -267,10 +175,6 @@ | InvalidMessage | UnificationFailed | ValueUndefined e1) { e1.printStackTrace(); } - - if (floor != null) floor.setMemento(floorMem); - if (sum != null) sum.setMemento(sumMem); - if (merge != null) merge.setMemento(mergeMem); return codes; } diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java index 8b35a6a..00d0b35 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyCodeGenerator.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.HashSet; +import java.util.Set; import code.ast.Annotation; import code.ast.Block; @@ -59,9 +60,11 @@ static public ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model) { ArrayList codes = new ArrayList<>(); - ArrayList resources = StoreResourceCheck(graph); +// ArrayList resources = StoreResourceCheck(graph); + Set resources = graph.getNodes(); - for (ResourceNode rn : resources) { + for (Node n : resources) { + ResourceNode rn = (ResourceNode) n; String resourceName = rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase() + rn.getIdentifierTemplate().getResourceName().substring(1); diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java index d0f5f6b..fccf7cf 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java @@ -17,14 +17,12 @@ import models.algebra.Expression; import models.algebra.InvalidMessage; import models.algebra.ParameterizedIdentifierIsFutureWork; -import models.algebra.Symbol; import models.algebra.Term; import models.algebra.Type; import models.algebra.UnificationFailed; import models.algebra.ValueUndefined; import models.dataConstraintModel.ChannelGenerator; import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.DataConstraintModel; import models.dataFlowModel.DataFlowModel; import models.dataFlowModel.DataflowChannelGenerator; import models.dataFlowModel.PushPullAttribute; @@ -39,95 +37,6 @@ private static String baseURL = "http://localhost:8080"; public static ArrayList doGenerate(ResourceDependencyGraph graph, DataFlowModel model, ArrayList codes) { - Symbol floor = model.getSymbol("floor"); - Symbol.Memento floorMem = null; - if (floor != null) { - floorMem = floor.createMemento(); - floor.setImplName("(int)Math.floor"); - floor.setImplOperatorType(Symbol.Type.PREFIX); - } - Symbol sum = model.getSymbol("sum"); - Symbol.Memento 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"); - Symbol.Memento 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"; - 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("AbstractMap.SimpleEntry")) { - idxGetter = ".getKey()"; - } - count[0]++; - String impl = ""; - impl += "" + interfaceType + " temp_l" + count[0] + " = new " + implType + "();\n"; - impl += "Iterator<" + compType + "> i1 = " + childrenImpl[0] + ".iterator();\n"; - impl += "Iterator<" + compType + "> i2 = " + childrenImpl[1] + ".iterator();\n"; - impl += compType + " t1 = null;\n"; - impl += compType + " t2 = null;\n"; - impl += "while (i1.hasNext() || i2.hasNext()) {\n"; - impl += "\tif (t1 == null && i1.hasNext()) {\n"; - impl += "\t\tt1 = i1.next();\n"; - impl += "\t}\n"; - impl += "\tif (t2 == null && i2.hasNext()) {\n"; - impl += "\t\tt2 = i2.next();\n"; - impl += "\t}\n"; - impl += "\tif (t1 == null || (t2 != null && t1" + idxGetter + " > t2" + idxGetter + ")) {\n"; - impl += "\t\ttemp_l" + count[0] +".add(t2);\n"; - impl += "\t\tt2 = null;\n"; - impl += "\t} else {\n"; - impl += "\t\ttemp_l" + count[0] + ".add(t1);\n"; - impl += "\t\tt1 = null;\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}); - } - // Create a map from type names (lower case) to their types. Map typeMap = new HashMap<>(); for (CompilationUnit code: codes) { @@ -269,10 +178,6 @@ | InvalidMessage | UnificationFailed | ValueUndefined e1) { e1.printStackTrace(); } - - if (floor != null) floor.setMemento(floorMem); - if (sum != null) sum.setMemento(sumMem); - if (merge != null) merge.setMemento(mergeMem); return codes; } diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index 7b37323..d035b02 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -9,7 +9,6 @@ import java.util.Map; import java.util.Set; -import models.Edge; import models.Node; import models.algebra.Expression; import models.algebra.Position; @@ -39,14 +38,14 @@ Map cons = new HashMap<>(); Map tuple = new HashMap<>(); Map> expToResource = new HashMap<>(); - Map> expToVariable = new HashMap<>(); + Map> expToVariable = new HashMap<>(); Map> expToMessage = new HashMap<>(); Map> expToCons = new HashMap<>(); Map> expToTuple = new HashMap<>(); Map idToRes = new HashMap<>(); Map> updateFromResource = new HashMap<>(); - Map> updateFromVariable = new HashMap<>(); + Map> updateFromVariable = new HashMap<>(); Map> updateFromMessage = new HashMap<>(); Map> updateFromCons = new HashMap<>(); Map> updateFromTuple = new HashMap<>(); @@ -133,14 +132,14 @@ } // Group expressions by variable. - Map> locals = new HashMap<>(); + Map> locals = new HashMap<>(); Map localTypes = new HashMap<>(); List allVariables = new ArrayList<>(); allVariables.addAll(st.getCurStateExpression().getVariables().values()); allVariables.addAll(st.getMessageExpression().getVariables().values()); allVariables.addAll(st.getNextStateExpression().getVariables().values()); for (Variable var: allVariables) { - List sameVariable = locals.get(var.getName()); + List sameVariable = locals.get(var.getName()); if (sameVariable == null) { sameVariable = new ArrayList<>(); sameVariable.add(var); @@ -151,13 +150,13 @@ sameVariable.add(var); expToVariable.put(System.identityHashCode(var), sameVariable); Type varType = localTypes.get(var.getName()); - Map updatedVars = getUpdateSet(updateFromVariable, sameVariable); + Map updatedVars = getUpdateSet(updateFromVariable, sameVariable); if (compareTypes(varType, var.getType())) { localTypes.put(var.getName(), var.getType()); - for (Variable v: sameVariable) { + for (Expression v: sameVariable) { if (v != var) { - if (compareTypes(v.getType(), var.getType())) { - v.setType(var.getType()); + if (compareTypes(((Variable) v).getType(), var.getType())) { + ((Variable) v).setType(var.getType()); updatedVars.put(System.identityHashCode(v), v); } } @@ -257,7 +256,7 @@ } } - Collection terms = new HashSet<>(); + List terms = new ArrayList<>(); if (st.getCurStateExpression() instanceof Term) { Map subTerms = ((Term) st.getCurStateExpression()).getSubTerms(Term.class); terms.addAll(subTerms.values()); @@ -272,30 +271,14 @@ } for (Term t: terms) { Symbol symbol = t.getSymbol(); - if (symbol.equals(DataConstraintModel.cons) || (symbol.getSignature() != null && symbol.getSignature()[0] == DataConstraintModel.typeList)) { + if (symbol.equals(DataConstraintModel.cons)) { // If the root symbol of the term is cons. List consExps = new ArrayList<>(); consExps.add(t); expToCons.put(System.identityHashCode(t), consExps); - if (symbol.equals(DataConstraintModel.cons)) { - for (Expression e: t.getChildren()) { - consExps.add(e); - expToCons.put(System.identityHashCode(e), consExps); - } - } else { - consExps.add(null); // consExps.get(1) - for (int i = 1; i < symbol.getSignature().length; i++) { - Type tc = symbol.getSignature()[i]; - if (tc == DataConstraintModel.typeList) { - Expression e = t.getChildren().get(i - 1); - consExps.add(e); // consExps.get(2) - expToCons.put(System.identityHashCode(e), consExps); - break; - } - } - if (consExps.size() < 2) { - consExps.add(null); - } + for (Expression e: t.getChildren()) { + consExps.add(e); + expToCons.put(System.identityHashCode(e), consExps); } Type newType = getExpTypeIfUpdatable(t.getType(), consExps.get(2)); if (newType != null) { @@ -370,7 +353,93 @@ Map updateExps = getUpdateSet(updateFromTuple, tupleExps); updateExps.put(System.identityHashCode(t), t); } - tuple.put(System.identityHashCode(tupleExps), t.getType()); + tuple.put(System.identityHashCode(tupleExps), t.getType()); + } else if (symbol.equals(DataConstraintModel.cond)) { + // If the root symbol of the term is if function. + Expression c1 = t.getChild(1); + Expression c2 = t.getChild(2); + List condTerms = new ArrayList<>(); + condTerms.add(t); + condTerms.add(c1); + condTerms.add(c2); + expToVariable.put(System.identityHashCode(t), condTerms); + expToVariable.put(System.identityHashCode(c1), condTerms); + expToVariable.put(System.identityHashCode(c2), condTerms); + Type condType = t.getType(); + Map updatedVars = getUpdateSet(updateFromVariable, condTerms); + Type child1Type = getExpTypeIfUpdatable(condType, c1); + if (child1Type != null) { + condType = child1Type; + t.setType(child1Type); + updatedVars.put(System.identityHashCode(t), t); + } else { + if (c1 instanceof Variable && compareTypes(((Variable) c1).getType(), condType)) { + ((Variable) c1).setType(condType); + updatedVars.put(System.identityHashCode(c1), c1); + } else if (c1 instanceof Term && compareTypes(((Term) c1).getType(), condType)) { + ((Term) c1).setType(condType); + updatedVars.put(System.identityHashCode(c1), c1); + } + } + Type child2Type = getExpTypeIfUpdatable(condType, c2); + if (child2Type != null) { + condType = child2Type; + t.setType(child2Type); + updatedVars.put(System.identityHashCode(t), t); + if (c1 instanceof Variable) { + ((Variable) c1).setType(child2Type); + updatedVars.put(System.identityHashCode(c1), c1); + } else if (c1 instanceof Term) { + ((Term) c1).setType(child2Type); + updatedVars.put(System.identityHashCode(c1), c1); + } + } else { + if (c2 instanceof Variable && compareTypes(((Variable) c2).getType(), condType)) { + ((Variable) c2).setType(condType); + updatedVars.put(System.identityHashCode(c2), c2); + } else if (c2 instanceof Term && compareTypes(((Term) c2).getType(), condType)) { + ((Term) c2).setType(condType); + updatedVars.put(System.identityHashCode(c2), c2); + } + } + variables.put(System.identityHashCode(condTerms), condType); + } else if (symbol.getSignature() != null && symbol.getSignature()[0] == DataConstraintModel.typeList) { + // If the root symbol of the term is the list type (except for the cons function). + List consExps = new ArrayList<>(); + consExps.add(t); + expToVariable.put(System.identityHashCode(t), consExps); + Type condType = t.getType(); + Map updatedVars = getUpdateSet(updateFromVariable, consExps); + for (int i = 1; i < symbol.getSignature().length; i++) { + Type tc = symbol.getSignature()[i]; + if (tc == DataConstraintModel.typeList) { + Expression e = t.getChildren().get(i - 1); + Type newType = getExpTypeIfUpdatable(condType, e); + if (newType != null) { + condType = newType; + for (Expression e2: consExps) { + if (e2 instanceof Variable) { + ((Variable) e2).setType(newType); + updatedVars.put(System.identityHashCode(e2), e2); + } else if (e2 instanceof Term) { + ((Term) e2).setType(newType); + updatedVars.put(System.identityHashCode(e2), e2); + } + } + } else { + if (e instanceof Variable && compareTypes(((Variable) e).getType(), condType)) { + ((Variable) e).setType(condType); + updatedVars.put(System.identityHashCode(e), e); + } else if (e instanceof Term && compareTypes(((Term) e).getType(), condType)) { + ((Term) e).setType(condType); + updatedVars.put(System.identityHashCode(e), e); + } + } + consExps.add(e); + expToVariable.put(System.identityHashCode(e), consExps); + } + } + variables.put(System.identityHashCode(consExps), condType); } } } @@ -394,11 +463,12 @@ if (updateFromVariable.size() > 0) { Set variableKeys = updateFromVariable.keySet(); Integer variableKey = variableKeys.iterator().next(); - Map variableValue = updateFromVariable.get(variableKey); + Map variableValue = updateFromVariable.get(variableKey); updateFromVariable.remove(variableKey); for (int i: variableValue.keySet()) { - Variable var = variableValue.get(i); + Expression var = variableValue.get(i); updateResourceTypes(var, resources, expToResource, updateFromResource); + updateVaribleTypes(var, variables, expToVariable, updateFromVariable); updateMessageTypes(var, messages, expToMessage, updateFromMessage); updateConsTypes(var, cons, expToCons, updateFromCons); updateTupleTypes(var, tuple, expToTuple, updateFromTuple); @@ -427,6 +497,7 @@ updateResourceTypes(consExp, resources, expToResource, updateFromResource); updateVaribleTypes(consExp, variables, expToVariable, updateFromVariable); updateMessageTypes(consExp, messages, expToMessage, updateFromMessage); + updateConsTypes(consExp, cons, expToCons, updateFromCons); updateTupleTypes(consExp, tuple, expToTuple, updateFromTuple); } } @@ -441,6 +512,7 @@ updateVaribleTypes(tupleExp, variables, expToVariable, updateFromVariable); updateMessageTypes(tupleExp, messages, expToMessage, updateFromMessage); updateConsTypes(tupleExp, cons, expToCons, updateFromCons); + updateTupleTypes(tupleExp, tuple, expToTuple, updateFromTuple); } } } @@ -472,19 +544,21 @@ } } - private static void updateVaribleTypes(Expression exp, Map variables, Map> expToVariable, Map> updateFromVariable) { - if (exp instanceof Variable) { - Variable var = (Variable) exp; - List sameVariable = expToVariable.get(System.identityHashCode(var)); - if (sameVariable == null) return; - Type varType = variables.get(System.identityHashCode(sameVariable)); - Type newVarType = getExpTypeIfUpdatable(varType, exp); - if (newVarType != null) { - variables.put(System.identityHashCode(sameVariable), newVarType); - Map updateVars = getUpdateSet(updateFromVariable, sameVariable); - for (Variable v: sameVariable) { - if (v != var) { - v.setType(newVarType); + private static void updateVaribleTypes(Expression exp, Map variables, Map> expToVariable, Map> updateFromVariable) { + List sameVariable = expToVariable.get(System.identityHashCode(exp)); + if (sameVariable == null) return; + Type varType = variables.get(System.identityHashCode(sameVariable)); + Type newVarType = getExpTypeIfUpdatable(varType, exp); + if (newVarType != null) { + variables.put(System.identityHashCode(sameVariable), newVarType); + Map updateVars = getUpdateSet(updateFromVariable, sameVariable); + for (Expression v: sameVariable) { + if (v != exp) { + if (v instanceof Variable) { + ((Variable) v).setType(newVarType); + updateVars.put(System.identityHashCode(v), v); + } else if (v instanceof Term) { + ((Term) v).setType(newVarType); updateVars.put(System.identityHashCode(v), v); } } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java index 8420a99..78a39ac 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JavaPrototypeGenerateAction.java @@ -15,6 +15,7 @@ import graphicalrefactor.editor.Editor; import models.dataConstraintModel.IdentifierTemplate; import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.ModelExtension; import models.dataFlowModel.ResourceDependencyGraph; public class JavaPrototypeGenerateAction extends AbstractEditorAction { @@ -35,6 +36,7 @@ if (graph != null) { DataFlowModel model = editor.getModel(); FinalDecisionOfStoringResourceStates.doDecide(graph); + ModelExtension.extendModel(model); TypeInference.infer(graph, model); String fileName = editor.getCurFileName(); String mainTypeName = fileName.split("\\.")[0]; @@ -51,6 +53,7 @@ JavaCodeGenerator.resetMainTypeName(); // use the default main type's name. } editor.setCodes(JavaMethodBodyGenerator.doGenerate(graph, model, JavaCodeGenerator.doGenerate(graph, model))); + ModelExtension.recoverModel(model); for (CompilationUnit file : editor.getCodes()) { System.out.println(file); } diff --git a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java index b1df27b..649185a 100644 --- a/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java +++ b/AlgebraicDataflowArchitectureModel/src/graphicalrefactor/actions/JerseyPrototypeGenerateAction.java @@ -16,6 +16,7 @@ import models.algebra.Type; import models.dataConstraintModel.IdentifierTemplate; import models.dataFlowModel.DataFlowModel; +import models.dataFlowModel.ModelExtension; import models.dataFlowModel.ResourceDependencyGraph; public class JerseyPrototypeGenerateAction extends AbstractEditorAction { @@ -36,6 +37,7 @@ if (graph != null) { DataFlowModel model = editor.getModel(); FinalDecisionOfStoringResourceStates.doDecide(graph); + ModelExtension.extendModel(model); TypeInference.infer(graph, model); String fileName = editor.getCurFileName(); String mainTypeName = fileName.split("\\.")[0]; @@ -52,6 +54,7 @@ JerseyCodeGenerator.resetMainTypeName(); // use the default main type's name. } editor.setCodes(JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model))); + ModelExtension.recoverModel(model); for (CompilationUnit file : editor.getCodes()) { System.out.println(file); } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java index 023e28d..d368dc8 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java @@ -25,7 +25,9 @@ @Override public Object clone() { - return new Constant(symbol); + Constant c = new Constant(symbol); + c.setType(type); + return c; } public String toString() { @@ -33,6 +35,10 @@ } public String toImplementation(String[] sideEffects) { + if (symbol.isImplGenerative()) { + String exp = symbol.generate(getType(), new String[] {}, sideEffects); + return exp; + } return symbol.getImplName(); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Position.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Position.java index d157bee..a11aa71 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Position.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Position.java @@ -41,6 +41,6 @@ } public int hashCode() { - return orders.size(); + return orders.hashCode(); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java index dc50323..74bf544 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java @@ -223,7 +223,7 @@ } } if (symbol.isImplWithSideEffect()) { - sideEffects[0] = sideEffects[0] + exp; + sideEffects[0] = sideEffects[0] + exp + ";"; if (implParamOrder == null) { exp = children.get(0).toImplementation(new String[] {""}); } else { @@ -274,7 +274,7 @@ } exp += ")"; if (symbol.isImplWithSideEffect()) { - sideEffects[0] = sideEffects[0] + exp; + sideEffects[0] = sideEffects[0] + exp + ";"; exp = children.get(0).toImplementation(new String[] {""}); } return exp; @@ -288,7 +288,7 @@ } exp += ")"; if (symbol.isImplWithSideEffect()) { - sideEffects[0] = sideEffects[0] + exp; + sideEffects[0] = sideEffects[0] + exp + ";"; exp = children.get(implParamOrder[0]).toImplementation(new String[] {""}); } return exp; diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 39d644b..c372588 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -22,25 +22,31 @@ public static final Type typeBoolean = new Type("Bool", "boolean"); public static final Type typeString = new Type("Str", "String"); public static final Type typeList = new Type("List", "ArrayList", "List"); -// public static final Type typeListOfStr = new Type("List", "ArrayList", "List", typeList); -// public static final Type typeListOfInt = new Type("List", "ArrayList", "List", typeList); -// public static final Type typeListOfFloat = new Type("List", "ArrayList", "List", typeList); -// public static final Type typeListOfDouble = new Type("List", "ArrayList", "List", typeList); -// public static final Type typeListOfList = new Type("List", "ArrayList", "List", typeList); -// public static final Type typeListOfTuple = new Type("List", "ArrayList", "List", typeList); public static final Type typeTuple = new Type("Tuple", "AbstractMap.SimpleEntry", "Map.Entry"); public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX); public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX);; public static final Symbol sub = new Symbol(Parser.SUB, 2, Symbol.Type.INFIX); public static final Symbol div = new Symbol(Parser.DIV, 2, Symbol.Type.INFIX); public static final Symbol minus = new Symbol(Parser.MINUS, 1); - public static final Symbol cons = new Symbol("cons", 2, Symbol.Type.PREFIX, "add", Symbol.Type.METHOD_WITH_SIDE_EFFECT, new int[] {1, 0}); + public static final Symbol cons = new Symbol("cons", 2, Symbol.Type.PREFIX, "($x,$y)->$x.add(0, $y)", Symbol.Type.LAMBDA_WITH_SIDE_EFFECT, new int[] {1, 0}); public static final Symbol head = new Symbol("head", 1, Symbol.Type.PREFIX, "($x)->$x.get(0)", Symbol.Type.LAMBDA); public static final Symbol tail = new Symbol("tail", 1, Symbol.Type.PREFIX, "($x)->$x.subList(1, $x.size())", Symbol.Type.LAMBDA); public static final Symbol get = new Symbol("get", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD); public static final Symbol set = new Symbol("set", 3, Symbol.Type.PREFIX, "set", Symbol.Type.METHOD_WITH_SIDE_EFFECT); public static final Symbol contains = new Symbol("contains", 2, Symbol.Type.PREFIX, "contains", Symbol.Type.METHOD); - public static final Symbol nil = new Symbol("nil", 0, Symbol.Type.PREFIX, "new ArrayList<>()", Symbol.Type.PREFIX); + public static final Symbol nil = new Symbol("nil", 0, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { + @Override + public String generate(Type type, String[] children, String[] sideEffects) { + String compType = ""; + if (type != null) { + String interfaceType = type.getInterfaceTypeName(); + if (interfaceType.contains("<")) { + compType = interfaceType.substring(interfaceType.indexOf("<") + 1, interfaceType.lastIndexOf(">")); + } + } + return "new ArrayList<" + compType + ">()"; + } + }); public static final Symbol cond = new Symbol("if", 3, Symbol.Type.PREFIX, "($x,$y,$z)->($x ? $y : $z)", Symbol.Type.LAMBDA); public static final Symbol eq = new Symbol("eq", 2, Symbol.Type.PREFIX, "==", Symbol.Type.INFIX); public static final Symbol neq = new Symbol("neq", 2, Symbol.Type.PREFIX, "!=", Symbol.Type.INFIX); diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ModelExtension.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ModelExtension.java new file mode 100644 index 0000000..b4b812f --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/ModelExtension.java @@ -0,0 +1,113 @@ +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"; + 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); + } +}