diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java index 5d55493..d061f00 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JavaMethodBodyGenerator.java @@ -16,6 +16,7 @@ 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; @@ -46,8 +47,80 @@ Symbol.Memento sumMem = null; if (sum != null) { sumMem = sum.createMemento(); - sum.setImplName("stream().mapToInt(x->x).sum"); - sum.setImplOperatorType(Symbol.Type.METHOD); + 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.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); } // Create a map from type names (lower case) to their types. @@ -77,12 +150,13 @@ if (((StoreAttribute) dst.getAttribute()).isStored()) { // update stored state of dst resource (when every incoming edge is in push style) Expression updateExp = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); - String curState = updateExp.toImplementation(); + String[] sideEffects = new String[] {""}; + String curState = updateExp.toImplementation(sideEffects); String updateStatement; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = curState + ";"; + updateStatement = sideEffects[0]; } else { - updateStatement = dstResourceName + " = " + curState + ";"; + updateStatement = sideEffects[0] + dstResourceName + " = " + curState + ";"; } if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { update.addFirstStatement(updateStatement); @@ -123,14 +197,15 @@ inputIdentifierToStateAccessor.put(((ResourceNode) dIn.getSource()).getIdentifierTemplate(), JavaCodeGenerator.pullAccessor); } } + String[] sideEffects = new String[] {""}; if (!isContainedPush) { // All incoming edges are in PULL style. - String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pullAccessor).toImplementation(); - getter.addStatement("return " + curState + ";"); + String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pullAccessor).toImplementation(sideEffects); + getter.addStatement(sideEffects[0] + "return " + curState + ";"); } else { // At least one incoming edge is in PUSH style. - String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pullAccessor, inputIdentifierToStateAccessor).toImplementation(); - getter.addStatement("return " + curState + ";"); + String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, JavaCodeGenerator.pullAccessor, inputIdentifierToStateAccessor).toImplementation(sideEffects); + getter.addStatement(sideEffects[0] + "return " + curState + ";"); } } } @@ -157,13 +232,14 @@ Term message = (Term) out.getStateTransition().getMessageExpression(); MethodDeclaration input = getMethod(type, message.getSymbol().getName()); if (input != null) { + String[] sideEffects = new String[] {""}; Expression updateExp = ioChannelAndMember.getKey().deriveUpdateExpressionOf(out, JavaCodeGenerator.pushAccessor); - String newState = updateExp.toImplementation(); + String newState = updateExp.toImplementation(sideEffects); String updateStatement; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = newState + ";"; + updateStatement = sideEffects[0]; } else { - updateStatement = "this." + resourceName + " = " + newState + ";"; + updateStatement = sideEffects[0] + "this." + resourceName + " = " + newState + ";"; } if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { input.addFirstStatement(updateStatement); @@ -191,6 +267,7 @@ 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/JerseyMethodBodyGenerator.java b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java index ff6e7de..ee6d6de 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/JerseyMethodBodyGenerator.java @@ -49,8 +49,80 @@ Symbol.Memento sumMem = null; if (sum != null) { sumMem = sum.createMemento(); - sum.setImplName("stream().mapToInt(x->x).sum"); - sum.setImplOperatorType(Symbol.Type.METHOD); + 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.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); } // Create a map from type names (lower case) to their types. @@ -81,12 +153,13 @@ if (((StoreAttribute) dst.getAttribute()).isStored()) { // update stored state of dst resource (when every incoming edge is in push style) Expression updateExp = d.getChannelGenerator().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor); - String curState = updateExp.toImplementation(); + String[] sideEffects = new String[] {""}; + String curState = updateExp.toImplementation(sideEffects); String updateStatement; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = curState + ";"; + updateStatement = sideEffects[0]; } else { - updateStatement = dstResourceName + " = " + curState + ";"; + updateStatement = sideEffects[0] + dstResourceName + " = " + curState + ";"; } if (update.getBody() == null || !update.getBody().getStatements().contains(updateStatement)) { update.addFirstStatement(updateStatement); @@ -146,8 +219,9 @@ // for pull (or push/pull) data transfer MethodDeclaration getter = getGetterMethod(dstType); if (getter.getBody() == null || getter.getBody().getStatements().size() == 0) { - String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pullAccessor).toImplementation(); - getter.addStatement("return " + curState + ";"); + String[] sideEffects = new String[] {""}; + String curState = d.getChannelGenerator().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pullAccessor).toImplementation(sideEffects); + getter.addStatement(sideEffects[0] + "return " + curState + ";"); } getter.addFirstStatement(getHttpMethodCallStatement(baseURL, srcResourceName, "get", src.getIdentifierTemplate().getResourceStateType())); } @@ -173,12 +247,13 @@ MethodDeclaration input = getMethod(type, message.getSymbol().getName()); if (input != null) { Expression updateExp = ioChannelAndMember.getKey().deriveUpdateExpressionOf(out, JerseyCodeGenerator.pushAccessor); - String newState = updateExp.toImplementation(); + String[] sideEffects = new String[] {""}; + String newState = updateExp.toImplementation(sideEffects); String updateStatement; if (updateExp instanceof Term && ((Term) updateExp).getSymbol().isImplWithSideEffect()) { - updateStatement = newState + ";"; + updateStatement = sideEffects[0]; } else { - updateStatement = "this." + resourceName + " = " + newState + ";"; + updateStatement = sideEffects[0] + "this." + resourceName + " = " + newState + ";"; } if (input.getBody() == null || !input.getBody().getStatements().contains(updateStatement)) { input.addFirstStatement(updateStatement); @@ -194,6 +269,7 @@ 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/models/algebra/Constant.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java index 1e698ed..023e28d 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java @@ -32,7 +32,7 @@ return symbol.getName(); } - public String toImplementation() { + public String toImplementation(String[] sideEffects) { return symbol.getImplName(); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Expression.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Expression.java index a99f62b..872f54a 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Expression.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Expression.java @@ -14,7 +14,7 @@ return getSubTerms(Variable.class); } - public String toImplementation() { + public String toImplementation(String[] sideEffects) { return toString(); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Field.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Field.java index c1af7f8..f51b3c4 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Field.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Field.java @@ -39,7 +39,7 @@ return new Field(symbol); } - public String toImplementation() { - return "this." + super.toImplementation(); + public String toImplementation(String[] sideEffects) { + return "this." + super.toImplementation(sideEffects); } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java index ac91474..9d7cc57 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java @@ -9,6 +9,7 @@ private Symbol[] inverses = null; private models.algebra.Type[] signature = null; private int[] implParamOrder = null; + private IImplGenerator generator = null; public Symbol(String name) { this.name = name; @@ -45,6 +46,26 @@ this.implParamOrder = implParamOrder; } + public Symbol(String name, int arity, Type operatorType, IImplGenerator generator) { + this.name = name; + this.arity = arity; + this.operatorType = operatorType; + this.generator = generator; + this.implOperatorType = Type.GENERATIVE; + } + + public Symbol(String name, int arity, Type operatorType, IImplGenerator generator, boolean bSideEffect) { + this.name = name; + this.arity = arity; + this.operatorType = operatorType; + this.generator = generator; + if (!bSideEffect) { + this.implOperatorType = Type.GENERATIVE; + } else { + this.implOperatorType = Type.GENERATIVE_WITH_SIDE_EFFECT; + } + } + public void setArity(int arity) { this.arity = arity; } @@ -109,8 +130,14 @@ return (implOperatorType == Type.LAMBDA || implOperatorType == Type.LAMBDA_WITH_SIDE_EFFECT); } + public boolean isImplGenerative() { + return (implOperatorType == Type.GENERATIVE || implOperatorType == Type.GENERATIVE_WITH_SIDE_EFFECT); + } + public boolean isImplWithSideEffect() { - return (implOperatorType == Type.METHOD_WITH_SIDE_EFFECT || implOperatorType == Type.LAMBDA_WITH_SIDE_EFFECT); + return (implOperatorType == Type.METHOD_WITH_SIDE_EFFECT + || implOperatorType == Type.LAMBDA_WITH_SIDE_EFFECT + || implOperatorType == Type.GENERATIVE_WITH_SIDE_EFFECT); } public void setImplOperatorType(Type implOperatorType) { @@ -120,6 +147,17 @@ public int[] getImplParamOrder() { return implParamOrder; } + + public void setGenerator(IImplGenerator generator) { + this.generator = generator; + } + + public String generate(models.algebra.Type type, String[] childrenImpl, String[] sideEffects) { + if (generator != null) { + return generator.generate(type, childrenImpl, sideEffects); + } + return null; + } public boolean equals(Object another) { if (!(another instanceof Symbol)) return false; @@ -145,7 +183,9 @@ METHOD, METHOD_WITH_SIDE_EFFECT, LAMBDA, - LAMBDA_WITH_SIDE_EFFECT + LAMBDA_WITH_SIDE_EFFECT, + GENERATIVE, + GENERATIVE_WITH_SIDE_EFFECT } public Memento createMemento() { @@ -166,4 +206,8 @@ this.implOperatorType = implOperatorType; } } + + public interface IImplGenerator { + public String generate(models.algebra.Type type, String children[], String[] sideEffects); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java index d468d09..dc50323 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java @@ -206,7 +206,7 @@ } - public String toImplementation() { + public String toImplementation(String[] sideEffects) { int[] implParamOrder = symbol.getImplParamOrder(); if (symbol.isImplLambda()) { String[] components = symbol.getImplName().split("->"); @@ -215,48 +215,90 @@ String exp = components[1]; if (implParamOrder == null) { for (int i = 0; i < params.length; i++) { - exp = exp.replace(params[i], children.get(i).toImplementation()); + exp = exp.replace(params[i], children.get(i).toImplementation(sideEffects)); } } else { for (int i = 0; i < params.length; i++) { - exp = exp.replace(params[i], children.get(implParamOrder[i]).toImplementation()); + exp = exp.replace(params[i], children.get(implParamOrder[i]).toImplementation(sideEffects)); + } + } + if (symbol.isImplWithSideEffect()) { + sideEffects[0] = sideEffects[0] + exp; + if (implParamOrder == null) { + exp = children.get(0).toImplementation(new String[] {""}); + } else { + exp = children.get(implParamOrder[0]).toImplementation(new String[] {""}); } } return exp; } + if (symbol.isImplGenerative()) { + String childrenImpl[] = new String[children.size()]; + if (implParamOrder == null) { + for (int i = 0; i < children.size(); i++) { + childrenImpl[i] = children.get(i).toImplementation(sideEffects); + } + String exp = symbol.generate(getType(), childrenImpl, sideEffects); + if (symbol.isImplWithSideEffect()) { + sideEffects[0] = sideEffects[0] + exp; + exp = children.get(0).toImplementation(new String[] {""}); + } + return exp; + } else { + for (int i = 0; i < children.size(); i++) { + childrenImpl[i] = children.get(implParamOrder[i]).toImplementation(sideEffects); + } + String exp = symbol.generate(getType(), childrenImpl, sideEffects); + if (symbol.isImplWithSideEffect()) { + sideEffects[0] = sideEffects[0] + exp; + exp = children.get(implParamOrder[0]).toImplementation(new String[] {""}); + } + return exp; + } + } if (getArity() == 2 && symbol.isImplInfix()) { if (implParamOrder == null) { - return "(" + children.get(0).toImplementation() + symbol.toImplementation() + children.get(1).toImplementation() + ")"; + return "(" + children.get(0).toImplementation(sideEffects) + symbol.toImplementation() + children.get(1).toImplementation(sideEffects) + ")"; } else { - return "(" + children.get(implParamOrder[0]).toImplementation() + symbol.toImplementation() + children.get(implParamOrder[1]).toImplementation() + ")"; + return "(" + children.get(implParamOrder[0]).toImplementation(sideEffects) + symbol.toImplementation() + children.get(implParamOrder[1]).toImplementation(sideEffects) + ")"; } } if (getArity() >= 1 && symbol.isImplMethod()) { if (implParamOrder == null) { - String exp = children.get(0).toImplementation() + "." + symbol.toImplementation() + "("; + String exp = children.get(0).toImplementation(sideEffects) + "." + symbol.toImplementation() + "("; String delimiter = ""; for (int i = 1; i < children.size(); i++) { Expression e = children.get(i); - exp += (delimiter + e.toImplementation()); + exp += (delimiter + e.toImplementation(sideEffects)); delimiter = ","; } - return exp + ")"; + exp += ")"; + if (symbol.isImplWithSideEffect()) { + sideEffects[0] = sideEffects[0] + exp; + exp = children.get(0).toImplementation(new String[] {""}); + } + return exp; } else { - String exp = children.get(implParamOrder[0]).toImplementation() + "." + symbol.toImplementation() + "("; + String exp = children.get(implParamOrder[0]).toImplementation(sideEffects) + "." + symbol.toImplementation() + "("; String delimiter = ""; for (int i = 1; i < children.size(); i++) { Expression e = children.get(implParamOrder[i]); - exp += (delimiter + e.toImplementation()); + exp += (delimiter + e.toImplementation(sideEffects)); delimiter = ","; } - return exp + ")"; + exp += ")"; + if (symbol.isImplWithSideEffect()) { + sideEffects[0] = sideEffects[0] + exp; + exp = children.get(implParamOrder[0]).toImplementation(new String[] {""}); + } + return exp; } } else { if (implParamOrder == null) { String exp = symbol.toImplementation() + "("; String delimiter = ""; for (Expression e: children) { - exp += (delimiter + e.toImplementation()); + exp += (delimiter + e.toImplementation(sideEffects)); delimiter = ","; } return exp + ")"; @@ -265,7 +307,7 @@ String delimiter = ""; for (int i = 0; i < children.size(); i++) { Expression e = children.get(implParamOrder[i]); - exp += (delimiter + e.toImplementation()); + exp += (delimiter + e.toImplementation(sideEffects)); delimiter = ","; } return exp + ")"; diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java index 7599d14..39d644b 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java @@ -37,13 +37,26 @@ 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 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 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); public static final Symbol gt = new Symbol("gt", 2, Symbol.Type.PREFIX, ">", Symbol.Type.INFIX); public static final Symbol lt = new Symbol("lt", 2, Symbol.Type.PREFIX, "<", Symbol.Type.INFIX); - public static final Symbol tuple = new Symbol("tuple", -1, Symbol.Type.PREFIX, "new AbstractMap.SimpleEntry<>", Symbol.Type.PREFIX); + public static final Symbol tuple = new Symbol("tuple", -1, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { + @Override + public String generate(Type type, String[] childrenImpl, String[] sideEffects) { + String impl = "new AbstractMap.SimpleEntry<>(" + childrenImpl[0] + "$x)"; + for (int i = 1; i < childrenImpl.length - 1; i++) { + impl = impl.replace("$x", ", new AbstractMap.SimpleEntry<>(" + childrenImpl[i] + "$x)"); + } + impl = impl.replace("$x", ", " + childrenImpl[childrenImpl.length - 1]); + return impl; + } + }); public static final Symbol fst = new Symbol("fst", 1, Symbol.Type.PREFIX, "getKey", Symbol.Type.METHOD); public static final Symbol snd = new Symbol("snd", 1, Symbol.Type.PREFIX, "getValue", Symbol.Type.METHOD); @@ -56,6 +69,8 @@ cons.setInverses(new Symbol[] {head, tail}); cons.setSignature(new Type[] {typeList, null, typeList}); contains.setSignature(new Type[] {typeBoolean, typeList, null}); + get.setSignature(new Type[] {null, typeList, typeInt}); + set.setSignature(new Type[] {typeList, typeList, typeInt, null}); tuple.setSignature(new Type[] {typeTuple, null, null}); tuple.setInverses(new Symbol[] {fst, snd}); fst.setSignature(new Type[] {null, typeTuple}); @@ -85,6 +100,9 @@ addSymbol(head); addSymbol(tail); addSymbol(contains); + addSymbol(get); + addSymbol(set); + addSymbol(nil); addSymbol(cond); addSymbol(eq); addSymbol(neq); diff --git a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java index d8307eb..500d428 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java @@ -205,8 +205,13 @@ } else { // constant or variable try { - Double d = Double.parseDouble(symbolName); - exp = new Constant(symbolName); + Symbol symbol = model.getSymbol(symbolName); + if (symbol != null && symbol.getArity() == 0) { + exp = new Constant(symbol); + } else { + Double d = Double.parseDouble(symbolName); + exp = new Constant(symbolName); + } } catch (NumberFormatException e) { if (stream.checkNext() != null && stream.checkNext().equals(COLON)) { // when a type is specified. diff --git a/AlgebraicDataflowArchitectureModel/src/tests/ParseTest.java b/AlgebraicDataflowArchitectureModel/src/tests/ParseTest.java index 04ad162..56d3740 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/ParseTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/ParseTest.java @@ -38,7 +38,8 @@ for (ChannelGenerator c: model.getChannelGenerators()) { for (ChannelMember out: ((DataflowChannelGenerator) c).getOutputChannelMembers()) { - System.out.println("next" + out.getIdentifierTemplate().getResourceName() + " = " + ((DataflowChannelGenerator) c).deriveUpdateExpressionOf(out).toImplementation()); + String[] sideEffects = new String[] {""}; + System.out.println("next" + out.getIdentifierTemplate().getResourceName() + " = " + ((DataflowChannelGenerator) c).deriveUpdateExpressionOf(out).toImplementation(sideEffects)); } } diff --git a/AlgebraicDataflowArchitectureModel/src/tests/UpdateCodeGenerationTest.java b/AlgebraicDataflowArchitectureModel/src/tests/UpdateCodeGenerationTest.java index 870769f..7d9d901 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/UpdateCodeGenerationTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/UpdateCodeGenerationTest.java @@ -142,8 +142,9 @@ System.out.println(c1); try { + String[] sideEffects = new String[] {""}; System.out.println("-----"); - System.out.println(c1.deriveUpdateExpressionOf(c1_loyalty).toImplementation()); + System.out.println(c1.deriveUpdateExpressionOf(c1_loyalty).toImplementation(sideEffects)); System.out.println("-- PUSH --"); Expression loyaltyPushUpdate = c1.deriveUpdateExpressionOf(c1_loyalty, pushAccessor); @@ -154,13 +155,13 @@ break; } } - System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation() + ") {"); - System.out.println("\t" + fLoyalty + " = " + loyaltyPushUpdate.toImplementation() + ";"); + System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation(sideEffects) + ") {"); + System.out.println("\t" + fLoyalty + " = " + loyaltyPushUpdate.toImplementation(sideEffects) + ";"); System.out.println("}"); System.out.println("-- PULL --"); System.out.println(loyalty.getResourceStateType().getImplementationTypeName() + " " + loyltyGetter.toImplementation() + "() {"); - System.out.println("\t return " + c1.deriveUpdateExpressionOf(c1_loyalty, pullAccessor).toImplementation() + ";"); + System.out.println("\t return " + c1.deriveUpdateExpressionOf(c1_loyalty, pullAccessor).toImplementation(sideEffects) + ";"); System.out.println("}"); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined e) { @@ -204,8 +205,9 @@ System.out.println(c2); try { + String[] sideEffects = new String[] {""}; System.out.println("-----"); - System.out.println(c2.deriveUpdateExpressionOf(c2_history).toImplementation()); + System.out.println(c2.deriveUpdateExpressionOf(c2_history).toImplementation(sideEffects)); System.out.println("-- PUSH --"); Expression historyPushUpdate = c2.deriveUpdateExpressionOf(c2_history, pushAccessor); @@ -216,13 +218,13 @@ break; } } - System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation() + ") {"); - System.out.println("\t" + fHistory + " = " + historyPushUpdate.toImplementation() + ";"); + System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation(sideEffects) + ") {"); + System.out.println("\t" + fHistory + " = " + historyPushUpdate.toImplementation(sideEffects) + ";"); System.out.println("}"); System.out.println("-- PULL --"); System.out.println(history.getResourceStateType().getImplementationTypeName() + " " + historyGetter.toImplementation() + "() {"); - System.out.println("\t return " + c2.deriveUpdateExpressionOf(c2_history, pullAccessor).toImplementation() + ";"); + System.out.println("\t return " + c2.deriveUpdateExpressionOf(c2_history, pullAccessor).toImplementation(sideEffects) + ";"); System.out.println("}"); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined e) { @@ -266,8 +268,9 @@ System.out.println(c3); try { + String[] sideEffects = new String[] {""}; System.out.println("-----"); - System.out.println(c3.deriveUpdateExpressionOf(c3_total).toImplementation()); + System.out.println(c3.deriveUpdateExpressionOf(c3_total).toImplementation(sideEffects)); System.out.println("-- PUSH --"); Expression totalPushUpdate = c3.deriveUpdateExpressionOf(c3_total, pushAccessor); @@ -278,13 +281,13 @@ break; } } - System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation() + ") {"); - System.out.println("\t" + fTotal + " = " + totalPushUpdate.toImplementation() + ";"); + System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation(sideEffects) + ") {"); + System.out.println("\t" + fTotal + " = " + totalPushUpdate.toImplementation(sideEffects) + ";"); System.out.println("}"); System.out.println("-- PULL --"); System.out.println(total.getResourceStateType().getImplementationTypeName() + " " + totalGetter.toImplementation() + "() {"); - System.out.println("\t return " + c3.deriveUpdateExpressionOf(c3_total, pullAccessor).toImplementation() + ";"); + System.out.println("\t return " + c3.deriveUpdateExpressionOf(c3_total, pullAccessor).toImplementation(sideEffects) + ";"); System.out.println("}"); } catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage | UnificationFailed | ValueUndefined e) {