Browse Source

DSL now supports loop_sa

Casper Thule 6 years ago
parent
commit
3a18450bfb
18 changed files with 394 additions and 218 deletions
  1. 28 35
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest.xtend
  2. BIN
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/Obstacle.fmu
  3. 12 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/Obstacle.mo
  4. BIN
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/WindowSA.fmu
  5. 74 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/loop_canonical.sa
  6. 25 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/modelDescription.xml
  7. 0 39
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/window_sa.BASE_canonical.sa
  8. 0 84
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/window_sa_canonical.BASE.sa
  9. 31 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/InnerFMUData.java
  10. 11 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/data/ReturnInformation.java
  11. 6 4
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/BuildUtilities.java
  12. 54 4
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ControlConditionSwitch.xtend
  13. 47 25
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/CppGenerator.xtend
  14. 9 0
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/GeneralConditionSwitch.xtend
  15. 2 4
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/InRulesConditionSwitch.xtend
  16. 2 1
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/OutRulesConditionSwitch.xtend
  17. 0 2
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ParamConditionSwitch.xtend
  18. 93 20
      DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/RulesConditionSwitch.xtend

+ 28 - 35
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest.xtend

@@ -40,20 +40,20 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 //		__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 window_sa_canonical_generated() {
-		__parseNoErrors('test_input/single_folder_spec/window/window_sa.BASE_canonical.sa', 'generated', "powerwindow_generated");
+		__parseNoErrors('test_input/single_folder_spec/window/window_sa_canonical_new.BASE.sa', 'generated',
+			"powerwindow");
 	}
-	
-	@Ignore
-	@Test def lazy_sa_canonical() {
+
+	@Test def lazy_canonical() {
 		__parseNoErrors('test_input/single_folder_spec/lazy/lazy_canonical.sa', 'generated', "lazy");
 	}
 
+	@Test def loop() {
+		__parseNoErrors('test_input/single_folder_spec/loop/loop_canonical.sa', 'generated', "loop");
+	}
+
 	def __parseNoErrorsWithValidation(String directory, String filename) {
 		val model = __parse(filename);
 		__assertNoParseErrors(model, filename);
@@ -103,7 +103,6 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 
 	}
 
-
 	def __parseNoErrors(String filename, String directory, String projectName) {
 		val saRootDir = new File(directory + File.separatorChar + projectName);
 		val srcGenPath = new File(saRootDir, "sources")
@@ -119,11 +118,11 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 		val IGeneratorContext ctxt = null;
 		val cppGen = new CppGenerator();
 		cppGen.doGenerate(model.eResource, fsa, ctxt);
-		
+
 		if (saRootDir.exists) {
 			BuildUtilities.deleteFolder(saRootDir);
 		}
-				
+
 		saRootDir.mkdirs();
 		srcGenPath.mkdirs();
 		resourcesPath.mkdirs();
@@ -131,41 +130,35 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 
 		for (files : fsa.allFiles.entrySet) {
 			val fName = files.key.substring(14);
-			
+
 			var File fp;
-			if(fName.equals("modelDescription.xml"))
-			{
+			if (fName.equals("modelDescription.xml")) {
 				fp = new File(saRootDir, fName);
-			}
-			else
-			{
+			} else {
 				fp = new File(srcGenPath, fName);
 			}
-			
-			BuildUtilities.writeToFile(fp, files.value.toString);	
+
+			BuildUtilities.writeToFile(fp, files.value.toString);
 		}
-		
-		val mainCpp = StaticGenerators.generateMainCppFile(resourcesPath.absolutePath.replace("\\","\\\\"));
-		BuildUtilities.writeToFile(new File(srcGenPath,"main.cpp"), mainCpp);
-		
-		
-		for(rf : cppGen.resourcePaths)
-		{
+
+		val mainCpp = StaticGenerators.generateMainCppFile(resourcesPath.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.copyFile(rf, sinkFile);
 		}
-		
-		
-		BuildUtilities.writeToFile(new File(saRootDir,"CMakeLists.txt"), StaticGenerators.generateCMakeLists(projectName, "framework"));
-		
+
+		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);
-		
-				
+
 	}
 
 	def __parseNoErrorsPrint(String filename) {

BIN
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/Obstacle.fmu


+ 12 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/Obstacle.mo

@@ -0,0 +1,12 @@
+model Obstacle
+  parameter Real c = 1e10;
+  parameter Real fixed_x = 0.45;
+  input Real disp;
+  output Real reaction_force;
+  Real compression;
+equation
+  compression = disp - fixed_x;
+  reaction_force = if disp > fixed_x then c * compression else 0;
+  annotation(
+    experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-06, Interval = 0.002));
+end Obstacle;

BIN
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/WindowSA.fmu


+ 74 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/loop_canonical.sa

@@ -0,0 +1,74 @@
+semantic adaptation reactive moore LoopSA loop_sa
+at "./path/to/LoopSA.fmu"
+	
+	for inner fmu WindowSA window_sa
+		at "./test_input/single_folder_spec/loop/WindowSA.fmu"
+		with input ports displacement (rad), speed (rad/s), reaction_force (N)
+		with output ports disp (m), tau (N.m)
+	
+	for inner fmu Obstacle obstacle
+		at "./test_input/single_folder_spec/loop/Obstacle.fmu"
+		with input ports disp (m)
+		with output ports reaction_force (m)
+	
+	coupled as window_sa.disp -> obstacle.disp, 
+				obstacle.reaction_force -> window_sa.reaction_force
+
+input ports displacement, speed
+
+output ports tau
+
+param 	MAXITER := 10, REL_TOL := 1e-05, ABS_TOL := 1e-05,
+		INIT_LOOP_SA_DISPLACEMENT := 0.0,
+		INIT_LOOP_SA_SPEED := 0.0,
+		INIT_WINDOW_SA_DISP := 0.0,
+		INIT_WINDOW_SA_TAU := 0.0,
+		INIT_OBSTACLE_REACTION_FORCE := 0.0;
+
+control var prev_disp := 0.0;
+control rules {
+	var repeat := false;
+	for (var iter in 0 .. MAXITER) {
+		save_state(obstacle);
+		save_state(window_sa);
+		obstacle.disp := prev_disp;
+		do_step(obstacle,t,H);
+		window_sa.reaction_force := stored_obstacle_reaction_force;
+		do_step(window_sa,t,H);
+		
+		repeat := is_close(prev_disp, stored_window_sa_disp, REL_TOL, ABS_TOL);
+		prev_disp := stored_window_sa_disp;
+		if (repeat) {
+			break;
+		} else {
+			rollback(obstacle);
+			rollback(window_sa);
+		}
+	}
+	return H;
+}
+
+in var 	stored_loop_sa_displacement := INIT_LOOP_SA_DISPLACEMENT,
+		stored_loop_sa_speed := INIT_LOOP_SA_SPEED;
+in rules {
+	true -> {
+		stored_loop_sa_displacement := loop_sa.displacement;
+		stored_loop_sa_speed := loop_sa.speed;
+	} --> {
+		window_sa.displacement := stored_loop_sa_displacement;
+		window_sa.speed := stored_loop_sa_speed;
+	};
+}
+
+out var	stored_window_sa_disp := INIT_WINDOW_SA_DISP,
+		stored_window_sa_tau := INIT_WINDOW_SA_TAU,
+		stored_obstacle_reaction_force := INIT_OBSTACLE_REACTION_FORCE;
+out rules{
+	true -> {
+		stored_window_sa_disp := window_sa.disp;
+		stored_window_sa_tau := window_sa.tau;
+		stored_obstacle_reaction_force := obstacle.reaction_force;
+	} --> {
+		loop_sa.tau := stored_window_sa_tau;
+	};
+}

+ 25 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/loop/modelDescription.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?><fmiModelDescription fmiVersion="2.0" guid="570bcfd2-d87a-4ab7-8d34-25bd0df92501" modelName="WindowSA" variableNamingConvention="flat">
+    <ModelVariables>
+        <ScalarVariable causality="input" name="reaction_force" valueReference="0" variability="continuous">
+            <Real start="0.0"/>
+        </ScalarVariable>
+        <ScalarVariable causality="input" name="displacement" valueReference="1" variability="continuous">
+            <Real start="0.0"/>
+        </ScalarVariable>
+        <ScalarVariable causality="input" name="speed" valueReference="2" variability="continuous">
+            <Real start="0.0"/>
+        </ScalarVariable>
+        <ScalarVariable causality="output" name="disp" valueReference="3" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="output" name="tau" valueReference="4" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+    </ModelVariables>
+    <ModelStructure>
+        <Outputs>
+            <Unknown dependencies="" index="4"/>
+            <Unknown dependencies="" index="5"/>
+        </Outputs>
+    </ModelStructure>
+</fmiModelDescription>

+ 0 - 39
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/window_sa.BASE_canonical.sa

@@ -1,39 +0,0 @@
-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 Real displacement(rad), Real speed (rad/s), Real reaction_force (N)
-		with output ports Real height (cm), Real reaction_torque (N.m)
-
-input ports Real displacement ( rad ) , Real speed ( rad / s ) , Real reaction_force ( N )
-
-output ports Real disp (m)  , Real tau (N)
-
-param Real INIT_DISPLACEMENT := 0.0 , Real INIT_SPEED := 0.0 , Real INIT_REACTION_FORCE := 0.0 , Real INIT_HEIGHT := 0.0 , Real INIT_REACTION_TORQUE := 0.0 ;
-
-control rules {
-var H_window := do_step ( window , t , H ) ;
-return min ( H_window ) ; }
-
-in var Real stored__displacement := INIT_DISPLACEMENT , Real stored__speed := INIT_SPEED , Real stored__reaction_force := INIT_REACTION_FORCE ; 
-in rules {
-	true -> {
-		stored__speed := windowSA . speed ;
-		stored__reaction_force := windowSA . reaction_force ;
-		stored__displacement := windowSA . displacement ; } --> {
-		window . speed := stored__speed ;
-		window . displacement := stored__displacement ;
-		window . reaction_force := stored__reaction_force ; } ; }
-		
-out var Real stored__reaction_torque := INIT_REACTION_TORQUE , Real stored__height := INIT_HEIGHT ; 
-out rules {
-	true -> {
-		stored__reaction_torque := window . reaction_torque ;
-		stored__height := window . height ; } --> {
-		windowSA . disp := stored__height / 100.0 ;
-		windowSA.tau := -stored__reaction_torque;
-	};
-}
-
-

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

@@ -1,84 +0,0 @@
-module Window_SA
-
-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)
-
-/*
-In the original version, no input ports where declared, so all dangling inputs of the original fmus are bound to the input ports of the adapted FMU.
-In the canonical version, the input and output ports are all declared explicitly, and their bindings are implemented in the in/out rules.
-*/
-
-input ports 	reaction_force,
-				displacement,
-				speed
-
-	output ports	disp,
-					tau
-
-
-control rules {
-	do_step(window, t, H); // includes update_in rules and update_out (update-in rules do not update state)
-	return H;
-}
-
-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 -> {
-		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;			
-			}
-	} --> {
-		window.displacement := stored_windowsa_displacement; 
-		};
-	
-	
-	true -> {		
-		if (is_set(windowSA.speed)){
-			stored_windowsa_speed := windowSA.speed;
-		}
-	} --> {
-		
-		window.speed := stored_windowsa_speed;
-	};
-}
-
-out var stored_window_reaction_torque := 0.0,
-		stored_window_height := 0.0;
-		
-out rules {
-
-	true -> {
-		stored_window_reaction_torque := window.reaction_torque;
-	} --> {
-		windowSA.tau := - stored_window_reaction_torque;
-	};
-	
-	true -> {
-		stored_window_height := window.height;
-	} --> {
-		windowSA.disp := stored_window_height * 100;
-	};
-
-}
-

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

@@ -0,0 +1,31 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data;
+
+public class InnerFMUData {
+	private String name;
+	private String typeName;
+	private String guid;
+	public InnerFMUData(String name, String typeName, String guid)
+	{
+		this.name = name;
+		this.typeName = typeName;
+		this.guid = guid;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getTypeName() {
+		return typeName;
+	}
+	public void setTypeName(String typeName) {
+		this.typeName = typeName;
+	}
+	public String getGuid() {
+		return guid;
+	}
+	public void setGuid(String guid) {
+		this.guid = guid;
+	}
+}

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

@@ -12,6 +12,7 @@ public class ReturnInformation {
 	private SAScalarVariable ConSaSv;
 	private GlobalInOutVariable conGlobVar;
 	private boolean forceType = false;
+	private boolean isExpression = false;
 
 	public ReturnInformation() {
 		// TODO Auto-generated constructor stub
@@ -28,6 +29,16 @@ public class ReturnInformation {
 	public void setCode(String code) {
 		this.code = code;
 	}
+	
+	public void setIsExpression(boolean isExpression)
+	{
+		this.isExpression = isExpression;
+	}
+	
+	public boolean getIsExpression()
+	{
+		return this.isExpression;
+	}
 
 	public SVType getType() throws Exception {
 		if(!typeIsSet)

+ 6 - 4
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/BuildUtilities.java

@@ -14,7 +14,7 @@ import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 
 public class BuildUtilities {
-	public List<File> copyNativeLibFiles(File outfolder) {
+	public void copyNativeLibFiles(File outfolder) {
 		List<File> libFiles;
 		File outputFile = null;
 		InputStream jarfile = null;
@@ -25,11 +25,15 @@ public class BuildUtilities {
 		if (!outfolder.exists()) {
 			outfolder.mkdir();
 		}
+		else
+		{
+			return;
+		}
 
 		libFiles = new LinkedList<>();
 
 		try {
-			jarfile = new FileInputStream(new File("jars/cppFramework.jar"));
+			jarfile = new FileInputStream(new File("target/classes/jars/cppFramework.jar"));
 			jarstream = new JarInputStream(jarfile);
 			filejarentry = jarstream.getNextJarEntry();
 
@@ -72,8 +76,6 @@ public class BuildUtilities {
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
-
-		return libFiles;
 	}
 
 	public static void writeToFile(File file, String content) throws IOException

+ 54 - 4
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ControlConditionSwitch.xtend

@@ -12,16 +12,37 @@ 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
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Assignment
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.MappedScalarVariable
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SaveState
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Close
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BreakStatement
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Rollback
+import java.util.List
 
 class ControlConditionSwitch extends RulesConditionSwitch {
 
 	new(
 		String adaptationClassName,
 		String adaptationName,
+		LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars,
 		LinkedHashMap<String, SAScalarVariable> SASVs,
-		LinkedHashMap<String, GlobalInOutVariable> params
+		LinkedHashMap<String, GlobalInOutVariable> params,
+		LinkedHashMap<String, GlobalInOutVariable> outVars
 	) {
-		super(adaptationClassName, adaptationName, "", null, SASVs, params);
+		super(adaptationClassName, adaptationName, "", mSVars, SASVs, params, outVars);
+	}
+
+	override ReturnInformation caseAssignment(Assignment object) {
+		
+		if (object.lvalue.owner !== null) {
+			var retVal = new ReturnInformation();
+			retVal.code = '''setValue(«object.lvalue.owner.name»,«mSVars.get(object.lvalue.owner.name).get(object.lvalue.ref.name).define»,«doSwitch(object.expr).code»)'''
+			return retVal;
+		} else {
+			return super.caseAssignment(object);
+		}
 	}
 
 	override ReturnInformation caseVariable(Variable object) {
@@ -80,14 +101,14 @@ class ControlConditionSwitch extends RulesConditionSwitch {
 
 	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.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»);''';
+		retVal.code = '''this->do_step(«object.fmu.name»,«doSwitch(object.h).code»,«doSwitch(object.t).code»)''';
 		return retVal;
 	}
 
@@ -102,4 +123,33 @@ class ControlConditionSwitch extends RulesConditionSwitch {
 		retVal.code = '''t''';
 		return retVal;
 	}
+	
+	
+
+	override ReturnInformation caseSaveState(SaveState object) {
+		var retVal = new ReturnInformation();
+		retVal.appendCode('''
+		saveState(«object.fmu.name»)''')
+		return retVal;
+	}
+	
+	override ReturnInformation caseClose(Close object)
+	{
+		var retVal = new ReturnInformation();
+		retVal.code = '''is_close(«object.args.map[e | doSwitch(e).code].join(", ")»)''';		
+		return retVal;
+	}
+	
+	override ReturnInformation caseBreakStatement(BreakStatement object){
+		var retVal = new ReturnInformation();
+		retVal.appendCode('''break''')
+		return retVal;
+	}
+	
+	override ReturnInformation caseRollback(Rollback object)
+	{
+		var retVal = new ReturnInformation();
+		retVal.appendCode('''rollback(«object.fmu.name»)''')
+		return retVal;
+	}
 }

+ 47 - 25
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/CppGenerator.xtend

@@ -30,6 +30,7 @@ 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
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.InnerFMUData
 
 class CppGenerator extends SemanticAdaptationGenerator {
 	private var IFileSystemAccess2 fsa;
@@ -55,13 +56,14 @@ class CppGenerator extends SemanticAdaptationGenerator {
 			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();
+			//var ArrayList<Pair<String, String>> fmus = newArrayList();
+			var ArrayList<InnerFMUData> innerFMUsData = 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.size > 1) {
+//				throw new IncorrectAmountOfElementsException("Only one InnerFmu is supported.")
+//			}
 			if (innerFmus.isEmpty) {
 				throw new IncorrectAmountOfElementsException("The adaptation does not contain any InnerFMUs.")
 			}
@@ -82,7 +84,8 @@ class CppGenerator extends SemanticAdaptationGenerator {
 				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);
+				innerFMUsData.add(new InnerFMUData(fmu.name, fmu.type.name, md.guid));
+				//fmus.add(fmu.name -> fmu.type.name);
 				val LinkedHashMap<String, MappedScalarVariable> mSV = newLinkedHashMap();
 				for (sv : md.sv.values) {
 					var mappedSv = new MappedScalarVariable(sv);
@@ -121,17 +124,16 @@ class CppGenerator extends SemanticAdaptationGenerator {
 				filter(OutRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables,
 				SASVs, params);
 
-			// Compile the Control Rules
+			// Compile the Control Rules. These might use the out vars, so pass these along.
 			val crtlRuleResult = compileControlRuleBlock(adaptation.eAllContents.toIterable.filter(ControlRuleBlock),
-				adapClassName, adapInteralRefName, SASVs, params);
+				adapClassName, adapInteralRefName, mappedScalarVariables, SASVs, params, outRuleResult.gVars);
 
 			/*
 			 * Compile the constructor, destructor and initialize functions
 			 */
 			val String deAndConstructorAndInitializeSource = compileDeAndConstructorAndInitialize(
 				adapClassName,
-				fmus.head.key,
-				fmus.head.value,
+				innerFMUsData,
 				md.guid,
 				paramsConstructorSource,
 				inRuleResult.constructorInitialization,
@@ -181,7 +183,7 @@ class CppGenerator extends SemanticAdaptationGenerator {
 				outRuleResult.functionSignatures,
 				crtlRuleResult.functionSignatures,
 				allGVars,
-				fmus,
+				innerFMUsData,
 				SASVs.values.map[CalcSVar()].toList
 			);
 			fsa.generateFile(adapClassName + ".h", headerFile);
@@ -263,7 +265,7 @@ class CppGenerator extends SemanticAdaptationGenerator {
 	 */
 	def String compileHeader(String adapClassName, String fmusDefines, String SADefines, List<String> inRulesFuncSig,
 		List<String> outRulesFuncSig, List<String> crtlRulesFuncSig,
-		LinkedHashMap<String, GlobalInOutVariable> globalVariables, ArrayList<Pair<String, String>> fmus,
+		LinkedHashMap<String, GlobalInOutVariable> globalVariables, ArrayList<InnerFMUData> fmus,
 		Collection<ScalarVariable> sVars) {
 		return '''
 			
@@ -314,7 +316,7 @@ class CppGenerator extends SemanticAdaptationGenerator {
 							«crtlRulesFuncSig.map[x | x+";"].join("\n")»
 							
 							«FOR fmu : fmus»
-								shared_ptr<FmuComponent> «fmu.key»;
+								shared_ptr<FmuComponent> «fmu.name»;
 							«ENDFOR»
 							
 							«FOR sv : sVars»
@@ -337,8 +339,24 @@ class CppGenerator extends SemanticAdaptationGenerator {
 	/*
 	 * Compiles the source file constructor, destructor and the initialize function
 	 */
-	def String compileDeAndConstructorAndInitialize(String adapClassName, String fmuName, String fmuTypeName,
+	def String compileDeAndConstructorAndInitialize(String adapClassName, ArrayList<InnerFMUData> fmus,
 		String guid, String paramsCons, String inCons, String outCons, String crtlCons) {
+			
+			var ArrayList<String> initialisations = newArrayList();
+			for( fmu : fmus)
+			{
+				initialisations.add('''
+				auto path = make_shared<string>(*resourceLocation);
+				path->append(string("«fmu.typeName».fmu"));
+				auto «fmu.name»Fmu = make_shared<fmi2::Fmu>(*path);
+				«fmu.name»Fmu->initialize();
+				this->«fmu.name» = «fmu.name»Fmu->instantiate("«fmu.name»",fmi2CoSimulation, "«fmu.guid»", true, true, shared_from_this());
+				
+				if(this->«fmu.name»->component == NULL)
+					this->lastErrorState = fmi2Fatal;
+				this->instances->push_back(this->«fmu.name»);
+				''');
+			}
 		return '''
 			«adapClassName»::«adapClassName»(shared_ptr<std::string> fmiInstanceName,shared_ptr<string> resourceLocation, const fmi2CallbackFunctions* functions) : 
 				SemanticAdaptation(fmiInstanceName, resourceLocation, createInputRules(),createOutputRules(), functions)
@@ -351,16 +369,19 @@ class CppGenerator extends SemanticAdaptationGenerator {
 			}
 			
 			void «adapClassName»::initialize()
-			{				
-				auto path = make_shared<string>(*resourceLocation);
-				path->append(string("«fmuTypeName».fmu"));
-				auto «fmuName»Fmu = make_shared<fmi2::Fmu>(*path);
-				«fmuName»Fmu->initialize();
-				this->«fmuName» = «fmuName»Fmu->instantiate("«fmuName»",fmi2CoSimulation, "«guid»", true, true, shared_from_this());
-				
-				if(this->«fmuName»->component == NULL)
-					this->lastErrorState = fmi2Fatal;
-				this->instances->push_back(this->«fmuName»);
+			{
+				«initialisations.join("\r\n")»
+«««				«FOR fmu : fmus»
+«««				auto path = make_shared<string>(*resourceLocation);
+«««				path->append(string("«fmu.value».fmu"));
+«««				auto «fmu.key»Fmu = make_shared<fmi2::Fmu>(*path);
+«««				«fmu.key»Fmu->initialize();
+«««				this->«fmu.key» = «fmu.key»Fmu->instantiate("«fmu.key»",fmi2CoSimulation, "«guid»", true, true, shared_from_this());
+«««				
+«««				if(this->«fmu.key»->component == NULL)
+«««					this->lastErrorState = fmi2Fatal;
+«««				this->instances->push_back(this->«fmu.key»);
+«««				«ENDFOR»
 			}
 			
 			«adapClassName»::~«adapClassName»()
@@ -474,9 +495,10 @@ class CppGenerator extends SemanticAdaptationGenerator {
 	 * Calculates necessary information on function signatures necessary for generation of the header file.
 	 */
 	def InOutRulesBlockResult compileControlRuleBlock(Iterable<ControlRuleBlock> crtlRuleBlocks, String adaptationClassName,
-		String adaptationName, LinkedHashMap<String, SAScalarVariable> SASVs, LinkedHashMap<String, GlobalInOutVariable> params) {
+		String adaptationName, LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars, 
+		LinkedHashMap<String, SAScalarVariable> SASVs, LinkedHashMap<String, GlobalInOutVariable> params, LinkedHashMap<String, GlobalInOutVariable> outVars) {
 		var cpp = "";
-		val visitor = new ControlConditionSwitch(adaptationClassName, adaptationName, SASVs, params);
+		val visitor = new ControlConditionSwitch(adaptationClassName, adaptationName, mSVars, SASVs, params, outVars);
 		for (crtlRule : crtlRuleBlocks) {
 			cpp += visitor.doSwitch(crtlRule).code;
 		}

+ 9 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/GeneralConditionSwitch.xtend

@@ -8,6 +8,7 @@ import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RealLiteral
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SingleParamDeclaration
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.util.SemanticAdaptationSwitch
 import org.eclipse.emf.ecore.EObject
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IntLiteral
 
 class GeneralConditionSwitch extends SemanticAdaptationSwitch<ReturnInformation> {
 	override ReturnInformation caseParamDeclarations(ParamDeclarations object) {
@@ -17,6 +18,14 @@ class GeneralConditionSwitch extends SemanticAdaptationSwitch<ReturnInformation>
 		return new ReturnInformation();
 	}
 
+	override ReturnInformation caseIntLiteral(IntLiteral object){
+		var retInfo = new ReturnInformation();
+		retInfo.type = SVType.Integer;
+		retInfo.value = Conversions.convertTypeToObject(retInfo.type, object);
+		retInfo.code = '''«object.value»''';
+		return retInfo;
+	}
+
 	override ReturnInformation caseRealLiteral(RealLiteral object) {
 		var retInfo = new ReturnInformation();
 		retInfo.type = SVType.Real;

+ 2 - 4
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/InRulesConditionSwitch.xtend

@@ -15,7 +15,7 @@ class InRulesConditionSwitch extends RulesConditionSwitch {
 	new(String adaptationClassName, String adaptationName, LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars, LinkedHashMap<String,SAScalarVariable> SASVs
 		,LinkedHashMap<String, GlobalInOutVariable> params
 	) {
-		super(adaptationClassName, adaptationName, "in_rule_", mSVars, SASVs, params);
+		super(adaptationClassName, adaptationName, "in_rule_", mSVars, SASVs, params, null);
 	}
 
 
@@ -32,9 +32,7 @@ class InRulesConditionSwitch extends RulesConditionSwitch {
 				
 		if (inOutputFunction) {
 			retVal.code = 	
-				'''
-					setValue(«object.lvalue.owner.name»,«mSVars.get(object.lvalue.owner.name).get(object.lvalue.ref.name).define»,«doSwitch(object.expr).code»);
-				''';
+				'''setValue(«object.lvalue.owner.name»,«mSVars.get(object.lvalue.owner.name).get(object.lvalue.ref.name).define»,«doSwitch(object.expr).code»)''';
 			return retVal;
 		}
 		else

+ 2 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/OutRulesConditionSwitch.xtend

@@ -11,7 +11,7 @@ public class OutRulesConditionSwitch extends RulesConditionSwitch {
 	new(String adaptationClassName, String adaptationName,
 		LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars,
 		LinkedHashMap<String, SAScalarVariable> SASVs, LinkedHashMap<String, GlobalInOutVariable> params) {
-		super(adaptationClassName, adaptationName, "out_rule_", mSVars, SASVs, params);
+		super(adaptationClassName, adaptationName, "out_rule_", mSVars, SASVs, params, null);
 	}
 
 	override ReturnInformation casePort(Port object) {
@@ -20,6 +20,7 @@ public class OutRulesConditionSwitch extends RulesConditionSwitch {
 		val type = mSVars.get(this.externalVariableOwner).get(object.name).mappedSv.type;
 		val define = mSVars.get(this.externalVariableOwner).get(object.name).define;
 		retVal.code = '''getValue«Conversions.fmiTypeToCppTypeCapitalized(type)»(«this.externalVariableOwner»,«define»)''';
+		this.externalVariableOwnerIsSet = false;
 
 		return retVal;
 	}

+ 0 - 2
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/ParamConditionSwitch.xtend

@@ -34,7 +34,5 @@ class ParamConditionSwitch extends GeneralConditionSwitch {
 			this->«gVar.name» = «doSwitchRes.code»;
 		'''
 		return retInfo;
-
 	}
-
 }

+ 93 - 20
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/generation/RulesConditionSwitch.xtend

@@ -34,6 +34,13 @@ import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InOutRules
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Min
 import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.TypeException
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Minus
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.For
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SaveState
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Rollback
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Range
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Close
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BreakStatement
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
 
 abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInformation> {
 	// Global in and out variables
@@ -58,9 +65,12 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 	 * It is necessary because of parsing error
 	 */
 	protected String externalVariableOwner;
+	protected boolean externalVariableOwnerIsSet = false;
 
 	protected final LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars;
 	protected final LinkedHashMap<String, SAScalarVariable> SASVs;
+	
+	LinkedHashMap<String, GlobalInOutVariable> outVars;
 
 	protected boolean inRuleCondition;
 	protected boolean inRuleTransition;
@@ -74,13 +84,19 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 	// Add scope information to this.
 	protected var LinkedHashMap<String, SVType> localDeclarations = newLinkedHashMap();
 
+	protected String forLoopIterVar;
+	protected boolean forLoopIterVarIsSet = false;
+	
+	
+
 	new(
 		String adaptationClassName,
 		String adaptationName,
 		String functionPrefix,
 		LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars,
 		LinkedHashMap<String, SAScalarVariable> SASVs,
-		LinkedHashMap<String, GlobalInOutVariable> params
+		LinkedHashMap<String, GlobalInOutVariable> params,
+		LinkedHashMap<String, GlobalInOutVariable> outVars
 	) {
 		this.params = params;
 		this.SASVs = SASVs;
@@ -88,6 +104,7 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 		this.adaptationClassName = adaptationClassName;
 		this.functionPrefix = functionPrefix;
 		this.mSVars = mSVars;
+		this.outVars = outVars;
 	}
 
 	/*
@@ -206,15 +223,18 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 		retVal.code = '''
 			«functionSig»{
 				«IF object.expression !== null»
-					«doSwitch(object.expression).code»
+					«val result = doSwitch(object.expression)»
+					«result.code»«if (!result.isExpression) ";"»
 				«ENDIF»
 				«IF object.statements !== null»
 					«FOR stm : object.statements»
-						«doSwitch(stm).code»
+						«val result = doSwitch(stm)»
+						«result.code»«if (!result.isExpression) ";"»
 					«ENDFOR»
 				«ENDIF»			
 				«IF object.assignment !== null»
-					«doSwitch(object.assignment).code»
+					«val result = doSwitch(object.assignment)»
+					«result.code»«if (!result.isExpression) ";"»
 				«ENDIF»
 			}
 		''';
@@ -224,13 +244,25 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 
 	override ReturnInformation caseIf(If object) {
 		var retVal = new ReturnInformation();
+		retVal.isExpression = true;
 		retVal.code = '''
 			if(«doSwitch(object.ifcondition).code»){
 				«FOR stm : object.ifstatements»
-					«doSwitch(stm).code»
+					«val result = doSwitch(stm)»
+					«result.code»«if (!result.isExpression) ";"»
 				«ENDFOR»
 			}
 		''';
+		if(object.elsestatements.length > 0)
+		{
+			retVal.appendCode('''
+			else {
+				«FOR stm : object.elsestatements»
+					«doSwitch(stm).code»;
+				«ENDFOR»
+			}
+			''')
+		}
 
 		return retVal;
 	}
@@ -265,7 +297,10 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 			calcConSaSvData(lValSwitch.conSaSv, rValSwitch);
 		}
 
-		retVal.code = '''«lValSwitch.code» = «rValSwitch.code»;''';
+
+			retVal.code = '''«lValSwitch.code» = «rValSwitch.code»''';
+
+		
 		return retVal;
 	}
 
@@ -310,14 +345,14 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 		retVal.code = '''
 			«functionSig»{
 				«FOR stm : object.statements»
-					«doSwitch(stm).code»
+					«val result = doSwitch(stm)»
+					«result.code»«if(!result.isExpression) ";"»
 				«ENDFOR»
 			}
 		''';
 		return retVal;
 	}
 
-
 	override ReturnInformation caseVariable(Variable object) {
 
 		var retVal = new ReturnInformation();
@@ -325,7 +360,7 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 		if (object.owner === null || object.owner.name == this.adaptationName) {
 
 			if (SASVs.containsKey(object.ref.name) || gVars.containsKey(object.ref.name) ||
-				params.containsKey(object.ref.name)) {
+				params.containsKey(object.ref.name) || outVars.containsKey(object.ref.name)) {
 
 				retVal.code = '''this->«object.ref.name»''';
 
@@ -336,13 +371,22 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 				} else if (params.containsKey(object.ref.name)) {
 					retVal.conGlobVar = params.get(object.ref.name);
 				}
+				else if (outVars.containsKey(object.ref.name)){
+					retVal.conGlobVar = outVars.get(object.ref.name);
+				}
 			} else if (localDeclarations.containsKey(object.ref.name)) {
 				retVal.code = '''«object.ref.name»'''
 				retVal.type = localDeclarations.get(object.ref.name);
 			}
+			else 
+			{
+				throw new Exception("Variable not found: " + object.ref.name);
+			}
 
 		} else {
+			// This has to be converted to an setValue using the FMU component. 
 			this.externalVariableOwner = object.owner.name;
+			this.externalVariableOwnerIsSet = true;
 			retVal.code = '''«doSwitch(object.ref).code»''';
 		}
 		return retVal;
@@ -373,7 +417,9 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 			} else {
 				// This is a local declaration.
 				val String type = Conversions.fmiTypeToCppType(doSwitchRes.type)
-				code = '''«type» «decl.name» = «doSwitchRes.code»''';
+				code = '''
+					«type» «decl.name» = «doSwitchRes.code»;
+				''';
 				this.localDeclarations.put(decl.name, doSwitchRes.type);
 			}
 			retVal.appendCode = code;
@@ -413,28 +459,55 @@ abstract class RulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInfor
 		return retInfo;
 	}
 
-	override ReturnInformation caseMin(Min object)
-	{
+	override ReturnInformation caseMin(Min object) {
 		var retInfo = new ReturnInformation();
 		var doSwitchResCode = newArrayList();
 		for (expr : object.args) {
 			val doSwitchRes_ = this.doSwitch(expr);
 			doSwitchResCode.add(doSwitchRes_.code);
-			retInfo = new ReturnInformation(retInfo, doSwitchRes_);
-		} 
-		retInfo.code = 
-		'''
-		min({«doSwitchResCode.join(",")»})
+			retInfo = new ReturnInformation(retInfo, doSwitchRes_);
+		}
+		retInfo.code = '''
+			min({«doSwitchResCode.join(",")»})
 		'''
 		return retInfo;
 	}
-	
-	override ReturnInformation caseMinus(Minus object){
+
+	override ReturnInformation caseMinus(Minus object) {
 		val doSwitchLeft = doSwitch(object.left);
 		val doSwitchRight = doSwitch(object.right);
 		var retVal = new ReturnInformation(doSwitchLeft, doSwitchRight);
 		retVal.code = '''«doSwitchLeft.code» - «doSwitchRight.code»''';
-		return retVal;		
+		return retVal;
+	}
+
+	override ReturnInformation caseFor(For object) {
+		{
+			var retVal = new ReturnInformation();
+			retVal.isExpression = true;
+			val iterator = doSwitch(object.iterator);
+			forLoopIterVar = iterator.code;
+			forLoopIterVarIsSet = true;
+			val iterable = doSwitch(object.iterable);
+			retVal.appendCode('''
+			for (int «forLoopIterVar» = «iterable.code»){
+				«FOR stm : object.statements»
+					«val result = doSwitch(stm)»		
+					«result.code»«if (!result.isExpression) ";"»
+				«ENDFOR»
+			}
+			''')
+			forLoopIterVarIsSet = false;
+			return retVal;
+		}
+	}
+	
+	override ReturnInformation caseRange(Range object){
+		var retVal = new ReturnInformation();
+		val left = doSwitch(object.left);
+		val right = doSwitch(object.right);
+			retVal.appendCode('''«left.code»; «forLoopIterVar»<=«right.code»; «forLoopIterVar»++''')
+		return retVal;
 	}
 
 }