Skip to content

Commit

Permalink
Give state variables hierarchical names
Browse files Browse the repository at this point in the history
Allows generation of substates with equal names in different regions
  • Loading branch information
dziegel committed Jan 20, 2024
1 parent ebc5ea1 commit 16b5aa0
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 76 deletions.
2 changes: 2 additions & 0 deletions generator/src/generator/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public static void main(String[] args) throws Exception {
uml.setName("UML");
uml.load();
uml_module.getContext().getModelRepository().addModel(uml);
uml_module.getContext().setUserInput(new UserInput());

System.out.println("Generating XMI/UML model " + filename + " to " + out_path);

Expand All @@ -63,6 +64,7 @@ public static void main(String[] args) throws Exception {
scxml.setName("SCXML");
scxml.load();
scxml_module.getContext().getModelRepository().addModel(scxml);
scxml_module.getContext().setUserInput(new UserInput());

System.out.println("Generating SCXML model " + filename + " to " + out_path);

Expand Down
11 changes: 6 additions & 5 deletions generator/src/generator/ScxmlModel.egl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ operation t_scxml getModel() : Tuple {

var region = new Tuple();
result.region = region;
region.initial = self.a_initial;
region.initial_id = self.a_initial;
region.initial_history = false;

region.states = new List();
Expand All @@ -21,6 +21,7 @@ operation t_scxml getModel() : Tuple {
operation t_state getModel() : Tuple {
var result = new Tuple();
result.name = self.a_id;
result.id = self.a_id;

if (self.e_onentry.isDefined() and self.e_onentry.e_script.isDefined()) {
result.entry = self.e_onentry.e_script.a_src;
Expand All @@ -35,18 +36,18 @@ operation t_state getModel() : Tuple {
result.region = region;

if (self.e_initial.isDefined() and self.e_initial.e_transition.isDefined()) {
region.initial = self.e_initial.e_transition.a_target;
region.initial_id = self.e_initial.e_transition.a_target;
region.initial_history = false;
}
if (self.e_history.isDefined() and self.e_history.e_transition.isDefined()) {
region.initial = self.e_history.e_transition.a_target;
region.initial_id = self.e_history.e_transition.a_target;
region.initial_history = true;
}

region.states = new List();
for (state in self.c_state) {
var state_model = state.getModel();
state_model.parent = result.name;
state_model.parent_state_id = result.id;
region.states.add(state_model);
}
}
Expand All @@ -64,7 +65,7 @@ operation t_state getModel() : Tuple {
operation t_transition getModel() : Tuple {
var result = new Tuple();

result.target = self.a_target;
result.target_state_id = self.a_target;
result.internal = (self.a_type = "internal");
result.trigger = self.a_event;

Expand Down
54 changes: 41 additions & 13 deletions generator/src/generator/Transformations.egl
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,62 @@ operation Tuple transformStatemachine() {
self.impl_type = "Impl";
self.impl_ptr_type = "ImplPtr";

self.all_states = new Map();
self.all_actions = new List();
self.all_guards = new List();
self.all_entry_exit = new List();

self.region.transformRegion(self);
self.region.transformRegionStates(self, null);
self.region.transformRegionTransitions(self, null);

self.all_actions = self.all_actions.sortBy(a | a);
self.all_guards = self.all_guards.sortBy(g | g);
self.all_entry_exit = self.all_entry_exit.sortBy(e | e);
}

operation Tuple transformRegion(statemachine : Tuple) {
self.initial_variable_name = "k" + self.initial;

operation Tuple transformRegionStates(statemachine : Tuple, parent_state : Tuple) {
self.states = self.states.sortBy(s | s.name);
for (state in self.states) {
state.transformState(statemachine, self);
state.transformState(statemachine, self, parent_state);

if (state.region.isDefined()) {
state.region.transformRegionStates(statemachine, state);
}
}
}

operation Tuple transformState(statemachine : Tuple, region : Tuple) {
self.variable_name = "k" + self.name;
operation Tuple transformRegionTransitions(statemachine : Tuple, parent_state : Tuple) {
var initial = statemachine.all_states.get(self.initial_id);
self.initial_variable_name = initial.variable_name;

for (state in self.states) {
if (state.region.isDefined()) {
state.region.transformRegionTransitions(statemachine, state);
}

state.transformTransitions(statemachine);
}
}

operation Tuple transformState(statemachine : Tuple, region : Tuple, parent_state : Tuple) {
statemachine.all_states.put(self.id, self);

if (parent_state.isDefined()) {
self.scoped_name = parent_state.scoped_name + self.name;
} else {
self.scoped_name = self.name;
}
self.variable_name = "k" + self.scoped_name;

self.state_type = statemachine.state_type;
if((region.initial = self.name) and region.initial_history) {
if((region.initial_id = self.id) and region.initial_history) {
self.state_type = statemachine.history_state_type;
}

self.parent_variable_pointer = "nullptr";
if (self.parent.isDefined()) {
self.parent_variable_pointer = "&k" + self.parent;
if (self.parent_state_id.isDefined()) {
var parent = statemachine.all_states.get(self.parent_state_id);
self.parent_variable_pointer = "&" + parent.variable_name;
}

self.entry_pointer = "nullptr";
Expand All @@ -55,17 +81,18 @@ operation Tuple transformState(statemachine : Tuple, region : Tuple) {
statemachine.all_entry_exit.add(self.exit);
}
}
}

operation Tuple transformTransitions(statemachine : Tuple) {
self.initial_variable_pointer = "nullptr";
if (self.region.isDefined()) {
self.region.transformRegion(statemachine);
self.initial_variable_pointer = "&" + self.region.initial_variable_name;
}

for (transition in self.transitions) {
transition.transformTransition(statemachine);
}
self.transitions = self.transitions.sortBy(t | t.trigger + "-" + t.priority + "-" + t.start + t.target);
self.transitions = self.transitions.sortBy(t | t.trigger + "-" + t.priority + "-" + t.start + t.target_state_id);

self.all_events = new List();
for (transition in self.transitions) {
Expand All @@ -85,7 +112,8 @@ operation Tuple transformTransition(statemachine : Tuple) {
if (self.internal) {
self.target_variable_name = "kNone";
} else {
self.target_variable_name = "k" + self.target;
var target = statemachine.all_states.get(self.target_state_id);
self.target_variable_name = target.variable_name;
}

var actions = new List();
Expand Down
49 changes: 49 additions & 0 deletions generator/src/generator/UserInput.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package generator;

import java.util.Collection;

import org.eclipse.epsilon.eol.exceptions.EolUserException;
import org.eclipse.epsilon.eol.userinput.IUserInput;

public class UserInput implements IUserInput {

@Override
public void inform(String message) {
System.out.println(message);
}

@Override
public boolean confirm(String question, boolean default_) throws EolUserException {
return false;
}

@Override
public Object chooseMany(String question, Collection<?> choices, Collection<?> default_) {
return null;
}

@Override
public Object choose(String question, Collection<?> choices, Object default_) {
return null;
}

@Override
public String prompt(String question, String default_) {
return "";
}

@Override
public int promptInteger(String question, int default_) {
return 0;
}

@Override
public float promptReal(String question, float default_) {
return 0;
}

@Override
public double promptReal(String question, double default_) {
return 0;
}
}
7 changes: 4 additions & 3 deletions generator/src/generator/XmiModel.egl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ operation Region getModel(sm : Tuple) : Tuple {
var result = new Tuple();

var initial = self.subvertices.select(s | s.isKindOf(Pseudostate) and ((s.kind = PseudostateKind#initial) or (s.kind = PseudostateKind#shallowHistory))).first;
result.initial = initial.outgoing.first.target.name;
result.initial_id = initial.outgoing.first.target.id;
result.initial_history = (initial.kind = PseudostateKind#shallowHistory);

result.states = new List();
Expand All @@ -26,9 +26,10 @@ operation Region getModel(sm : Tuple) : Tuple {
operation State getModel(sm : Tuple) : Tuple {
var result = new Tuple();
result.name = self.name;
result.id = self.id;

if (self.container.state != null) {
result.parent = self.container.state.name;
result.parent_state_id = self.container.state.id;
}

if (self.entry != null) {
Expand Down Expand Up @@ -72,7 +73,7 @@ operation Transition getTarget(sm : Tuple, transition : Tuple, transitions : Lis
}

if (self.target.isKindOf(State)) {
transition.target = self.target.name;
transition.target_state_id = self.target.id;
transitions.add(transition);
}

Expand Down
10 changes: 5 additions & 5 deletions test/ScXmlFsmImpl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ void ScXmlFsmImpl::Test()
assert(fsm_.CurrentState() == nullptr);
fsm_.Start();

assert(fsm_.CurrentState() == &ScXmlTest::kState_2);
assert(fsm_.CurrentState() == &ScXmlTest::kState_1State_2);
fsm_.React(EScXmlEvent::Internal);
assert(fsm_.CurrentState() == &ScXmlTest::kState_2);
assert(fsm_.CurrentState() == &ScXmlTest::kState_1State_2);
fsm_.React(EScXmlEvent::Transition_3);
assert(fsm_.CurrentState() == &ScXmlTest::kState_3);
assert(fsm_.CurrentState() == &ScXmlTest::kState_1State_3);
fsm_.React(EScXmlEvent::Transition_7);
assert(fsm_.CurrentState() == &ScXmlTest::kState_4);
assert(fsm_.CurrentState() == &ScXmlTest::kState_1State_4);
fsm_.React(EScXmlEvent::Transition_8);
assert(fsm_.CurrentState() == &ScXmlTest::kState_2);
assert(fsm_.CurrentState() == &ScXmlTest::kState_1State_2);
}

void ScXmlFsmImpl::entry()
Expand Down
8 changes: 4 additions & 4 deletions test/XmiFsmImpl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ void XmiFsmImpl::Test()

assert(fsm_.CurrentState() == &IoArHandlerMain::kClosed);
fsm_.React(EXmiEvent::S_PNS_ArOpend_ind);
assert(fsm_.CurrentState() == &IoArHandlerMain::kParameterizing);
assert(fsm_.CurrentState() == &IoArHandlerMain::kOpenParameterizing);
fsm_.React(EXmiEvent::S_PNS_ParamEndInd);
assert(fsm_.CurrentState() == &IoArHandlerMain::kWaitApplicationReady);
assert(fsm_.CurrentState() == &IoArHandlerMain::kOpenWaitApplicationReady);
fsm_.React(EXmiEvent::SPnpbAppTimeout);
assert(fsm_.CurrentState() == &IoArHandlerMain::kWaitApplicationReady);
assert(fsm_.CurrentState() == &IoArHandlerMain::kOpenWaitApplicationReady);
fsm_.React(EXmiEvent::SPnpbAppTimeout);
assert(fsm_.CurrentState() == &IoArHandlerMain::kWaitApplicationReadyCnf);
assert(fsm_.CurrentState() == &IoArHandlerMain::kOpenWaitApplicationReadyCnf);
fsm_.React(EXmiEvent::S_PNS_ArClosed_ind);
assert(fsm_.CurrentState() == &IoArHandlerMain::kClosed);
}
Expand Down
22 changes: 11 additions & 11 deletions test/generated/IoArHandlerMainDeclaration.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,45 +17,45 @@ class IoArHandlerMain final : public IoArHandlerMainBase

// State ApplicationReady
static Transition ApplicationReadyHandler(ImplPtr impl, Event event);
static const State kApplicationReady;
static const State kOpenApplicationReady;

// State DynamicReconfigurationRunning
static Transition DynamicReconfigurationRunningHandler(ImplPtr impl, Event event);
static const State kDynamicReconfigurationRunning;
static const State kOpenApplicationReadyDynamicReconfigurationRunning;

// State DrPlugPrmSequence
static Transition DrPlugPrmSequenceHandler(ImplPtr impl, Event event);
static const State kDrPlugPrmSequence;
static const State kOpenApplicationReadyDynamicReconfigurationRunningDrPlugPrmSequence;

// State DrWaitApplicationReadyCnfPlugSubmodule
static Transition DrWaitApplicationReadyCnfPlugSubmoduleHandler(ImplPtr impl, Event event);
static const State kDrWaitApplicationReadyCnfPlugSubmodule;
static const State kOpenApplicationReadyDynamicReconfigurationRunningDrWaitApplicationReadyCnfPlugSubmodule;

// State DrWaitApplicationReadyPlugSubmodule
static Transition DrWaitApplicationReadyPlugSubmoduleHandler(ImplPtr impl, Event event);
static const State kDrWaitApplicationReadyPlugSubmodule;
static const State kOpenApplicationReadyDynamicReconfigurationRunningDrWaitApplicationReadyPlugSubmodule;

// State DrWaitPlugCnf
static Transition DrWaitPlugCnfHandler(ImplPtr impl, Event event);
static const State kDrWaitPlugCnf;
static const State kOpenApplicationReadyDynamicReconfigurationRunningDrWaitPlugCnf;

// State DrWaitPullCnf
static Transition DrWaitPullCnfHandler(ImplPtr impl, Event event);
static const State kDrWaitPullCnf;
static const State kOpenApplicationReadyDynamicReconfigurationRunningDrWaitPullCnf;

// State Ready
static Transition ReadyHandler(ImplPtr impl, Event event);
static const State kReady;
static const State kOpenApplicationReadyReady;

// State Parameterizing
static Transition ParameterizingHandler(ImplPtr impl, Event event);
static const State kParameterizing;
static const State kOpenParameterizing;

// State WaitApplicationReady
static Transition WaitApplicationReadyHandler(ImplPtr impl, Event event);
static const State kWaitApplicationReady;
static const State kOpenWaitApplicationReady;

// State WaitApplicationReadyCnf
static Transition WaitApplicationReadyCnfHandler(ImplPtr impl, Event event);
static const State kWaitApplicationReadyCnf;
static const State kOpenWaitApplicationReadyCnf;
};
Loading

0 comments on commit 16b5aa0

Please sign in to comment.