Skip to content

Commit ef4a5b0

Browse files
authored
Merge pull request #602 from nasa/issue-566-packet-semantics
Telemetry packet semantics
2 parents 5ca639f + 9ca97e3 commit ef4a5b0

File tree

91 files changed

+3037
-1377
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+3037
-1377
lines changed

compiler/lib/src/main/resources/META-INF/native-image/reflect-config.json

Lines changed: 976 additions & 896 deletions
Large diffs are not rendered by default.

compiler/lib/src/main/scala/analysis/Analysis.scala

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ case class Analysis(
6565
topology: Option[Topology] = None,
6666
/** The map from state machine symbols to state machines */
6767
stateMachineMap: Map[Symbol.StateMachine, StateMachine] = Map(),
68+
/** The map from topology symbols to dictionaries */
69+
dictionaryMap: Map[Symbol.Topology, Dictionary] = Map(),
70+
/** The dictionary under construction */
71+
dictionary: Option[Dictionary] = None,
72+
/** The telemetry packet group under construction */
73+
tlmPacketGroup: Option[TlmPacketGroup] = None
6874
) {
6975

7076
/** Gets the qualified name of a symbol */
@@ -245,6 +251,11 @@ case class Analysis(
245251
for (ts <- getTopologySymbol(id))
246252
yield this.topologyMap(ts)
247253

254+
/** Gets a dictionary from the dictionary map */
255+
def getDictionary(id: AstNode.Id): Result.Result[Dictionary] =
256+
for (ts <- getTopologySymbol(id))
257+
yield this.dictionaryMap(ts)
258+
248259
/** Gets a BigInt value from an AST node */
249260
def getBigIntValue(id: AstNode.Id): BigInt = {
250261
val Value.Integer(v) = Analysis.convertValueToType(
@@ -404,6 +415,48 @@ case class Analysis(
404415

405416
object Analysis {
406417

418+
/** Adds a dictionary element mapped by ID */
419+
def addElementToIdMap[T](
420+
map: Map[BigInt, T],
421+
id: BigInt,
422+
element: T,
423+
getLoc: T => Location
424+
): Result.Result[(Map[BigInt,T], BigInt)] = {
425+
map.get(id) match {
426+
case Some(prevElement) =>
427+
// Element already there: report the error
428+
val idValue = displayIdValue(id)
429+
val loc = getLoc(element)
430+
val prevLoc = getLoc(prevElement)
431+
Left(SemanticError.DuplicateIdValue(idValue, loc, prevLoc))
432+
case None =>
433+
// New element: compute the new map and the new default ID
434+
Right(map + (id -> element), id + 1)
435+
}
436+
}
437+
438+
/** Checks for duplicate names in dictionary */
439+
def checkDictionaryNames[Id,Value](
440+
dictionary: Map[Id,Value],
441+
kind: String,
442+
getName: Value => String,
443+
getLoc: Value => Location
444+
) = {
445+
val initialMap: Map[String, Location] = Map()
446+
Result.foldLeft (dictionary.toList) (initialMap) ((map, pair) => {
447+
val (_, value) = pair
448+
val name = getName(value)
449+
val loc = getLoc(value)
450+
map.get(name) match {
451+
case Some(prevLoc) =>
452+
Left(SemanticError.DuplicateDictionaryName(
453+
kind, name, loc, prevLoc
454+
))
455+
case _ => Right(map + (name -> loc))
456+
}
457+
})
458+
}
459+
407460
/** Compute the common type for two types */
408461
def commonType(t1: Type, t2: Type, errorLoc: Location): Result.Result[Type] =
409462
Type.commonType(t1, t2) match {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package fpp.compiler.analysis
2+
3+
import fpp.compiler.ast._
4+
import fpp.compiler.util._
5+
6+
/** Analyze telemetry packet group members */
7+
trait TlmPacketGroupAnalyzer extends Analyzer {
8+
9+
override def specTlmPacketGroupAnnotatedNode(
10+
a: Analysis,
11+
node: Ast.Annotated[AstNode[Ast.SpecTlmPacketGroup]]
12+
) = {
13+
val (_, node1, _) = node
14+
val data = node1.data
15+
visitList(a, data.members, matchTlmPacketGroupMember)
16+
}
17+
18+
}

compiler/lib/src/main/scala/analysis/Analyzers/TypeExpressionAnalyzer.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ trait TypeExpressionAnalyzer
99
with ComponentAnalyzer
1010
with ModuleAnalyzer
1111
with StateMachineAnalyzer
12+
with TlmPacketGroupAnalyzer
1213
with TopologyAnalyzer
1314
{
1415

@@ -266,4 +267,13 @@ trait TypeExpressionAnalyzer
266267
} yield a
267268
}
268269

270+
override def specTlmPacketAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacket]]) = {
271+
val (_, node, _) = aNode
272+
val data = node.data
273+
for {
274+
a <- opt(exprNode)(a, data.id)
275+
a <- exprNode(a, data.level)
276+
} yield a
277+
}
278+
269279
}

compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,22 @@ trait UseAnalyzer extends TypeExpressionAnalyzer {
133133
}
134134
}
135135

136+
override def specTlmPacketAnnotatedNode(
137+
a: Analysis,
138+
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacket]]
139+
) = for {
140+
a <- super.specTlmPacketAnnotatedNode(a, aNode)
141+
a <- visitList(a, aNode._2.data.members, tlmPacketMember)
142+
} yield a
143+
144+
override def specTlmPacketGroupAnnotatedNode(
145+
a: Analysis,
146+
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacketGroup]]
147+
) = for {
148+
a <- super.specTlmPacketGroupAnnotatedNode(a, aNode)
149+
a <- visitList(a, aNode._2.data.omitted, tlmChannelIdentifierNode)
150+
} yield a
151+
136152
override def specTopImportAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.SpecTopImport]]) = {
137153
val (_, node1, _) = node
138154
val data = node1.data
@@ -154,4 +170,17 @@ trait UseAnalyzer extends TypeExpressionAnalyzer {
154170
f(a, qualIdent, use)
155171
}
156172

173+
private def tlmChannelIdentifierNode (
174+
a: Analysis,
175+
node: AstNode[Ast.TlmChannelIdentifier]
176+
): Result =
177+
qualIdentNode (componentInstanceUse) (a, node.data.componentInstance)
178+
179+
private def tlmPacketMember(a: Analysis, member: Ast.TlmPacketMember) =
180+
member match {
181+
case Ast.TlmPacketMember.SpecInclude(node) => Right(a)
182+
case Ast.TlmPacketMember.TlmChannelIdentifier(node) =>
183+
tlmChannelIdentifierNode(a, node)
184+
}
185+
157186
}

compiler/lib/src/main/scala/analysis/CheckSemantics/CheckExprTypes.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,19 @@ object CheckExprTypes extends UseAnalyzer {
296296
yield a
297297
}
298298

299+
override def specTlmPacketAnnotatedNode(
300+
a: Analysis,
301+
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacket]]
302+
) = {
303+
val (_, node, _) = aNode
304+
val data = node.data
305+
for {
306+
a <- super.specTlmPacketAnnotatedNode(a, aNode)
307+
_ <- convertNodeToNumericOpt(a, data.id)
308+
_ <- convertNodeToNumeric(a, data.level)
309+
} yield a
310+
}
311+
299312
override def structTypeMemberAnnotatedNode(
300313
a: Analysis,
301314
aNode: Ast.Annotated[AstNode[Ast.StructTypeMember]]

compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSemantics.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ object CheckSemantics {
3030
_ <- CheckComponentInstanceDefs.checkIdRanges(a)
3131
a <- CheckStateMachineDefs.visitList(a, tul, CheckStateMachineDefs.transUnit)
3232
a <- CheckTopologyDefs.visitList(a, tul, CheckTopologyDefs.transUnit)
33+
a <- ConstructDictionaryMap.visitList(a, tul, ConstructDictionaryMap.transUnit)
3334
a <- BuildSpecLocMap.visitList(a, tul, BuildSpecLocMap.transUnit)
3435
a <- CheckSpecLocs.visitList(a, tul, CheckSpecLocs.transUnit)
3536
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package fpp.compiler.analysis
2+
3+
import fpp.compiler.ast._
4+
import fpp.compiler.util._
5+
6+
/** Construct the dictionary map */
7+
object ConstructDictionaryMap
8+
extends Analyzer
9+
with ModuleAnalyzer
10+
with TopologyAnalyzer
11+
with TlmPacketGroupAnalyzer
12+
{
13+
14+
override def defTopologyAnnotatedNode(
15+
a: Analysis,
16+
aNode: Ast.Annotated[AstNode[Ast.DefTopology]]
17+
) = {
18+
val symbol = Symbol.Topology(aNode)
19+
val t = a.topologyMap(symbol)
20+
val d = {
21+
val d1 = Dictionary()
22+
val d2 = DictionaryUsedSymbols(a, t).updateUsedSymbols(d1)
23+
DictionaryEntries(a, t).updateEntries(d2)
24+
}
25+
val a1 = a.copy(dictionary = Some(d))
26+
for {
27+
a <- super.defTopologyAnnotatedNode(a1, aNode)
28+
}
29+
yield {
30+
val d = a.dictionary.get
31+
a.copy(dictionaryMap = a.dictionaryMap + (symbol -> d))
32+
}
33+
}
34+
35+
override def specTlmPacketGroupAnnotatedNode(
36+
a: Analysis,
37+
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacketGroup]]
38+
) = {
39+
val tpgOpt = Some(TlmPacketGroup(aNode))
40+
val a1 = a.copy(tlmPacketGroup = tpgOpt)
41+
val d = a.dictionary.get
42+
for {
43+
a <- super.specTlmPacketGroupAnnotatedNode(a1, aNode)
44+
tpg <- TlmPacketGroup.complete (
45+
a,
46+
d,
47+
a.topology.get
48+
) (a.tlmPacketGroup.get)
49+
d <- d.addTlmPacketGroup(tpg)
50+
}
51+
yield a.copy(dictionary = Some(d))
52+
}
53+
54+
override def specTlmPacketAnnotatedNode(
55+
a: Analysis,
56+
aNode: Ast.Annotated[AstNode[Ast.SpecTlmPacket]]
57+
) = {
58+
val data = aNode._2.data
59+
for {
60+
idOpt <- a.getNonnegativeBigIntValueOpt(data.id)
61+
packet <- TlmPacket.fromSpecTlmPacket(
62+
a,
63+
a.dictionary.get,
64+
a.topology.get,
65+
aNode
66+
)
67+
g <- a.tlmPacketGroup.get.addPacket(idOpt, packet)
68+
}
69+
yield a.copy(tlmPacketGroup = Some(g))
70+
}
71+
72+
}

compiler/lib/src/main/scala/analysis/Dictionary.scala

Lines changed: 0 additions & 124 deletions
This file was deleted.

0 commit comments

Comments
 (0)