Browse Source

Added generation of getters and setters for interface elements.

markus.muehlbrandt@gmail.com 13 years ago
parent
commit
9b951c2109

+ 6 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Naming.xtend

@@ -18,6 +18,7 @@ import org.yakindu.sct.model.stext.stext.VariableDefinition
 class Naming {
 
 	@Inject extension Navigation
+	@Inject extension Base
 	
 	def module(ExecutionFlow it) {
 		name.asIdentifier.toFirstUpper	
@@ -184,4 +185,9 @@ class Naming {
 	def scHandleDecl(EObject it) { flow.type + '* ' + scHandle }
 	
 	def scHandle() { 'handle' }
+	
+	def valueParams(EventDefinition it) {
+		if (hasValue) ', ' + type.cPrimitive + ' value' 
+		else ''
+	}
 }

+ 19 - 9
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Navigation.xtend

@@ -23,6 +23,8 @@ import org.yakindu.sct.model.stext.stext.FeatureCall
 import org.yakindu.sct.model.stext.stext.OperationDefinition
 import org.yakindu.sct.model.stext.stext.Direction
 import org.yakindu.sct.model.stext.stext.InternalScope
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import org.yakindu.sct.model.stext.stext.VariableDefinition
 
 class Navigation {
 	
@@ -70,24 +72,24 @@ class Navigation {
 		scopes.fold(new ArrayList<OperationDefinition>(), [ l, s | l.addAll(s.declarations.filter( typeof(OperationDefinition))) return l ])
 	}
 	
-	def List<Event> getIncomingEvents(Scope scope) {
-		val events = new ArrayList<Event>()
-		scope.declarations.filter(typeof(EventDefinition)).forEach(ev | if (ev.direction == Direction::IN) events += ev)
+	def List<EventDefinition> getIncomingEvents(Scope it) {
+		val events = new ArrayList<EventDefinition>()
+		declarations.filter(typeof(EventDefinition)).forEach(ev | if (ev.direction == Direction::IN) events += ev)
 		return events
 	}
 	
-	def boolean hasIncomingEvents(Scope scope) {
-		return !scope.incomingEvents.empty
+	def boolean hasIncomingEvents(Scope it) {
+		return !incomingEvents.empty
 	}
 	
-	def List<Event> getOutgoingEvents(Scope scope) {
-		val events = new ArrayList<Event>()
+	def List<EventDefinition> getOutgoingEvents(Scope scope) {
+		val events = new ArrayList<EventDefinition>()
 		scope.declarations.filter(typeof(EventDefinition)).forEach(ev | if (ev.direction == Direction::OUT) events += ev)
 		return events
 	}
 	
-	def boolean hasOutgoingEvents(Scope scope) {
-		return !scope.outgoingEvents.empty
+	def boolean hasOutgoingEvents(Scope it) {
+		return !outgoingEvents.empty
 	}
 	
 	def InternalScope getLocalScope(ExecutionFlow it) {
@@ -98,6 +100,14 @@ class Navigation {
 		return localScope != null;
 	}
 	
+	def Iterable<VariableDefinition> getVariableDefinitions(Scope it) {
+		return declarations.filter(typeof(VariableDefinition))
+	} 
+	
+	def Iterable<InterfaceScope> getInterfaceScopes(ExecutionFlow it) {
+		return scopes.filter(typeof(InterfaceScope))
+	}
+	
 	def dispatch Reaction reaction(Check it) { eContainer as Reaction }
 	def dispatch Reaction reaction(EObject it) { eContainer?.reaction }
 	def dispatch Reaction reaction(Reaction it) { it }

+ 2 - 7
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Statemachine.xtend

@@ -101,7 +101,7 @@ class Statemachine {
 	def dispatch structDeclaration(Declaration it) ''''''
 	
 	
-	def dispatch scopeTypeDecl(Scope it) '''
+	def scopeTypeDecl(Scope it) '''
 		//! Type definition of the data structure for the «it.type» interface scope.
 		typedef struct {
 			«FOR d : declarations »
@@ -148,7 +148,7 @@ class Statemachine {
 	def dispatch functionPrototypes(EventDefinition it) '''
 		«IF direction == Direction::IN»
 		/*! Raises the in event '«name»' that is defined in the «scope.scopeDescription». */ 
-		extern «type.cPrimitive» «asRaiser»(«it.flow.type»* handle«valueParams»);
+		extern void «asRaiser»(«it.flow.type»* handle«valueParams»);
 		
 		«ELSE»
 			/*! Checks if the out event '«name»' that is defined in the «scope.scopeDescription» has been raised. */ 
@@ -170,9 +170,4 @@ class Statemachine {
 			extern void «asSetter»(«it.flow.type»* handle, «type.cPrimitive» value);
 		«ENDIF»
 	'''
-
-	def valueParams(EventDefinition it) {
-		if (hasValue) ', ' + type.cPrimitive + ' value' 
-		else ''
-	}
 }

+ 41 - 4
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/StatemachineC.xtend

@@ -4,16 +4,17 @@ import com.google.inject.Inject
 import java.util.List
 import org.eclipse.xtext.generator.IFileSystemAccess
 import org.yakindu.sct.model.sexec.Check
+import org.yakindu.sct.model.sexec.Execution
 import org.yakindu.sct.model.sexec.ExecutionFlow
 import org.yakindu.sct.model.sexec.Step
 import org.yakindu.sct.model.sgraph.Statechart
-import org.yakindu.sct.model.sexec.Execution
 
 class StatemachineC {
 	
 	@Inject extension Naming
 	@Inject extension Navigation
 	@Inject extension FlowCode
+	@Inject extension Base
 	
 	
 	def generateStatemachineC(ExecutionFlow flow, Statechart sc, IFileSystemAccess fsa) {
@@ -100,6 +101,11 @@ class StatemachineC {
 				«scHandle»->«scope.instance».«event.name.asIdentifier»_raised = false;
 				«ENDFOR»
 			«ENDFOR»
+			«IF hasLocalScope»
+				«FOR event : localScope.events»
+				«scHandle»->«localScope.instance».«event.name.asIdentifier»_raised = false; 
+				«ENDFOR»
+			«ENDIF»
 		}
 	'''
 	
@@ -110,8 +116,6 @@ class StatemachineC {
 				«scHandle»->«scope.instance».«event.name.asIdentifier»_raised = false;
 				«ENDFOR»
 			«ENDFOR»
-			«IF hasLocalScope»
-			«ENDIF»
 		}
 	'''
 	
@@ -155,7 +159,40 @@ class StatemachineC {
 	 */
 	
 	def interfaceFunctions(ExecutionFlow it) '''
-		#warning generate interface functions
+		«FOR scope : interfaceScopes»
+			«FOR event : scope.incomingEvents»
+				void «event.asRaiser»(«scHandleDecl»«event.valueParams») {
+					«IF event.hasValue»
+					«scHandle»->«scope.instance».«event.name.value» = value;
+					«ENDIF»
+					«scHandle»->«scope.instance».«event.name.asIdentifier»_raised = true;
+				}
+			«ENDFOR»
+			
+			«FOR event : scope.outgoingEvents»
+				sc_boolean «event.asRaised»(«scHandleDecl») {
+					return «scHandle»->«scope.instance».«event.name.asIdentifier»_raised;
+				}
+				«IF event.hasValue» 
+					«event.type.cPrimitive» «event.asGetter»(«scHandleDecl») {
+						//TODO: Check if event is not raised
+						return «scHandle»->«scope.instance».«event.name.value»;
+					}
+				«ENDIF»
+			«ENDFOR»
+			
+			«FOR variable : scope.variableDefinitions»
+				 «variable.type.cPrimitive» «variable.asGetter»(«scHandleDecl») {
+				 	return «scHandle»->«scope.instance».«variable.name.asIdentifier»;
+				 }
+				 
+				«IF !variable.readonly»
+void «variable.asSetter»(«scHandleDecl», «variable.type.cPrimitive» value) {
+	«scHandle»->«scope.instance».«variable.name.asIdentifier» = value;
+} 
+				«ENDIF»
+			«ENDFOR»
+		«ENDFOR»
 	'''
 	
 	/* ===================================================================================