Skip to content
Open
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
726 changes: 435 additions & 291 deletions compiler/lib/src/main/resources/META-INF/native-image/reflect-config.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions compiler/lib/src/main/scala/ast/Ast.scala
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ object Ast {
final case class DefSignal(node: AstNode[Ast.DefSignal]) extends Node
final case class DefState(node: AstNode[Ast.DefState]) extends Node
final case class SpecInitialTransition(node: AstNode[Ast.SpecInitialTransition]) extends Node
final case class SpecInclude(node: AstNode[Ast.SpecInclude]) extends Node
}

/** Action definition */
Expand Down Expand Up @@ -241,6 +242,7 @@ object Ast {
final case class SpecStateEntry(node: AstNode[Ast.SpecStateEntry]) extends Node
final case class SpecStateExit(node: AstNode[Ast.SpecStateExit]) extends Node
final case class SpecStateTransition(node: AstNode[Ast.SpecStateTransition]) extends Node
final case class SpecInclude(node: AstNode[Ast.SpecInclude]) extends Node
}

/** Initial state specifier */
Expand Down
124 changes: 124 additions & 0 deletions compiler/lib/src/main/scala/ast/AstTransformer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,60 @@ trait AstTransformer {
node: Ast.Annotated[AstNode[Ast.DefStateMachine]]
): ResultAnnotatedNode[Ast.DefStateMachine] = Right(default(in), node)

def defActionAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.DefAction]]
): ResultAnnotatedNode[Ast.DefAction] =
Right(default(in), node)

def defChoiceAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.DefChoice]]
): ResultAnnotatedNode[Ast.DefChoice] =
Right(default(in), node)

def defGuardAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.DefGuard]]
): ResultAnnotatedNode[Ast.DefGuard] =
Right(default(in), node)

def defSignalAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.DefSignal]]
): ResultAnnotatedNode[Ast.DefSignal] =
Right(default(in), node)

def defStateAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.DefState]]
): ResultAnnotatedNode[Ast.DefState] =
Right(default(in), node)

def specInitialTransitionAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.SpecInitialTransition]]
): ResultAnnotatedNode[Ast.SpecInitialTransition] =
Right(default(in), node)

def specStateEntryAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.SpecStateEntry]]
): ResultAnnotatedNode[Ast.SpecStateEntry] =
Right(default(in), node)

def specStateExitAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.SpecStateExit]]
): ResultAnnotatedNode[Ast.SpecStateExit] =
Right(default(in), node)

def specStateTransitionAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.SpecStateTransition]]
): ResultAnnotatedNode[Ast.SpecStateTransition] =
Right(default(in), node)

def defStructAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.DefStruct]]
Expand Down Expand Up @@ -315,6 +369,76 @@ trait AstTransformer {
case e : Ast.ExprUnop => exprUnopNode(in, node, e)
}

final def matchStateMember(in: In, member: Ast.StateMember): Result[Ast.StateMember] = {
def transform[T](
result: ResultAnnotatedNode[T],
f: AstNode[T] => Ast.StateMember.Node
) = {
for { pair <- result } yield {
val (out, (pre, node, post)) = pair
(out, Ast.StateMember(pre, f(node), post))
}
}
val (pre, node, post) = member.node
node match {
case Ast.StateMember.DefChoice(node1) =>
transform(defChoiceAnnotatedNode(in, (pre, node1, post)), Ast.StateMember.DefChoice(_))
case Ast.StateMember.DefState(node1) =>
transform(defStateAnnotatedNode(in, (pre, node1, post)), Ast.StateMember.DefState(_))
case Ast.StateMember.SpecInitialTransition(node1) =>
transform(specInitialTransitionAnnotatedNode(in, (pre, node1, post)), Ast.StateMember.SpecInitialTransition(_))
case Ast.StateMember.SpecStateEntry(node1) =>
transform(specStateEntryAnnotatedNode(in, (pre, node1, post)), Ast.StateMember.SpecStateEntry(_))
case Ast.StateMember.SpecStateExit(node1) =>
transform(specStateExitAnnotatedNode(in, (pre, node1, post)), Ast.StateMember.SpecStateExit(_))
case Ast.StateMember.SpecStateTransition(node1) =>
transform(specStateTransitionAnnotatedNode(in, (pre, node1, post)), Ast.StateMember.SpecStateTransition(_))
case Ast.StateMember.SpecInclude(node1) =>
transform(specIncludeAnnotatedNode(in, (pre, node1, post)), Ast.StateMember.SpecInclude(_))
}
}

final def matchStateMachineMember(in: In, member: Ast.StateMachineMember): Result[Ast.StateMachineMember] = {
def transform[T](
result: ResultAnnotatedNode[T],
f: AstNode[T] => Ast.StateMachineMember.Node
) = {
for { pair <- result } yield {
val (out, (pre, node, post)) = pair
(out, Ast.StateMachineMember(pre, f(node), post))
}
}
val (pre, node, post) = member.node
node match {
case Ast.StateMachineMember.DefAbsType(node1) =>
transform(defAbsTypeAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefAbsType(_))
case Ast.StateMachineMember.DefAliasType(node1) =>
transform(defAliasTypeAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefAliasType(_))
case Ast.StateMachineMember.DefArray(node1) =>
transform(defArrayAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefArray(_))
case Ast.StateMachineMember.DefConstant(node1) =>
transform(defConstantAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefConstant(_))
case Ast.StateMachineMember.DefEnum(node1) =>
transform(defEnumAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefEnum(_))
case Ast.StateMachineMember.DefStruct(node1) =>
transform(defStructAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefStruct(_))
case Ast.StateMachineMember.DefAction(node1) =>
transform(defActionAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefAction(_))
case Ast.StateMachineMember.DefChoice(node1) =>
transform(defChoiceAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefChoice(_))
case Ast.StateMachineMember.DefGuard(node1) =>
transform(defGuardAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefGuard(_))
case Ast.StateMachineMember.DefSignal(node1) =>
transform(defSignalAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefSignal(_))
case Ast.StateMachineMember.DefState(node1) =>
transform(defStateAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefState(_))
case Ast.StateMachineMember.SpecInitialTransition(node1) =>
transform(specInitialTransitionAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.SpecInitialTransition(_))
case Ast.StateMachineMember.SpecInclude(node1) =>
transform(specIncludeAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.SpecInclude(_))
}
}

final def matchModuleMember(in: In, member: Ast.ModuleMember): Result[Ast.ModuleMember] = {
def transform[T](
result: ResultAnnotatedNode[T],
Expand Down
2 changes: 2 additions & 0 deletions compiler/lib/src/main/scala/ast/AstVisitor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ trait AstVisitor {
case Ast.StateMachineMember.DefState(node1) => defStateAnnotatedNode(in, (pre, node1, post))
case Ast.StateMachineMember.DefStruct(node1) => defStructAnnotatedNode(in, (pre, node1, post))
case Ast.StateMachineMember.SpecInitialTransition(node1) => specInitialTransitionAnnotatedNode(in, (pre, node1, post))
case Ast.StateMachineMember.SpecInclude(node1) => specIncludeAnnotatedNode(in, (pre, node1, post))
}
}

Expand All @@ -236,6 +237,7 @@ trait AstVisitor {
case Ast.StateMember.DefChoice(node1) => defChoiceAnnotatedNode(in, (pre, node1, post))
case Ast.StateMember.DefState(node1) => defStateAnnotatedNode(in, (pre, node1, post))
case Ast.StateMember.SpecInitialTransition(node1) => specInitialTransitionAnnotatedNode(in, (pre, node1, post))
case Ast.StateMember.SpecInclude(node1) => specIncludeAnnotatedNode(in, (pre, node1, post))
case Ast.StateMember.SpecStateEntry(node1) => specStateEntryAnnotatedNode(in, (pre, node1, post))
case Ast.StateMember.SpecStateExit(node1) => specStateExitAnnotatedNode(in, (pre, node1, post))
case Ast.StateMember.SpecStateTransition(node1) => specStateTransitionAnnotatedNode(in, (pre, node1, post))
Expand Down
8 changes: 5 additions & 3 deletions compiler/lib/src/main/scala/syntax/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -888,30 +888,32 @@ object Parser extends Parsers {
node(defSignal) ^^ (n => Ast.StateMachineMember.DefSignal(n)) |
node(defState) ^^ (n => Ast.StateMachineMember.DefState(n)) |
node(defStruct) ^^ (n => Ast.StateMachineMember.DefStruct(n)) |
node(specInclude) ^^ (n => Ast.StateMachineMember.SpecInclude(n)) |
node(specInitialTransition) ^^ (n => Ast.StateMachineMember.SpecInitialTransition(n)) |
failure("state machine member expected")
}

private def stateMachineMembers: Parser[List[Ast.StateMachineMember]] =
def stateMachineMembers: Parser[List[Ast.StateMachineMember]] =
annotatedElementSequence(
stateMachineMemberNode,
semi,
Ast.StateMachineMember(_)
)

private def stateMemberNode: Parser[Ast.StateMember.Node] = {
node(defChoice) ^^ (n => Ast.StateMember.DefChoice(n)) |
node(defChoice) ^^ (n => Ast.StateMember.DefChoice(n)) |
node(defState) ^^ (n => Ast.StateMember.DefState(n)) |
node(specInitialTransition) ^^ (n =>
Ast.StateMember.SpecInitialTransition(n)) |
node(specStateEntry) ^^ (n => Ast.StateMember.SpecStateEntry(n)) |
node(specStateExit) ^^ (n => Ast.StateMember.SpecStateExit(n)) |
node(specInclude) ^^ (n => Ast.StateMember.SpecInclude(n)) |
node(specStateTransition) ^^ (n =>
Ast.StateMember.SpecStateTransition(n)) |
failure("state member expected")
}

private def stateMembers: Parser[List[Ast.StateMember]] =
def stateMembers: Parser[List[Ast.StateMember]] =
annotatedElementSequence(stateMemberNode, semi, Ast.StateMember(_))

def structTypeMember: Parser[Ast.StructTypeMember] = {
Expand Down
63 changes: 63 additions & 0 deletions compiler/lib/src/main/scala/transform/ResolveSpecInclude.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,41 @@ object ResolveSpecInclude extends AstStateTransformer {
}
}

override def defStateMachineAnnotatedNode(
a: Analysis,
node: Ast.Annotated[AstNode[Ast.DefStateMachine]]
) = {
val (pre, node1, post) = node
val Ast.DefStateMachine(name, members) = node1.data
members match {
case None => Right((a, node))
case Some(members) => {
for { result <- transformList(a, members, stateMachineMember) }
yield {
val (a1, members1) = result
val defStateMachine = Ast.DefStateMachine(name, Some(members1.flatten))
val node2 = AstNode.create(defStateMachine, node1.id)
(a1, (pre, node2, post))
}
}
}
}

override def defStateAnnotatedNode(
a: Analysis,
node: Ast.Annotated[AstNode[Ast.DefState]]
) = {
val (pre, node1, post) = node
val Ast.DefState(name, members) = node1.data
for { result <- transformList(a, members, stateMember) }
yield {
val (a1, members1) = result
val defStateMachine = Ast.DefState(name, members1.flatten)
val node2 = AstNode.create(defStateMachine, node1.id)
(a1, (pre, node2, post))
}
}

override def defTopologyAnnotatedNode(
a: Analysis,
node: Ast.Annotated[AstNode[Ast.DefTopology]]
Expand Down Expand Up @@ -207,6 +242,34 @@ object ResolveSpecInclude extends AstStateTransformer {
}
}

private def stateMember(a: Analysis, member: Ast.StateMember): Result[List[Ast.StateMember]] = {
val (_, node, _) = member.node
node match {
case Ast.StateMember.SpecInclude(node1) => resolveSpecInclude(
a,
node1,
Parser.stateMembers,
stateMember
)
case _ => for { result <- matchStateMember(a, member) }
yield (result._1, List(result._2))
}
}

private def stateMachineMember(a: Analysis, member: Ast.StateMachineMember): Result[List[Ast.StateMachineMember]] = {
val (_, node, _) = member.node
node match {
case Ast.StateMachineMember.SpecInclude(node1) => resolveSpecInclude(
a,
node1,
Parser.stateMachineMembers,
stateMachineMember
)
case _ => for { result <- matchStateMachineMember(a, member) }
yield (result._1, List(result._2))
}
}

private def tuMember(a: Analysis, tum: Ast.TUMember) = moduleMember(a, tum)

}
12 changes: 12 additions & 0 deletions compiler/tools/fpp-syntax/test/include-state-machine.fpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
state machine M {@ Action a1
action a1

@ Action a2
action a2

include "subdir/state.fppi"

state S2 {
include "subdir/state.fppi"
}
}
56 changes: 56 additions & 0 deletions compiler/tools/fpp-syntax/test/include-state-machine.ref.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
def state machine
ident M
@ Action a1
def action
ident a1
@ Action a2
def action
ident a2
def state
ident S1
spec state entry
action ident a1
action ident a2
spec state exit
action ident a1
action ident a2
@ Initial transition
spec initial
action ident a1
action ident a2
target qual ident S3
@ Choice C
def choice
ident C
guard ident g1
action ident a1
action ident a2
target qual ident S1
action ident a2
action ident a3
target qual ident S2.S3
def state
ident S2
def state
ident S1
spec state entry
action ident a1
action ident a2
spec state exit
action ident a1
action ident a2
@ Initial transition
spec initial
action ident a1
action ident a2
target qual ident S3
@ Choice C
def choice
ident C
guard ident g1
action ident a1
action ident a2
target qual ident S1
action ident a2
action ident a3
target qual ident S2.S3
5 changes: 5 additions & 0 deletions compiler/tools/fpp-syntax/test/run
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ include_subdir()
run_test -ia include-subdir
}

include_state_machine()
{
run_test -ia include-state-machine
}

include_topology()
{
run_test -ia include-topology
Expand Down
10 changes: 10 additions & 0 deletions compiler/tools/fpp-syntax/test/subdir/state.fppi
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
state S1 {
entry do { a1, a2 }
exit do { a1, a2 }

@ Initial transition
initial do { a1, a2 } enter S3

@ Choice C
choice C { if g1 do { a1, a2 } enter S1 else do { a2, a3 } enter S2.S3 }
}
1 change: 1 addition & 0 deletions compiler/tools/fpp-syntax/test/update-ref
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ update -ia include-component
update -ia include-constant-1 include-constant-1
update -ia include-module
update -ia include-subdir
update -ia include-state-machine
update -ia include-topology
update -ia subdir/include-parent-dir
update -ia syntax syntax-include-ast
Expand Down
Loading