Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,28 @@ class KExpressionsValuedObjectExtensions {

def boolean isVariableReference(ValuedObjectReference valuedObjectReference) {
valuedObjectReference.valuedObject.isVariableReference
}
}

def boolean isEnumReference(ValuedObject valuedObject) {
val decl = valuedObject.declaration
if (decl instanceof ReferenceDeclaration) {
val refVO = decl.reference
if (refVO instanceof ValuedObject) {
val refDecl = refVO.declaration
if (refDecl instanceof ClassDeclaration) {
return refDecl.type == ValueType.ENUM
}
}
} else if (decl.isEnum) {
// check direct enum reference
return true
}
return false
}

def boolean isEnumReference(ValuedObjectReference valuedObjectReference) {
valuedObjectReference.valuedObject.isEnumReference
}

def boolean isModelReference(ValuedObject valuedObject) {
valuedObject.declaration instanceof ReferenceDeclaration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ class EquationSynthesis extends SubSynthesis<Assignment, KNode> {
* @param output Should be true if output nodes should be generated
*/
private def dispatch KNode performTransformation(ValuedObjectReference reference, List<KNode> nodes, boolean output) {
if (!reference.isModelReference
if (!reference.isModelReference && !reference.isEnumReference
&& (
(
reference.isClassReference
Expand Down Expand Up @@ -599,7 +599,7 @@ class EquationSynthesis extends SubSynthesis<Assignment, KNode> {
}
node.setProperty(output ? OUTPUT_FLAG : INPUT_FLAG, true)

if (reference.isModelReference) {
if (reference.isModelReference && !reference.isEnumReference) {
// in case of a model reference the subreference should not be in the label of the node
text = reference.valuedObject.reference.serializeHR.toString
for (i : reference.indices) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,15 @@ class StateSynthesis extends SubSynthesis<State, KNode> {

//pre-evaluate type
val isConnector = state.isConnector
val isInitialConnector = isConnector && state.isInitial;

// Basic state style
switch state {
case isInitialConnector: {
node.addInitialConnectorFigure
node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.CONNECTOR_STATE)
proxy.addInitialConnectorFigure
}
case isConnector: {
node.addConnectorFigure
node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.CONNECTOR_STATE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.*
import static de.cau.cs.kieler.sccharts.ui.synthesis.styles.ColorStore.Color.*

import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.*
import de.cau.cs.kieler.sccharts.extensions.SCChartsCoreExtensions
import de.cau.cs.kieler.annotations.extensions.PragmaExtensions

/**
* Transforms {@link Transition} into {@link KEdge} diagram elements.
Expand Down Expand Up @@ -67,8 +69,11 @@ class TransitionSynthesis extends SubSynthesis<Transition, KEdge> {
@Inject extension TransitionStyles
@Inject extension ColorStore
@Inject extension AdaptiveZoom
@Inject extension SCChartsCoreExtensions
@Inject extension PragmaExtensions

override performTranformation(Transition transition) {
val legacySemantics = transition.getSCCharts.hasPragma("LegacySemantics");
val edge = transition.createEdge().associateWith(transition);
edge.configureEdgeLOD(transition)

Expand All @@ -89,7 +94,7 @@ class TransitionSynthesis extends SubSynthesis<Transition, KEdge> {
edge.addTransitionSpline();

// Modifiers
if (transition.isImplicitlyImmediate) {
if (transition.isImplicitlyImmediate && (legacySemantics || !transition.sourceState.isConnector)) {
edge.setImmediateStyle
}
if (transition.nondeterministic) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ class StateStyles {
]
}

/**
* Adds an initial connector figure.
*/
def KRoundedRectangle addInitialConnectorFigure(KNode node) {
node.setMinimalNodeSize(0.5f * DEFAULT_FIGURE_MIN_NODE_SIZE, 0.5f * DEFAULT_FIGURE_MIN_NODE_SIZE);
node.addRoundedRectangle(DEFAULT_FIGURE_CORNER_RADIUS, DEFAULT_FIGURE_CORNER_RADIUS, baseLineWidth) => [
background = STATE_CONNECTOR.color;
foreground = STATE_CONNECTOR.color;
]
}

/**
* Adds a small state figure.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* KIELER - Kiel Integrated Environment for Layout Eclipse RichClient
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2026 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
*
* This code is provided under the terms of the Eclipse Public License (EPL).
*/
package de.cau.cs.kieler.sccharts.definitions;

import java.util.EnumSet;
import java.util.List;

import de.cau.cs.kieler.annotations.Pragma;
import de.cau.cs.kieler.annotations.Pragmatable;
import de.cau.cs.kieler.annotations.StringPragma;

/**
* @author dam, als
*/
public class Semantics {

public enum SCCharts {
LEAN, CLASSIC
}

public static String PRAGMA_SEMANTICS = "semantics";

public static EnumSet<SCCharts> getSemantics(Pragmatable model) {
List<String> sem = null;
for (Pragma p : model.getPragmas()) {
if (PRAGMA_SEMANTICS.equalsIgnoreCase(p.getName())) {
if (p instanceof StringPragma sp) {
if (!sp.getValues().isEmpty()) {
sem = sp.getValues();
}
}
}
}
if (sem != null) {
return EnumSet.copyOf(sem.stream().map(s -> SCCharts.valueOf(s.toUpperCase())).toList());
} else {
return EnumSet.noneOf(SCCharts.class);
}
}

public static boolean hasSemantics(Pragmatable model, SCCharts sem) {
EnumSet<SCCharts> semantics = getSemantics(model);
if (semantics.isEmpty() && sem == SCCharts.CLASSIC) {
return true;
} else {
return semantics.contains(sem);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ class SCChartsActionExtensions {
def getDuringActions(Scope scope) {
scope.actions.filter(DuringAction)
}

def getImmediateDuringActions(Scope scope) {
scope.actions.filter(DuringAction).filter[immediate]
}

def getExitActions(Scope scope) {
scope.actions.filter(ExitAction)
Expand All @@ -168,6 +172,10 @@ class SCChartsActionExtensions {
def hasDuringActions(Scope scope) {
!scope.duringActions.empty
}

def hasImmediateDuringActions(Scope scope) {
!scope.immediateDuringActions.empty
}

def hasExitActions(Scope scope) {
!scope.exitActions.empty
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* KIELER - Kiel Integrated Environment for Layout Eclipse RichClient
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2026 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
*
* This code is provided under the terms of the Eclipse Public License (EPL).
*/
package de.cau.cs.kieler.sccharts.processors.statebased.codegen

import com.google.inject.Singleton
import de.cau.cs.kieler.kexpressions.keffects.Assignment
import de.cau.cs.kieler.scg.ControlFlow
import de.cau.cs.kieler.scg.processors.codegen.c.CCodeSerializeHRExtensions
import org.eclipse.xtend.lib.annotations.Data
import org.eclipse.xtend.lib.annotations.Delegate
import de.cau.cs.kieler.kexpressions.keffects.ReferenceCallEffect
import de.cau.cs.kieler.kexpressions.ReferenceCall

/**
* @author als
*
*/
@Singleton
class StatebasedCCodeSerializeHRExtensions2 extends CCodeSerializeHRExtensions {

dispatch override CharSequence serializeHR(Assignment assignment) {
// Use assignment serialization for SCH nodes in underlying serializer
return (new DelegationSCGAssignment(assignment) as de.cau.cs.kieler.scg.Assignment).serializeHR
}

dispatch override CharSequence serializeHR(ReferenceCallEffect e) {
// Delegate to less specific implementation
_serializeHR(e as ReferenceCall)
}
}

@Data
class DelegationSCGAssignment implements de.cau.cs.kieler.scg.Assignment {
@Delegate val Assignment delegate

override getNext() {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}

override setNext(ControlFlow value) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}

override isIsInitial() {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}

override isSchizophrenic() {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}

override setIsInitial(boolean value) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}

override setSchizophrenic(boolean value) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}

override getName() {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}

override setName(String value) {
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
*/
package de.cau.cs.kieler.sccharts.processors.statebased.lean.codegen

import de.cau.cs.kieler.core.properties.Property
import de.cau.cs.kieler.sccharts.ControlflowRegion
import de.cau.cs.kieler.sccharts.Scope
import de.cau.cs.kieler.sccharts.State
import java.util.List
import java.util.Map
import de.cau.cs.kieler.core.properties.Property
import org.eclipse.xtend.lib.annotations.AccessorType
import org.eclipse.xtend.lib.annotations.Accessors

/**
* Common functionality for Lean State-Based Code Generation using a template.
Expand All @@ -31,10 +33,10 @@ abstract class AbstractStatebasedLeanTemplate {

protected State rootState

protected List<Scope> scopes
protected Map<Scope, String> scopeNames
protected Map<Scope, String> scopeEnumNames
protected Map<Scope, String> contextStructNames
@Accessors(AccessorType.PUBLIC_GETTER) protected List<Scope> scopes
@Accessors(AccessorType.PUBLIC_GETTER) protected Map<Scope, String> scopeNames
@Accessors(AccessorType.PUBLIC_GETTER) protected Map<Scope, String> scopeEnumNames
@Accessors(AccessorType.PUBLIC_GETTER) protected Map<Scope, String> contextStructNames
protected var int regionCounter
protected var int stateEnumCounter

Expand Down Expand Up @@ -124,21 +126,21 @@ abstract class AbstractStatebasedLeanTemplate {
/**
* Retrieves the unique name of the given {@link Scope} from the name cache.
*/
protected def String uniqueName(Scope scope) {
def String uniqueName(Scope scope) {
scopeNames.get(scope)
}

/**
* Retrieves the name of the enum literal, created for the given {@link State}, from the name cache.
*/
protected def String uniqueEnumName(State state) {
def String uniqueEnumName(State state) {
scopeEnumNames.get(state)
}

/**
* Retrieves the name of the context object used in other contexts, created for the given {@link Scope}.
*/
protected def String uniqueContextName(Scope scope) {
def String uniqueContextName(Scope scope) {
if (scope instanceof State) {
if (scope == rootState) {
"TickData"
Expand All @@ -153,7 +155,7 @@ abstract class AbstractStatebasedLeanTemplate {
/**
* Retrieves the name of the context type, created for the given {@link Scope}.
*/
protected def String uniqueContextMemberName(Scope scope) {
def String uniqueContextMemberName(Scope scope) {
if (scope instanceof State) {
if (scope == rootState) {
'''TickData'''
Expand Down
Loading
Loading