mirror of
https://github.com/nasa/fpp.git
synced 2025-12-13 16:47:48 -06:00
99 lines
3.6 KiB
Scala
99 lines
3.6 KiB
Scala
package fpp.compiler.codegen
|
|
|
|
import fpp.compiler.analysis._
|
|
import fpp.compiler.ast._
|
|
|
|
/** A visitor for generating state machine enter functions */
|
|
case class StateMachineEntryFns(
|
|
s: CppWriterState,
|
|
aNode: Ast.Annotated[AstNode[Ast.DefStateMachine]]
|
|
) extends StateMachineCppVisitor(s, aNode) {
|
|
|
|
def write = defStateMachineAnnotatedNode(Nil, aNode)
|
|
|
|
override def defChoiceAnnotatedNode(
|
|
mm: List[CppDoc.Class.Member],
|
|
aNode: Ast.Annotated[AstNode[Ast.DefChoice]]
|
|
) = {
|
|
val data = aNode._2.data
|
|
val choiceSym = StateMachineSymbol.Choice(aNode)
|
|
val choiceName = writeSmSymbolName(choiceSym)
|
|
val te = StateMachineTypedElement.Choice(aNode)
|
|
val typeOpt = sma.typeOptionMap(te)
|
|
val valueArgOpt = typeOpt.map(_ => valueParamName)
|
|
val guardSym = sma.getGuardSymbol(data.guard)
|
|
val writeChoiceTransition = writeTransition (signalParamName) (valueArgOpt)
|
|
val ifTransition = sma.flattenedChoiceTransitionMap(data.ifTransition)
|
|
val elseTransition = sma.flattenedChoiceTransitionMap(data.elseTransition)
|
|
val member = functionClassMember(
|
|
Some(s"Enter choice $choiceName"),
|
|
getEnterFunctionName(choiceSym),
|
|
getParamsWithTypeOpt(typeOpt),
|
|
CppDoc.Type("void"),
|
|
wrapInIfElse(
|
|
writeGuardCall (signalParamName) (valueArgOpt) (guardSym),
|
|
writeChoiceTransition (ifTransition),
|
|
writeChoiceTransition (elseTransition)
|
|
)
|
|
)
|
|
member :: mm
|
|
}
|
|
|
|
override def defStateAnnotatedNodeInner(
|
|
mm: List[CppDoc.Class.Member],
|
|
aNode: Ast.Annotated[AstNode[Ast.DefState]],
|
|
substates: List[Ast.Annotated[AstNode[Ast.DefState]]]
|
|
) = {
|
|
val members = super.defStateAnnotatedNodeInner(mm, aNode, substates)
|
|
val initSpecifier = State.getInitialSpecifier(aNode._2.data).get._2.data
|
|
val transition = initSpecifier.transition.data
|
|
val actionSymbols = transition.actions.map(sma.getActionSymbol)
|
|
val targetSymbol = sma.useDefMap(transition.target.id)
|
|
val actionPrefix = line("// Do the actions for the initial transition")
|
|
val actionLines = actionSymbols.flatMap(writeActionCall (signalParamName) (None))
|
|
val enterPrefix = line("// Enter the target of the initial transition")
|
|
val enterLines = writeEnterCall (signalParamName) (None) (targetSymbol)
|
|
val initial = List.concat(
|
|
Line.addPrefixLine (actionPrefix) (actionLines),
|
|
Line.addPrefixLine (enterPrefix) (enterLines)
|
|
)
|
|
val member = getStateEnterFn(aNode, initial)
|
|
member :: members
|
|
}
|
|
|
|
override def defStateAnnotatedNodeLeaf(
|
|
mm: List[CppDoc.Class.Member],
|
|
aNode: Ast.Annotated[AstNode[Ast.DefState]]
|
|
) = {
|
|
val members = super.defStateAnnotatedNodeLeaf(mm, aNode)
|
|
val stateSym = StateMachineSymbol.State(aNode)
|
|
val update = writeStateUpdate(stateSym)
|
|
val member = getStateEnterFn(aNode, update)
|
|
member :: members
|
|
}
|
|
|
|
private def getStateEnterFn(
|
|
aNode: Ast.Annotated[AstNode[Ast.DefState]],
|
|
initialOrUpdate: List[Line]
|
|
): CppDoc.Class.Member = {
|
|
val stateSym = StateMachineSymbol.State(aNode)
|
|
val stateName = writeSmSymbolName(stateSym)
|
|
val entryActionSymbols =
|
|
State.getEntryActions(aNode._2.data).map(sma.getActionSymbol)
|
|
val entryActionComment = line("// Do the entry actions")
|
|
val entryActionLines =
|
|
entryActionSymbols.flatMap(writeActionCall (signalParamName) (None))
|
|
functionClassMember(
|
|
Some(s"Enter state $stateName"),
|
|
getEnterFunctionName(stateSym),
|
|
List(signalParam),
|
|
CppDoc.Type("void"),
|
|
List.concat(
|
|
Line.addPrefixLine (entryActionComment) (entryActionLines),
|
|
initialOrUpdate
|
|
)
|
|
)
|
|
}
|
|
|
|
}
|