Browse Source

addInRules_External2Stored_Assignments

Cláudio Gomes 3 years ago
parent
commit
189a6832b2

+ 10 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.tests/src/be/uantwerpen/ansymo/semanticadaptation/tests/SemanticAdaptationGeneratorTest.xtend

@@ -19,6 +19,7 @@ import org.eclipse.xtext.xbase.testing.CompilationTestHelper.Result
 import org.junit.Test
 import org.junit.runner.RunWith
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Assignment
 
 @RunWith(XtextRunner)
 @InjectWith(SemanticAdaptationInjectorProvider)
@@ -66,6 +67,15 @@ class SemanticAdaptationGeneratorTest extends AbstractSemanticAdaptationTest{
 			}
 		}) }
 	
+	@Test def test_addExternal2StoredAssignments_sample1() { __generate('input/canonical_generation/sample1.sa', new IAcceptor<CompilationTestHelper.Result>(){
+			override accept(Result t) {
+				var Adaptation sa = t.resourceSet.resources.head.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation).head
+				sa.in.rules.head.statetransitionfunction.statements.head instanceof Assignment
+				(sa.in.rules.head.statetransitionfunction.statements.head as Assignment).lvalue.ref.name == "stored__innerFMU2__input_port3"
+				((sa.in.rules.head.statetransitionfunction.statements.head as Assignment).expr as Variable).ref.name == "innerFMU2__input_port3"
+			}
+		}) }
+	
 	@Test def window_SA_parseNoExceptions() { __generate('input/power_window_case_study/window_sa.BASE.sa', new IAcceptor<CompilationTestHelper.Result>(){
 			override accept(Result t) { }
 		}) }

+ 49 - 2
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/formatting2/SemanticAdaptationFormatter.xtend

@@ -5,10 +5,14 @@ package be.uantwerpen.ansymo.semanticadaptation.formatting2
 
 import be.uantwerpen.ansymo.semanticadaptation.generator.Log
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DataRule
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptationPackage
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.StateTransitionFunction
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Statement
 import org.eclipse.xtext.formatting2.AbstractFormatter2
 import org.eclipse.xtext.formatting2.IFormattableDocument
-import org.eclipse.xtext.util.Strings
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CompositeOutputFunction
 
 class SemanticAdaptationFormatter extends AbstractFormatter2 {
 	
@@ -40,7 +44,11 @@ class SemanticAdaptationFormatter extends AbstractFormatter2 {
 		sa.regionFor.keyword('param').prepend[newLine]
 		
 		if (sa.in !== null){
-			sa.in.allRegionsFor.keyword('in').prepend[newLine]
+			sa.in.regionFor.keyword('in').prepend[newLine]
+			
+			for (rule : sa.in.rules){
+				rule.format
+			}
 		}
 		
 		
@@ -57,4 +65,43 @@ class SemanticAdaptationFormatter extends AbstractFormatter2 {
 		Log.pop("Formatting adaptation")	
 	}
 	
+	def dispatch void format(DataRule rule, extension IFormattableDocument document){
+		Log.push("Formatting DataRule")
+		
+		rule.prepend[newLine]
+		
+		rule.statetransitionfunction.format
+		
+		rule.outputfunction.format
+		
+		Log.pop("Formatting DataRule")	
+	}
+	
+	def dispatch void format(StateTransitionFunction function, extension IFormattableDocument document){
+		Log.push("Formatting StateTransitionFunction")
+		
+		for (statement : function.statements){
+			statement.format
+		}
+		
+		Log.pop("Formatting StateTransitionFunction")	
+	}
+	
+	def dispatch void format(CompositeOutputFunction function, extension IFormattableDocument document){
+		Log.push("Formatting CompositeOutputFunction")
+		
+		for (statement : function.statements){
+			statement.format
+		}
+		
+		Log.pop("Formatting CompositeOutputFunction")	
+	}
+	
+	def dispatch void format(Statement statement, extension IFormattableDocument document){
+		Log.push("Formatting Statement")
+		
+		statement.prepend[newLine]
+		
+		Log.pop("Formatting Statement")	
+	}
 }

+ 75 - 1
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation/src/be/uantwerpen/ansymo/semanticadaptation/generator/SemanticAdaptationCanonicalGenerator.xtend

@@ -8,6 +8,7 @@ import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BoolLiteral
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BuiltinFunction
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Close
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Connection
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DataRule
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DeclaredParameter
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Expression
 import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.FMU
@@ -35,7 +36,7 @@ import org.eclipse.xtext.EcoreUtil2
 import org.eclipse.xtext.generator.AbstractGenerator
 import org.eclipse.xtext.generator.IFileSystemAccess2
 import org.eclipse.xtext.generator.IGeneratorContext
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Declaration
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.StateTransitionFunction
 
 /**
  * Generates code from your model files on save.
@@ -222,9 +223,82 @@ class SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
 		
 		val inputPort2InVarDeclaration = addInVars(sa, inputPort2parameterDeclaration)
 		
+		addInRules_External2Stored_Assignments(sa, inputPort2InVarDeclaration)
+		
+		
+		
 		Log.pop("Canonicalize")
 	}
 	
+	def addInRules_External2Stored_Assignments(Adaptation sa, HashMap<Port, SingleVarDeclaration> inputPort2InVarDeclaration) {
+		Log.push("addInRules_External2Stored_Assignments")
+		
+		val dataRule  = getOrPrependTrueInRule(sa)
+		
+		for(inPort : inputPort2InVarDeclaration.keySet){
+			val storedVarDecl = inputPort2InVarDeclaration.get(inPort)
+			addAssignmentToStoredVar(dataRule.statetransitionfunction, inPort, storedVarDecl)
+		}
+		
+		Log.pop("addInRules_External2Stored_Assignments")
+	}
+	
+	def addAssignmentToStoredVar(StateTransitionFunction function, Port inPort, SingleVarDeclaration storedVarDecl) {
+		Log.push("addAssignmentToStoredVar")
+		
+		if (function.expression !== null){
+			throw new Exception("Expressions in rules are not supported yet.")
+			// This and the one below are asily solved with a syntactic sugar substitution.
+		}
+		if (function.assignment !== null){
+			throw new Exception("Assignment in rules are not supported yet.")
+		}
+		
+		val assignment = SemanticAdaptationFactory.eINSTANCE.createAssignment()
+		assignment.lvalue = SemanticAdaptationFactory.eINSTANCE.createVariable()
+		assignment.lvalue.ref = storedVarDecl
+		assignment.expr = SemanticAdaptationFactory.eINSTANCE.createVariable()
+		(assignment.expr as Variable).owner = inPort.eContainer as Adaptation
+		(assignment.expr as Variable).ref = inPort
+		
+		function.statements.add(0, assignment)
+		
+		Log.println("Assignment " + storedVarDecl.name + " := " + inPort.name + " created.")
+		
+		Log.pop("addAssignmentToStoredVar")
+	}
+	
+	def getOrPrependTrueInRule(Adaptation sa) {
+		if (sa.in === null){
+			sa.in = SemanticAdaptationFactory.eINSTANCE.createInRulesBlock()
+		}
+		var DataRule rule = null
+		if (sa.in.rules.size == 0 || !isTrueRule(sa.in.rules.head)){
+			Log.println("No existing rule found with true condition. Creating one.")
+			val trueRule = SemanticAdaptationFactory.eINSTANCE.createDataRule()
+			trueRule.condition = SemanticAdaptationFactory.eINSTANCE.createRuleCondition()
+			val trueExpr = SemanticAdaptationFactory.eINSTANCE.createBoolLiteral()
+			trueExpr.value = "true"
+			trueRule.condition.condition = trueExpr
+			
+			trueRule.statetransitionfunction = SemanticAdaptationFactory.eINSTANCE.createStateTransitionFunction()
+			
+			sa.in.rules.add(0, trueRule)
+			rule = trueRule
+		} else {
+			Log.println("Existing rule with true condition found.")
+			rule = sa.in.rules.head
+		}
+		return rule
+	}
+	
+	def isTrueRule(DataRule rule){
+		if (rule.condition.condition instanceof BoolLiteral){
+			return (rule.condition.condition as BoolLiteral).value == "true"
+		}
+		return false
+	}
+	
 	def addInVars(Adaptation sa, Map<Port, SingleParamDeclaration> inputPort2parameterDeclaration){
 		Log.push("addInVars")