Skip to content

Commit

Permalink
Merge pull request #578 from nasa/issue-565-packet-syntax
Browse files Browse the repository at this point in the history
Add syntax for telemetry packets
  • Loading branch information
bocchino authored Jan 31, 2025
2 parents 38d7ba8 + 2d2915c commit ac7685d
Show file tree
Hide file tree
Showing 25 changed files with 6,328 additions and 672 deletions.
508 changes: 316 additions & 192 deletions compiler/lib/src/main/resources/META-INF/native-image/reflect-config.json

Large diffs are not rendered by default.

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

Expand Down Expand Up @@ -739,6 +740,21 @@ object Ast {

}

/** Telemetry packet specifier */
final case class SpecTlmPacket(
name: Ident,
id: Option[AstNode[Expr]],
level: AstNode[Expr],
members: List[TlmPacketMember]
)

/** Telemetry packet group specifier */
final case class SpecTlmPacketGroup(
name: Ident,
members: List[TlmPacketGroupMember],
omitted: List[AstNode[TlmChannelIdentifier]]
)

/** Topology import specifier */
final case class SpecTopImport(top: AstNode[QualIdent])

Expand All @@ -753,6 +769,34 @@ object Ast {
format: Option[AstNode[String]]
)

/** Telemetry channel identifier */
final case class TlmChannelIdentifier(
componentInstance: AstNode[QualIdent],
channelName: AstNode[Ident]
)

/** Telemetry packet group member */
final case class TlmPacketGroupMember(node: Annotated[TlmPacketGroupMember.Node])
object TlmPacketGroupMember {
sealed trait Node
final case class SpecInclude(node: AstNode[Ast.SpecInclude])
extends Node
final case class SpecTlmPacket(node: AstNode[Ast.SpecTlmPacket])
extends Node
}

/** Telemetry packet member */
sealed trait TlmPacketMember
object TlmPacketMember {

final case class SpecInclude(node: AstNode[Ast.SpecInclude])
extends TlmPacketMember

final case class TlmChannelIdentifier(node: AstNode[Ast.TlmChannelIdentifier])
extends TlmPacketMember

}

/** Translation unit member */
type TUMember = ModuleMember
val TUMember = ModuleMember
Expand Down
31 changes: 31 additions & 0 deletions compiler/lib/src/main/scala/ast/AstTransformer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,16 @@ trait AstTransformer {
node: Ast.Annotated[AstNode[Ast.SpecTlmChannel]]
): ResultAnnotatedNode[Ast.SpecTlmChannel] = Right(default(in), node)

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

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

def specTopImportAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.SpecTopImport]]
Expand Down Expand Up @@ -305,6 +315,25 @@ trait AstTransformer {
}
}

final def matchTlmPacketGroupMember(in: In, member: Ast.TlmPacketGroupMember): Result[Ast.TlmPacketGroupMember] = {
def transform[T](
result: ResultAnnotatedNode[T],
f: AstNode[T] => Ast.TlmPacketGroupMember.Node
) = {
for (pair <- result) yield {
val (out, (pre, node, post)) = pair
(out, Ast.TlmPacketGroupMember(pre, f(node), post))
}
}
val (pre, node, post) = member.node
node match {
case Ast.TlmPacketGroupMember.SpecInclude(node1) =>
transform(specIncludeAnnotatedNode(in, (pre, node1, post)), Ast.TlmPacketGroupMember.SpecInclude(_))
case Ast.TlmPacketGroupMember.SpecTlmPacket(node1) =>
transform(specTlmPacketAnnotatedNode(in, (pre, node1, post)), Ast.TlmPacketGroupMember.SpecTlmPacket(_))
}
}

final def matchTopologyMember(in: In, member: Ast.TopologyMember): Result[Ast.TopologyMember] = {
def transform[T](
result: ResultAnnotatedNode[T],
Expand All @@ -323,6 +352,8 @@ trait AstTransformer {
transform(specConnectionGraphAnnotatedNode(in, (pre, node1, post)), Ast.TopologyMember.SpecConnectionGraph(_))
case Ast.TopologyMember.SpecInclude(node1) =>
transform(specIncludeAnnotatedNode(in, (pre, node1, post)), Ast.TopologyMember.SpecInclude(_))
case Ast.TopologyMember.SpecTlmPacketGroup(node1) =>
transform(specTlmPacketGroupAnnotatedNode(in, (pre, node1, post)), Ast.TopologyMember.SpecTlmPacketGroup(_))
case Ast.TopologyMember.SpecTopImport(node1) =>
transform(specTopImportAnnotatedNode(in, (pre, node1, post)), Ast.TopologyMember.SpecTopImport(_))
}
Expand Down
13 changes: 13 additions & 0 deletions compiler/lib/src/main/scala/ast/AstVisitor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ trait AstVisitor {

def specTlmChannelAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.SpecTlmChannel]]): Out = default(in)

def specTlmPacketAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.SpecTlmPacket]]): Out = default(in)

def specTlmPacketGroupAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.SpecTlmPacketGroup]]): Out = default(in)

def specTopImportAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.SpecTopImport]]): Out = default(in)

def transUnit(in: In, tu: Ast.TransUnit): Out = default(in)
Expand Down Expand Up @@ -211,12 +215,21 @@ trait AstVisitor {
}
}

final def matchTlmPacketGroupMember(in: In, member: Ast.TlmPacketGroupMember): Out = {
val (pre, node, post) = member.node
node match {
case Ast.TlmPacketGroupMember.SpecInclude(node1) => specIncludeAnnotatedNode(in, (pre, node1, post))
case Ast.TlmPacketGroupMember.SpecTlmPacket(node1) => specTlmPacketAnnotatedNode(in, (pre, node1, post))
}
}

final def matchTopologyMember(in: In, member: Ast.TopologyMember): Out = {
val (pre, node, post) = member.node
node match {
case Ast.TopologyMember.SpecCompInstance(node1) => specCompInstanceAnnotatedNode(in, (pre, node1, post))
case Ast.TopologyMember.SpecConnectionGraph(node1) => specConnectionGraphAnnotatedNode(in, (pre, node1, post))
case Ast.TopologyMember.SpecInclude(node1) => specIncludeAnnotatedNode(in, (pre, node1, post))
case Ast.TopologyMember.SpecTlmPacketGroup(node1) => specTlmPacketGroupAnnotatedNode(in, (pre, node1, post))
case Ast.TopologyMember.SpecTopImport(node1) => specTopImportAnnotatedNode(in, (pre, node1, post))
}
}
Expand Down
57 changes: 57 additions & 0 deletions compiler/lib/src/main/scala/codegen/AstWriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,43 @@ object AstWriter extends AstVisitor with LineUtils {
).map(indentIn)
}

override def specTlmPacketGroupAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacketGroup]]
) = {
val (_, node, _) = aNode
val data = node.data
List.concat(
lines("def tlm packet group"),
List.concat(
ident(data.name),
List.concat(
lines("members"),
data.members.flatMap(tlmPacketGroupMember).map(indentIn)
),
List.concat(
lines("omitted"),
data.omitted.flatMap(applyToData(tlmChannelIdentifier)).map(indentIn)
)
).map(indentIn)
)
}

override def specTlmPacketAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacket]]
) = {
val (_, node, _) = aNode
val data = node.data
lines("spec tlm packet") ++
List.concat(
ident(data.name),
linesOpt(addPrefix("id", exprNode), data.id),
addPrefix("level", exprNode) (data.level),
data.members.flatMap(tlmPacketMember)
).map(indentIn)
}

override def specTopImportAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.SpecTopImport]]
Expand Down Expand Up @@ -755,6 +792,11 @@ object AstWriter extends AstVisitor with LineUtils {
qualIdent(qid)
}

private def tlmChannelIdentifier(tci: Ast.TlmChannelIdentifier): Out = {
val qid = Ast.QualIdent.Qualified(tci.componentInstance, tci.channelName)
qualIdent(qid)
}

private def qualIdent(qid: Ast.QualIdent): Out =
lines("qual ident " ++ qualIdentString(qid))

Expand Down Expand Up @@ -806,6 +848,21 @@ object AstWriter extends AstVisitor with LineUtils {
).map(indentIn)
}

private def tlmPacketGroupMember(member: Ast.TlmPacketGroupMember) = {
val l = matchTlmPacketGroupMember((), member)
val (a1, _, a2) = member.node
annotate(a1, l, a2)
}

private def tlmPacketMember(member: Ast.TlmPacketMember) =
member match {
case Ast.TlmPacketMember.SpecInclude(node) =>
specIncludeAnnotatedNode((), (Nil, node, Nil))
case Ast.TlmPacketMember.TlmChannelIdentifier(node) =>
lines("tlm channel identifier") ++
tlmChannelIdentifier(node.data).map(indentIn)
}

private def todo = lines("TODO")

private def topologyMember(tm: Ast.TopologyMember) = {
Expand Down
50 changes: 50 additions & 0 deletions compiler/lib/src/main/scala/codegen/FppWriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ object FppWriter extends AstVisitor with LineUtils {
annotate(a1, l, a2)
}

def tlmPacketGroupMember(member: Ast.TlmPacketGroupMember): Out = {
val (a1, _, a2) = member.node
val l = matchTlmPacketGroupMember((), member)
annotate(a1, l, a2)
}

def topologyMember(member: Ast.TopologyMember): Out = {
val (a1, _, a2) = member.node
val l = matchTopologyMember((), member)
Expand Down Expand Up @@ -642,6 +648,38 @@ object FppWriter extends AstVisitor with LineUtils {
joinOptWithBreak (optList(data.high)) ("high ") (limitSeq)
}

override def specTlmPacketAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacket]]
) = {
val (_, node, _) = aNode
val data = node.data
lines(s"packet ${ident(data.name)}").
joinOpt (data.id) (" id ") (exprNode).
join (" level ") (exprNode(data.level)).
joinNoIndent (" ") (
addBraces(data.members.flatMap(tlmPacketMember))
)
}

override def specTlmPacketGroupAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacketGroup]]
) = {
val (_, node, _) = aNode
val data = node.data
lines(s"telemetry packets ${ident(data.name)}").
joinNoIndent (" ") (
addBraces(
Line.blank ::
(Line.blankSeparated (tlmPacketGroupMember) (data.members) :+ Line.blank)
)
).
joinNoIndent (" omit ") (
addBracesIfNonempty(data.omitted.flatMap(applyToData(tlmChannelId)))
)
}

override def specTopImportAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.SpecTopImport]]
Expand Down Expand Up @@ -792,6 +830,18 @@ object FppWriter extends AstVisitor with LineUtils {
join (" ") (typeNameNode(member.typeName)).
joinOpt (member.format) (" format ") (applyToData(string))

private def tlmChannelId(tci: Ast.TlmChannelIdentifier) =
qualIdent(tci.componentInstance.data).
addSuffix(s".${ident(tci.channelName.data)}")

private def tlmPacketMember(member: Ast.TlmPacketMember) =
member match {
case Ast.TlmPacketMember.SpecInclude(node) =>
specIncludeAnnotatedNode((), (Nil, node, Nil))
case Ast.TlmPacketMember.TlmChannelIdentifier(node) =>
tlmChannelId(node.data)
}

private def typeNameNode(node: AstNode[Ast.TypeName]) = matchTypeNameNode((), node)

private def unop(op: Ast.Unop) = op.toString
Expand Down
4 changes: 4 additions & 0 deletions compiler/lib/src/main/scala/syntax/Lexer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -293,15 +293,19 @@ object Lexer extends RegexParsers {
("input", (u: Unit) => Token.INPUT()),
("instance", (u: Unit) => Token.INSTANCE()),
("internal", (u: Unit) => Token.INTERNAL()),
("level", (u: Unit) => Token.LEVEL()),
("locate", (u: Unit) => Token.LOCATE()),
("low", (u: Unit) => Token.LOW()),
("machine", (u: Unit) => Token.MACHINE()),
("match", (u: Unit) => Token.MATCH()),
("module", (u: Unit) => Token.MODULE()),
("omit", (u: Unit) => Token.OMIT()),
("on", (u: Unit) => Token.ON()),
("opcode", (u: Unit) => Token.OPCODE()),
("orange", (u: Unit) => Token.ORANGE()),
("output", (u: Unit) => Token.OUTPUT()),
("packet", (u: Unit) => Token.PACKET()),
("packets", (u: Unit) => Token.PACKETS()),
("param", (u: Unit) => Token.PARAM()),
("passive", (u: Unit) => Token.PASSIVE()),
("phase", (u: Unit) => Token.PHASE()),
Expand Down
Loading

0 comments on commit ac7685d

Please sign in to comment.