|
@@ -1,12 +1,3 @@
|
|
|
-/**
|
|
|
- Copyright (c) 2012 committers of YAKINDU and others.
|
|
|
- All rights reserved. This program and the accompanying materials
|
|
|
- are made available under the terms of the Eclipse Public License v1.0
|
|
|
- which accompanies this distribution, and is available at
|
|
|
- http://www.eclipse.org/legal/epl-v10.html
|
|
|
- Contributors:
|
|
|
- Markus Muehlbrandt - Initial contribution and API
|
|
|
- */
|
|
|
package org.yakindu.sct.generator.sccd
|
|
|
|
|
|
import org.eclipse.xtext.generator.IFileSystemAccess
|
|
@@ -17,57 +8,155 @@ import org.yakindu.sct.model.sgraph.Region
|
|
|
import org.yakindu.sct.model.sgraph.State
|
|
|
import org.yakindu.sct.model.sgraph.Statechart
|
|
|
import org.yakindu.sct.model.sgraph.Transition
|
|
|
-import org.yakindu.sct.model.sgraph.Trigger
|
|
|
import org.yakindu.sct.model.stext.stext.DefaultTrigger
|
|
|
import org.yakindu.sct.model.stext.stext.ReactionTrigger
|
|
|
-import org.yakindu.sct.model.stext.stext.impl.ReactionTriggerImpl
|
|
|
+import org.yakindu.sct.model.stext.stext.TimeEventSpec
|
|
|
+import org.yakindu.sct.model.stext.stext.RegularEventSpec
|
|
|
+import org.yakindu.base.expressions.expressions.PrimitiveValueExpression
|
|
|
+import org.yakindu.base.expressions.expressions.IntLiteral
|
|
|
+import org.yakindu.sct.model.stext.stext.TimeEventType
|
|
|
+import org.yakindu.sct.model.stext.stext.AlwaysEvent
|
|
|
+import org.yakindu.base.expressions.expressions.ElementReferenceExpression
|
|
|
+import org.yakindu.sct.model.stext.stext.EventDefinition
|
|
|
+import org.yakindu.sct.model.stext.stext.TimeUnit
|
|
|
+import org.yakindu.sct.model.stext.stext.ReactionEffect
|
|
|
+import org.yakindu.sct.model.stext.stext.EntryEvent
|
|
|
+import org.yakindu.sct.model.stext.stext.ExitEvent
|
|
|
+//import org.yakindu.sct.model.stext.stext.BuiltinEventSpec
|
|
|
+import org.yakindu.sct.model.stext.stext.Guard
|
|
|
+import org.yakindu.sct.model.sgraph.EntryKind
|
|
|
+import org.yakindu.sct.model.sgraph.Choice
|
|
|
+import org.yakindu.sct.model.sgraph.Exit
|
|
|
+import org.yakindu.sct.model.sgraph.Synchronization
|
|
|
+import org.yakindu.sct.model.sgraph.FinalState
|
|
|
+import org.yakindu.base.expressions.expressions.DoubleLiteral
|
|
|
+import org.yakindu.base.expressions.expressions.FloatLiteral
|
|
|
+import org.yakindu.base.expressions.expressions.BoolLiteral
|
|
|
+import org.yakindu.base.expressions.expressions.StringLiteral
|
|
|
+import org.yakindu.base.expressions.expressions.NullLiteral
|
|
|
+import org.yakindu.base.expressions.expressions.HexLiteral
|
|
|
+import org.yakindu.base.expressions.expressions.BinaryLiteral
|
|
|
+import org.yakindu.base.expressions.expressions.AssignmentExpression
|
|
|
+import org.yakindu.base.expressions.expressions.AssignmentOperator
|
|
|
+//import org.yakindu.base.expressions.expressions.UnaryExpression
|
|
|
+import org.yakindu.base.expressions.expressions.ParenthesizedExpression
|
|
|
+import org.yakindu.base.expressions.expressions.UnaryOperator
|
|
|
+import org.yakindu.sct.model.stext.stext.EventRaisingExpression
|
|
|
+//import org.yakindu.base.expressions.expressions.BinaryExpression
|
|
|
+import org.yakindu.base.expressions.expressions.ConditionalExpression
|
|
|
+import org.yakindu.base.expressions.expressions.Expression
|
|
|
+import org.eclipse.emf.ecore.EObject
|
|
|
+import org.yakindu.sct.model.sgraph.Scope
|
|
|
+//import org.yakindu.base.types.Event
|
|
|
+import org.yakindu.sct.model.stext.stext.VariableDefinition
|
|
|
+import org.yakindu.sct.model.sgen.PropertyDefinition
|
|
|
+import org.yakindu.base.expressions.expressions.RelationalOperator
|
|
|
+//import org.yakindu.base.expressions.expressions.BitwiseOperator
|
|
|
+import org.yakindu.base.expressions.expressions.AdditiveOperator
|
|
|
+//import org.yakindu.base.expressions.expressions.LogicalOperator
|
|
|
+import org.yakindu.base.expressions.expressions.MultiplicativeOperator
|
|
|
+import org.yakindu.base.expressions.expressions.PostFixOperator
|
|
|
+import org.yakindu.base.expressions.expressions.ShiftOperator
|
|
|
+import org.yakindu.sct.model.sgraph.Vertex
|
|
|
+import org.yakindu.base.base.NamedElement
|
|
|
+import org.yakindu.base.expressions.expressions.BitwiseAndExpression
|
|
|
+import org.yakindu.base.expressions.expressions.BitwiseOrExpression
|
|
|
+import org.yakindu.base.expressions.expressions.BitwiseXorExpression
|
|
|
+import org.yakindu.base.expressions.expressions.LogicalAndExpression
|
|
|
+import org.yakindu.base.expressions.expressions.LogicalOrExpression
|
|
|
+import org.yakindu.base.expressions.expressions.LogicalRelationExpression
|
|
|
+import org.yakindu.base.expressions.expressions.NumericalAddSubtractExpression
|
|
|
+import org.yakindu.base.expressions.expressions.NumericalMultiplyDivideExpression
|
|
|
+import org.yakindu.base.expressions.expressions.ShiftExpression
|
|
|
+import org.yakindu.base.expressions.expressions.LogicalNotExpression
|
|
|
+import org.yakindu.base.expressions.expressions.NumericalUnaryExpression
|
|
|
+import org.yakindu.base.expressions.expressions.PostFixUnaryExpression
|
|
|
+import org.yakindu.sct.model.stext.stext.EventValueReferenceExpression
|
|
|
+import org.yakindu.sct.model.stext.stext.ActiveStateReferenceExpression
|
|
|
+import org.yakindu.sct.model.stext.stext.LocalReaction
|
|
|
+import org.yakindu.sct.model.stext.stext.OperationDefinition
|
|
|
+import org.yakindu.sct.model.stext.stext.InterfaceScope
|
|
|
+import org.yakindu.sct.model.stext.stext.InternalScope
|
|
|
+import org.yakindu.sct.model.stext.stext.SimpleScope
|
|
|
+//import org.yakindu.sct.model.stext.stext.StatechartScope
|
|
|
+import org.yakindu.base.types.Parameter
|
|
|
+import org.yakindu.sct.model.sgraph.Reaction
|
|
|
+import java.util.List
|
|
|
+import org.yakindu.sct.model.stext.stext.ImportScope
|
|
|
+import org.yakindu.base.expressions.expressions.Argument
|
|
|
+import org.yakindu.base.expressions.expressions.FeatureCall
|
|
|
+import org.yakindu.base.types.Annotation
|
|
|
+import org.yakindu.base.types.AnnotationType
|
|
|
+import org.yakindu.base.types.Declaration
|
|
|
|
|
|
-/**
|
|
|
- * This is the Java code generators main class.
|
|
|
- *
|
|
|
- * @author Markus Mühlbrandt
|
|
|
- * @author Axel Terfloth - extensions
|
|
|
- */
|
|
|
class SCCDGenerator implements ISGraphGenerator {
|
|
|
+ val parallelRegionsName = "parallelRegionsOf_"
|
|
|
+ val openCData = "<![CDATA["
|
|
|
+ val closeCData = "]]>"
|
|
|
|
|
|
- /*
|
|
|
- @Inject extension GenmodelEntries
|
|
|
- @Inject extension EventBasedRunnableFeature
|
|
|
- @Inject extension CycleBasedWrapperFeature
|
|
|
-
|
|
|
- @Inject extension SExecExtensions
|
|
|
- @Inject extension IStatemachine
|
|
|
- @Inject extension ITimerCallback
|
|
|
- @Inject extension ITimer
|
|
|
- @Inject extension TimerService
|
|
|
- @Inject extension RuntimeService
|
|
|
- @Inject extension StatemachineInterface
|
|
|
- @Inject extension Statemachine
|
|
|
- @Inject extension EventBasedRunnableWrapper
|
|
|
- @Inject extension CycleBasedSynchronizedWrapper
|
|
|
- @Inject INamingService namingService
|
|
|
- */
|
|
|
-
|
|
|
override generate(Statechart sc, GeneratorEntry entry, IFileSystemAccess fsa) {
|
|
|
fsa.generateFile(sc.name + '.xml', sc.generate as String)
|
|
|
}
|
|
|
+// ##### Modifying Names #####
|
|
|
+ def dispatch void generateAbsoluteName(Statechart it, String currentName){
|
|
|
+ for(Region region : regions){
|
|
|
+ generateAbsoluteName(region, "")
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch void generateAbsoluteName(Region it, String currentName){
|
|
|
+ for(Vertex vertex : vertices){
|
|
|
+ if(vertex instanceof State && (vertex as State).regions.size >= 2){
|
|
|
+ vertex.name = currentName + "/" + vertex.name
|
|
|
+ for(Region reg : (vertex as State).regions){
|
|
|
+ //generateAbsoluteName(reg, vertex.name + "/" + reg.name)
|
|
|
+ generateAbsoluteName(reg, vertex.name + "/" + this.parallelRegionsName + vertex.generateName + "/" + reg.name)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ vertex.name = currentName + "/" + vertex.name
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ def CharSequence generateName(NamedElement it){
|
|
|
+ var splitName = name.split("/")
|
|
|
+ '''«splitName.reverse.head»'''
|
|
|
+ //'''«name»'''
|
|
|
+ }
|
|
|
|
|
|
- def String generate(Statechart it){
|
|
|
+// ##########
|
|
|
+
|
|
|
+ def dispatch String generate(Statechart it){
|
|
|
+ // TODO : <in/outport> for in/out event in the interface of Yakindu ?
|
|
|
'''
|
|
|
+ «generateAbsoluteName(it, "")»
|
|
|
<?xml version="1.0" ?>
|
|
|
- <diagram author="foo" name="aName">
|
|
|
+ <diagram author="unknown" name="«name»">
|
|
|
+ <description>
|
|
|
+ Code generated by the SCCD Generator
|
|
|
+ </description>
|
|
|
<class name="MainApp" default="true">
|
|
|
+ «generatePorts»
|
|
|
+ «IF scopes.length > 0»
|
|
|
+ <constructor>
|
|
|
+ «generateListScope(scopes)»
|
|
|
+ </constructor>
|
|
|
+ «ENDIF»
|
|
|
+ «generateMethods»
|
|
|
«IF regions.size >= 2»
|
|
|
- <scxml initial="parallelRegions">
|
|
|
- <parallel id="parallelRegions">
|
|
|
+ <scxml initial="«this.parallelRegionsName»«it.generateName»">
|
|
|
+ <parallel id="«this.parallelRegionsName»«it.generateName»">
|
|
|
«FOR region : regions»
|
|
|
- <state id="«region.name»" initial="«region.initialState»">
|
|
|
+ <state id="«region.generateName»" initial="«region.initialState.generateName»">
|
|
|
«region.generate»
|
|
|
</state>
|
|
|
«ENDFOR»
|
|
|
</parallel>
|
|
|
«ELSE»
|
|
|
- <scxml initial="«regions.head.initialState»">
|
|
|
+ <scxml initial="«regions.head.initialState.generateName»">
|
|
|
«FOR region : regions»
|
|
|
«region.generate»
|
|
|
«ENDFOR»
|
|
@@ -78,45 +167,566 @@ class SCCDGenerator implements ISGraphGenerator {
|
|
|
'''
|
|
|
}
|
|
|
|
|
|
- def generate(Region it){
|
|
|
+ def dispatch CharSequence generate(Region it){
|
|
|
'''
|
|
|
- «FOR vertex : vertices.filter(State)»
|
|
|
+ «FOR vertex : vertices»
|
|
|
«vertex.generate»
|
|
|
«ENDFOR»
|
|
|
'''
|
|
|
}
|
|
|
|
|
|
def initialState(Region it){
|
|
|
- vertices.filter(Entry).head.outgoingTransitions.head.target.name
|
|
|
+ vertices.filter(Entry).filter([entry | entry.kind == EntryKind.INITIAL]).head.outgoingTransitions.head.target
|
|
|
}
|
|
|
|
|
|
- def generate(State it){
|
|
|
+ def dispatch CharSequence generate(State it){
|
|
|
'''
|
|
|
- <state id="«name»">
|
|
|
+ <state id="«generateName»">
|
|
|
+ «generateOneExitEntry(it.localReactions)»
|
|
|
+ «FOR react : it.localReactions»
|
|
|
+ «react.generate»
|
|
|
+ «ENDFOR»
|
|
|
«FOR transition : outgoingTransitions»
|
|
|
«transition.generate»
|
|
|
«ENDFOR»
|
|
|
+ «IF regions.length >= 2»
|
|
|
+ <parallel id="«this.parallelRegionsName»«it.generateName»">
|
|
|
+ «FOR region : regions»
|
|
|
+ <state id="«region.name»" initial="«region.initialState.generateName»">
|
|
|
+ «region.generate»
|
|
|
+ </state>
|
|
|
+ «ENDFOR»
|
|
|
+ </parallel>
|
|
|
+ «ELSE»
|
|
|
+ «IF regions.head !== null»
|
|
|
+ <state id="«regions.head.name»" initial="«regions.head.initialState.generateName»">
|
|
|
+ «regions.head.generate»
|
|
|
+ </state>
|
|
|
+ «ENDIF»
|
|
|
+ «ENDIF»
|
|
|
</state>
|
|
|
'''
|
|
|
}
|
|
|
|
|
|
- def generate(Transition it){
|
|
|
+ def dispatch CharSequence generate(FinalState it){
|
|
|
+ // TODO
|
|
|
+ ''''''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(Entry it){
|
|
|
'''
|
|
|
- «trigger.generateTrigger»
|
|
|
- Instance of : «trigger instanceof Trigger»
|
|
|
- Instance of : «trigger instanceof ReactionTrigger»
|
|
|
- Instance of : «trigger instanceof ReactionTriggerImpl»
|
|
|
- <transition target="/«target.name»">
|
|
|
+ «IF kind == EntryKind.DEEP_HISTORY»
|
|
|
+ <history id="«generateName»" type="deep"/>
|
|
|
+ «ELSEIF kind == EntryKind.SHALLOW_HISTORY»
|
|
|
+ <history id="«generateName»" type="shallow"/>
|
|
|
+ «ENDIF»
|
|
|
+ '''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(Choice it){
|
|
|
+ // TODO
|
|
|
+ ''''''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(Exit it){
|
|
|
+ // TODO
|
|
|
+ ''''''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(Synchronization it){
|
|
|
+ // TODO
|
|
|
+ ''''''
|
|
|
+ }
|
|
|
+
|
|
|
+// ##### Transitions & Reactions #####
|
|
|
+// TODO : Properties ??
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(Transition it){
|
|
|
+ '''
|
|
|
+ <transition«trigger.generateTrigger»«trigger.generateGuard»target="«target.name»">
|
|
|
+ «IF effect !== null»
|
|
|
+ «effect.generate»
|
|
|
+ «ENDIF»
|
|
|
</transition>
|
|
|
'''
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- def dispatch generateTrigger(DefaultTrigger it) {
|
|
|
+ def dispatch CharSequence generateGuard(ReactionTrigger it){
|
|
|
+ var CharSequence stringGuard = "";
|
|
|
+ if(guard !== null){
|
|
|
+ stringGuard = guard.generate
|
|
|
+ }
|
|
|
+ '''«IF stringGuard.length > 0» cond="«stringGuard»" «ENDIF»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generateGuard(DefaultTrigger it){
|
|
|
+ '''defaultTriggerGuard'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(Guard it){
|
|
|
+ '''«it.expression.generate»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch String generateTrigger(ReactionTrigger it){
|
|
|
+ // In Statechart, only ONE event can trigger a transition
|
|
|
+ // TODO : support multiple triggers ?
|
|
|
+ '''«IF triggers.head !== null»«triggers.head.generate»«ENDIF»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch String generateTrigger(DefaultTrigger it) {
|
|
|
'''defaultTrigger'''
|
|
|
}
|
|
|
|
|
|
- def dispatch generateTrigger(ReactionTrigger it){
|
|
|
- '''«triggers.toString()»'''
|
|
|
+ def dispatch String generate(ReactionEffect it){
|
|
|
+ // TODO : a single <script> tag ? Filter the list and then generate ?
|
|
|
+ '''«FOR act : actions»«IF act !== null»
|
|
|
+ «IF act instanceof EventRaisingExpression»
|
|
|
+ «act.generate»
|
|
|
+ «ELSE»
|
|
|
+ <script>
|
|
|
+ «this.openCData»
|
|
|
+ «act.generate»
|
|
|
+ «this.closeCData»
|
|
|
+ </script>
|
|
|
+ «ENDIF»
|
|
|
+ «ENDIF»
|
|
|
+ «ENDFOR»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(LocalReaction it){
|
|
|
+ val string = String::format(it.trigger.generateTrigger, it.effect.generate)
|
|
|
+ '''«string»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def CharSequence generateOneExitEntry(List<Reaction> localReact){
|
|
|
+ var listEntry = localReact.filter([reaction | (reaction.trigger as ReactionTrigger).triggers.head instanceof EntryEvent])
|
|
|
+ var listExit= localReact.filter([reaction | (reaction.trigger as ReactionTrigger).triggers.head instanceof ExitEvent])
|
|
|
+ '''
|
|
|
+ «IF listEntry.size > 0»
|
|
|
+ <onentry>
|
|
|
+ «FOR entry : listEntry»
|
|
|
+ «entry.effect.generate»
|
|
|
+ «ENDFOR»
|
|
|
+ </onentry>
|
|
|
+ «ENDIF»
|
|
|
+ «IF listExit.size > 0»
|
|
|
+ <onexit>
|
|
|
+ «FOR exit : listExit»
|
|
|
+ «exit.effect.generate»
|
|
|
+ «ENDFOR»
|
|
|
+ </onexit>
|
|
|
+ «ENDIF»
|
|
|
+ '''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(AlwaysEvent it){
|
|
|
+ ''' '''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(EntryEvent it){
|
|
|
+ // Those events are handled by the generateOneExitEntry functions
|
|
|
+ // Only one <onentry> is allowed
|
|
|
+ ''''''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(ExitEvent it){
|
|
|
+ // Those events are handled by the generateOneExitEntry functions
|
|
|
+ // Only one <onexit> is allowed
|
|
|
+ ''''''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(TimeEventSpec it){
|
|
|
+ var String operation;
|
|
|
+ switch it.unit {
|
|
|
+ case TimeUnit.MILLISECOND : operation = " / 1000"
|
|
|
+ case TimeUnit.MICROSECOND : operation = " / 1000000"
|
|
|
+ case TimeUnit.NANOSECOND : operation = " / 1000000000"
|
|
|
+ default : operation = ""
|
|
|
+ }
|
|
|
+ // To PrimitiveValueExpression
|
|
|
+ '''«IF type == TimeEventType.AFTER» after="«value.generate»«operation»" «ENDIF»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(RegularEventSpec event){
|
|
|
+ ''' event="«event.event.generate»" '''
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+// ##########
|
|
|
+// ##### Scopes and Co #####
|
|
|
+
|
|
|
+ def dispatch CharSequence generateListScope(List<Scope> it){
|
|
|
+ // All variables and events of all interface are in common
|
|
|
+ // TODO : bug if 2 variables or events have the name but are in different interfaces. Solutions ?
|
|
|
+ val listToGenerate = newArrayList()
|
|
|
+ for(Scope scope : it){
|
|
|
+ var temp = scope.declarations
|
|
|
+ for(Declaration decla : temp){
|
|
|
+ if(decla instanceof VariableDefinition){
|
|
|
+ listToGenerate.add(decla)
|
|
|
+ }
|
|
|
+ else if (decla instanceof EventDefinition && (decla as EventDefinition).type !== null){
|
|
|
+ listToGenerate.add(decla)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ '''
|
|
|
+ «FOR decla : listToGenerate»
|
|
|
+ «IF decla instanceof EventDefinition && decla.type !== null»
|
|
|
+ <parameter name="«decla.generate»_value"/>
|
|
|
+ «ELSE»
|
|
|
+ <parameter name="«decla.generate»"/>
|
|
|
+ «ENDIF»
|
|
|
+ «ENDFOR»
|
|
|
+ <body>
|
|
|
+ «FOR decla : listToGenerate»
|
|
|
+ «IF decla instanceof EventDefinition && decla.type !== null»
|
|
|
+ self.«decla.generate»_value = None
|
|
|
+ «ELSE»
|
|
|
+ self.«decla.generate» = None
|
|
|
+ «ENDIF»
|
|
|
+ «ENDFOR»
|
|
|
+ </body>
|
|
|
+ '''
|
|
|
+ /*«FOR decla : declarations.filter(VariableDefinition)»
|
|
|
+ <parameter name="«decla.generate»"/>
|
|
|
+ «ENDFOR»
|
|
|
+ <body>
|
|
|
+ «this.openCData»
|
|
|
+ «FOR decla : declarations.filter(VariableDefinition)»
|
|
|
+ self.«decla.name» = None
|
|
|
+ «ENDFOR»
|
|
|
+ «this.closeCData»
|
|
|
+ </body>
|
|
|
+ «FOR dec : declarations.filter(EventDefinition)»
|
|
|
+ «IF dec.type !== null»
|
|
|
+ self.«dec.generate»_value = None
|
|
|
+ «ENDIF»
|
|
|
+ «ENDFOR»
|
|
|
+ '''*/
|
|
|
+ }
|
|
|
+
|
|
|
+ def CharSequence generatePorts(Statechart it){
|
|
|
+ // TODO : generate in/output for every interface ?
|
|
|
+ // TODO : How to change the <raise> to get the correct port ?
|
|
|
+ '''
|
|
|
+ <inport name="defaultInput"/>
|
|
|
+ <outport name="defaultOutput"/>
|
|
|
+ '''
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence port(InterfaceScope it){
|
|
|
+ '''«name»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence port(SimpleScope it){}
|
|
|
+ def dispatch CharSequence port(InternalScope it){}
|
|
|
+ def dispatch CharSequence port(ImportScope it){}
|
|
|
+
|
|
|
+ /*def dispatch CharSequence generate(StatechartScope it){
|
|
|
+ '''
|
|
|
+ «FOR decla : declarations»
|
|
|
+ self.«decla.generate» = 0
|
|
|
+ «ENDFOR»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(SimpleScope it){
|
|
|
+ '''
|
|
|
+ «FOR decla : declarations»
|
|
|
+ self.«decla.generate» = 0
|
|
|
+ «ENDFOR»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(InternalScope it){
|
|
|
+ '''
|
|
|
+ «FOR decla : declarations»
|
|
|
+ self.«decla.generate» = 0
|
|
|
+ «ENDFOR»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(InterfaceScope it){
|
|
|
+ '''
|
|
|
+ «FOR decla : declarations»
|
|
|
+ self.«decla.generate» = 0
|
|
|
+ «ENDFOR»'''
|
|
|
+ }*/
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(VariableDefinition it){
|
|
|
+ '''«name»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(EventDefinition it){
|
|
|
+ '''«name»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(OperationDefinition it){
|
|
|
+ '''«name»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(PropertyDefinition it){
|
|
|
+ '''«name»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def CharSequence genereteListParameter(List<Parameter> it){
|
|
|
+ '''«FOR para : it SEPARATOR ", "»«para.name»«ENDFOR»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def CharSequence generateMethods(Statechart it){
|
|
|
+ '''
|
|
|
+ «FOR scope : scopes»
|
|
|
+ «FOR decla : scope.declarations.filter(OperationDefinition)»
|
|
|
+ <method name="«decla.name»">
|
|
|
+ «FOR parameter : decla.parameters»
|
|
|
+ «parameter.generate»
|
|
|
+ «ENDFOR»
|
|
|
+ <body>
|
|
|
+ raise NotImplementedError("The function '«decla.name»' is not implemented")
|
|
|
+ </body>
|
|
|
+ </method>
|
|
|
+ «ENDFOR»
|
|
|
+ «ENDFOR»
|
|
|
+ '''
|
|
|
+ }
|
|
|
+ def CharSequence generateListPara(OperationDefinition it){
|
|
|
+ '''«FOR para : parameters SEPARATOR ", "»«para.name»«ENDFOR»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(Parameter it){
|
|
|
+ // TODO : support for type of the arguments ?
|
|
|
+ '''<parameter name="«name»"/>'''
|
|
|
+ }
|
|
|
+
|
|
|
+// ##########
|
|
|
+// ##### Expressions #####
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(Expression it){
|
|
|
+ '''unhandled Expression : «it.class.toString()»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(FeatureCall it){
|
|
|
+ // Used when you called one attribut of a interface
|
|
|
+ // Owner refers to Scopes
|
|
|
+ // Feature refers to definition (Variable, Event, Operation)
|
|
|
+ val listArgs = it.arguments
|
|
|
+ '''self.«it.owner.generate».«it.feature.generate»«it.arguments.generateListArgs»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def CharSequence generateListArgs(List<Argument> it){
|
|
|
+ '''«IF it.length > 0»(«FOR arg : it SEPARATOR ", "»«arg.value.generate»«ENDFOR»)«ENDIF»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ /*def dispatch CharSequence generate(Argument it){
|
|
|
+ '''«IF value !== null»«value.generate»«ENDIF»«IF parameter !== null»parameter : «parameter.generate»«ENDIF»'''
|
|
|
+ }*/
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(ActiveStateReferenceExpression it){
|
|
|
+ '''INSTATE(«value.name»)'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(ConditionalExpression it){
|
|
|
+ // exp1 ? exp2 : exp3
|
|
|
+ // In Python exp2 if exp1 else exp3
|
|
|
+ '''«trueCase.generate» if «condition.generate» else «falseCase.generate»'''
|
|
|
+ }
|
|
|
+ // ##### BinaryExpression #####
|
|
|
+ def dispatch CharSequence generate(BitwiseAndExpression it){
|
|
|
+ '''«leftOperand.generate» & «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(BitwiseOrExpression it){
|
|
|
+ '''«leftOperand.generate» | «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(BitwiseXorExpression it){
|
|
|
+ '''«leftOperand.generate» ^ «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(LogicalAndExpression it){
|
|
|
+ '''«leftOperand.generate» and «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(LogicalOrExpression it){
|
|
|
+ '''«leftOperand.generate» or «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(LogicalRelationExpression it){
|
|
|
+ var String operator;
|
|
|
+ switch it.operator {
|
|
|
+ // Relational Operator
|
|
|
+ case RelationalOperator.EQUALS: operator = "=="
|
|
|
+ case RelationalOperator.GREATER: operator = ">"
|
|
|
+ case RelationalOperator.GREATER_EQUAL: operator = ">="
|
|
|
+ case RelationalOperator.NOT_EQUALS: operator = "!="
|
|
|
+ case RelationalOperator.SMALLER: operator = "<"
|
|
|
+ case RelationalOperator.SMALLER_EQUAL: operator = "<="
|
|
|
+ default: operator = "##"
|
|
|
+ }
|
|
|
+ '''«leftOperand.generate» «operator» «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(NumericalAddSubtractExpression it){
|
|
|
+ var String operator;
|
|
|
+ switch it.operator{
|
|
|
+ // Additive Operator
|
|
|
+ case AdditiveOperator.MINUS: operator = "-"
|
|
|
+ case AdditiveOperator.PLUS: operator = "+"
|
|
|
+ default: operator = "##"
|
|
|
+ }
|
|
|
+ '''«leftOperand.generate» «operator» «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(NumericalMultiplyDivideExpression it){
|
|
|
+ var String operator;
|
|
|
+ switch it.operator{
|
|
|
+ // Multiplicative Operator
|
|
|
+ case MultiplicativeOperator.DIV: operator = "*"
|
|
|
+ case MultiplicativeOperator.MOD: operator = "%"
|
|
|
+ case MultiplicativeOperator.MUL: operator = "/"
|
|
|
+ default: operator = "##"
|
|
|
+ }
|
|
|
+ '''«leftOperand.generate» «operator» «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(ShiftExpression it){
|
|
|
+ var String operator;
|
|
|
+ switch it.operator{
|
|
|
+ // Shift Operator
|
|
|
+ case ShiftOperator.LEFT: operator = "<<"
|
|
|
+ case ShiftOperator.RIGHT: operator = ">>"
|
|
|
+ default: operator = "##"
|
|
|
+ }
|
|
|
+ '''«leftOperand.generate» «operator» «rightOperand.generate»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ // ##########
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(EventRaisingExpression it){
|
|
|
+ // TODO : support for different scopes ?
|
|
|
+ // TODO : how to support the different port for the event ? Use placeholders for strings ?
|
|
|
+ '''<raise event="«event.generate»" scope="local" port="defaultOutput"/>
|
|
|
+ «IF value !== null»
|
|
|
+ <script>
|
|
|
+ self.«event.generate»_value = «value.generate»
|
|
|
+ </script>
|
|
|
+ «ENDIF»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(EventValueReferenceExpression it){
|
|
|
+ // TODO : what is this expression ? builtin fct : valueof(event) ?
|
|
|
+ '''«value.generate»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ // ##### UnaryExpression #####
|
|
|
+ def dispatch CharSequence generate(LogicalNotExpression it){
|
|
|
+ '''not («operand.generate»)'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(NumericalUnaryExpression it){
|
|
|
+ var String operator;
|
|
|
+ switch it.operator{
|
|
|
+ // UnaryOperator
|
|
|
+ case UnaryOperator.COMPLEMENT: operator = "~"
|
|
|
+ case UnaryOperator.NEGATIVE: operator = "-"
|
|
|
+ case UnaryOperator.POSITIVE: operator = "+"
|
|
|
+ default: operator = "##"
|
|
|
+ }
|
|
|
+ '''«operator»«operand.generate»'''
|
|
|
+ }
|
|
|
+ def dispatch CharSequence generate(PostFixUnaryExpression it){
|
|
|
+ var String operator;
|
|
|
+ switch it.operator{
|
|
|
+ // Postfix Operator
|
|
|
+ case PostFixOperator.DECREMENT: operator = "+= 1"
|
|
|
+ case PostFixOperator.INCREMENT: operator = "-= 1"
|
|
|
+ default: operator = "##"
|
|
|
+ }
|
|
|
+ '''«operand.generate» «operator»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ // ##########
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(ParenthesizedExpression it){
|
|
|
+ '''(«it.expression.generate»)'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(AssignmentExpression it){
|
|
|
+ var String operator;
|
|
|
+ switch it.operator {
|
|
|
+ // Assignment Operator
|
|
|
+ case AssignmentOperator.ADD_ASSIGN: operator = "+="
|
|
|
+ case AssignmentOperator.AND_ASSIGN: operator = "&="
|
|
|
+ case AssignmentOperator.ASSIGN: operator = "="
|
|
|
+ case AssignmentOperator.DIV_ASSIGN: operator = "/="
|
|
|
+ case AssignmentOperator.LEFT_SHIFT_ASSIGN: operator = "<<="
|
|
|
+ case AssignmentOperator.RIGHT_SHIFT_ASSIGN: operator = ">>="
|
|
|
+ case AssignmentOperator.MOD_ASSIGN: operator = "%="
|
|
|
+ case AssignmentOperator.MULT_ASSIGN: operator = "*="
|
|
|
+ case AssignmentOperator.OR_ASSIGN: operator = "|="
|
|
|
+ case AssignmentOperator.SUB_ASSIGN: operator = "-="
|
|
|
+ case AssignmentOperator.XOR_ASSIGN: operator = "^="
|
|
|
+
|
|
|
+ // Default
|
|
|
+ default: operator = "##"
|
|
|
+ }
|
|
|
+ '''«it.varRef.generate» «operator» «it.expression.generate»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(PrimitiveValueExpression it){
|
|
|
+ // To SomethingLiteral
|
|
|
+ '''«value.generate»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(IntLiteral it){
|
|
|
+ '''«value»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(HexLiteral it){
|
|
|
+ // In Python, hexadecimal numbers are represented like this : 0x127AF
|
|
|
+ '''0x«value»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(BinaryLiteral it){
|
|
|
+ // In Python, binary numbers are represented like this : 0b01010101
|
|
|
+ '''0b«value»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(DoubleLiteral it){
|
|
|
+ '''«value»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(FloatLiteral it){
|
|
|
+ '''«value»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(BoolLiteral it){
|
|
|
+ // In Python, true -> True and false -> False
|
|
|
+ '''«IF value»True«ELSE»False«ENDIF»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(StringLiteral it){
|
|
|
+ // In Python, strings are surrounded by "
|
|
|
+ '''"""«value»"""'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(NullLiteral it){
|
|
|
+ // In Python, null singleton is None
|
|
|
+ '''None'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(ElementReferenceExpression it){
|
|
|
+ // To Somewhere
|
|
|
+ // ElementReferenceExpression.reference returns an EObject
|
|
|
+ var name = ""
|
|
|
+ if(it.reference instanceof NamedElement){
|
|
|
+ name = (it.reference as NamedElement).name
|
|
|
+ }
|
|
|
+ var CharSequence args = ""
|
|
|
+ if(it.operationCall){
|
|
|
+ args = it.arguments.generateListArgs
|
|
|
+ }
|
|
|
+ '''«name»«args»'''
|
|
|
+ //'''«IF it.reference instanceof NamedElement»«(it.reference as NamedElement).name»«ELSE»«it.reference.generate»«ENDIF»'''
|
|
|
+ }
|
|
|
+
|
|
|
+ def CharSequence generateListExpr(List<Argument> it){
|
|
|
+ '''«FOR arg : it SEPARATOR ", "»«arg.value.generate»«ENDFOR»'''
|
|
|
+ }
|
|
|
+
|
|
|
+// ##### EObject #####
|
|
|
+
|
|
|
+ def dispatch CharSequence generate(EObject it){
|
|
|
+ '''not handled : «it.class.toString()»'''
|
|
|
}
|
|
|
}
|