Commit e7f7dbed authored by Alexander David Hellwig's avatar Alexander David Hellwig
Browse files

Fixed: Arrays of size 1 generate wrong code

parent 0c0587f6
......@@ -34,6 +34,10 @@ public class Variable {
List<String> properties = new ArrayList<>();
Optional<String> customTypeName = Optional.empty();
public void setArray(boolean array) {
isArray = array;
}
public Variable() {
}
......@@ -241,7 +245,7 @@ public class Variable {
isArray = true;
Log.debug("set isArray to true of v: " + getName(), "VARIABLE");
} else {
isArray = false;
//keep array status until explicitly changed
}
}
}
......@@ -4,33 +4,36 @@ import de.monticore.lang.monticar.generator.BluePrint;
import de.monticore.lang.monticar.generator.Variable;
import de.se_rwth.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Sascha Schneiders
*/
public class BluePrintFixer {
public static void fixBluePrintVariableArrays(BluePrint bluePrint) {
List<Variable> newVars = new ArrayList<>();
for (Variable variable : bluePrint.getVariables()) {
String currentArrayName = variable.getNameWithoutArrayNamePart();
boolean add = true;
for (Variable newVar : newVars) {
if (currentArrayName.equals(newVar.getNameWithoutArrayNamePart())) {
newVar.setName(newVar.getNameWithoutArrayNamePart());
add = false;
newVar.setArraySize(newVar.getArraySize() + 1);
}
}
if (add)
newVars.add(variable);
}
for (Variable v : newVars) {
Log.info("v: " + v.getName() + " isArray: " + v.isArray() + " size: " + v.getArraySize() + " ", "NEW VAR:");
}
//Group variables of the same array
//Ports that are not part of an array are handled as array with size 1
Map<String, List<Variable>> nameToVariable = bluePrint.getVariables().stream()
.collect(Collectors.groupingBy(Variable::getNameWithoutArrayNamePart));
//Used to keep the original order
List<String> orderedUniqueNames = bluePrint.getVariables().stream()
.map(Variable::getNameWithoutArrayNamePart)
.distinct()
.collect(Collectors.toList());
//Only keep one and set the right array size
orderedUniqueNames.forEach((nameWithoutArray) -> {
List<Variable> varList = nameToVariable.get(nameWithoutArray);
Variable firstVar = varList.get(0);
firstVar.setName(nameWithoutArray);
firstVar.setArraySize(varList.size());
newVars.add(firstVar);
});
bluePrint.setVariables(newVars);
}
}
......@@ -24,6 +24,19 @@ import static org.junit.Assert.assertNotNull;
public class GenerationTest extends AbstractSymtabTest {
@Test
public void testSingleElemArray() throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources");
ExpandedComponentInstanceSymbol componentSymbol = symtab.<ExpandedComponentInstanceSymbol>resolve("test.singleElemArray", ExpandedComponentInstanceSymbol.KIND).orElse(null);
assertNotNull(componentSymbol);
GeneratorCPP generatorCPP = new GeneratorCPP();
generatorCPP.setGenerationTargetPath("./target/generated-sources-cpp/testSingleElemArray");
List<File> files = generatorCPP.generateFiles(symtab, componentSymbol, symtab);
String restPath = "testSingleElemArray/";
testFilesAreEqual(files, restPath);
}
@Test
public void testBasicConstantAssignment() throws IOException {
TaggingResolver symtab = createSymTabAndTaggingResolver("src/test/resources");
......
#ifndef HELPER_H
#define HELPER_H
#include <iostream>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/interpreter.h>
#include <stdarg.h>
#include <initializer_list>
class Helper
{
public:
static void init()
{
string_vector argv(2);
argv(0) = "embedded";
argv(1) = "-q";
octave_main(2, argv.c_str_vec(), 1);
//octave_debug=1;
//feval ("pkg", ovl ("load", "all"), 0);
}
static octave_value_list convertToOctaveValueList(double a)
{
octave_value_list in;
in(0) = a;
return in;
}
static octave_value_list convertToOctaveValueList(Matrix a)
{
octave_value_list in;
in(0) = a;
return in;
}
static octave_value_list convertToOctaveValueList(RowVector a)
{
octave_value_list in;
in(0) = a;
return in;
}
static octave_value_list convertToOctaveValueList(ColumnVector a)
{
octave_value_list in;
in(0) = a;
return in;
}
static octave_value_list convertToOctaveValueList(double a, double b)
{
octave_value_list in;
in(0) = a;
in(1) = b;
return in;
}
static octave_value_list convertToOctaveValueList(std::initializer_list<double> args)
{
octave_value_list in;
int counter = 0;
for(double element : args) {
in(counter) = octave_value(element);
++counter;
}
return in;
}
static octave_value_list convertToOctaveValueList(Matrix a, double b)
{
octave_value_list in;
in(0) = a;
in(1) = b;
return in;
}
static octave_value_list convertToOctaveValueList(RowVector a, double b)
{
octave_value_list in;
in(0) = a;
in(1) = b;
return in;
}
static octave_value_list convertToOctaveValueList(ColumnVector a, double b)
{
octave_value_list in;
in(0) = a;
in(1) = b;
return in;
}
static octave_value_list callOctaveFunction(octave_value_list in, std::string functionName,int argsOut)
{
/*octave_idx_type n = 2;
octave_value_list in;
for(octave_idx_type i = 0; i < n; i++)
in(i) = octave_value(5 * (i + 2));
octave_value_list out = feval("gcd", in, 1);
if(!error_state && out.length() > 0)
std::cout << "GCD of [" << in(0).int_value() << ", " << in(1).int_value() << "] is " << out(0).int_value()
<< std::endl;
else
std::cout << "invalid\n";
clean_up_and_exit(0);*/
/* if(functionName=="eigs")
return feval(functionName, in, 2);
else if(functionName=="kmeans")
return feval(functionName, in, 2);
*/
return feval(functionName, in, argsOut);
}
static int callOctaveFunctionIntFirstResult(octave_value_list in, std::string functionName, int argsOut)
{
// printf("callOctaveFunctionIntFirstResult pre return functionName: %s\n",functionName.c_str());
return callOctaveFunction(in, functionName,argsOut)(0).int_value();
}
static double callOctaveFunctionDoubleFirstResult(octave_value_list in, std::string functionName, int argsOut)
{
// printf("callOctaveFunctionDoubleFirstResult pre return functionName: %s\n",functionName.c_str());
return callOctaveFunction(in, functionName,argsOut)(0).double_value();
}
static Matrix callOctaveFunctionMatrixFirstResult(octave_value_list in, std::string functionName, int argsOut)
{
return callOctaveFunction(in, functionName,argsOut)(0).matrix_value();
}
static ColumnVector callOctaveFunctionColumnVectorFirstResult(octave_value_list in, std::string functionName, int argsOut)
{
printf("pre Call %s\n", functionName.c_str());
try {
in=octave_value_list();
octave_value_list list = callOctaveFunction(in, functionName,argsOut);
printf("post Call %s\n", functionName.c_str());
return list(0).array_value().as_column();
} catch(const std::exception& e) {
printf("%s\n", e.what());
}
return ColumnVector();
}
static RowVector callOctaveFunctionRowVectorFirstResult(octave_value_list in, std::string functionName, int argsOut)
{
return callOctaveFunction(in, functionName,argsOut)(0).array_value().as_row();
}
static int callOctaveFunctionIntSecondResult(octave_value_list in, std::string functionName, int argsOut)
{
return callOctaveFunction(in, functionName,argsOut)(1).int_value();
}
static double callOctaveFunctionDoubleSecondResult(octave_value_list in, std::string functionName, int argsOut)
{
return callOctaveFunction(in, functionName,argsOut)(1).double_value();
}
static Matrix callOctaveFunctionMatrixSecondResult(octave_value_list in, std::string functionName, int argsOut)
{
return callOctaveFunction(in, functionName,argsOut)(1).matrix_value();
}
static ColumnVector callOctaveFunctionColumnVectorSecondResult(octave_value_list in, std::string functionName, int argsOut)
{
return callOctaveFunction(in, functionName,argsOut)(1).array_value().as_column();
}
static RowVector callOctaveFunctionRowVectorSecondResult(octave_value_list in, std::string functionName, int argsOut)
{
return callOctaveFunction(in, functionName,argsOut)(1).array_value().as_row();
}
static Matrix getMatrixFromOctaveListFirstResult(octave_value_list list){
return list(0).matrix_value();
}
static RowVector getRowVectorFromOctaveListFirstResult(octave_value_list list){
return list(0).array_value().as_row();
}
static ColumnVector getColumnVectorFromOctaveListFirstResult(octave_value_list list){
return list(0).array_value().as_column();
}
static double getDoubleFromOctaveListFirstResult(octave_value_list list){
return list(0).double_value();
}
static int getIntFromOctaveListFirstResult(octave_value_list list){
return list(0).int_value();
}
static Matrix getSqrtMatrixDiag(Matrix A){
int rows = Helper::getDoubleFromOctaveListFirstResult(Fsize(Helper::convertToOctaveValueList(A),0));
for(int i=0;i<rows;++i){
double curVal = A(i,i);
A(i,i) = sqrt(curVal);
}
return A;
}
}
static Matrix invertDiagMatrix(mat A){
int rows = Helper::getDoubleFromOctaveListFirstResult(Fsize(Helper::convertToOctaveValueList(A),0));
for(int i=0;i<rows;++i){
double curVal = A(i,i);
A(i,i) = 1/curVal;
}
return A;
}
};
#endif // HELPER_H
\ No newline at end of file
#ifndef TEST_SINGLEELEMARRAY
#define TEST_SINGLEELEMARRAY
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include "octave/oct.h"
#include "test_singleElemArray_arrayComp_1_.h"
class test_singleElemArray{
public:
double arrayPort[1];
test_singleElemArray_arrayComp_1_ arrayComp[1];
void init()
{
arrayComp[0].init();
}
void execute()
{
arrayComp[0].execute();
}
};
#endif
#ifndef TEST_SINGLEELEMARRAY_ARRAYCOMP_1_
#define TEST_SINGLEELEMARRAY_ARRAYCOMP_1_
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include "octave/oct.h"
class test_singleElemArray_arrayComp_1_{
public:
void init()
{
}
void execute()
{
}
};
#endif
package test;
component SingleElemArray{
port in Q arrayPort[1];
component SubComp{
}
instance SubComp arrayComp[1];
}
\ No newline at end of file
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