|
|
@@ -3,29 +3,55 @@ from sccd.statechart.static.tree import *
|
|
|
from sccd.util.visit_tree import *
|
|
|
|
|
|
def ident(state: State) -> str:
|
|
|
- return state.opt.full_name.replace('/', '_');
|
|
|
+ # if state.opt.full_name == "/":
|
|
|
+ # return ""
|
|
|
+ # else:
|
|
|
+ return state.opt.full_name.replace('/', '_');
|
|
|
+
|
|
|
+def ident_type(state: State) -> str:
|
|
|
+ return "State" + ident(state)
|
|
|
+
|
|
|
+def ident_field(state: State) -> str:
|
|
|
+ return "s" + ident(state)
|
|
|
|
|
|
def compile_to_rust(tree: StateTree):
|
|
|
# 1. Write types
|
|
|
|
|
|
def write_state_type(state: State, children: str):
|
|
|
- if isinstance(state, ParallelState):
|
|
|
- # We use Rust structs for And-states
|
|
|
- print("struct T%s {" % ident(state))
|
|
|
+ def as_struct():
|
|
|
+ print("struct %s {" % ident_type(state))
|
|
|
+ for child in children:
|
|
|
+ print(" %s: %s," % (ident_field(child), ident_type(child)))
|
|
|
+ print("}")
|
|
|
+
|
|
|
+ def as_enum():
|
|
|
+ print("enum %s {" % ident_type(state))
|
|
|
for child in children:
|
|
|
- print(" s%s: T%s," % (child, child))
|
|
|
+ print(" %s(%s)," % (ident_field(child), ident_type(child)))
|
|
|
print("}")
|
|
|
+
|
|
|
+ if isinstance(state, ParallelState):
|
|
|
+ as_struct()
|
|
|
elif isinstance(state, HistoryState):
|
|
|
print("Skipping HistoryState: ", state.opt.full_name)
|
|
|
elif isinstance(state, State):
|
|
|
- # Or-state (with children) or Basic state (without children)
|
|
|
- # We use Rust enums (typed unions)
|
|
|
- print("enum T%s {" % ident(state))
|
|
|
- for child in children:
|
|
|
- print(" s%s(T%s)," % (child, child))
|
|
|
- print("}")
|
|
|
+ if len(state.children) > 0:
|
|
|
+ as_enum() # Or-state
|
|
|
+ else:
|
|
|
+ # Basic state: write as empty struct
|
|
|
+ #
|
|
|
+ # An empty struct in Rust is a type with one possible value.
|
|
|
+ # An empty struct is a Zero-Sized Type.
|
|
|
+ #
|
|
|
+ # An empty enum is also a valid type in Rust, but no instances
|
|
|
+ # of it can be created. Also called an "uninhabited type".
|
|
|
+ as_struct()
|
|
|
+
|
|
|
+ # The above if-else construction hints at the fact that we would have
|
|
|
+ # better used empty And-states to model basic states, instead of empty Or-states...
|
|
|
+
|
|
|
print()
|
|
|
- return ident(state)
|
|
|
+ return state
|
|
|
|
|
|
visit_tree(tree.root, lambda s: s.children,
|
|
|
parent_first=[],
|