Skip to content
Merged
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
79 changes: 46 additions & 33 deletions autocoder/fprime_backend/fppcoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,39 +73,47 @@ def processNode(node: Node,

indent = " " * level

for child in node.children:

if child.name == "INITIAL":
target = xmiModel.idMap[child.target].stateName
doExpr = f" do {{ {format_funcs(child.action, False)} }}" if child.action else ""
fppFile.write(f"{indent}initial{doExpr} enter {target}\n")

if child.name == "JUNCTION":
ifTarget = xmiModel.idMap[child.ifTarget].stateName
elseTarget = xmiModel.idMap[child.elseTarget].stateName
doIfExpr = f" do {{ {format_funcs(child.ifAction, False)} }}" if child.ifAction else ""
doElseExpr = f" do {{ {format_funcs(child.elseAction, False)} }}" if child.elseAction else ""
fppFile.write(f"{indent}choice {child.stateName} {{\n")
fppFile.write(f"{indent} if {child.guard}{doIfExpr} enter {ifTarget} else{doElseExpr} enter {elseTarget}\n")
fppFile.write(f"{indent}}}\n")

if child.name == "TRANSITION":
guardExpr = f" if {format_funcs(child.guard, False)}" if child.guard else ""
enterExpr = f" enter {xmiModel.idMap[child.target].stateName}" if child.kind is None else ""
doExpr = f" do {{ {format_funcs(child.action, False)} }}" if child.action else ""
fppFile.write(f"{indent}on {child.event}{guardExpr}{doExpr}{enterExpr}\n")

if child.name == "STATE":
stateName = child.stateName
enterExpr = f" entry do {{ {format_funcs(child.entry, False)} }}" if child.entry else ""
exitExpr = f" exit do {{ {format_funcs(child.exit, False)} }}" if child.exit else ""
fppFile.write(f"{indent}state {stateName} {{\n")
if enterExpr:
fppFile.write(f"{indent}{enterExpr}\n")
if exitExpr:
fppFile.write(f"{indent}{exitExpr}\n")
processNode(child, xmiModel, fppFile, level+1)
fppFile.write(f"{indent}}}\n\n")
# Separate children by type for consistent ordering
initials = [child for child in node.children if child.name == "INITIAL"]
junctions = [child for child in node.children if child.name == "JUNCTION"]
transitions = [child for child in node.children if child.name == "TRANSITION"]
states = [child for child in node.children if child.name == "STATE"]

# Process INITIAL children (typically only one, maintain order)
for child in initials:
target = xmiModel.idMap[child.target].stateName
doExpr = f" do {{ {format_funcs(child.action, False)} }}" if child.action else ""
fppFile.write(f"{indent}initial{doExpr} enter {target}\n")

# Process TRANSITION children in sorted order by event name for consistency
for child in sorted(transitions, key=lambda t: t.event if t.event else ""):
guardExpr = f" if {format_funcs(child.guard, False)}" if child.guard else ""
enterExpr = f" enter {xmiModel.idMap[child.target].stateName}" if child.kind is None else ""
doExpr = f" do {{ {format_funcs(child.action, False)} }}" if child.action else ""
fppFile.write(f"{indent}on {child.event}{guardExpr}{doExpr}{enterExpr}\n")

# Process STATE children in sorted (alphabetical) order for consistency
for child in sorted(states, key=lambda s: s.stateName):
stateName = child.stateName
enterExpr = f" entry do {{ {format_funcs(child.entry, False)} }}" if child.entry else ""
exitExpr = f" exit do {{ {format_funcs(child.exit, False)} }}" if child.exit else ""
fppFile.write(f"{indent}state {stateName} {{\n")
if enterExpr:
fppFile.write(f"{indent}{enterExpr}\n")
if exitExpr:
fppFile.write(f"{indent}{exitExpr}\n")
processNode(child, xmiModel, fppFile, level+1)
fppFile.write(f"{indent}}}\n\n")

# Process JUNCTION children last (maintain order, typically referenced by transitions)
for child in junctions:
ifTarget = xmiModel.idMap[child.ifTarget].stateName
elseTarget = xmiModel.idMap[child.elseTarget].stateName
doIfExpr = f" do {{ {format_funcs(child.ifAction, False)} }}" if child.ifAction else ""
doElseExpr = f" do {{ {format_funcs(child.elseAction, False)} }}" if child.elseAction else ""
fppFile.write(f"{indent}choice {child.stateName} {{\n")
fppFile.write(f"{indent} if {child.guard}{doIfExpr} enter {ifTarget} else{doElseExpr} enter {elseTarget}\n")
fppFile.write(f"{indent}}}\n")

# -----------------------------------------------------------------------
# getInitTranstions
Expand Down Expand Up @@ -217,6 +225,11 @@ def generateCode(xmiModel: XmiModel):
(actions, guards, signals) = getStateMachineMethods(xmiModel)

moveTransitions(xmiModel)

# Renumber junctions for consistent output across input formats
junctions = [node for node in PreOrderIter(xmiModel.tree) if node.name == "JUNCTION"]
for idx, junction in enumerate(sorted(junctions, key=lambda j: (j.parent.stateName if hasattr(j.parent, 'stateName') else "", j.guard or ""))):
junction.stateName = f"J{idx}"

fppFile.write(f"state machine {xmiModel.tree.stateMachine} {{\n\n")

Expand Down
2 changes: 1 addition & 1 deletion models/TestModels/golden/Actions/fprime.fppi
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ state machine Actions {

signal EV1

initial enter S1
state S1 {
entry do { s1Entry }
exit do { s1Exit }
Expand All @@ -22,5 +23,4 @@ state machine Actions {
on EV1 do { a2 } enter S1
}

initial enter S1
}
2 changes: 1 addition & 1 deletion models/TestModels/golden/Arg_Actions/fprime.fppi
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ state machine Arg_Actions {
signal EV1: e
signal EV2

initial enter S1
state S1 {
entry do { s1Entry, s1Entry2, foo }
exit do { s1Exit, s1Exit2, foo }
Expand All @@ -31,5 +32,4 @@ state machine Arg_Actions {
on EV1 do { a1, a2, foo } enter S1
}

initial enter S1
}
67 changes: 0 additions & 67 deletions models/TestModels/golden/Cameo/cpp-cameo.txt

This file was deleted.

67 changes: 0 additions & 67 deletions models/TestModels/golden/Cameo/cpp-plantuml.txt

This file was deleted.

62 changes: 0 additions & 62 deletions models/TestModels/golden/Cameo/fprime-plantuml.fppi

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ state machine Cameo {
signal Ev4
signal Ev5

state StateS1 {
entry do { S1Entry }
exit do { S1Exit }
on Ev2 do { a2 } enter Running
}

initial enter J0
state Running {
entry do { runningEntry }
exit do { runningExit }
initial enter J2
on Ev1 if guard2 do { a1 } enter StateS1
on Ev3 enter J1
on Ev4 do { a4 } enter J1
on Ev5 enter Running
state StateS2 {
entry do { s2Entry }
exit do { s2Exit }
Expand All @@ -42,21 +42,21 @@ state machine Cameo {
exit do { s3Exit }
}

initial enter J6
choice J6 {
choice J2 {
if guard4() enter StateS3 else enter StateS2
}
on Ev1 if guard2 do { a1 } enter StateS1
on Ev3 enter J8
on Ev4 do { a4 } enter J8
on Ev5 enter Running
}

initial enter J7
choice J7 {
state StateS1 {
entry do { S1Entry }
exit do { S1Exit }
on Ev2 do { a2 } enter Running
}

choice J0 {
if guard() enter StateS1 else enter Running
}
choice J8 {
choice J1 {
if guard3() enter StateS1 else do { a2 } enter Running
}
}
Loading
Loading