Commit d085dd41 authored by Julian Dierkes's avatar Julian Dierkes
Browse files

adding ScaleCube command

parent 3aa54423
...@@ -202,6 +202,7 @@ ...@@ -202,6 +202,7 @@
<version>2.22.1</version> <version>2.22.1</version>
<configuration> <configuration>
<useSystemClassLoader>false</useSystemClassLoader> <useSystemClassLoader>false</useSystemClassLoader>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
......
package de.monticore.lang.monticar.generator.cpp.commands;
import de.monticore.lang.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math._symboltable.matrix.MathMatrixAccessSymbol;
import de.monticore.lang.math._symboltable.matrix.MathMatrixNameExpressionSymbol;
import de.monticore.lang.monticar.generator.*;
import de.monticore.lang.monticar.generator.cpp.BluePrintCPP;
import de.monticore.lang.monticar.generator.cpp.MathFunctionFixer;
import de.monticore.lang.monticar.generator.cpp.OctaveHelper;
import de.monticore.lang.monticar.generator.cpp.converter.ExecuteMethodGenerator;
import de.monticore.lang.monticar.generator.cpp.converter.MathConverter;
import de.monticore.lang.monticar.generator.cpp.symbols.MathStringExpression;
import de.se_rwth.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class MathScaleCubeCommand extends MathCommand {
//todo
private static final String SUM_SYNTAX_EXTENDED = "sum( EXPRESSION , SUM_VARIABLE , START_VALUE , END_VALUE )";
private static final String SCALER_METHOD_NAME = "scaleCube";
private static int scalerCommandCounter = 0;
public MathScaleCubeCommand() {
setMathCommandName("scaleCube");
}
@Override
public void convert(MathExpressionSymbol mathExpressionSymbol, BluePrint bluePrint) {
String backendName = MathConverter.curBackend.getBackendName();
if (backendName.equals("OctaveBackend")) {
convertUsingOctaveBackend(mathExpressionSymbol, bluePrint);
} else if (backendName.equals("ArmadilloBackend")) {
convertUsingArmadilloBackend(mathExpressionSymbol, bluePrint);
}
}
public void convertUsingOctaveBackend(MathExpressionSymbol mathExpressionSymbol, BluePrint bluePrint) {
MathMatrixNameExpressionSymbol mathMatrixNameExpressionSymbol = (MathMatrixNameExpressionSymbol) mathExpressionSymbol;
mathMatrixNameExpressionSymbol.setNameToAccess("");
String valueListString = "";
for (MathMatrixAccessSymbol accessSymbol : mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols())
MathFunctionFixer.fixMathFunctions(accessSymbol, (BluePrintCPP) bluePrint);
valueListString += ExecuteMethodGenerator.generateExecuteCode(mathExpressionSymbol, new ArrayList<>());
//OctaveHelper.getCallOctaveFunction(mathExpressionSymbol, "sum","Double", valueListString));
List<MathMatrixAccessSymbol> newMatrixAccessSymbols = new ArrayList<>();
MathStringExpression stringExpression = new MathStringExpression(OctaveHelper.getCallBuiltInFunction(mathExpressionSymbol, "Fsum", "Double", valueListString, "FirstResult", false, 1), mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols());
newMatrixAccessSymbols.add(new MathMatrixAccessSymbol(stringExpression));
mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().setMathMatrixAccessSymbols(newMatrixAccessSymbols);
((BluePrintCPP) bluePrint).addAdditionalIncludeString("octave/builtin-defun-decls");
// error if using extended syntax here
if (mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().size() == 4) {
//todo
Log.error(String.format("Syntax: \"%s\" is not supported when using deprecated backend Octave", SUM_SYNTAX_EXTENDED));
}
}
public void convertUsingArmadilloBackend(MathExpressionSymbol mathExpressionSymbol, BluePrint bluePrint) {
MathMatrixNameExpressionSymbol mathMatrixNameExpressionSymbol = (MathMatrixNameExpressionSymbol) mathExpressionSymbol;
mathMatrixNameExpressionSymbol.setNameToAccess("");
BluePrintCPP bluePrintCPP = (BluePrintCPP) bluePrint;
for (MathMatrixAccessSymbol accessSymbol : mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols())
MathFunctionFixer.fixMathFunctions(accessSymbol, bluePrintCPP);
if (mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().size() == 4) {
MathMatrixAccessSymbol cube = mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().get(0);
MathMatrixAccessSymbol axis = mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().get(1);
MathMatrixAccessSymbol new_x = mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().get(2);
MathMatrixAccessSymbol new_y = mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().get(3);
convertExtendedScalerImplementationArmadillo(mathMatrixNameExpressionSymbol, cube, axis, new_x, new_y, bluePrintCPP);
} else {
//todo
Log.error(String.format("No implementation found for sum operation: \"sum(%s)\". Possible syntax is \"sum( X )\", \"sum(X,dim)\" or \"%s\"", mathExpressionSymbol.getTextualRepresentation(), SUM_SYNTAX_EXTENDED));
}
}
private void convertSumImplementationArmadillo(MathMatrixNameExpressionSymbol mathMatrixNameExpressionSymbol, BluePrintCPP bluePrintCPP) {
String valueListString = ExecuteMethodGenerator.generateExecuteCode(mathMatrixNameExpressionSymbol, new ArrayList<>());
// correct index for armadillo
valueListString = valueListString.substring(0, valueListString.length() - 1) + "-1)";
MathStringExpression stringExpression = new MathStringExpression("sum" + valueListString, mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols());
List<MathMatrixAccessSymbol> newMatrixAccessSymbols = new ArrayList<>();
newMatrixAccessSymbols.add(new MathMatrixAccessSymbol(stringExpression));
mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().setMathMatrixAccessSymbols(newMatrixAccessSymbols);
}
/**
* Implements the sum command using Armadillos accu command
*
* @param mathMatrixNameExpressionSymbol MathMatrixNameExpressionSymbol passed to convert
* @param bluePrint BluePrint of current code generation
* @see <a href="http://arma.sourceforge.net/docs.html#accu">Armadillo Documentation</a>
*/
private void convertAccuSumImplementationArmadillo(MathMatrixNameExpressionSymbol mathMatrixNameExpressionSymbol, BluePrintCPP bluePrint) {
String valueListString = ExecuteMethodGenerator.generateExecuteCode(mathMatrixNameExpressionSymbol, new ArrayList<>());
//OctaveHelper.getCallOctaveFunction(mathExpressionSymbol, "sum","Double", valueListString));
MathStringExpression stringExpression = new MathStringExpression("accu" + valueListString, mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols());
List<MathMatrixAccessSymbol> newMatrixAccessSymbols = new ArrayList<>();
newMatrixAccessSymbols.add(new MathMatrixAccessSymbol(stringExpression));
mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().setMathMatrixAccessSymbols(newMatrixAccessSymbols);
bluePrint.addAdditionalIncludeString("HelperA"); // question: why? (CR)
}
/**
* Implements a sum function with syntax "sum( EXPRESSION , SUM_VARIABLE , START_VALUE , END_VALUE )"
* This syntax makes sum expressions easier to model.
*
* @param mathMatrixNameExpressionSymbol symbol to convert
* @param cube expression from which the sum is calculates
* @param axis name of the sum variable
* @param new_x start value of the sum variable
* @param new_y end value of the sum variable
*/
private void convertExtendedScalerImplementationArmadillo(MathMatrixNameExpressionSymbol mathMatrixNameExpressionSymbol, MathMatrixAccessSymbol cube, MathMatrixAccessSymbol axis, MathMatrixAccessSymbol new_x, MathMatrixAccessSymbol new_y, BluePrintCPP bluePrint) {
mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().setAccessStartSymbol("");
mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().setAccessEndSymbol("");
mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().clear();
// create method
Method calcSumMethod = getScalerCalculationMethod(cube, axis, new_x, new_y, bluePrint);
// create code string
String code = calcSumMethod.getTargetLanguageMethodCall();
MathStringExpression codeExpr = new MathStringExpression(code, mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols());
mathMatrixNameExpressionSymbol.getMathMatrixAccessOperatorSymbol().getMathMatrixAccessSymbols().add(new MathMatrixAccessSymbol(codeExpr));
// add method to bluePrint
bluePrint.addMethod(calcSumMethod);
}
private Method getScalerCalculationMethod(MathMatrixAccessSymbol cube, MathMatrixAccessSymbol axis, MathMatrixAccessSymbol new_x, MathMatrixAccessSymbol new_y, BluePrintCPP bluePrint) {
// create new method
Method method = getNewEmptyScalerCalculationMethod();
// generate function code
String c = ExecuteMethodGenerator.generateExecuteCode(cube, new ArrayList<>());
String a = ExecuteMethodGenerator.generateExecuteCode(axis, new ArrayList<>());
String n_x = ExecuteMethodGenerator.generateExecuteCode(new_x, new ArrayList<>());
String n_y = ExecuteMethodGenerator.generateExecuteCode(new_y, new ArrayList<>());
// add loop var
Variable loopVar = generateLoopVariable(c, bluePrint);
// parameters
setParameters(method, bluePrint);
// add instructions
method.addInstruction(ifClauses());
/*method.addInstruction(accumulatorInitialization());
method.addInstruction(forLoopHeader(varString, start, end));
method.addInstruction(forLoopBody(f));
method.addInstruction(returnAccumulator()); */
// add loopvar to children
addLoopVarParamToMethod(method, loopVar, bluePrint);
// delete loop var
bluePrint.getMathInformationRegister().getVariables().remove(loopVar);
return method;
}
private Method getNewEmptyScalerCalculationMethod() {
scalerCommandCounter++;
Method method = new Method();
method.setName(SCALER_METHOD_NAME + scalerCommandCounter);
method.setReturnTypeName("cube");
return method;
}
private void setParameters(Method method, BluePrint bluePrint) {
List<Variable> vars = bluePrint.getMathInformationRegister().getVariables();
for (int i = 0; i < vars.size() - 2; i++) { // the last variable is the one we are assigning now
method.addParameterUnique(vars.get(i));
}
}
private Variable generateLoopVariable(String name, BluePrint bluePrint) {
Variable loopVar = new Variable(name, Variable.FORLOOPINFO);
loopVar.setVariableType(new VariableType("Integer", "int", ""));
bluePrint.getMathInformationRegister().addVariable(loopVar);
return loopVar;
}
private Instruction ifClauses() {
return new Instruction() {
@Override
public String getTargetLanguageInstruction() {
return " cout << 'HelloWorld!' << endl; \n";
}
@Override
public boolean isConnectInstruction() {
return false;
}
};
}
private Instruction accumulatorInitialization() {
return new Instruction() {
@Override
public String getTargetLanguageInstruction() {
return " double res = 0; \n";
}
@Override
public boolean isConnectInstruction() {
return false;
}
};
}
private Instruction forLoopHeader(String sumVar, String sumStart, String sumEnd) {
return new Instruction() {
@Override
public String getTargetLanguageInstruction() {
return String.format(" for (int %s = %s; %s <= %s; %s++)\n", sumVar, sumStart, sumVar, sumEnd, sumVar);
}
@Override
public boolean isConnectInstruction() {
return false;
}
};
}
private Instruction forLoopBody(String func) {
return new Instruction() {
@Override
public String getTargetLanguageInstruction() {
return String.format(" res += %s;\n", func);
}
@Override
public boolean isConnectInstruction() {
return false;
}
};
}
private Instruction returnAccumulator() {
return new Instruction() {
@Override
public String getTargetLanguageInstruction() {
return " return res;\n";
}
@Override
public boolean isConnectInstruction() {
return false;
}
};
}
private void addLoopVarParamToMethod(Method method, Variable loopVar, BluePrintCPP bluePrint) {
String func = method.getInstructions().get(2).getTargetLanguageInstruction();
if (func.contains(SCALER_METHOD_NAME)) {
String[] split1 = func.split(SCALER_METHOD_NAME);
String[] split2 = split1[1].split("[)]");
func = SCALER_METHOD_NAME + split2[0] + ", " + loopVar.getNameTargetLanguageFormat() + ")";
// and change the method signiture of the calc sum function
String mName = SCALER_METHOD_NAME + split1[1].substring(0, split1[1].indexOf("("));
Optional<Method> affectedMethod = bluePrint.getMethod(mName);
if (affectedMethod.isPresent()) {
affectedMethod.get().addParameterUnique(loopVar);
addLoopVarParamToMethod(affectedMethod.get(), loopVar, bluePrint);
}
method.getInstructions().set(2, forLoopBody(func));
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment