Browse Source

Merge remote-tracking branch 'remotes/origin/au/window'

# Conflicts:
#	DSL_SemanticAdaptation/README.txt
Cláudio Gomes 4 years ago
parent
commit
04dd79e278
60 changed files with 4310 additions and 1014 deletions
  1. 0 0
      .gitmodules
  2. 1 0
      DSL_SemanticAdaptation/.gitignore
  3. 24 5
      DSL_SemanticAdaptation/README.txt
  4. 35 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.lib/pom.xml
  5. BIN
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/input/single_folder_spec/window/Window.fmu
  6. 0 30
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/input/single_folder_spec/window/modelDescription.xml
  7. 2 2
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppAutoTest.xtend
  8. 133 11
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest.xtend
  9. 0 93
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest2.xtend
  10. 0 112
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppModuleTest.xtend
  11. BIN
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/lazy/Controller.fmu
  12. 69 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/lazy/lazy.sa
  13. 117 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/lazy/lazy_canonical.sa
  14. BIN
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/Window.fmu
  15. 23 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/modelDescription.xml
  16. 231 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/windowSA.cpp
  17. 92 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/windowSA.h
  18. 35 18
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/input/single_folder_spec/window/window_sa_canonical.BASE.sa
  19. 56 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/window_sa_canonical_new.BASE.sa
  20. 19 18
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/META-INF/MANIFEST.MF
  21. 2 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/build.properties
  22. 54 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/pom.xml
  23. 0 39
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/CppGenerator.xtend
  24. 0 26
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/MapEntry.java
  25. 0 101
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/ModelDescriptionCreator.xtend
  26. 12 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/GlobalInOutVariable.java
  27. 19 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/InOutRulesBlockResult.java
  28. 6 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/InputOutputRuleType.java
  29. 31 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/MappedScalarVariable.java
  30. 186 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/ReturnInformation.java
  31. 12 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/RulesBlockResult.java
  32. 103 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/SAScalarVariable.java
  33. 9 9
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/SVCausality.java
  34. 9 9
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/SVType.java
  35. 8 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/SVVariability.java
  36. 114 91
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/ScalarVariable.java
  37. 7 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/exceptions/IncorrectAmountOfElementsException.java
  38. 8 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/exceptions/InvalidConversionException.java
  39. 8 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/exceptions/MissingScalarVariableInformationException.java
  40. 7 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/exceptions/TypeException.java
  41. 102 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/BuildUtilities.java
  42. 105 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ControlConditionSwitch.xtend
  43. 123 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/Conversions.java
  44. 585 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/CppGenerator.xtend
  45. 44 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/GeneralConditionSwitch.xtend
  46. 46 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/InRulesConditionSwitch.xtend
  47. 107 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ModelDescription.xtend
  48. 19 5
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/ModelDescriptionBuilder.java
  49. 40 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ModelDescriptionCreator.java
  50. 27 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/OutRulesConditionSwitch.xtend
  51. 40 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ParamConditionSwitch.xtend
  52. 440 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/RulesConditionSwitch.xtend
  53. 428 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/StaticGenerators.xtend
  54. 10 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.testframework/pom.xml
  55. 317 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.testframework/src/be/uantwerpen/ansymo/semanticadaptation/testframework/StaticGenerators.xtend
  56. 410 410
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.ui/plugin.xml_gen
  57. 10 10
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/plugin.xml_gen
  58. 1 0
      DSL_SemanticAdaptation/pom.xml
  59. 6 5
      Jenkinsfile
  60. 18 18
      ModelicaModels/Window.mo

+ 0 - 0
.gitmodules


+ 1 - 0
DSL_SemanticAdaptation/.gitignore

@@ -0,0 +1 @@
+*.project

+ 24 - 5
DSL_SemanticAdaptation/README.txt

@@ -1,18 +1,37 @@
-Installation Instructions:
+# Checkout
+
+```bash
+git clone <repo-url>
+git submodule update --init --recursive
+```
+
+# Development environmant:
+
+Install instructions:
 - Download Eclipse NEON (64 bits) installer.
 - Run it, and select "Eclipse DSL Tools" environment.
 or if you already have Eclipse DSL Tools, then just install the xText plugins as follows:
 	http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/
 		select plugins `Xtend IDE` and `Xtend Complete SDK`, and install
 
+# Compilation
+
+## Using Eclipse
+Generation and Compilation
+- Import all projects in this folder.
+- Right click in be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/SemanticAdaptation.xtext   and select "run as -> generate xtext artifacts"
+- Check that the console log is similar to the one in File "first_generation_sucessful_log.txt".
+
+## Using Maven
 - In CONSOLE run "mvn package" in DSL_SemanticAdaptation
 - In eclipse choose import -> Maven -> Existing Maven Projects and choose the LEAF nodes
 - Might be necessary to right click on a project -> Maven -> Update project
 
-Build Instructions:
-mvn clean
-mvn package
+```bash
+# Perform a clean build
+mvn clean package
+```
 
-Other tasks:
+### Other tasks:
 	Run the plugin: 
 		After building everything, right-click /be.uantwerpen.ansymo.semanticadaptation -> run as -> eclipse application

+ 35 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.lib/pom.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<relativePath>../pom.xml</relativePath>
+		<groupId>be.uantwerpen.ansymo.semanticadaptation</groupId>
+		<artifactId>parent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>be.uantwerpen.ansymo.semanticadaptation.cg.cpp.lib</artifactId>
+	<packaging>jar</packaging>
+
+	<name>be.uantwerpen.ansymo.semanticadaptation Code Generation to C++ Framework</name>
+
+
+
+	<build>
+
+		<resources>
+			<resource>
+				<directory>src/resources/hybridCosimulation-framework/semantic-adaptation</directory>
+				<targetPath>${project.build.directory}/classes/hybridCosimulation-framework</targetPath>
+				<filtering>false</filtering>
+				<includes>
+					<include>**/*</include>
+				</includes>
+			</resource>
+		</resources>
+
+  </build>
+
+
+</project>

BIN
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/input/single_folder_spec/window/Window.fmu


+ 0 - 30
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/input/single_folder_spec/window/modelDescription.xml

@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<fmiModelDescription fmiVersion="2.0" modelName="SingleWatertank" guid="{cfc65592-9ece-4563-9705-1581b6e7071c}" generationTool="20-sim" numberOfEventIndicators="0" copyright="Controllab Products B.V." license="-">
-<CoSimulation modelIdentifier="SingleWatertank" needsExecutionTool="false" canHandleVariableCommunicationStepSize="true" canInterpolateInputs="false" maxOutputDerivativeOrder="0" canRunAsynchronuously="false" canBeInstantiatedOnlyOncePerProcess="true" canNotUseMemoryManagementFunctions="true" canGetAndSetFMUstate="false" canSerializeFMUstate="false" providesDirectionalDerivative="false" />
-
-<ModelVariables>
-<ScalarVariable name="reaction_force" valueReference="1" variability="continuous" causality="input">
-<Real start="0.0" />
-</ScalarVariable>
-<ScalarVariable name="displacement" valueReference="2" variability="continuous" causality="input">
-<Real start="0.0" />
-</ScalarVariable>
-<ScalarVariable name="speed" valueReference="3" variability="continuous" causality="input">
-<Real start="0.0" />
-</ScalarVariable>
-
-<ScalarVariable name="disp" valueReference="4" variability="continuous" causality="output">
-<Real />
-</ScalarVariable>
-<ScalarVariable name="tau" valueReference="5" variability="continuous" causality="output">
-<Real />
-</ScalarVariable>
-
-</ModelVariables>
-<ModelStructure>
-<Outputs>
-<Unknown index="4" />
-<Unknown index="5" />
-</Outputs>
-</ModelStructure>
-</fmiModelDescription>

+ 2 - 2
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppAutoTest.xtend

@@ -3,7 +3,6 @@
  */
 package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests
 
-import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.CppGenerator
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
 import be.uantwerpen.ansymo.semanticadaptation.testframework.XtextParametersRunnerFactory
 import be.uantwerpen.ansymo.semanticadaptation.tests.AbstractSemanticAdaptationTest
@@ -27,6 +26,7 @@ import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 import org.junit.runners.Parameterized.Parameters
 import org.junit.Ignore
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.CppGenerator
 
 @RunWith(typeof(Parameterized))
 @InjectWith(SemanticAdaptationInjectorProvider)
@@ -44,7 +44,7 @@ class CgCppAutoTest extends AbstractSemanticAdaptationTest {
 	@Parameters(name = "{index}")
 	def static Collection<Object[]> data() {
 		val files = new ArrayList<List<File>>();
-		listf("input/single_folder_spec", files);
+		listf("test_input/single_folder_spec", files);
 		val test = new ArrayList();
 		test.add(files.get(0));
 		//val test2 = new ArrayList();

+ 133 - 11
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest.xtend

@@ -3,45 +3,164 @@
  */
 package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests
 
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.BuildUtilities
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.CppGenerator
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
 import be.uantwerpen.ansymo.semanticadaptation.tests.AbstractSemanticAdaptationTest
 import be.uantwerpen.ansymo.semanticadaptation.tests.SemanticAdaptationInjectorProvider
 import com.google.inject.Inject
+import java.io.File
+import java.io.FileWriter
+import java.nio.file.Files
 import java.util.regex.Pattern
 import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.resource.ResourceSet
+import org.eclipse.xtext.generator.IGeneratorContext
+import org.eclipse.xtext.generator.InMemoryFileSystemAccess
 import org.eclipse.xtext.testing.InjectWith
 import org.eclipse.xtext.testing.XtextRunner
 import org.eclipse.xtext.testing.util.ParseHelper
 import org.eclipse.xtext.testing.validation.ValidationTestHelper
 import org.junit.Test
 import org.junit.runner.RunWith
-import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.CppGenerator
-import org.eclipse.xtext.generator.InMemoryFileSystemAccess
-import org.eclipse.xtext.generator.IGeneratorContext
-import org.eclipse.emf.ecore.resource.ResourceSet
+import be.uantwerpen.ansymo.semanticadaptation.testframework.StaticGenerators
 import org.junit.Ignore
 
 @RunWith(XtextRunner)
 @InjectWith(SemanticAdaptationInjectorProvider)
 class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 
-	// @Inject CppGenerator underTest
+// @Inject CppGenerator underTest
 	@Inject extension ParseHelper<SemanticAdaptation>
 	@Inject extension  ValidationTestHelper
 
+	@Ignore
+	@Test def window_sa_canonical() {
+		__parseNoErrors('test_input/single_folder_spec/window/window_sa_canonical.BASE.sa', 'generated', "powerwindow");
+//		__parseNoErrorsWithValidation('test_input/single_folder_spec/window',
+//			'test_input/single_folder_spec/window/window_sa_canonical.BASE.sa');
+	}
+	
+	@Test def window_sa_canonical_new() {
+		__parseNoErrors('test_input/single_folder_spec/window/window_sa_canonical_new.BASE.sa', 'generated', "powerwindow");
+	}
 	
-	@Test def powerwindow_model_only() { __parseNoErrors('input/single_folder_spec/window/window_sa_canonical.BASE.sa') }
+	@Test def lazy_sa_canonical() {
+		__parseNoErrors('test_input/single_folder_spec/lazy/lazy_canonical.sa', 'generated', "lazy");
+	}
+
+	def __parseNoErrorsWithValidation(String directory, String filename) {
+		val model = __parse(filename);
+		__assertNoParseErrors(model, filename);
+
+		val correctFileDirectory = new File(directory + File.separator + "correct");
+
+		val fsa = new InMemoryFileSystemAccess()
+		val IGeneratorContext ctxt = null;
+		val cppGen = new CppGenerator();
+		cppGen.doGenerate(model.eResource, fsa, ctxt);
+
+		for (files : fsa.allFiles.entrySet) {
+			val filename2 = files.key.substring(14);
+			val file = new File(correctFileDirectory, filename2);
+			val correctFileContent = Files.readAllLines(file.toPath);
+
+			var path = new File("generated");
+			if (path.exists)
+				path.delete
+			else
+				path.mkdir;
+
+			path = new File(path, files.key.substring(14))
+
+			val FileWriter writer = new FileWriter(path);
+			writer.write(files.value.toString);
+			writer.close;
+
+			val testFileContent = Files.readAllLines(path.toPath);
+
+			if (correctFileContent.size != testFileContent.size) {
+				System.out.println("Error: Lines are of different length in file: " + filename2);
+			} else {
+				val error = false;
+				for (var i = 0; i < testFileContent.size; i++) {
+					val testLine = testFileContent.get(i);
+					val correctLine = correctFileContent.get(i);
+					if (testLine.compareTo(correctLine) != 0) {
+						if (!testLine.contains("guid")) {
+							System.out.println("ERROR: The following lines are not equal: \n" + testLine + "\n" +
+								correctLine);
+						}
+					}
+				}
+			}
+		}
+
+	}
+
+
+	def __parseNoErrors(String filename, String directory, String projectName) {
+		val saRootDir = new File(directory + File.separatorChar + projectName);
+		val srcGenPath = new File(saRootDir, "sources")
+		val resourcesPath = new File(saRootDir, "resources");
+		val saFrameworkPath = new File(saRootDir, "framework")
+
+		System.out.println("Rootdir: " + saRootDir.absolutePath)
 
-	def __parseNoErrors(String filename) {
 		val model = __parse(filename)
 		__assertNoParseErrors(model, filename)
 
-		val fsa = new InMemoryFileSystemAccess()
+		val fsa = new InMemoryFileSystemAccess();
 		val IGeneratorContext ctxt = null;
-		new CppGenerator().doGenerate(model.eResource, fsa, ctxt);
+		val cppGen = new CppGenerator();
+		cppGen.doGenerate(model.eResource, fsa, ctxt);
+		
+		if (saRootDir.exists) {
+			BuildUtilities.deleteFolder(saRootDir);
+		}
+				
+		saRootDir.mkdirs();
+		srcGenPath.mkdirs();
+		resourcesPath.mkdirs();
+		saFrameworkPath.mkdirs();
+
+		for (files : fsa.allFiles.entrySet) {
+			val fName = files.key.substring(14);
+			
+			var File fp;
+			if(fName.equals("modelDescription.xml"))
+			{
+				fp = new File(saRootDir, fName);
+			}
+			else
+			{
+				fp = new File(srcGenPath, fName);
+			}
+			
+			BuildUtilities.writeToFile(fp, files.value.toString);	
+		}
+		
+		val mainCpp = StaticGenerators.generateMainCppFile(saRootDir.absolutePath.replace("\\","\\\\"));
+		BuildUtilities.writeToFile(new File(srcGenPath,"main.cpp"), mainCpp);
+		
+		
+		for(rf : cppGen.resourcePaths)
+		{
+			val sinkFile = new File(resourcesPath, rf.name);
+			System.out.println("Copied file to: " + sinkFile);
+			BuildUtilities.copyFile(rf, sinkFile);	
+		}			
+		
+		
+		BuildUtilities.writeToFile(new File(saRootDir,"CMakeLists.txt"), StaticGenerators.generateCMakeLists(projectName, "framework"));
+		
+		val cMakeToolChain = StaticGenerators.generateToolChainCmake();
+		BuildUtilities.writeToFile(new File(saRootDir, "msys-toolchain.cmake"), cMakeToolChain);
 		
+		(new BuildUtilities()).copyNativeLibFiles(saFrameworkPath);
+		System.out.println("Stored framework at: " + saFrameworkPath);
 		
-		System.out.println(fsa.allFiles)		
+				
 	}
 
 	def __parseNoErrorsPrint(String filename) {
@@ -54,7 +173,10 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 		return readFile(filename).parse
 	}
 
-	def __parse(String filename, ResourceSet resourceSetToUse) {
+	def __parse(
+		String filename,
+		ResourceSet resourceSetToUse
+	) {
 
 		return readFile(filename).parse(resourceSetToUse)
 	}

+ 0 - 93
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest2.xtend

@@ -1,93 +0,0 @@
-/*
- * generated by Xtext 2.10.0
- */
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests
-
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
-import be.uantwerpen.ansymo.semanticadaptation.tests.AbstractSemanticAdaptationTest
-import be.uantwerpen.ansymo.semanticadaptation.tests.SemanticAdaptationInjectorProvider
-import com.google.inject.Inject
-import java.util.regex.Pattern
-import org.eclipse.emf.ecore.EObject
-import org.eclipse.xtext.testing.InjectWith
-import org.eclipse.xtext.testing.XtextRunner
-import org.eclipse.xtext.testing.util.ParseHelper
-import org.eclipse.xtext.testing.validation.ValidationTestHelper
-import org.junit.Test
-import org.junit.runner.RunWith
-import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.CppGenerator
-import org.eclipse.xtext.generator.InMemoryFileSystemAccess
-import org.eclipse.xtext.generator.IGeneratorContext
-import org.eclipse.emf.ecore.resource.ResourceSet
-import org.junit.Ignore
-
-@RunWith(XtextRunner)
-@InjectWith(SemanticAdaptationInjectorProvider)
-class CgCppBasicTest2 extends AbstractSemanticAdaptationTest {
-
-	// @Inject CppGenerator underTest
-	@Inject extension ParseHelper<SemanticAdaptation>
-	@Inject extension  ValidationTestHelper
-
-	@Ignore
-	@Test def powerwindow_model_only() { __parseNoErrors('input/window/window_sa_canonical.BASE.sa') }
-
-	def __parseNoErrors(String filename) {
-		val model = __parse(filename)
-		__assertNoParseErrors(model, filename)
-
-		val fsa = new InMemoryFileSystemAccess()
-		val IGeneratorContext ctxt = null;
-		new CppGenerator().doGenerate(model.eResource, fsa, ctxt)
-
-		System.out.println(fsa.allFiles)
-	}
-
-	def __parseNoErrorsPrint(String filename) {
-		val root = __parse(filename)
-		print_ast(root)
-		__assertNoParseErrors(root, filename)
-	}
-
-	def __parse(String filename) {
-		val model = readFile(filename).parse
-		return model;
-	}
-
-	def __parse(String filename, ResourceSet resourceSetToUse) {
-
-		return readFile(filename).parse(resourceSetToUse)
-	}
-
-	def __assertNoParseErrors(EObject root, String filename) {
-		try {
-			root.assertNoErrors
-		} catch (AssertionError e) {
-			val p = Pattern.compile(".*, offset (?<offset>[0-9]+), length (?<length>[0-9]+)")
-			val code = readFile(filename)
-			for (String line : e.message.split("\n")) {
-				val m = p.matcher(line)
-				m.matches()
-				val count = __occurrencesInString(code.subSequence(0, Integer.valueOf(m.group("offset"))).toString(),
-					"\n")
-				print(filename + " at line " + (count + 1) + ": ")
-				println(line)
-			}
-			throw e
-		}
-	}
-
-	def __occurrencesInString(String str, String findstr) {
-		var lastIndex = 0
-		var count = 0
-		while (lastIndex != -1) {
-			lastIndex = str.indexOf(findstr, lastIndex)
-			if (lastIndex != -1) {
-				count++
-				lastIndex += findstr.length()
-			}
-		}
-		return count
-	}
-
-}

+ 0 - 112
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppModuleTest.xtend

@@ -1,112 +0,0 @@
-/*
- * generated by Xtext 2.10.0
- */
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests
-
-import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.CppGenerator
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
-import be.uantwerpen.ansymo.semanticadaptation.tests.AbstractSemanticAdaptationTest
-import be.uantwerpen.ansymo.semanticadaptation.tests.SemanticAdaptationInjectorProvider
-import com.google.inject.Inject
-import java.io.File
-import java.util.regex.Pattern
-import org.eclipse.emf.ecore.EObject
-import org.eclipse.emf.ecore.resource.ResourceSet
-import org.eclipse.xtext.generator.IGeneratorContext
-import org.eclipse.xtext.generator.InMemoryFileSystemAccess
-import org.eclipse.xtext.testing.InjectWith
-import org.eclipse.xtext.testing.XtextRunner
-import org.eclipse.xtext.testing.util.ParseHelper
-import org.eclipse.xtext.testing.validation.ValidationTestHelper
-import org.junit.Test
-import org.junit.runner.RunWith
-
-import static org.junit.Assert.assertTrue
-import org.junit.Ignore
-
-@RunWith(XtextRunner)
-@InjectWith(SemanticAdaptationInjectorProvider)
-class CgCppModuleTest extends AbstractSemanticAdaptationTest {
-
-	// @Inject CppGenerator underTest
-	@Inject extension ParseHelper<SemanticAdaptation>
-	@Inject extension  ValidationTestHelper
-
-	@Ignore
-	@Test def powerwindow_model_only() { __parseNoErrors('input/single_folder_spec/window/window_sa_canonical.BASE.sa') }
-
-	def __parseNoErrors(String filename) {
-
-		val file = new File(filename)
-
-		assertTrue("File not found: " + filename, file.exists);
-		
-		var SemanticAdaptation model = null;
-		if (file.isDirectory) {
-			for (f : file.listFiles) {
-				if (model === null) {
-					model = __parse(f.absolutePath)
-				} else {
-					model = __parse(f.absolutePath, model.eResource.resourceSet)
-				}
-				__assertNoParseErrors(model, f.absolutePath)
-			}
-		} else {
-			model = __parse(filename)
-			__assertNoParseErrors(model, filename)
-		}
-
-		val fsa = new InMemoryFileSystemAccess()
-		val IGeneratorContext ctxt = null;
-		new CppGenerator().doGenerate(model.eResource, fsa, ctxt)
-
-		System.out.println(fsa.allFiles)
-	}
-
-	def __parseNoErrorsPrint(String filename) {
-		val root = __parse(filename)
-		print_ast(root)
-		__assertNoParseErrors(root, filename)
-	}
-
-	def __parse(String filename) {
-		return readFile(filename).parse
-	}
-
-	def __parse(String filename, ResourceSet resourceSetToUse) {
-
-		return readFile(filename).parse(resourceSetToUse)
-	}
-
-	def __assertNoParseErrors(EObject root, String filename) {
-		try {
-			root.assertNoErrors
-		} catch (AssertionError e) {
-			val p = Pattern.compile(".*, offset (?<offset>[0-9]+), length (?<length>[0-9]+)")
-			val code = readFile(filename)
-			for (String line : e.message.split("\n")) {
-				val m = p.matcher(line)
-				m.matches()
-				val count = __occurrencesInString(code.subSequence(0, Integer.valueOf(m.group("offset"))).toString(),
-					"\n")
-				print(filename + " at line " + (count + 1) + ": ")
-				println(line)
-			}
-			throw e
-		}
-	}
-
-	def __occurrencesInString(String str, String findstr) {
-		var lastIndex = 0
-		var count = 0
-		while (lastIndex != -1) {
-			lastIndex = str.indexOf(findstr, lastIndex)
-			if (lastIndex != -1) {
-				count++
-				lastIndex += findstr.length()
-			}
-		}
-		return count
-	}
-
-}

BIN
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/lazy/Controller.fmu


+ 69 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/lazy/lazy.sa

@@ -0,0 +1,69 @@
+semantic adaptation reactive moore LazySA lazy_sa
+at "./path/to/LazySA.fmu"
+
+	for inner fmu Controller controller
+	at "test_input/single_folder_spec/lazy/Controller.fmu"
+	with input ports obj_detected, passenger_up, passenger_down, passenger_stop, driver_up, driver_down, driver_stop
+	with output ports up, down, stop
+
+input ports obj_detected -> controller.obj_detected,
+			passenger_up -> controller.passenger_up,
+			passenger_down -> controller.passenger_down,
+			passenger_stop -> controller.passenger_stop,
+			driver_up -> controller.driver_up,
+			driver_down -> controller.driver_down,
+			driver_stop -> controller.driver_stop
+
+output ports up, down, stop
+
+param 	INIT_OBJ_DETECTED := false,
+		INIT_PASSENGER_UP := false,
+		INIT_PASSENGER_DOWN := false,
+		INIT_PASSENGER_STOP := false,
+		INIT_DRIVER_UP := false,
+		INIT_DRIVER_DOWN := false,
+		INIT_DRIVER_STOP := false;
+
+control var	tn := -1.0,
+			tl := -1.0,
+			prev_obj_detected := INIT_OBJ_DETECTED,
+			prev_passenger_up := INIT_PASSENGER_UP,
+			prev_passenger_down := INIT_PASSENGER_DOWN,
+			prev_passenger_stop := INIT_PASSENGER_STOP,
+			prev_driver_up := INIT_DRIVER_UP,
+			prev_driver_down := INIT_DRIVER_DOWN,
+			prev_driver_stop := INIT_DRIVER_STOP;
+
+control rules {
+	if (tl < 0.0){
+		tl := t;
+	}
+	
+	var step_size := min(H, tn - t); 
+	if (lazy_sa.obj_detected != prev_obj_detected or
+		lazy_sa.passenger_up != prev_passenger_up or
+		lazy_sa.passenger_down != prev_passenger_down or
+		lazy_sa.passenger_stop != prev_passenger_stop or
+		lazy_sa.driver_up != prev_driver_up or
+		lazy_sa.driver_down != prev_driver_down or
+		lazy_sa.driver_stop != prev_driver_stop or
+		(t+H) >= tn
+	){
+		var step_to_be_done := (t+H-tl);
+		var step_done := do_step(controller, t, step_to_be_done); 
+		tn := tl + step_done + get_next_time_step(controller); 
+		step_size := tl + step_done - t; 
+		tl := tl + step_done; 
+	}
+	
+	prev_obj_detected := lazy_sa.obj_detected;
+	prev_passenger_up := lazy_sa.passenger_up;
+	prev_passenger_down := lazy_sa.passenger_down;
+	prev_passenger_stop := lazy_sa.passenger_stop;
+	prev_driver_up := lazy_sa.driver_up;
+	prev_driver_down := lazy_sa.driver_down;
+	prev_driver_stop := lazy_sa.driver_stop;
+	
+	return step_size;
+}
+

+ 117 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/lazy/lazy_canonical.sa

@@ -0,0 +1,117 @@
+semantic adaptation reactive moore LazySA lazy_sa
+at "./path/to/LazySA.fmu"
+
+	for inner fmu Controller controller
+	at "test_input/single_folder_spec/lazy/Controller.fmu"
+	with input ports obj_detected, passenger_up, passenger_down, passenger_stop, driver_up, driver_down, driver_stop
+	with output ports up, down, stop
+
+input ports obj_detected,
+			passenger_up,
+			passenger_down,
+			passenger_stop,
+			driver_up,
+			driver_down,
+			driver_stop
+
+output ports up, down, stop
+
+param 	INIT_OBJ_DETECTED := false,
+		INIT_PASSENGER_UP := false,
+		INIT_PASSENGER_DOWN := false,
+		INIT_PASSENGER_STOP := false,
+		INIT_DRIVER_UP := false,
+		INIT_DRIVER_DOWN := false,
+		INIT_DRIVER_STOP := false,
+		INIT_UP := false,
+		INIT_DOWN := false,
+		INIT_STOP := false;
+
+control var	tn := -1.0,
+			tl := -1.0,
+			prev_obj_detected := INIT_OBJ_DETECTED,
+			prev_passenger_up := INIT_PASSENGER_UP,
+			prev_passenger_down := INIT_PASSENGER_DOWN,
+			prev_passenger_stop := INIT_PASSENGER_STOP,
+			prev_driver_up := INIT_DRIVER_UP,
+			prev_driver_down := INIT_DRIVER_DOWN,
+			prev_driver_stop := INIT_DRIVER_STOP;
+
+control rules {
+	if (tl < 0.0){
+		tl := t;
+	}
+	
+	var step_size := min(H, tn - t); 
+	if (lazy_sa.obj_detected != prev_obj_detected or
+		lazy_sa.passenger_up != prev_passenger_up or
+		lazy_sa.passenger_down != prev_passenger_down or
+		lazy_sa.passenger_stop != prev_passenger_stop or
+		lazy_sa.driver_up != prev_driver_up or
+		lazy_sa.driver_down != prev_driver_down or
+		lazy_sa.driver_stop != prev_driver_stop or
+		(t+H) >= tn
+	){
+		var step_to_be_done := (t+H-tl);
+		var step_done := do_step(controller, t, step_to_be_done); 
+		tn := tl + step_done + get_next_time_step(controller); 
+		step_size := tl + step_done - t; 
+		tl := tl + step_done; 
+	}
+	
+	prev_obj_detected := lazy_sa.obj_detected;
+	prev_passenger_up := lazy_sa.passenger_up;
+	prev_passenger_down := lazy_sa.passenger_down;
+	prev_passenger_stop := lazy_sa.passenger_stop;
+	prev_driver_up := lazy_sa.driver_up;
+	prev_driver_down := lazy_sa.driver_down;
+	prev_driver_stop := lazy_sa.driver_stop;
+	
+	return step_size;
+}
+
+in var 
+	stored_sa_obj_detected := INIT_OBJ_DETECTED,
+	stored_sa_passenger_up := INIT_PASSENGER_UP,
+	stored_sa_passenger_down := INIT_PASSENGER_DOWN,
+	stored_sa_passenger_stop := INIT_PASSENGER_STOP,
+	stored_sa_driver_up := INIT_DRIVER_UP,
+	stored_sa_driver_down := INIT_DRIVER_DOWN,
+	stored_sa_driver_stop := INIT_DRIVER_STOP;
+
+in rules {
+	true -> {
+		stored_sa_obj_detected := lazy_sa.obj_detected;
+		stored_sa_passenger_up := lazy_sa.passenger_up;
+		stored_sa_passenger_down := lazy_sa.passenger_down;
+		stored_sa_passenger_stop := lazy_sa.passenger_stop;
+		stored_sa_driver_up := lazy_sa.driver_up;
+		stored_sa_driver_down := lazy_sa.driver_down;
+		stored_sa_driver_stop := lazy_sa.driver_stop;
+	} --> {
+		controller.obj_detected := stored_sa_obj_detected;
+		controller.passenger_up := stored_sa_passenger_up;
+		controller.passenger_down := stored_sa_passenger_down;
+		controller.passenger_stop := stored_sa_passenger_stop;
+		controller.driver_up := stored_sa_driver_up;
+		controller.driver_down := stored_sa_driver_down;
+		controller.driver_stop := stored_sa_driver_stop;
+	};
+}
+	
+out var
+	stored_sa_up := INIT_UP,
+	stored_sa_down := INIT_DOWN,
+	stored_sa_stop := INIT_STOP;
+out rules {
+	true -> {
+		stored_sa_up := controller.up;
+		stored_sa_down := controller.down;
+		stored_sa_stop := controller.stop;
+	} --> {
+		up := stored_sa_up;
+		down := stored_sa_down;
+		stop := stored_sa_stop;
+	};
+	
+}

BIN
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/Window.fmu


+ 23 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/modelDescription.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?><fmiModelDescription fmiVersion="2.0" guid="ea92ae6c-f37d-482c-b875-ca0ac374128b" modelName="WindowSA" variableNamingConvention="flat">
+    <ModelVariables>
+        <ScalarVariable causality="input" name="reaction_force" valueReference="0" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="input" name="displacement" valueReference="1" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="input" name="speed" valueReference="2" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="output" name="disp" valueReference="3" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="output" name="tau" valueReference="4" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+    </ModelVariables>
+    <Outputs>
+        <Unknown index="4"/>
+        <Unknown index="5"/>
+    </Outputs>
+</fmiModelDescription>

+ 231 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/windowSA.cpp

@@ -0,0 +1,231 @@
+#include "WindowSA.h"
+
+namespace adaptation 
+{
+	WindowSA::WindowSA(shared_ptr<string> resourceLocation, const fmi2CallbackFunctions* functions) : 
+		SemanticAdaptation(resourceLocation, createInputRules(),createOutputRules(), functions)
+	{
+		this->stored_window_reaction_torque = 0.0;
+		this->stored_window_height = 0.0;
+		this->stored_windowsa_reaction_force = 0.0;
+		this->stored_windowsa_displacement = 0.0;
+		this->stored_windowsa_speed = 0.0;
+		
+		const char* path = Fmu::combinePath(resourceLocation, make_shared<string>("Window.fmu"))->c_str();
+		auto windowFmu = make_shared<fmi2::Fmu>(path);
+		windowFmu->initialize();
+		this->window = windowFmu->instantiate("window",fmi2CoSimulation, "{efb4a002-4c0c-487b-8816-c0311d2f04d9}", true, true, make_shared<Callback>()); 
+	}
+	
+	void WindowSA::initialize()
+	{
+		const char* path = Fmu::combinePath(resourceLocation, make_shared<string>("Window.fmu"))->c_str();
+		auto windowFmu = make_shared<fmi2::Fmu>(*path);
+		windowFmu->initialize();
+		this->window = windowFmu->instantiate("window",fmi2CoSimulation, "{efb4a002-4c0c-487b-8816-c0311d2f04d9}", true, true, shared_from_this());
+		
+		if(this->window->component == NULL)
+			this->lastErrorState = fmi2Fatal;
+		this->instances->push_back(this->window);
+	}
+	
+	WindowSA::~WindowSA()
+	{
+	}
+	
+	WindowSA* WindowSA::getRuleThis()
+	{
+		return this;
+	}
+	
+	double WindowSA::getFmiValueReal(fmi2ValueReference id)
+	{
+		switch (id)
+		{
+			case WINDOWSADISP:
+			{
+				return this->disp;
+			}
+			case WINDOWSATAU:
+			{
+				return this->tau;
+			}
+			default:
+			{
+				return 0.0;
+			}
+		}
+		
+	}
+	
+	string WindowSA::getFmiValueString(fmi2ValueReference id)
+	{
+		return "";
+	}
+	
+	int WindowSA::getFmiValueInteger(fmi2ValueReference id)
+	{
+		return 0;
+	}
+	
+	bool WindowSA::getFmiValueBoolean(fmi2ValueReference id)
+	{
+		return false;
+	}
+	
+	void WindowSA::setFmiValue(fmi2ValueReference id, double value)
+	{
+		switch (id)	
+			{
+				case WINDOWSAREACTION_FORCE:
+				{
+					this->reaction_force = value;
+					this->isSetreaction_force = true;
+					break;
+				}
+				case WINDOWSADISPLACEMENT:
+				{
+					this->displacement = value;
+					this->isSetdisplacement = true;
+					break;
+				}
+				case WINDOWSASPEED:
+				{
+					this->speed = value;
+					this->isSetspeed = true;
+					break;
+				}
+				default:
+				{
+				}
+			}
+	}
+	
+	void WindowSA::setFmiValue(fmi2ValueReference id, string value)
+	{
+	}
+	
+	void WindowSA::setFmiValue(fmi2ValueReference id, int value)
+	{
+	}
+	
+	void WindowSA::setFmiValue(fmi2ValueReference id, bool value)
+	{
+	}
+	
+	bool WindowSA::in_rule_condition1(){
+		return true;
+	}
+	void WindowSA::in_rule_body1(){
+		if(this->isSetreaction_force){
+			this->stored_windowsa_reaction_force = this->reaction_force;
+		}
+	}
+	void WindowSA::in_rule_flush1(){
+		setValue(window,WINDOWREACTION_FORCE,this->stored_windowsa_reaction_force);
+	}
+	bool WindowSA::in_rule_condition2(){
+		return true;
+	}
+	void WindowSA::in_rule_body2(){
+		if(this->isSetdisplacement){
+			this->stored_windowsa_displacement = this->displacement;
+		}
+	}
+	void WindowSA::in_rule_flush2(){
+		setValue(window,WINDOWDISPLACEMENT,this->stored_windowsa_displacement);
+	}
+	bool WindowSA::in_rule_condition3(){
+		return true;
+	}
+	void WindowSA::in_rule_body3(){
+		if(this->isSetspeed){
+			this->stored_windowsa_speed = this->speed;
+		}
+	}
+	void WindowSA::in_rule_flush3(){
+		setValue(window,WINDOWSPEED,this->stored_windowsa_speed);
+	}
+	shared_ptr<list<Rule<WindowSA>>> WindowSA::createInputRules()
+	{
+		auto list = make_shared<std::list<Rule<WindowSA>>>();
+		
+		list->push_back(
+			(Rule<WindowSA>){
+				&WindowSA::in_rule_condition1(),
+				&WindowSA::in_rule_body1(),
+				&WindowSA::in_rule_flush1()
+			});
+		
+		
+		list->push_back(
+			(Rule<WindowSA>){
+				&WindowSA::in_rule_condition2(),
+				&WindowSA::in_rule_body2(),
+				&WindowSA::in_rule_flush2()
+			});
+		
+		
+		list->push_back(
+			(Rule<WindowSA>){
+				&WindowSA::in_rule_condition3(),
+				&WindowSA::in_rule_body3(),
+				&WindowSA::in_rule_flush3()
+			});
+		
+		
+		return list;
+		
+	}
+	
+	
+	void WindowSA::executeInternalControlFlow(double h, double dt)
+	{
+		this->do_step(window,h,dt);
+	}
+	
+	bool WindowSA::out_rule_condition1(){
+		return true;
+	}
+	void WindowSA::out_rule_body1(){
+		this->stored_window_reaction_torque = getValueDouble(window,WINDOWREACTION_TORQUE);
+	}
+	void WindowSA::out_rule_flush1(){
+		this->tau = this->stored_window_reaction_torque;
+	}
+	bool WindowSA::out_rule_condition2(){
+		return true;
+	}
+	void WindowSA::out_rule_body2(){
+		this->stored_window_height = getValueDouble(window,WINDOWHEIGHT);
+	}
+	void WindowSA::out_rule_flush2(){
+		this->disp = this->stored_window_height * 100;
+	}
+	shared_ptr<list<Rule<WindowSA>>> WindowSA::createOutputRules()
+	{
+		auto list = make_shared<std::list<Rule<WindowSA>>>();
+		
+		list->push_back(
+			(Rule<WindowSA>){
+				&WindowSA::out_rule_condition1(),
+				&WindowSA::out_rule_body1(),
+				&WindowSA::out_rule_flush1()
+			});
+		
+		
+		list->push_back(
+			(Rule<WindowSA>){
+				&WindowSA::out_rule_condition2(),
+				&WindowSA::out_rule_body2(),
+				&WindowSA::out_rule_flush2()
+			});
+		
+		
+		return list;
+		
+	}
+	
+
+}
+

+ 92 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/windowSA.h

@@ -0,0 +1,92 @@
+
+	#ifndef SRC_WINDOWSA_H
+	#define SRC_WINDOWSA_H
+
+	#include "SemanticAdaptation.h"
+	#include <memory>
+	#include "Fmu.h"
+	
+	using namespace std;
+	using namespace fmi2;
+	
+	namespace adaptation
+	{
+		
+		#define WINDOWDISPLACEMENT 0
+		#define WINDOWFRICTION 1
+		#define WINDOWHEIGHT 2
+		#define WINDOWREACTION_FORCE 3
+		#define WINDOWREACTION_TORQUE 4
+		#define WINDOWSPEED 5
+		#define WINDOWV 6
+		#define WINDOWB 7
+		#define WINDOWR 8
+		
+		#define WINDOWSAREACTION_FORCE 0
+		#define WINDOWSADISPLACEMENT 1
+		#define WINDOWSASPEED 2
+		#define WINDOWSADISP 3
+		#define WINDOWSATAU 4
+	
+		class WindowSA : public SemanticAdaptation<WindowSA>, public enable_shared_from_this<WindowSA>
+		{
+			public:
+				WindowSA(shared_ptr<string> resourceLocation, const fmi2CallbackFunctions* functions);
+				void initialize();
+				virtual ~WindowSA();
+				
+				void setFmiValue(fmi2ValueReference id, int value);
+				void setFmiValue(fmi2ValueReference id, bool value);
+				void setFmiValue(fmi2ValueReference id, double value);
+				void setFmiValue(fmi2ValueReference id, string value);
+			
+				int getFmiValueInteger(fmi2ValueReference id);
+				bool getFmiValueBoolean(fmi2ValueReference id);
+				double getFmiValueReal(fmi2ValueReference id);
+				string getFmiValueString(fmi2ValueReference id);
+				
+			private:
+				
+				WindowSA* getRuleThis();
+				
+				/*in rules*/
+				bool in_rule_condition1();
+				void in_rule_body1();
+				void in_rule_flush1();
+				bool in_rule_condition2();
+				void in_rule_body2();
+				void in_rule_flush2();
+				bool in_rule_condition3();
+				void in_rule_body3();
+				void in_rule_flush3();
+				shared_ptr<list<Rule<WindowSA>>> createInputRules();;
+				
+				/*out rules*/
+				bool out_rule_condition1();
+				void out_rule_body1();
+				void out_rule_flush1();
+				bool out_rule_condition2();
+				void out_rule_body2();
+				void out_rule_flush2();
+				shared_ptr<list<Rule<WindowSA>>> createOutputRules();;
+				
+				void executeInternalControlFlow(double h, double dt);;
+				
+				shared_ptr<FmuComponent> window;
+				
+				double reaction_force;
+				bool isSetreaction_force;
+				double displacement;
+				bool isSetdisplacement;
+				double speed;
+				bool isSetspeed;
+				double disp;
+				double tau;
+				
+				double stored_window_reaction_torque;
+				double stored_window_height;
+				double stored_windowsa_reaction_force;
+				double stored_windowsa_displacement;
+				double stored_windowsa_speed;
+		};
+	}

+ 35 - 18
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/input/single_folder_spec/window/window_sa_canonical.BASE.sa

@@ -4,7 +4,7 @@ semantic adaptation reactive mealy WindowSA windowSA
 at "./path/to/WindowSA.fmu"
 
 	for inner fmu Window window
-		at "input/single_folder_spec/window/Window.fmu"
+		at "test_input/single_folder_spec/window/Window.fmu"
 		with input ports displacement (rad), speed (rad/s), reaction_force (N)
 		with output ports height (m), reaction_torque (N.m)
 
@@ -17,8 +17,8 @@ input ports 	reaction_force,
 				displacement,
 				speed
 
-output ports	disp,
-				tau
+	output ports	disp,
+					tau
 
 
 control rules {
@@ -26,42 +26,59 @@ control rules {
 	return H;
 }
 
-in var 	stored_windowsa_reaction_force := 0., 
-		stored_windowsa_displacement := 0., 
-		stored_windowsa_speed := 0.;
+in var 	stored_windowsa_reaction_force := 0.0, 
+		stored_windowsa_displacement := 0.0, 
+		stored_windowsa_speed := 0.0;
 
 in rules {
+	/*
+	is_set checks whether the input value is given in the setValues call of the adapted FMU.
+	Notice that in the canonical version, all ports are prefixed.
+	*/
+
 	true -> {
-		/*
-		is_set checks whether the input value is given in the setValues call of the adapted FMU.
-		Notice that in the canonical version, all ports are prefixed.
-		*/
 		if (is_set(windowSA.reaction_force)){
 			stored_windowsa_reaction_force := windowSA.reaction_force;
 		}
+	} --> {
+			window.reaction_force := stored_windowsa_reaction_force;
+		};
+	
+	true -> {
 		if (is_set(windowSA.displacement)){
-			stored_windowsa_displacement := windowSA.displacement;			
-		}
+				stored_windowsa_displacement := windowSA.displacement;			
+			}
+	} --> {
+		window.displacement := stored_windowsa_displacement; 
+		};
+	
+	
+	true -> {		
 		if (is_set(windowSA.speed)){
 			stored_windowsa_speed := windowSA.speed;
 		}
 	} --> {
-		window.reaction_force := stored_windowsa_reaction_force;
-		window.displacement := stored_windowsa_displacement; 
+		
 		window.speed := stored_windowsa_speed;
 	};
 }
 
-out var stored_window_reaction_torque := 0,
-		stored_window_height := 0;
+out var stored_window_reaction_torque := 0.0,
+		stored_window_height := 0.0;
 		
 out rules {
+
 	true -> {
 		stored_window_reaction_torque := window.reaction_torque;
-		stored_window_height := window.height;
 	} --> {
 		windowSA.tau := - stored_window_reaction_torque;
-		windowSA.disp := stored_window_height / 100;
 	};
+	
+	true -> {
+		stored_window_height := window.height;
+	} --> {
+		windowSA.disp := stored_window_height * 100;
+	};
+
 }
 

+ 56 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/window_sa_canonical_new.BASE.sa

@@ -0,0 +1,56 @@
+semantic adaptation reactive mealy WindowSA windowSA
+at "./path/to/WindowSA.fmu"
+
+	for inner fmu Window window
+		at "test_input/single_folder_spec/window/Window.fmu"
+		with input ports displacement (rad), speed (rad/s), reaction_force (N)
+		with output ports height (m), reaction_torque (N.m)
+
+input ports 	reaction_force,
+				displacement,
+				speed
+
+output ports	disp,
+				tau
+
+param 	INIT_WINDOWSA_REACTION_FORCE := 0.0,
+		INIT_WINDOWSA_DISPLACEMENT := 0.0,
+		INIT_WINDOWSA_SPEED := 0.0,
+		INIT_WINDOW_REACTION_TORQUE := 0.0,
+		INIT_WINDOW_REACTION_HEIGHT := 0.0;
+
+control rules {
+	var H_window := do_step(window, t, H);
+	return H_window;
+}
+
+in var 	stored_windowsa_reaction_force := INIT_WINDOWSA_REACTION_FORCE, 
+		stored_windowsa_displacement := INIT_WINDOWSA_DISPLACEMENT, 
+		stored_windowsa_speed := INIT_WINDOWSA_SPEED;
+
+in rules {
+	true -> {
+		stored_windowsa_reaction_force := windowSA.reaction_force;
+		stored_windowsa_displacement := windowSA.displacement;			
+		stored_windowsa_speed := windowSA.speed;
+	} --> {
+		window.reaction_force := stored_windowsa_reaction_force;
+		window.displacement := stored_windowsa_displacement; 
+		window.speed := stored_windowsa_speed;
+	};
+}
+
+out var stored_window_reaction_torque := INIT_WINDOW_REACTION_TORQUE,
+		stored_window_height := INIT_WINDOW_REACTION_HEIGHT;
+
+out rules {
+	true -> {
+		stored_window_reaction_torque := window.reaction_torque;
+		stored_window_height := window.height;
+	} --> {
+		windowSA.disp := stored_window_height / 100;
+	};
+	true -> { } --> {
+		windowSA.tau := -stored_window_reaction_torque;
+	};
+}

+ 19 - 18
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/META-INF/MANIFEST.MF

@@ -1,18 +1,19 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: be.uantwerpen.ansymo.semanticadaptation.cg.cpp
-Bundle-Vendor: University of Antwerp, Ansymo Lab
-Bundle-Version: 1.0.0.qualifier
-Bundle-SymbolicName: be.uantwerpen.ansymo.semanticadaptation.cg.cpp; singleton:=true
-Bundle-ActivationPolicy: lazy
-Require-Bundle: be.uantwerpen.ansymo.semanticadaptation,
- org.junit;bundle-version="4.7.0",
- org.eclipse.xtext.junit4,
- org.eclipse.xtext.xbase.junit,
- org.eclipse.xtext.xbase.lib,
- org.eclipse.jdt.core,
- org.eclipse.xtext.testing,
- org.eclipse.xtext.xbase.testing
-Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.apache.log4j
-Export-Package: be.uantwerpen.ansymo.semanticadaptation.cg.cpp
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: be.uantwerpen.ansymo.semanticadaptation.cg.cpp
+Bundle-Vendor: University of Antwerp, Ansymo Lab
+Bundle-Version: 1.0.0.qualifier
+Bundle-SymbolicName: be.uantwerpen.ansymo.semanticadaptation.cg.cpp; singleton:=true
+Bundle-ActivationPolicy: lazy
+Require-Bundle: be.uantwerpen.ansymo.semanticadaptation,
+ org.junit;bundle-version="4.7.0",
+ org.eclipse.xtext.junit4,
+ org.eclipse.xtext.xbase.junit,
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.jdt.core,
+ org.eclipse.xtext.testing,
+ org.eclipse.xtext.xbase.testing,
+ org.eclipse.xtext.util
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Import-Package: org.apache.log4j
+Export-Package: be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation

+ 2 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/build.properties

@@ -3,7 +3,8 @@ source.. = src/,\
            xtend-gen/
 bin.includes = .,\
                META-INF/,\
-               plugin.xml
+               plugin.xml,\
+               jars/
 additional.bundles = org.eclipse.xtext.xbase,\
                      org.eclipse.xtext.common.types,\
                      org.eclipse.xtext.xtext.generator,\

+ 54 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/pom.xml

@@ -18,6 +18,17 @@
     <main.basedir>${project.parent.basedir}</main.basedir>
 	</properties>
 
+	<dependencies>
+
+		<!-- dependency>
+			<groupId>be.uantwerpen.ansymo.semanticadaptation</groupId>
+			<artifactId>be.uantwerpen.ansymo.semanticadaptation.cg.cpp.lib</artifactId>
+			<type>jar</type>
+			<version>${project.version}</version>
+			<scope>compile</scope>
+		</dependency-->
+	</dependencies>
+
 	<build>
 		<plugins>
 
@@ -25,6 +36,49 @@
 				<groupId>org.eclipse.xtend</groupId>
 				<artifactId>xtend-maven-plugin</artifactId>
 			</plugin>
+
+
+
+			<!-- plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-dependency-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>copy-dependencies</id>
+						<phase>process-resources</phase>
+						<goals>
+							<goal>copy</goal>
+						</goals>
+						<configuration>
+
+							<artifactItems>
+								
+								
+								<artifactItem>
+									<groupId>be.uantwerpen.ansymo.semanticadaptation</groupId>
+									<artifactId>be.uantwerpen.ansymo.semanticadaptation.cg.cpp.lib</artifactId>
+									<type>jar</type>
+									<version>${project.version}</version>
+									
+									<overWrite>true</overWrite>
+									
+									<destFileName>cppFramework.jar</destFileName>
+								</artifactItem>
+
+							</artifactItems>
+
+
+							<outputDirectory>${project.basedir}/jars</outputDirectory>
+							<overWriteReleases>false</overWriteReleases>
+							<overWriteSnapshots>false</overWriteSnapshots>
+							<overWriteIfNewer>true</overWriteIfNewer>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin-->
+
+
+			
 		</plugins>
 		
 		

+ 0 - 39
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/CppGenerator.xtend

@@ -1,39 +0,0 @@
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp
-
-import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationGenerator
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
-import org.eclipse.emf.ecore.resource.Resource
-import org.eclipse.xtext.generator.IFileSystemAccess2
-import org.eclipse.xtext.generator.IGeneratorContext
-
-class CppGenerator extends SemanticAdaptationGenerator {
-
-	var ModelDescriptionCreator mdCreator = new ModelDescriptionCreator()
-
-	override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
-
-		for (type : resource.allContents.toIterable.filter(SemanticAdaptation)){
-				fsa.generateFile(type.name + ".cpp", type.compile)
-				mdCreator.name = type.name;
-				fsa.generateFile("modelDescription.xml", mdCreator.modelDescription);
-		}
-	}
-
-// TODO: Verify adaptation.name is not a C++ keyword
-// TODO: Add initial value to inputs in the model description file
-	def CharSequence compile(SemanticAdaptation adaptation) {
-		var adaptationCharSequence = newArrayList()
-		for (type : adaptation.elements.filter(Adaptation)) {
-			mdCreator.CreateInputsOutput(type);
-			adaptationCharSequence.add(type.compile)
-		}
-
-		return adaptationCharSequence.join('''\n''');
-	}
-
-	def CharSequence compile(Adaptation adaptation) {
-		
-		return '''compiling «adaptation.toString»''';
-	}
-}

+ 0 - 26
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/MapEntry.java

@@ -1,26 +0,0 @@
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp;
-
-import java.util.Map.Entry;
-
-public class MapEntry<K, V> implements Entry<K, V> {
-    private final K key;
-    private V value;
-    public MapEntry(final K key) {
-        this.key = key;
-    }
-    public MapEntry(final K key, final V value) {
-        this.key = key;
-        this.value = value;
-    }
-    public K getKey() {
-        return key;
-    }
-    public V getValue() {
-        return value;
-    }
-    public V setValue(final V value) {
-        final V oldValue = this.value;
-        this.value = value;
-        return oldValue;
-    }
-}

+ 0 - 101
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/ModelDescriptionCreator.xtend

@@ -1,101 +0,0 @@
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp;
-
-import java.util.List;
-import java.util.Vector;
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InnerFMU
-import java.io.File
-import org.w3c.dom.Document
-import java.util.zip.ZipFile
-import java.util.Enumeration
-import java.util.zip.ZipEntry
-import javax.xml.parsers.DocumentBuilderFactory
-import javax.xml.parsers.DocumentBuilder
-import java.util.HashMap
-import java.util.Map
-import javax.xml.xpath.XPathFactory
-import javax.xml.xpath.XPath
-import javax.xml.xpath.XPathExpression
-import org.w3c.dom.Node
-import javax.xml.xpath.XPathConstants
-import java.util.UUID
-
-public class ModelDescriptionCreator {
-	private List<ScalarVariable> sVars = new Vector<ScalarVariable>();
-	private ModelDescriptionBuilder mdBuilder = new ModelDescriptionBuilder();
-	private String mdName;
-	private String guid;
-	def String getModelDescription(){
-		if(mdName === null){
-			throw new IllegalStateException("Model Description name is missing");		
-		}
-		mdBuilder.CreateTemplate(mdName, UUID.randomUUID().toString);
-		for(sVar : sVars)
-		{
-			mdBuilder.addScalarVariable(sVar);
-		}
-		
-		return mdBuilder.toString();
-	}
-
-	def void setName(String name){
-		mdName = name;
-	}
-	
-	private def Document getModelDescription(File path) {
-		System.out.println(path.absolutePath);
-		var ZipFile fmu = new ZipFile(path);
-		var Enumeration<? extends ZipEntry> entries = fmu.entries();
-		var boolean entryFound = false;
-		var ZipEntry locatedEntry;
-
-		while (!entryFound && entries.hasMoreElements()) {
-			var ZipEntry entry = entries.nextElement();
-			if (entry.name.equalsIgnoreCase("modelDescription.xml"))
-				locatedEntry = entry;
-		}
-		var DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
-		var DocumentBuilder builder = fac.newDocumentBuilder();
-		val is = fmu.getInputStream(locatedEntry)
-		var Document doc = builder.parse(is);
-		is.close();
-		return doc;
-	}
-
-	def void CreateInputsOutput(Adaptation adaptation) {
-		var Map<String, Document> wrappedFMUs = new HashMap<String, Document>();
-
-		var test = adaptation.inner.eAllContents.toIterable.filter(InnerFMU);
-		for (type : test) {
-			var file = new File(type.path.replace('\"', ''));
-			var modelDesc = getModelDescription(file);
-			wrappedFMUs.put(type.name, modelDesc);
-		}
-
-		val XPathFactory xPathfactory = XPathFactory.newInstance();
-		val XPath xpath = xPathfactory.newXPath();
-
-		for (port : adaptation.inports) {
-			for (Map.Entry<String,Document> entry : wrappedFMUs.entrySet()) {
-				// Get the input type
-				val XPathExpression expr = xpath.compile(
-					"/fmiModelDescription/ModelVariables/ScalarVariable[@name='" + port.name + "']/*[1]");
-				val Node nl = expr.evaluate(entry.value, XPathConstants.NODE) as Node;
-				sVars.add(
-					ScalarVariable.Create().setName(port.name).setValueReference(mdBuilder.nextValueReference).setCausality(
-						SVCausality.input).setType(SVType.valueOf(nl.nodeName)));
-			}
-		}
-
-		for (port : adaptation.outports) {
-			for (Map.Entry<String,Document> entry : wrappedFMUs.entrySet()) {
-				val XPathExpression expr = xpath.compile(
-					"/fmiModelDescription/ModelVariables/ScalarVariable[@name='" + port.name + "']/*[1]");
-				val Node nl = expr.evaluate(entry.value, XPathConstants.NODE) as Node;
-				sVars.add(
-					ScalarVariable.Create().setName(port.name).setValueReference(mdBuilder.nextValueReference).setCausality(
-						SVCausality.output).setType(SVType.valueOf(nl.nodeName)));
-			}
-		}
-	}
-}

+ 12 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/GlobalInOutVariable.java

@@ -0,0 +1,12 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+public class GlobalInOutVariable {
+
+	public final String name;
+	public final SVType type;
+	
+	public GlobalInOutVariable(String name, SVType type) {
+		this.name=name;
+		this.type = type;
+	}
+}

+ 19 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/InOutRulesBlockResult.java

@@ -0,0 +1,19 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import org.eclipse.xtext.xbase.lib.Pair;
+
+public class InOutRulesBlockResult extends RulesBlockResult {
+	public final LinkedHashMap<String, GlobalInOutVariable> gVars;
+	public final String constructorInitialization;
+
+	public InOutRulesBlockResult(String generatedCpp, List<String> functionSignatures,
+			LinkedHashMap<String, GlobalInOutVariable> gVars, String constructorInitialization)
+	{
+		super(generatedCpp, functionSignatures);
+		this.gVars = gVars;
+		this.constructorInitialization = constructorInitialization;
+	}
+}

+ 6 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/InputOutputRuleType.java

@@ -0,0 +1,6 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+public enum InputOutputRuleType {
+	Input,
+	Output
+}

+ 31 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/MappedScalarVariable.java

@@ -0,0 +1,31 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+public class MappedScalarVariable {
+
+	private String define;
+	private ScalarVariable mappedSV;
+	public MappedScalarVariable(ScalarVariable sv) {
+		this.mappedSV = sv;
+	}
+	
+	public ScalarVariable getMappedSv()
+	{
+		return this.mappedSV;
+	}
+	
+	public void setDefine(String define)
+	{
+		this.define = define;
+	}
+	
+	public String getDefine()
+	{
+		return this.define;
+	}
+
+	public String getValueReference()
+	{
+		return this.mappedSV.getValueReference();
+	}
+
+}

+ 186 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/ReturnInformation.java

@@ -0,0 +1,186 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.InvalidConversionException;
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation.Conversions;
+
+public class ReturnInformation {
+
+	private SVType type;
+	private boolean typeIsSet;
+	private Object value;
+	private String code = "";
+	private SAScalarVariable ConSaSv;
+	private GlobalInOutVariable conGlobVar;
+	private boolean forceType = false;
+
+	public ReturnInformation() {
+		// TODO Auto-generated constructor stub
+	}
+
+	public void appendCode(String code) {
+		this.code += code;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+	public SVType getType() throws Exception {
+		if(!typeIsSet)
+		{
+			throw new Exception(
+					"Attempt to retrieve unset type for code: " + code);
+		}
+		return type;
+	}
+
+	public void setType(SVType type) throws InvalidConversionException {
+		if (this.typeIsSet) {
+			this.type = Conversions.typeDecider(this.type, type);
+		} else {
+			this.type = type;
+			this.typeIsSet = true;
+		}
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public void setValue(Object value) {
+		this.value = value;
+	}
+
+	public boolean isTypeIsSet() {
+		return typeIsSet;
+	}
+
+	public SAScalarVariable getConSaSv() {
+		return ConSaSv;
+	}
+
+	public void setConSaSv(SAScalarVariable conSaSv) {
+		ConSaSv = conSaSv;
+	}
+
+	public GlobalInOutVariable getConGlobVar() {
+		return conGlobVar;
+	}
+
+	public void setConGlobVar(GlobalInOutVariable conGlobVar) throws InvalidConversionException {
+		this.conGlobVar = conGlobVar;
+		if (this.typeIsSet) {
+			this.type = Conversions.typeDecider(conGlobVar.type, this.type);
+		}
+		else
+		{
+			this.type = conGlobVar.type;
+			this.typeIsSet = true;
+		}
+	}
+
+	/*
+	 * This method automatically extracts type information
+	 */
+	public ReturnInformation(ReturnInformation information) throws InvalidConversionException {
+		this.conGlobVar = information.conGlobVar;
+		if (information.typeIsSet)
+			this.setType(information.type);
+		this.ConSaSv = information.ConSaSv;
+
+	}
+
+	/*
+	 * This method automatically extracts and compares type information
+	 */
+	
+	public ReturnInformation(ReturnInformation information, ReturnInformation information2) throws Exception {
+		if (information.conGlobVar != null) {
+			if (information2.conGlobVar != null) {
+				if (information.conGlobVar == information2.conGlobVar) {
+					this.conGlobVar = information.conGlobVar;
+				}
+				// In this case they must have the same type otherwise the
+				// return value is impossible to typecheck.
+				else if (information.conGlobVar.type != information2.conGlobVar.type) {
+					throw new Exception("The two connected global variables: " + information.conGlobVar.name
+							+ " and " + information2.conGlobVar.name + " have different types");
+				}
+
+			} else {
+				this.conGlobVar = information.conGlobVar;
+			}
+		} else {
+			if (information2.conGlobVar != null) {
+				this.conGlobVar = information2.conGlobVar;
+			}
+		}
+
+		if (information.typeIsSet) {
+			if (information2.typeIsSet == false) {
+				this.setType(information.getType());
+			} else {
+				if (information.getType() != information2.getType()) {
+					this.type = Conversions.typeDecider(information.getType(), information2.getType());
+				} else {
+					this.setType(information.getType());
+				}
+			}
+		} else {
+			if (information2.typeIsSet) {
+				this.setType(information2.getType());
+			}
+		}
+
+		if (information.ConSaSv != null) {
+			if (information2.ConSaSv != null) {
+				if (information.ConSaSv != information2.ConSaSv) {
+					throw new Exception(
+							"Two connected return informations contain different ConSaSv have the wrong type: "
+									+ information.ConSaSv.getName() + " and " + information2.ConSaSv.getName());
+				} else {
+					this.setConSaSv(information.ConSaSv);
+				}
+			} else {
+				this.setConSaSv(information.ConSaSv);
+			}
+		} else {
+			if (information2.ConSaSv != null) {
+				this.setConSaSv(information2.ConSaSv);
+			}
+		}
+		
+		if(information.forceType && information2.forceType)
+		{
+			if(information.getType() != information2.getType())
+			{
+				throw new Exception(
+						"Two connected return informations with force types contain different types: "
+								+ information.getType() + " and " + information2.getType());
+			}
+		}
+		else if(information.forceType || information2.forceType)
+		{
+			
+			this.forceType = true;
+			if(information.forceType)
+				this.type = information.type;
+			else
+				this.type = information2.type;
+		}
+
+	}
+
+	public boolean getForceType() {
+		return forceType;
+	}
+
+	public void setForceType(boolean forceType) {
+		this.forceType = forceType;
+	}
+
+}

+ 12 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/RulesBlockResult.java

@@ -0,0 +1,12 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+import java.util.List;
+
+public class RulesBlockResult {
+	public final String generatedCpp;
+	public final List<String> functionSignatures;
+	public RulesBlockResult(String generatedCpp, List<String> functionSignatures) {
+		this.generatedCpp = generatedCpp;
+		this.functionSignatures = functionSignatures;
+	}
+}

+ 103 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/SAScalarVariable.java

@@ -0,0 +1,103 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+import java.util.ArrayList;
+import java.util.Optional;
+
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.MissingScalarVariableInformationException;
+
+public class SAScalarVariable {
+
+	private String defineName;
+	private Optional<Integer> valueReference = Optional.empty();
+	private Optional<SVCausality> causality = Optional.empty();
+	private Optional<SVType> type = Optional.empty();
+	private String name;
+	private Optional<SVVariability> variability = Optional.empty();
+	private boolean partOfMD = false;
+
+	public ScalarVariable CalcSVar() throws MissingScalarVariableInformationException {
+
+		ArrayList<String> error = new ArrayList<String>();
+		if (!this.causality.isPresent()) {
+			error.add("Missing causality information");
+		}
+		if (!this.type.isPresent()) {
+			error.add("Missing type information");
+		}
+		if (!this.variability.isPresent()) {
+			error.add("Missing variability information");
+		}
+		if (this.name == null) {
+			error.add("Missing name information");
+		}
+		if (!this.valueReference.isPresent()) {
+			error.add("Missing value reference information");
+		}
+
+		if (error.isEmpty()) {
+			return ScalarVariable.Create().setCausality(this.causality.get()).setVariability(this.variability.get())
+					.setType(this.type.get()).setName(this.name).setValueReference(this.getValueReference().toString());
+		} else {
+			throw new MissingScalarVariableInformationException(String.join(" -- ", error));
+		}
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Optional<SVCausality> getCausality() {
+		return causality;
+	}
+
+	public void setCausality(SVCausality causality) {
+		this.causality = Optional.of(causality);
+	}
+
+	public Optional<SVType> getType() {
+		return type;
+	}
+
+	public void setType(SVType type) {
+		this.type = Optional.of(type);
+	}
+
+	public Optional<SVVariability> getVariability() {
+		return variability;
+	}
+
+	public void setVariability(SVVariability variability) {
+		this.variability = Optional.of(variability);
+	}
+
+	public Integer getValueReference() throws MissingScalarVariableInformationException {
+		if (!this.valueReference.isPresent()) {
+			throw new MissingScalarVariableInformationException("Missing value reference information");
+		}
+		return valueReference.get();
+	}
+
+	public void setValueReference(Integer valueReference) {
+		this.valueReference = Optional.of(valueReference);
+	}
+
+	public String getDefineName() {
+		return defineName;
+	}
+
+	public void setDefineName(String defineName) {
+		this.defineName = defineName;
+	}
+
+	public boolean getPartOfMD() {
+		return partOfMD;
+	}
+
+	public void SetPartOfMD(boolean partOfMD) {
+		this.partOfMD = partOfMD;
+	}
+}

+ 9 - 9
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/SVCausality.java

@@ -1,9 +1,9 @@
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp;
-
-//Changing these names must be reflected in the ModelDescriptionBuilder as well
-public enum SVCausality {
-	output,
-	local,
-	input,
-	parameter,
-}
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+//Changing these names must be reflected in the ModelDescriptionBuilder as well
+public enum SVCausality {
+	output,
+	local,
+	input,
+	parameter,
+}

+ 9 - 9
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/SVType.java

@@ -1,9 +1,9 @@
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp;
-
-//Changing these names must be reflected in the ModelDescriptionBuilder as well
-public enum SVType {
-	Real,
-	String,
-	Int,
-	Bool
-}
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+//Changing these names must be reflected in the ModelDescriptionBuilder as well
+public enum SVType {
+	Real,
+	String,
+	Integer,
+	Boolean
+}

+ 8 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/SVVariability.java

@@ -0,0 +1,8 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+public enum SVVariability {
+	continuous,
+	discrete,
+	fixed
+
+}

+ 114 - 91
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/ScalarVariable.java

@@ -1,91 +1,114 @@
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp;
-
-import java.util.Optional;
-
-public class ScalarVariable {
-	private String name;
-	private String valueReference;
-	private String description;
-	private String variability;
-	private SVCausality causality;
-	private String initial;
-	private SVType type;
-	private String start;
-	private ScalarVariable(){
-		
-	}
-	public static ScalarVariable Create(){
-		return new ScalarVariable();
-	}
-	public String getName() {
-		return name;
-	}
-
-	public ScalarVariable setName(String name) {
-		this.name = name;
-		return this;
-	}
-
-	public String getValueReference() {
-		return valueReference;
-	}
-
-	public ScalarVariable setValueReference(String valueReference) {
-		this.valueReference = valueReference;
-		return this;
-	}
-
-	public String getVariability() {
-		return variability;
-	}
-
-	public ScalarVariable setVariability(String variability) {
-		this.variability = variability;
-		return this;
-	}
-
-	public SVCausality getCausality() {
-		return causality;
-	}
-
-	public ScalarVariable setCausality(SVCausality causality) {
-		this.causality = causality;
-		return this;
-	}
-
-	public String getInitial() {
-		return initial;
-	}
-
-	public ScalarVariable setInitial(String initial) {
-		this.initial = initial;
-		return this;
-	}
-
-	public SVType getType() {
-		return type;
-	}
-
-	public ScalarVariable setType(SVType type) {
-		this.type = type;
-		return this;
-	}
-
-	public String getStart() {
-		return start;
-	}
-
-	public ScalarVariable setStart(String start) {
-		this.start = start;
-		return this;
-	}
-
-	public String getDescription() {
-		return description;
-	}
-
-	public ScalarVariable setDescription(String description) {
-		this.description = description;
-		return this;
-	}
-}
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+public class ScalarVariable {
+	private String owner;
+	private String name;
+	private String valueReference;
+	private String description;
+	private SVVariability variability;
+	private SVCausality causality;
+	private String initial;
+	private SVType type;
+	private String start;
+	private String index;
+
+	private ScalarVariable() {
+
+	}
+	
+	protected ScalarVariable(ScalarVariable var) {
+		
+	}
+	
+	public static ScalarVariable Create() {
+		return new ScalarVariable();
+	}
+
+	public ScalarVariable setIndex(String index){
+		this.index = index;
+		return this;
+	}
+	
+	public String getIndex(){
+		return this.index;
+	}
+	
+	public ScalarVariable setOwner(String owner) {
+		this.owner = owner;
+		return this;
+	}
+
+	public String getOwner(){return this.owner;}
+
+	public String getName() {
+		return name;
+	}
+
+	public ScalarVariable setName(String name) {
+		this.name = name;
+		return this;
+	}
+
+	public String getValueReference() {
+		return valueReference;
+	}
+
+	public ScalarVariable setValueReference(String valueReference) {
+		this.valueReference = valueReference;
+		return this;
+	}
+
+	public SVVariability getVariability() {
+		return variability;
+	}
+
+	public ScalarVariable setVariability(SVVariability svVariability) {
+		this.variability = svVariability;
+		return this;
+	}
+
+	public SVCausality getCausality() {
+		return causality;
+	}
+
+	public ScalarVariable setCausality(SVCausality causality) {
+		this.causality = causality;
+		return this;
+	}
+
+	public String getInitial() {
+		return initial;
+	}
+
+	public ScalarVariable setInitial(String initial) {
+		this.initial = initial;
+		return this;
+	}
+
+	public SVType getType() {
+		return type;
+	}
+
+	public ScalarVariable setType(SVType type) {
+		this.type = type;
+		return this;
+	}
+
+	public String getStart() {
+		return start;
+	}
+
+	public ScalarVariable setStart(String start) {
+		this.start = start;
+		return this;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public ScalarVariable setDescription(String description) {
+		this.description = description;
+		return this;
+	}
+}

+ 7 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/exceptions/IncorrectAmountOfElementsException.java

@@ -0,0 +1,7 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions;
+
+public class IncorrectAmountOfElementsException extends Exception {
+	public IncorrectAmountOfElementsException(String arg0) {
+		super(arg0);
+	}
+}

+ 8 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/exceptions/InvalidConversionException.java

@@ -0,0 +1,8 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions;
+
+public class InvalidConversionException extends Exception {
+	// Constructor that accepts a message
+	public InvalidConversionException(String message) {
+		super(message);
+	}
+}

+ 8 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/exceptions/MissingScalarVariableInformationException.java

@@ -0,0 +1,8 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions;
+
+public class MissingScalarVariableInformationException extends Exception {
+	public MissingScalarVariableInformationException(String message) {
+		super(message);
+	}
+
+}

+ 7 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/exceptions/TypeException.java

@@ -0,0 +1,7 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions;
+
+public class TypeException extends Exception {
+	public TypeException(String arg0) {
+		super(arg0);
+	}
+}

+ 102 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/BuildUtilities.java

@@ -0,0 +1,102 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+public class BuildUtilities {
+	public List<File> copyNativeLibFiles(File outfolder) {
+		List<File> libFiles;
+		File outputFile = null;
+		InputStream jarfile = null;
+		FileOutputStream fos = null;
+		JarInputStream jarstream = null;
+		JarEntry filejarentry = null;
+
+		if (!outfolder.exists()) {
+			outfolder.mkdir();
+		}
+
+		libFiles = new LinkedList<>();
+
+		try {
+			jarfile = this.getClass().getClassLoader().getResourceAsStream("jars/cppFramework.jar");
+			jarstream = new JarInputStream(jarfile);
+			filejarentry = jarstream.getNextJarEntry();
+
+			// Extract the framework files
+			while (filejarentry != null) {
+				if (!filejarentry.getName().contains("hybridCosimulation-framework") || filejarentry.isDirectory()) {
+					filejarentry = jarstream.getNextJarEntry();
+					continue;
+				}
+
+				// Ignore these files
+				if (filejarentry.getName().contains(".gitignore") || filejarentry.getName().contains(".gitmodules")
+						/*|| filejarentry.getName().contains("README.md")*/ || filejarentry.getName().contains("LICENSE")) {
+					filejarentry = jarstream.getNextJarEntry();
+					continue;
+				}
+				String tmpFileName = filejarentry.getName().replace("hybridCosimulation-framework/", "");
+
+				outputFile = new File(outfolder.toString() + File.separator + tmpFileName);
+
+				libFiles.add(new File(outfolder.getName() + File.separator + tmpFileName));
+
+				outputFile.getParentFile().mkdirs();
+				fos = new FileOutputStream(outputFile);
+
+				while (jarstream.available() > 0) {
+					int b = jarstream.read();
+					if (b >= 0) {
+						fos.write(b);
+					}
+				}
+				fos.flush();
+				fos.close();
+				jarstream.closeEntry();
+				filejarentry = jarstream.getNextJarEntry();
+			}
+			jarstream.close();
+			jarfile.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		return libFiles;
+	}
+
+	public static void writeToFile(File file, String content) throws IOException
+	{
+		FileWriter writer = new FileWriter(file);
+		writer.write(content);
+		writer.close();
+		System.out.println("Stored file: " + file);
+	}
+
+	public static void copyFile(File sourceFile, File sinkFile) throws IOException {
+	  Files.copy(sourceFile.toPath(), sinkFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+	}
+	
+	public static void deleteFolder(File folder) {
+		File[] files = folder.listFiles();
+		if (files != null) { // some JVMs return null for empty dirs
+			for (File f : files) {
+				if (f.isDirectory()) {
+					deleteFolder(f);
+				} else {
+					f.delete();
+				}
+			}
+		}
+		folder.delete();
+	}
+}

+ 105 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ControlConditionSwitch.xtend

@@ -0,0 +1,105 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation
+
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.GlobalInOutVariable
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.ReturnInformation
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SAScalarVariable
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ControlRuleBlock
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CurrentTime
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CustomControlRule
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DoStep
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DoStepFun
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.StepSize
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
+import java.util.LinkedHashMap
+
+class ControlConditionSwitch extends RulesConditionSwitch {
+
+	new(
+		String adaptationClassName,
+		String adaptationName,
+		LinkedHashMap<String, SAScalarVariable> SASVs,
+		LinkedHashMap<String, GlobalInOutVariable> params
+	) {
+		super(adaptationClassName, adaptationName, "", null, SASVs, params);
+	}
+
+	override ReturnInformation caseVariable(Variable object) {
+		var retVal = new ReturnInformation();
+
+		// H and t are protected variables.
+		if ((object.owner === null || object.owner.name == this.adaptationName) &&
+			(object.ref.name == "H" || object.ref.name == "t")) {
+			retVal.type = SVType.Real;
+			retVal.forceType = true;
+			retVal.code = object.ref.name;
+		} else {
+			retVal = super.caseVariable(object);
+		}
+
+		return retVal;
+	}
+
+	override ReturnInformation caseControlRuleBlock(ControlRuleBlock object) {
+		this.globalDeclaration = true;
+
+		var retVal = new ReturnInformation();
+
+		// Get the global variables added to globalVars
+		for (gVar : object.globalCtrlVars) {
+			constructorInitialization += doSwitch(gVar).code;
+		}
+
+		this.globalDeclaration = false;
+		retVal.appendCode(doSwitch(object.rule).code);
+
+		return retVal;
+	}
+
+	override ReturnInformation caseCustomControlRule(CustomControlRule object) {
+		var retVal = new ReturnInformation();
+
+		var String tempDoSwitchCode = "";
+		for (ruleStm : object.controlRulestatements) {
+			tempDoSwitchCode += doSwitch(ruleStm).code;
+		}
+		tempDoSwitchCode += System.lineSeparator() + '''return «doSwitch(object.returnstatement).code»;
+		''';
+
+		var functionPrefix = "double ";
+		var functionNameArgs = "executeInternalControlFlow(double H, double t)"
+		functionSignatures.add(functionPrefix + functionNameArgs);
+		retVal.code = '''
+			«functionPrefix+this.adaptationClassName»::«functionNameArgs»
+			{
+				«tempDoSwitchCode»
+			}
+		''';
+		return retVal;
+	}
+
+	override ReturnInformation caseDoStepFun(DoStepFun object) {
+		var retVal = new ReturnInformation();
+		retVal.code = '''this->do_step(«object.fmu.name»,«doSwitch(object.h).code»,«doSwitch(object.t).code»);''';
+		retVal.type = SVType.Integer;
+		return retVal;
+	}
+
+	override ReturnInformation caseDoStep(DoStep object) {
+		var retVal = new ReturnInformation();
+		retVal.code = '''this->do_step(«object.fmu.name»,«doSwitch(object.h).code»,«doSwitch(object.t).code»);''';
+		return retVal;
+	}
+
+	override ReturnInformation caseStepSize(StepSize object) {
+		var retVal = new ReturnInformation();
+		retVal.code = '''H''';
+		return retVal;
+	}
+
+	override ReturnInformation caseCurrentTime(CurrentTime object) {
+		var retVal = new ReturnInformation();
+		retVal.code = '''t''';
+		return retVal;
+	}
+}

+ 123 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/Conversions.java

@@ -0,0 +1,123 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation;
+
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType;
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVVariability;
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.InvalidConversionException;
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BoolLiteral;
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IntLiteral;
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Literal;
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RealLiteral;
+
+public class Conversions {
+	public static String fmiTypeToCppType(SVType t) throws InvalidConversionException {
+		switch (t) {
+		case Real:
+			return "double";
+		case Integer:
+			return "int";
+		case Boolean:
+			return "bool";
+		case String:
+			return "string";
+		default:
+			throw new InvalidConversionException("The value type: " + t + " is invalid.");
+		}
+	}
+	
+	public static String fmiTypeToCppTypeCapitalized(SVType t) throws InvalidConversionException
+	{
+		String converted = fmiTypeToCppType(t);
+		return converted.substring(0,1).toUpperCase()+ converted.substring(1);
+	}
+
+	public static SVVariability fmiTypeToFmiVariability(SVType t) throws InvalidConversionException {
+		switch (t) {
+		case Real:
+			return SVVariability.continuous;
+		case Integer:
+		case Boolean:
+		case String:
+			return SVVariability.discrete;
+		default:
+			throw new InvalidConversionException("The value type: " + t + " is invalid.");
+		}
+	}
+
+	public static String fmiTypeToCppDefaultValue(SVType t) throws InvalidConversionException {
+		switch (t) {
+		case Real:
+			return "0.0";
+		case Integer:
+			return "0";
+		case Boolean:
+			return "false";
+		case String:
+			return "\"\"";
+		default:
+			throw new InvalidConversionException("The value type: " + t + " is invalid.");
+		}
+	}
+
+	public static SVType typeDecider(SVType t1, SVType t2) throws InvalidConversionException {
+		switch (t1) {
+		case Real:
+			switch (t2) {
+			case Real:
+			case Integer:
+				return SVType.Real;
+			default:
+				throw new InvalidConversionException(
+						"The type: " + t1.name() + " is unmergable with " + t2.name() + ".");
+			}
+		case Integer:
+			switch (t2) {
+			case Real:
+				return SVType.Real;
+			case Integer:
+				return SVType.Integer;
+			default:
+				throw new InvalidConversionException(
+						"The type: " + t1.name() + " is unmergable with " + t2.name() + ".");
+			}
+		case Boolean:
+			switch (t2) {
+			case Boolean:
+				return SVType.Boolean;
+			default:
+				throw new InvalidConversionException(
+						"The type: " + t1.name() + " is unmergable with " + t2.name() + ".");
+			}
+		case String:
+			switch (t2) {
+			case String:
+				return SVType.String;
+			default:
+				throw new InvalidConversionException(
+						"The type: " + t1.name() + " is unmergable with " + t2.name() + ".");
+			}
+		default:
+			throw new InvalidConversionException("The type: " + t1 + " is invalid.");
+		}
+	}
+	
+	/*
+	 * UTILITY FUNCTIONS 
+	 */
+	public static Object convertTypeToObject(SVType type, Literal object) throws Exception {
+		switch (type) {
+			case Real: {
+				return (new Float(((RealLiteral)object).getValue())).doubleValue();
+			}
+			case Integer: {
+				return ((IntLiteral)object).getValue();
+			}
+			case Boolean: {
+				return Boolean.parseBoolean(((BoolLiteral)object).getValue());
+			}
+			default: {
+				throw new Exception("Missing conversion");
+			}
+		}
+	}
+
+}

+ 585 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/CppGenerator.xtend

@@ -0,0 +1,585 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation
+
+import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationGenerator
+import org.eclipse.xtext.generator.IFileSystemAccess2
+
+import org.eclipse.xtext.generator.IGeneratorContext
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
+import org.eclipse.emf.ecore.resource.Resource
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
+import java.util.ArrayList
+import java.util.LinkedHashMap
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.MappedScalarVariable
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InnerFMU
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.IncorrectAmountOfElementsException
+import java.io.File
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SAScalarVariable
+import org.eclipse.emf.common.util.EList
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVCausality
+import java.util.Collection
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InOutRules
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InRulesBlock
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.InOutRulesBlockResult
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.OutRulesBlock
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.GlobalInOutVariable
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ControlRuleBlock
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.RulesBlockResult
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.ScalarVariable
+import java.util.List
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ParamDeclarations
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.InputOutputRuleType
+
+class CppGenerator extends SemanticAdaptationGenerator {
+	private var IFileSystemAccess2 fsa;
+	private List<File> resourcePaths = newArrayList();
+
+	override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
+		this.fsa = fsa;
+		for (SemanticAdaptation type : resource.allContents.toIterable.filter(SemanticAdaptation)) {
+			type.compile;
+
+		}
+	}
+
+	// TODO: Verify adaptation.name is not a C++ keyword
+	def void compile(SemanticAdaptation adaptation) {
+		for (Adaptation adap : adaptation.elements.filter(Adaptation)) {
+			// Value used for scoping variables in the .sa file
+			val adapInteralRefName = adap.name;
+
+			// The CPP class name
+			val adapClassName = adap.name.toFirstUpper;
+
+			// This is the external name used in the model description file for the semantic adaptation FMU.
+			val adapExternalName = adap.type.name;
+
+			// List of FMUs with a pairing between its name and its type.name.
+			var ArrayList<Pair<String, String>> fmus = newArrayList();
+
+			// TODO: Currently only 1 inner fmu is supported
+			val innerFmus = adap.inner.eAllContents.toList.filter(InnerFMU);
+			if (innerFmus.size > 1) {
+				throw new IncorrectAmountOfElementsException("Only one InnerFmu is supported.")
+			}
+			if (innerFmus.isEmpty) {
+				throw new IncorrectAmountOfElementsException("The adaptation does not contain any InnerFMUs.")
+			}
+
+			/*
+			 * This map will contain scalar variables from the FMUs defined in InnerFMU.
+			 * The structure is fmuName -> (SVName -> mappedSV) where SVName = mappedSV.name for easy lookup.
+			 * The mappedSV contains the original scalar variable and extra data such as define name.
+			 */
+			var LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mappedScalarVariables = newLinkedHashMap();
+
+			/*
+			 * Loading the FMU defined in InnerFMU, the related model description file and its scalar variables.
+			 */
+			// TODO: Add support for multiple inner fmus
+			var ModelDescription md;
+			for (fmu : adap.inner.eAllContents.toList.filter(InnerFMU)) {
+				val fmuFile = new File(fmu.path.replace('\"', ''));
+				this.resourcePaths.add(fmuFile);
+				md = new ModelDescription(fmu.name, fmu.type.name, fmuFile);
+				fmus.add(fmu.name -> fmu.type.name);
+				val LinkedHashMap<String, MappedScalarVariable> mSV = newLinkedHashMap();
+				for (sv : md.sv.values) {
+					var mappedSv = new MappedScalarVariable(sv);
+					mappedSv.define = (mappedSv.mappedSv.owner + mappedSv.mappedSv.name).toUpperCase;
+					mSV.put(mappedSv.mappedSv.name, mappedSv);
+				}
+				mappedScalarVariables.put(fmu.name, mSV);
+			}
+
+			// C++ Defines for accessing FMU scalar variables.
+			val String fmusDefines = calcDefines(mappedScalarVariables);
+
+			// Compile Params
+			var LinkedHashMap<String, GlobalInOutVariable> params = newLinkedHashMap;
+			val String paramsConstructorSource = compileParams(params, adap.params);
+
+			/*
+			 * This map contains all the ScalarVariables for the semantic adaptation. 
+			 * The are not populated yet, but they will be during the compilation of the in and out rule blocks. 
+			 */
+			var LinkedHashMap<String, SAScalarVariable> SASVs = calcSASVsFromInportsOutports(adapInteralRefName,
+				adap.inports, adap.outports)
+
+			// C++ defines for accessing semantic adaptation scalar variables 
+			val String SADefines = calcSADefines(SASVs.values);
+
+			// Compile the transparent in mappings
+
+			// Compile the in rules
+			val inRuleResult = compileInOutRuleBlocks(InputOutputRuleType.Input, adaptation.eAllContents.toIterable.filter(
+				InRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables, SASVs,
+				params);
+
+			// Compile the out rules
+			val outRuleResult = compileInOutRuleBlocks(InputOutputRuleType.Output, adaptation.eAllContents.toIterable.
+				filter(OutRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables,
+				SASVs, params);
+
+			// Compile the Control Rules
+			val crtlRuleResult = compileControlRuleBlock(adaptation.eAllContents.toIterable.filter(ControlRuleBlock),
+				adapClassName, adapInteralRefName, SASVs, params);
+
+			/*
+			 * Compile the constructor, destructor and initialize functions
+			 */
+			val String deAndConstructorAndInitializeSource = compileDeAndConstructorAndInitialize(
+				adapClassName,
+				fmus.head.key,
+				fmus.head.value,
+				md.guid,
+				paramsConstructorSource,
+				inRuleResult.constructorInitialization,
+				outRuleResult.constructorInitialization,
+				crtlRuleResult.constructorInitialization
+			);
+
+			/*
+			 * Compile getRuleThis function
+			 */
+			val String getRuleThisSource = compileGetRuleThis(adapClassName);
+
+			/*
+			 * The in and out rules have populated the semantic adaptation scalar variables we can generate the getFmiValue* and setFmiValue functions.
+			 */
+			val String getFuncsSource = compileGetFmiValueFunctions(adapClassName, SASVs);
+			val String setFuncsSource = compileSetFmiValueFunctions(adapClassName, SASVs);
+
+			// Compile the source file
+			val String sourceInclude = '''#include "«adapClassName».h"''';
+			val sourceFile = compileSource(
+				sourceInclude,
+				deAndConstructorAndInitializeSource,
+				getRuleThisSource,
+				getFuncsSource,
+				setFuncsSource,
+				inRuleResult.generatedCpp,
+				outRuleResult.generatedCpp,
+				crtlRuleResult.generatedCpp
+			);
+			fsa.generateFile(adapClassName + ".cpp", sourceFile);
+
+			// Merge the global variables for use in compiling the header file.
+			// TODO: Check for duplicates
+			var LinkedHashMap<String, GlobalInOutVariable> allGVars = newLinkedHashMap();
+			allGVars.putAll(params);
+			allGVars.putAll(outRuleResult.gVars);
+			allGVars.putAll(inRuleResult.gVars);
+			allGVars.putAll(crtlRuleResult.gVars);
+
+			// Compile the header file
+			val headerFile = compileHeader(
+				adapClassName,
+				fmusDefines,
+				SADefines,
+				inRuleResult.functionSignatures,
+				outRuleResult.functionSignatures,
+				crtlRuleResult.functionSignatures,
+				allGVars,
+				fmus,
+				SASVs.values.map[CalcSVar()].toList
+			);
+			fsa.generateFile(adapClassName + ".h", headerFile);
+
+			// Compile the model description file
+			val modelDescCreator = new ModelDescriptionCreator(adapExternalName);
+			val modelDescription = modelDescCreator.generateModelDescription(SASVs.values);
+			fsa.generateFile("modelDescription.xml", modelDescription);
+
+			// Compile the fmu.cpp file
+			val fmuCppFile = StaticGenerators.GenFmuCppFile(adapClassName);
+			fsa.generateFile("Fmu.cpp", fmuCppFile);
+
+		}
+	}
+
+	def String compileParams(LinkedHashMap<String, GlobalInOutVariable> gVars, EList<ParamDeclarations> params) {
+		val paramsConditionSwitch = new ParamConditionSwitch(gVars);
+		var String paramsConstructorSource = "";
+		for (paramDecl : params) {
+			val doSwitchRes = paramsConditionSwitch.doSwitch(paramDecl);
+			paramsConstructorSource += doSwitchRes.code;
+		}
+		return paramsConstructorSource;
+	}
+
+	def calcSADefines(Collection<SAScalarVariable> variables) {
+		var ArrayList<String> defines = newArrayList();
+
+		for (SASV : variables) {
+			defines.add("#define " + SASV.defineName + " " + SASV.valueReference);
+		}
+
+		return defines.join("\n");
+	}
+
+	def calcDefines(LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> map) {
+		var ArrayList<String> defines = newArrayList();
+
+		for (fmuEntries : map.entrySet) {
+			for (MappedScalarVariable mSV : fmuEntries.value.values) {
+				defines.add("#define " + mSV.define + " " + mSV.valueReference);
+			}
+		}
+
+		return defines.join("\n");
+	}
+
+	// Compiles the final source file
+	def String compileSource(String include, String constructor, String getRuleThis, String getFunctions,
+		String setFunctions, String inFunctions, String outFunctions, String controlFunction) {
+		return '''
+			«include»
+			
+			namespace adaptation 
+			{
+				«constructor»
+				
+				«getRuleThis»
+				
+				«getFunctions»
+				
+				«setFunctions»
+				
+				«inFunctions»
+				
+				«controlFunction»
+				
+				«outFunctions»
+			
+			}
+			
+		'''
+	}
+
+	/*
+	 * Compiles the header file split into two: The first part contains the includes and using namespace definitions and start t