Browse Source

Fixed issue with new C code generator plugin and added internal function prototypes to state charts C file.

terfloth@itemis.de 13 years ago
parent
commit
4d8fb0ca7d

+ 1 - 1
plugins/org.yakindu.sct.generator.c/plugin.xml

@@ -13,7 +13,7 @@
             name="YAKINDU C Code Generator">
       </SCTGenerator>
       <SCTGenerator
-            class="org.yakindu.sct.generator.c.CSCTGenerator"
+            class="org.yakindu.sct.generator.c.CCodeGenerator2"
             contentType="statechart"
             elementRefType="org.yakindu.sct.model.sgraph.Statechart"
             description="SCT C Code Generator"

+ 16 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/CCodeGenerator2.java

@@ -0,0 +1,16 @@
+package org.yakindu.sct.generator.c;
+
+import org.yakindu.sct.generator.core.impl.GenericJavaBasedGenerator;
+import org.yakindu.sct.model.sgen.GeneratorEntry;
+import org.yakindu.sct.model.sgraph.Statechart;
+
+public class CCodeGenerator2 extends GenericJavaBasedGenerator {
+
+	@Override
+	public void runGenerator(Statechart flow, GeneratorEntry entry) {
+		CSCTGenerator delegate = getInjector(entry).getInstance(CSCTGenerator.class);		
+		delegate.generate(createExecutionFlow(flow, entry), entry, getFileSystemAccess(entry));
+	}
+
+	
+}

+ 8 - 8
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/FlowCode.xtend

@@ -38,12 +38,12 @@ class FlowCode {
 
 	def dispatch code(SaveHistory it) '''
 		«stepComment»
-		handle->historyVector[«region.historyVector.offset»] = handle->stateConfVector[«region.stateVector.offset»];
+		«scHandle»->historyVector[«region.historyVector.offset»] = «scHandle»->stateConfVector[«region.stateVector.offset»];
 	'''
 	
 	def dispatch code(HistoryEntry it) '''
 		«stepComment»
-		if (handle->historyVector[«region.historyVector.offset»] != last_state) {
+		if («scHandle»->historyVector[«region.historyVector.offset»] != last_state) {
 			«historyStep.code»
 		} else {
 			«initialStep.code»
@@ -53,9 +53,9 @@ class FlowCode {
 	def dispatch code(StateSwitch it) '''
 		«stepComment»
 		«IF historyRegion != null»
-			switch(handle->historyVector[ «historyRegion.historyVector.offset» ]) {
+			switch(«scHandle»->historyVector[ «historyRegion.historyVector.offset» ]) {
 		«ELSE»
-			switch(handle->stateConfVector[ «stateConfigurationIdx» ]) {
+			switch(«scHandle»->stateConfVector[ «stateConfigurationIdx» ]) {
 		«ENDIF»
 			«FOR caseid : cases»
 				case «caseid.state.name.asIdentifier» : {
@@ -111,12 +111,12 @@ class FlowCode {
 	'''
 	
 	def dispatch code(EnterState it) '''
-		handle->stateConfVector[«state.stateVector.offset»] = «state.name.asIdentifier»;
-		handle->stateConfVectorPosition = «state.stateVector.offset»;
+		«scHandle»->stateConfVector[«state.stateVector.offset»] = «state.name.asIdentifier»;
+		«scHandle»->stateConfVectorPosition = «state.stateVector.offset»;
 	'''
 
 	def dispatch code(ExitState it) '''
-		handle->stateConfVector[«state.stateVector.offset»] = last_state;
-		handle->stateConfVectorPosition = «state.stateVector.offset»;
+		«scHandle»->stateConfVector[«state.stateVector.offset»] = last_state;
+		«scHandle»->stateConfVectorPosition = «state.stateVector.offset»;
 	'''
 }

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

@@ -8,6 +8,13 @@ import org.yakindu.sct.model.sgraph.Scope
 import org.yakindu.sct.model.stext.stext.VariableDefinition
 import org.yakindu.sct.model.stext.stext.EventDefinition
 import org.yakindu.sct.model.stext.stext.OperationDefinition
+import org.yakindu.sct.model.sexec.Check
+import org.eclipse.emf.ecore.EObject
+import org.yakindu.sct.model.sexec.ExecutionScope
+import org.yakindu.sct.model.sexec.ExecutionState
+import org.yakindu.sct.model.sexec.Step
+import org.yakindu.sct.model.sexec.ExecutionNode
+import java.util.List
 
 class Naming {
 
@@ -73,6 +80,10 @@ class Naming {
 		type.toFirstLower	
 	}
 
+	def functionPrefix(ExecutionFlow it) {
+		type.toFirstLower	
+	}
+
 
 	def asRaiser(EventDefinition it) {
 		scope.functionPrefix + '_raise_' + name.asIdentifier.toFirstLower	
@@ -97,6 +108,43 @@ class Naming {
 	def asFunction(OperationDefinition it) {
 		scope.functionPrefix + '_' + name.asIdentifier.toFirstLower	
 	}
+		
+	
+	def asCheckFunction(Check it) { functionName(newArrayList('check', elementName, reaction.name)) }
+	 
+	def asEffectFunction(Step it) { functionName(newArrayList('effect', elementName, reaction.name)) }
+	 
+	def asEntryActionFunction(Step it) { functionName('entryaction') }
+	
+	def asExitActionFunction(Step it) { functionName('exitaction') }
+	 
+	def asEnterSequenceFunction(Step it) { functionName('entersequence') }
+		 
+	def asDeepEnterSequenceFunction(Step it) { functionName('deepentersequence') }
+	 
+	def asShallowEnterSequenceFunction(Step it) { functionName('shallowentersequence') }
+	 
+	def asExitSequenceFunction(Step it) { functionName('exitsequence') }
+	 
+	def asReactFunction(Step it) { functionName('react') }
+	
+	
+	def functionName(Step it, String fName) { functionName(newArrayList(fName, elementName)) }
+	
+	def functionName(EObject it, List<String> segments) {
+		flow.functionPrefix + segments.fold("", [s, seg | s + if (seg.empty) "" else "_" + seg]).asIdentifier
+	}
+
+	def dispatch String elementName(EObject it) { eContainer.elementName }
+	
+	def dispatch String elementName(ExecutionScope it) { (if (superScope != null && ! superScope.elementName.empty) superScope.elementName + "_" else "") + name }	
+	
+	def dispatch String elementName(ExecutionState it) { (if (superScope != null && ! superScope.elementName.empty) superScope.elementName + "_" else "") + simpleName }	
+	
+	def dispatch String elementName(ExecutionNode it) { name }	
+	
+	def dispatch String elementName(ExecutionFlow it) { "" }	
+	
 	
 	
 	def h(String it) { it + ".h" }
@@ -114,4 +162,8 @@ class Naming {
 	
 	def dispatch scopeDescription(InterfaceScope it) '''«IF name==null || name.empty»default interface scope«ELSE»interface scope '«name»'«ENDIF»'''
 	def dispatch scopeDescription(InternalScope it) '''internal scope'''
+	
+	def scHandleDecl(EObject it) { flow.type + '* ' + scHandle }
+	
+	def scHandle() { 'handle_' }
 }

+ 17 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Navigation.xtend

@@ -12,6 +12,10 @@ import org.yakindu.sct.model.stext.stext.EventDefinition
 import java.util.ArrayList
 import org.yakindu.sct.model.stext.stext.OperationDefinition
 import org.eclipse.emf.ecore.EObject
+import org.yakindu.sct.model.sexec.Check
+import org.yakindu.sct.model.sexec.Reaction
+import org.yakindu.sct.model.sexec.ExecutionNode
+import org.yakindu.sct.model.sexec.Step
 
 class Navigation {
 	
@@ -54,5 +58,18 @@ class Navigation {
 		scopes.fold(new ArrayList<OperationDefinition>(), [ l, s | l.addAll(s.declarations.filter( typeof(OperationDefinition))) return l ])
 	}
 	
+	def dispatch Reaction reaction(Check it) { eContainer as Reaction }
+	def dispatch Reaction reaction(EObject it) { eContainer?.reaction }
+	def dispatch Reaction reaction(Reaction it) { it }
+
+	def referencedChecks(ExecutionNode it) {
+		reactions.filter( r | r.check != null && r.check.refs.size > 0).map( r | r.check )
+	}
+
+	def referencedEffects(ExecutionNode it) {
+		reactions.filter( r | r.effect != null && r.effect.caller.size > 0).map( r | r.effect )
+	}
+
+	def isCalled(Step it) { it != null && caller.size > 0 }
 
 }

+ 123 - 8
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/StatemachineC.xtend

@@ -4,6 +4,10 @@ import com.google.inject.Inject
 import org.yakindu.sct.model.sexec.ExecutionFlow
 import org.yakindu.sct.model.sgraph.Statechart
 import org.eclipse.xtext.generator.IFileSystemAccess
+import org.yakindu.sct.model.sexec.ExecutionNode
+import org.yakindu.sct.model.sexec.Check
+import java.util.List
+import org.yakindu.sct.model.sexec.Step
 
 class StatemachineC {
 	
@@ -24,8 +28,11 @@ class StatemachineC {
 		#include <stdlib.h>
 		#include <string.h>
 
-
-		// function prototypes
+		/*! \file Implementation of the state machine '«name»'
+		*/
+		
+		«functionPrototypes»
+		
 		// function implementations
 
 		«initFunction»
@@ -37,19 +44,19 @@ class StatemachineC {
 	
 	
 	def initFunction(ExecutionFlow it) '''
-		void «type.toFirstLower»_init(«type»* handle)
+		void «type.toFirstLower»_init(«scHandleDecl»)
 		{
 			int i;
 
 			for (i = 0; i < «type.toUpperCase»_MAX_ORTHOGONAL_STATES; ++i)
-				handle->stateConfVector[i] = last_state;
+				«scHandle»->stateConfVector[i] = last_state;
 			
 			«IF ! historyVector.empty»
 			for (i = 0; i < «type.toUpperCase»_MAX_HISTORY_STATES; ++i)
-				handle->historyVector[i] = last_state;
+				«scHandle»->historyVector[i] = last_state;
 			«ENDIF»
 			
-			handle->stateConfVectorPosition = 0;
+			«scHandle»->stateConfVectorPosition = 0;
 
 			// TODO: initialize all events ...
 			// TODO: initialize all variables ... (set default values - here or inenter sequence ?!?)
@@ -58,17 +65,125 @@ class StatemachineC {
 	'''
 	
 	def enterFunction(ExecutionFlow it) '''
-		void «type.toFirstLower»_enter(«type»* handle)
+		void «type.toFirstLower»_enter(«scHandleDecl»)
 		{
 			«enterSequence.code»
 		}
 	'''
 	
 	def exitFunction(ExecutionFlow it) '''
-		void «type.toFirstLower»_exit(«type»* handle)
+		void «type.toFirstLower»_exit(«scHandleDecl»)
 		{
 			«exitSequence.code»
 		}
 	'''
 	
+	def functionPrototypes(ExecutionFlow it) '''
+		// prototypes of all internal functions
+		
+		«checkFunctionPrototypes»
+		«effectFunctionPrototypes»
+		«entryActionFunctionPrototypes»
+		«exitActionFunctionPrototypes»
+		«enterSequenceFunctionPrototypes»
+		«exitSequenceFunctionPrototypes»
+		«reactFunctionPrototypes»
+		
+	'''
+	 
+	 
+	def checkFunctionPrototypes(ExecutionFlow it) '''
+		«referencedChecks.checkFunctionPrototypes»
+		«FOR s : states»«s.referencedChecks.checkFunctionPrototypes»«ENDFOR»
+		«FOR n : nodes»«n.referencedChecks.checkFunctionPrototypes»«ENDFOR»
+	'''
+	
+	def checkFunctionPrototypes(Iterable<Check> it) '''
+		«FOR c : it»«c.checkFunctionPrototype»«ENDFOR»
+	'''
+	
+	def checkFunctionPrototype(Check it) '''
+		static sc_boolean «asCheckFunction»(«scHandleDecl»);
+	'''
+	
+	
+	
+	def effectFunctionPrototypes(ExecutionFlow it) '''
+		«referencedEffects.effectFunctionPrototypes»
+		«FOR s : states»«s.referencedEffects.effectFunctionPrototypes»«ENDFOR»
+		«FOR n : nodes»«n.referencedEffects.effectFunctionPrototypes»«ENDFOR»
+	'''
+	
+	def effectFunctionPrototypes(Iterable<Step> it) '''
+		«FOR c : it»«c.effectFunctionPrototype»«ENDFOR»
+	'''
+	
+	def effectFunctionPrototype(Step it) '''
+		static sc_boolean «asEffectFunction»(«scHandleDecl»);
+	'''
+	
+	
+	
+	def entryActionFunctionPrototypes(ExecutionFlow it) '''
+		«if (entryAction.called) entryAction.entryActionFunctionPrototype»
+		«FOR s : states»«if (s.entryAction.called) s.entryAction.entryActionFunctionPrototype»«ENDFOR»
+	'''
+	
+	def entryActionFunctionPrototype(Step it) '''
+		static void «asEntryActionFunction»(«scHandleDecl»);
+	'''
+	
+	
+	def exitActionFunctionPrototypes(ExecutionFlow it) '''
+		«if (exitAction.called) exitAction.exitActionFunctionPrototype»
+		«FOR s : states»«if (s.exitAction.called) s.exitAction.exitActionFunctionPrototype»«ENDFOR»
+	'''
+	
+	def exitActionFunctionPrototype(Step it) '''
+		static void «asExitActionFunction»(«scHandleDecl»);
+	'''
+	
+	
+	def enterSequenceFunctionPrototypes(ExecutionFlow it) '''
+		«if (enterSequence.called) enterSequence.enterSequenceFunctionPrototype»
+		«FOR s : states»«if (s.enterSequence.called) s.enterSequence.enterSequenceFunctionPrototype»«ENDFOR»
+		«FOR r : regions»
+			«if (r.enterSequence.called) r.enterSequence.enterSequenceFunctionPrototype»
+			«if (r.deepEnterSequence.called) r.enterSequence.deepEnterSequenceFunctionPrototype»
+			«if (r.shallowEnterSequence.called) r.enterSequence.shallowEnterSequenceFunctionPrototype»
+		«ENDFOR»
+	'''
+	
+	def enterSequenceFunctionPrototype(Step it) '''
+		static void «asEnterSequenceFunction»(«scHandleDecl»);
+	'''
+	
+	def deepEnterSequenceFunctionPrototype(Step it) '''
+		static void «asDeepEnterSequenceFunction»(«scHandleDecl»);
+	'''
+	
+	def shallowEnterSequenceFunctionPrototype(Step it) '''
+		static void «asShallowEnterSequenceFunction»(«scHandleDecl»);
+	'''
+	
+	
+	def exitSequenceFunctionPrototypes(ExecutionFlow it) '''
+		«if (enterSequence.called) exitSequence.exitSequenceFunctionPrototype»
+		«FOR s : states»«if (s.exitSequence.called) s.exitSequence.exitSequenceFunctionPrototype»«ENDFOR»
+		«FOR r : regions»«if (r.exitSequence.called) r.exitSequence.exitSequenceFunctionPrototype»«ENDFOR»
+	'''
+	
+	def exitSequenceFunctionPrototype(Step it) '''
+		static void «asExitSequenceFunction»(«scHandleDecl»);
+	'''
+	
+	def reactFunctionPrototypes(ExecutionFlow it) '''
+		«if (reactSequence.called) reactSequence.reactFunctionPrototype»
+		«FOR s : states»«if (s.reactSequence.called) s.reactSequence.reactFunctionPrototype»«ENDFOR»
+		«FOR n : nodes»«if (n.reactSequence.called) n.reactSequence.reactFunctionPrototype»«ENDFOR»
+	'''
+	
+	def reactFunctionPrototype(Step it) '''
+		static void «asReactFunction»(«scHandleDecl»);
+	'''	
 }

+ 6 - 2
plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/GenericJavaBasedGenerator.java

@@ -97,8 +97,7 @@ public class GenericJavaBasedGenerator extends AbstractSExecModelGenerator {
 
 	@Override
 	public void runGenerator(Statechart flow, GeneratorEntry entry) {
-		String templateClass = entry.getFeatureConfiguration(TEMPLATE_FEATURE)
-				.getParameterValue(GENERATOR_CLASS).getStringValue();
+		String templateClass = getTemplateClassName(entry);
 		final ClassLoader classLoader = getClassLoader(entry);
 		IFileSystemAccess fsa = getFileSystemAccess(entry);
 		try {
@@ -134,6 +133,11 @@ public class GenericJavaBasedGenerator extends AbstractSExecModelGenerator {
 		}
 	}
 
+	protected String getTemplateClassName(GeneratorEntry entry) {
+		return entry.getFeatureConfiguration(TEMPLATE_FEATURE)
+				.getParameterValue(GENERATOR_CLASS).getStringValue();
+	}
+
 	/**
 	 * resolve the project that defines the lookup path for the XpandFacade
 	 *