From 43e8dd9ef095911743157e0b35c071939f39ef31 Mon Sep 17 00:00:00 2001
From: jawest
Date: Tue, 15 Apr 2025 13:33:41 -0700
Subject: [PATCH 1/7] Add dictionary mode and implied uses of Fw types
---
.../src/main/scala/analysis/Analysis.scala | 6 +++--
.../analysis/Analyzers/UseAnalyzer.scala | 25 +++++++++++++++++++
.../src/main/scala/fpp-to-dict.scala | 2 +-
docs/fpp-spec.html | 14 ++++++++++-
docs/fpp-users-guide.html | 2 +-
docs/spec/Specifiers/Command-Specifiers.adoc | 2 ++
docs/spec/Specifiers/Event-Specifiers.adoc | 2 ++
.../Telemetry-Channel-Specifiers.adoc | 2 ++
.../Telemetry-Packet-Specifiers.adoc | 2 ++
9 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/compiler/lib/src/main/scala/analysis/Analysis.scala b/compiler/lib/src/main/scala/analysis/Analysis.scala
index ce17e2ed7..d109b1511 100644
--- a/compiler/lib/src/main/scala/analysis/Analysis.scala
+++ b/compiler/lib/src/main/scala/analysis/Analysis.scala
@@ -47,7 +47,7 @@ case class Analysis(
/** The mapping from type and constant symbols, expressions,
* and type names to their types */
typeMap: Map[AstNode.Id, Type] = Map(),
- /** THe mapping from constant symbols and expressions to their values. */
+ /** The mapping from constant symbols and expressions to their values. */
valueMap: Map[AstNode.Id, Value] = Map(),
/** The set of symbols used. Used during code generation. */
usedSymbolSet: Set[Symbol] = Set(),
@@ -70,7 +70,9 @@ case class Analysis(
/** The dictionary under construction */
dictionary: Option[Dictionary] = None,
/** The telemetry packet set under construction */
- tlmPacketSet: Option[TlmPacketSet] = None
+ tlmPacketSet: Option[TlmPacketSet] = None,
+ /** The dictionary generation mode */
+ dictionaryMode: Boolean = false
) {
/** Gets the qualified name of a symbol */
diff --git a/compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala b/compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala
index 8afc23a39..2a5a22b9b 100644
--- a/compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala
+++ b/compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala
@@ -160,6 +160,31 @@ trait UseAnalyzer extends TypeExpressionAnalyzer {
typeUse(a, node, use)
}
+ override def defTopologyAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefTopology]]) = {
+ a.dictionaryMode match {
+ case true => {
+ val impliedTypeUses = List(
+ "FwChanIdType",
+ "FwEventIdType",
+ "FwOpcodeType",
+ "FwPacketDescriptorType",
+ "FwTlmPacketizeIdType"
+ )
+ val (pre, node1, post) = node
+ for {
+ a <- super.defTopologyAnnotatedNode(a, node)
+ a <- Result.foldLeft (impliedTypeUses) (a) ((a, t) => {
+ val ident = Ast.QualIdent.Unqualified(t)
+ val typeNode = AstNode.create(Ast.TypeNameQualIdent(AstNode.create(ident, node1.id)), node1.id)
+ val impliedUse = Name.Qualified.fromQualIdent(ident)
+ typeUse(a, typeNode, impliedUse)
+ })
+ } yield a
+ }
+ case _ => super.defTopologyAnnotatedNode(a, node)
+ }
+ }
+
private def portInstanceIdentifierNode(a: Analysis, node: AstNode[Ast.PortInstanceIdentifier]): Result =
qualIdentNode (componentInstanceUse) (a, node.data.componentInstance)
diff --git a/compiler/tools/fpp-to-dict/src/main/scala/fpp-to-dict.scala b/compiler/tools/fpp-to-dict/src/main/scala/fpp-to-dict.scala
index 06eab9aed..2fe769cd6 100644
--- a/compiler/tools/fpp-to-dict/src/main/scala/fpp-to-dict.scala
+++ b/compiler/tools/fpp-to-dict/src/main/scala/fpp-to-dict.scala
@@ -27,7 +27,7 @@ object FPPToDict {
case Nil => List(File.StdIn)
case list => list
}
- val a = Analysis(inputFileSet = options.files.toSet)
+ val a = Analysis(inputFileSet = options.files.toSet, dictionaryMode = true)
val metadata = DictionaryMetadata(
projectVersion=options.projectVersion,
frameworkVersion=options.frameworkVersion,
diff --git a/docs/fpp-spec.html b/docs/fpp-spec.html
index 18bc973c9..7fabe1eff 100644
--- a/docs/fpp-spec.html
+++ b/docs/fpp-spec.html
@@ -5141,6 +5141,9 @@ 7.1.2. Semantics
This specifier is valid only if the kind of the command is async
.
If no specifier appears, then the default behavior is assert
.
+
+Commands have an implied use of the type FwOpcodeType
.
+
@@ -5767,6 +5770,9 @@ 7.5.2. Semantics
Integer and must evaluate to an integer
in the range [0,231).
+
+Events have an implied use of the type FwEventIdType
.
+
@@ -7145,6 +7151,9 @@ 7.15.2. Semantics
+
+Telemetry Channels have an implied use of the type FwChanIdType
.
+
@@ -7373,6 +7382,9 @@ 7.17.2. Semantics
or through
import.
+
+Telemetry Packets have an implied use of the type FwTlmPacketizeIdType
.
+
@@ -11159,7 +11171,7 @@
diff --git a/docs/fpp-users-guide.html b/docs/fpp-users-guide.html
index 81af9ec8f..a610457e5 100644
--- a/docs/fpp-users-guide.html
+++ b/docs/fpp-users-guide.html
@@ -15166,7 +15166,7 @@ 15.4. S
diff --git a/docs/spec/Specifiers/Command-Specifiers.adoc b/docs/spec/Specifiers/Command-Specifiers.adoc
index ecccb0958..70f839751 100644
--- a/docs/spec/Specifiers/Command-Specifiers.adoc
+++ b/docs/spec/Specifiers/Command-Specifiers.adoc
@@ -64,6 +64,8 @@ when the input full is queue.
This specifier is valid only if the kind of the command is `async`.
If no specifier appears, then the default behavior is `assert`.
+* Commands have an implied use of the type `FwOpcodeType`.
+
==== Examples
[source,fpp]
diff --git a/docs/spec/Specifiers/Event-Specifiers.adoc b/docs/spec/Specifiers/Event-Specifiers.adoc
index 4b252c99c..59fd9bd1c 100644
--- a/docs/spec/Specifiers/Event-Specifiers.adoc
+++ b/docs/spec/Specifiers/Event-Specifiers.adoc
@@ -62,6 +62,8 @@ The type of _e_ must be convertible to
<> and must evaluate to an integer
in the range [0,2^31^).
+* Events have an implied use of the type `FwEventIdType`.
+
==== Examples
[source,fpp]
diff --git a/docs/spec/Specifiers/Telemetry-Channel-Specifiers.adoc b/docs/spec/Specifiers/Telemetry-Channel-Specifiers.adoc
index 540fc09b6..26101ef42 100644
--- a/docs/spec/Specifiers/Telemetry-Channel-Specifiers.adoc
+++ b/docs/spec/Specifiers/Telemetry-Channel-Specifiers.adoc
@@ -88,6 +88,8 @@ limit is applied directly to _v_.
(e.g., it is an array), then the limit is applied recursively to each member
value of _v_.
+. Telemetry Channels have an implied use of the type `FwChanIdType`.
+
==== Examples
[source,fpp]
diff --git a/docs/spec/Specifiers/Telemetry-Packet-Specifiers.adoc b/docs/spec/Specifiers/Telemetry-Packet-Specifiers.adoc
index 79dceb3b4..4f9b60dfa 100644
--- a/docs/spec/Specifiers/Telemetry-Packet-Specifiers.adoc
+++ b/docs/spec/Specifiers/Telemetry-Packet-Specifiers.adoc
@@ -66,6 +66,8 @@ available in the enclosing topology, either through
or through
<>.
+. Telemetry Packets have an implied use of the type `FwTlmPacketizeIdType`.
+
==== Examples
[source,fpp]
From 5f9898129a95b5dc1e5cfbb45f33d2e1f1ae9b57 Mon Sep 17 00:00:00 2001
From: jawest
Date: Tue, 15 Apr 2025 18:13:44 -0700
Subject: [PATCH 2/7] Move Fw uses to CheckUses, added test case
---
.../src/main/scala/analysis/Analysis.scala | 4 +-
.../analysis/Analyzers/UseAnalyzer.scala | 25 ----
.../analysis/CheckSemantics/CheckUses.scala | 25 ++++
.../DictionaryUsedSymbols.scala | 2 +
.../DictionaryJsonEncoder.scala | 2 +-
.../top/BasicDpTopologyDictionary.ref.json | 134 +++++++++++++----
.../top/FirstTopTopologyDictionary.ref.json | 136 ++++++++++++++----
...alifiedCompInstTopologyDictionary.ref.json | 80 +++++++++++
.../top/SecondTopTopologyDictionary.ref.json | 136 ++++++++++++++----
...alifiedCompInstTopologyDictionary.ref.json | 80 +++++++++++
.../tools/fpp-to-dict/test/top/fwTypes.fpp | 5 +
.../test/top/missingFwEventIdType.fpp | 8 ++
.../test/top/missingFwEventIdType.ref.txt | 5 +
.../test/top/missingFwOpcodeType.fpp | 8 ++
.../test/top/missingFwOpcodeType.ref.txt | 5 +
15 files changed, 545 insertions(+), 110 deletions(-)
create mode 100644 compiler/tools/fpp-to-dict/test/top/fwTypes.fpp
create mode 100644 compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.fpp
create mode 100644 compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.ref.txt
create mode 100644 compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.fpp
create mode 100644 compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.ref.txt
diff --git a/compiler/lib/src/main/scala/analysis/Analysis.scala b/compiler/lib/src/main/scala/analysis/Analysis.scala
index d109b1511..7a953025f 100644
--- a/compiler/lib/src/main/scala/analysis/Analysis.scala
+++ b/compiler/lib/src/main/scala/analysis/Analysis.scala
@@ -72,7 +72,9 @@ case class Analysis(
/** The telemetry packet set under construction */
tlmPacketSet: Option[TlmPacketSet] = None,
/** The dictionary generation mode */
- dictionaryMode: Boolean = false
+ dictionaryMode: Boolean = false,
+ /** The set of type symbols used by the dictionary */
+ dictionaryTypeSymbolSet: Set[Symbol] = Set()
) {
/** Gets the qualified name of a symbol */
diff --git a/compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala b/compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala
index 2a5a22b9b..8afc23a39 100644
--- a/compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala
+++ b/compiler/lib/src/main/scala/analysis/Analyzers/UseAnalyzer.scala
@@ -160,31 +160,6 @@ trait UseAnalyzer extends TypeExpressionAnalyzer {
typeUse(a, node, use)
}
- override def defTopologyAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefTopology]]) = {
- a.dictionaryMode match {
- case true => {
- val impliedTypeUses = List(
- "FwChanIdType",
- "FwEventIdType",
- "FwOpcodeType",
- "FwPacketDescriptorType",
- "FwTlmPacketizeIdType"
- )
- val (pre, node1, post) = node
- for {
- a <- super.defTopologyAnnotatedNode(a, node)
- a <- Result.foldLeft (impliedTypeUses) (a) ((a, t) => {
- val ident = Ast.QualIdent.Unqualified(t)
- val typeNode = AstNode.create(Ast.TypeNameQualIdent(AstNode.create(ident, node1.id)), node1.id)
- val impliedUse = Name.Qualified.fromQualIdent(ident)
- typeUse(a, typeNode, impliedUse)
- })
- } yield a
- }
- case _ => super.defTopologyAnnotatedNode(a, node)
- }
- }
-
private def portInstanceIdentifierNode(a: Analysis, node: AstNode[Ast.PortInstanceIdentifier]): Result =
qualIdentNode (componentInstanceUse) (a, node.data.componentInstance)
diff --git a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
index 1449aac50..afa53c5ea 100644
--- a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
+++ b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
@@ -117,6 +117,31 @@ object CheckUses extends UseAnalyzer {
yield a.copy(nestedScope = a.nestedScope.pop)
}
+ override def defTopologyAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefTopology]]) = {
+ a.dictionaryMode match {
+ case true => {
+ val impliedTypeUses = List(
+ "FwChanIdType",
+ "FwEventIdType",
+ "FwOpcodeType",
+ "FwPacketDescriptorType",
+ "FwTlmPacketizeIdType"
+ )
+ val (_, node1, _) = node
+ val mapping = a.nestedScope.get (NameGroup.Type) _
+ for {
+ a <- Result.foldLeft (impliedTypeUses) (a) ((a, t) => {
+ for (symbol <- helpers.getSymbolForName(mapping)(node1.id, t)) yield {
+ a.copy(dictionaryTypeSymbolSet = a.dictionaryTypeSymbolSet + symbol)
+ }
+ })
+ a <- super.defTopologyAnnotatedNode(a, node)
+ } yield a
+ }
+ case false => super.defTopologyAnnotatedNode(a, node)
+ }
+ }
+
override def portUse(a: Analysis, node: AstNode[Ast.QualIdent], use: Name.Qualified) =
helpers.visitQualIdentNode (NameGroup.Port) (a, node)
diff --git a/compiler/lib/src/main/scala/analysis/Semantics/ConstructDictionary/DictionaryUsedSymbols.scala b/compiler/lib/src/main/scala/analysis/Semantics/ConstructDictionary/DictionaryUsedSymbols.scala
index 503583b0b..9bd1aed29 100644
--- a/compiler/lib/src/main/scala/analysis/Semantics/ConstructDictionary/DictionaryUsedSymbols.scala
+++ b/compiler/lib/src/main/scala/analysis/Semantics/ConstructDictionary/DictionaryUsedSymbols.scala
@@ -13,6 +13,7 @@ final case class DictionaryUsedSymbols(a: Analysis, t: Topology) {
private def getUsedSymbolsForInstance(ci: ComponentInstance) = {
val component = ci.component
+ val dictionaryTypeSymbols = a.dictionaryTypeSymbolSet
val commandSymbols = getUsedSymbolsForSpecifier(
component.commandMap,
{
@@ -42,6 +43,7 @@ final case class DictionaryUsedSymbols(a: Analysis, t: Topology) {
container => UsedSymbols.specContainerAnnotatedNode(a, container.aNode)
)
Set.concat(
+ dictionaryTypeSymbols,
commandSymbols,
eventSymbols,
tlmChannelSymbols,
diff --git a/compiler/lib/src/main/scala/codegen/DictionaryJsonWriter/DictionaryJsonEncoder.scala b/compiler/lib/src/main/scala/codegen/DictionaryJsonWriter/DictionaryJsonEncoder.scala
index 4b1714d21..7fa2f98cc 100644
--- a/compiler/lib/src/main/scala/codegen/DictionaryJsonWriter/DictionaryJsonEncoder.scala
+++ b/compiler/lib/src/main/scala/codegen/DictionaryJsonWriter/DictionaryJsonEncoder.scala
@@ -546,7 +546,7 @@ case class DictionaryJsonEncoder(
/** Main interface for the class. JSON Encoding for a complete dictionary */
def dictionaryAsJson: Json = {
- /** Split set into individual sets consisting of each symbol type (arrays, enums, structs) */
+ /** Split set into individual sets consisting of each symbol type (arrays, enums, structs, aliases) */
val typeDefSymbols = splitTypeSymbolSet(dictionary.usedSymbolSet, Set())
/** Convert each dictionary element to JSON and return the complete dictionary JSON */
Json.obj(
diff --git a/compiler/tools/fpp-to-dict/test/top/BasicDpTopologyDictionary.ref.json b/compiler/tools/fpp-to-dict/test/top/BasicDpTopologyDictionary.ref.json
index cc774d537..bede989ff 100644
--- a/compiler/tools/fpp-to-dict/test/top/BasicDpTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/BasicDpTopologyDictionary.ref.json
@@ -8,6 +8,85 @@
"dictionarySpecVersion" : "1.0.0"
},
"typeDefinitions" : [
+ {
+ "kind" : "struct",
+ "qualifiedName" : "FppTest.DpTestComponent.Complex",
+ "members" : {
+ "f1" : {
+ "type" : {
+ "name" : "FppTest.DpTestComponent.Data",
+ "kind" : "qualifiedIdentifier"
+ },
+ "index" : 0,
+ "annotation" : "A struct in the struct"
+ },
+ "f2" : {
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "index" : 1,
+ "annotation" : "A simple U32 field"
+ }
+ },
+ "default" : {
+ "f1" : {
+ "u16Field" : 0
+ },
+ "f2" : 0
+ },
+ "annotation" : "Data for a ComplexRecord"
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwTlmPacketizeIdType",
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwEventIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwPacketDescriptorType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
{
"kind" : "alias",
"qualifiedName" : "FppTest.DpTestComponent.AliasU16",
@@ -44,35 +123,36 @@
"annotation" : "Data for a DataRecord"
},
{
- "kind" : "struct",
- "qualifiedName" : "FppTest.DpTestComponent.Complex",
- "members" : {
- "f1" : {
- "type" : {
- "name" : "FppTest.DpTestComponent.Data",
- "kind" : "qualifiedIdentifier"
- },
- "index" : 0,
- "annotation" : "A struct in the struct"
- },
- "f2" : {
- "type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
- },
- "index" : 1,
- "annotation" : "A simple U32 field"
- }
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
},
- "default" : {
- "f1" : {
- "u16Field" : 0
- },
- "f2" : 0
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwChanIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
},
- "annotation" : "Data for a ComplexRecord"
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
}
],
"commands" : [
diff --git a/compiler/tools/fpp-to-dict/test/top/FirstTopTopologyDictionary.ref.json b/compiler/tools/fpp-to-dict/test/top/FirstTopTopologyDictionary.ref.json
index 95750abff..68c006021 100644
--- a/compiler/tools/fpp-to-dict/test/top/FirstTopTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/FirstTopTopologyDictionary.ref.json
@@ -10,34 +10,6 @@
"dictionarySpecVersion" : "1.0.0"
},
"typeDefinitions" : [
- {
- "kind" : "struct",
- "qualifiedName" : "Module1.S2",
- "members" : {
- "x" : {
- "type" : {
- "name" : "Module1.E2",
- "kind" : "qualifiedIdentifier"
- },
- "index" : 0
- },
- "y" : {
- "type" : {
- "name" : "Module1.EnumArray",
- "kind" : "qualifiedIdentifier"
- },
- "index" : 1
- }
- },
- "default" : {
- "x" : "Module1.E2.PASS",
- "y" : [
- "Module1.E3.YES",
- "Module1.E3.YES",
- "Module1.E3.YES"
- ]
- }
- },
{
"kind" : "enum",
"qualifiedName" : "Module1.E2",
@@ -59,6 +31,22 @@
],
"default" : "Module1.E2.PASS"
},
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwEventIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
{
"kind" : "alias",
"qualifiedName" : "Module1.AliasT1",
@@ -241,6 +229,22 @@
],
"annotation" : "An array of 2 String values"
},
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwPacketDescriptorType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
{
"kind" : "alias",
"qualifiedName" : "Module1.AliasT3",
@@ -320,6 +324,50 @@
],
"annotation" : "An array of 3 enum values"
},
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwTlmPacketizeIdType",
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "struct",
+ "qualifiedName" : "Module1.S2",
+ "members" : {
+ "x" : {
+ "type" : {
+ "name" : "Module1.E2",
+ "kind" : "qualifiedIdentifier"
+ },
+ "index" : 0
+ },
+ "y" : {
+ "type" : {
+ "name" : "Module1.EnumArray",
+ "kind" : "qualifiedIdentifier"
+ },
+ "index" : 1
+ }
+ },
+ "default" : {
+ "x" : "Module1.E2.PASS",
+ "y" : [
+ "Module1.E3.YES",
+ "Module1.E3.YES",
+ "Module1.E3.YES"
+ ]
+ }
+ },
{
"kind" : "array",
"qualifiedName" : "Module1.F64x4",
@@ -354,6 +402,38 @@
4
],
"annotation" : "An array of 4 U32 values"
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwChanIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
}
],
"commands" : [
diff --git a/compiler/tools/fpp-to-dict/test/top/QualifiedCompInstTopologyDictionary.ref.json b/compiler/tools/fpp-to-dict/test/top/QualifiedCompInstTopologyDictionary.ref.json
index 5a44fa428..048db6a09 100644
--- a/compiler/tools/fpp-to-dict/test/top/QualifiedCompInstTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/QualifiedCompInstTopologyDictionary.ref.json
@@ -10,6 +10,22 @@
"dictionarySpecVersion" : "1.0.0"
},
"typeDefinitions" : [
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwTlmPacketizeIdType",
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ }
+ },
{
"kind" : "enum",
"qualifiedName" : "M.E1",
@@ -34,6 +50,70 @@
}
],
"default" : "M.E1.X"
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwEventIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwPacketDescriptorType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwChanIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
}
],
"commands" : [
diff --git a/compiler/tools/fpp-to-dict/test/top/SecondTopTopologyDictionary.ref.json b/compiler/tools/fpp-to-dict/test/top/SecondTopTopologyDictionary.ref.json
index b0cc4451c..c0556d62a 100644
--- a/compiler/tools/fpp-to-dict/test/top/SecondTopTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/SecondTopTopologyDictionary.ref.json
@@ -10,34 +10,6 @@
"dictionarySpecVersion" : "1.0.0"
},
"typeDefinitions" : [
- {
- "kind" : "struct",
- "qualifiedName" : "Module1.S2",
- "members" : {
- "x" : {
- "type" : {
- "name" : "Module1.E2",
- "kind" : "qualifiedIdentifier"
- },
- "index" : 0
- },
- "y" : {
- "type" : {
- "name" : "Module1.EnumArray",
- "kind" : "qualifiedIdentifier"
- },
- "index" : 1
- }
- },
- "default" : {
- "x" : "Module1.E2.PASS",
- "y" : [
- "Module1.E3.YES",
- "Module1.E3.YES",
- "Module1.E3.YES"
- ]
- }
- },
{
"kind" : "enum",
"qualifiedName" : "Module1.E2",
@@ -59,6 +31,22 @@
],
"default" : "Module1.E2.PASS"
},
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwEventIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
{
"kind" : "alias",
"qualifiedName" : "Module1.AliasT1",
@@ -241,6 +229,22 @@
],
"annotation" : "An array of 2 String values"
},
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwPacketDescriptorType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
{
"kind" : "alias",
"qualifiedName" : "Module1.AliasT3",
@@ -320,6 +324,50 @@
],
"annotation" : "An array of 3 enum values"
},
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwTlmPacketizeIdType",
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "struct",
+ "qualifiedName" : "Module1.S2",
+ "members" : {
+ "x" : {
+ "type" : {
+ "name" : "Module1.E2",
+ "kind" : "qualifiedIdentifier"
+ },
+ "index" : 0
+ },
+ "y" : {
+ "type" : {
+ "name" : "Module1.EnumArray",
+ "kind" : "qualifiedIdentifier"
+ },
+ "index" : 1
+ }
+ },
+ "default" : {
+ "x" : "Module1.E2.PASS",
+ "y" : [
+ "Module1.E3.YES",
+ "Module1.E3.YES",
+ "Module1.E3.YES"
+ ]
+ }
+ },
{
"kind" : "array",
"qualifiedName" : "Module1.F64x4",
@@ -354,6 +402,38 @@
4
],
"annotation" : "An array of 4 U32 values"
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwChanIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
}
],
"commands" : [
diff --git a/compiler/tools/fpp-to-dict/test/top/UnqualifiedCompInstTopologyDictionary.ref.json b/compiler/tools/fpp-to-dict/test/top/UnqualifiedCompInstTopologyDictionary.ref.json
index 7703d031f..de571167c 100644
--- a/compiler/tools/fpp-to-dict/test/top/UnqualifiedCompInstTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/UnqualifiedCompInstTopologyDictionary.ref.json
@@ -10,6 +10,22 @@
"dictionarySpecVersion" : "1.0.0"
},
"typeDefinitions" : [
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwTlmPacketizeIdType",
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ }
+ },
{
"kind" : "enum",
"qualifiedName" : "M.E1",
@@ -34,6 +50,70 @@
}
],
"default" : "M.E1.X"
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwEventIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwPacketDescriptorType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwChanIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
}
],
"commands" : [
diff --git a/compiler/tools/fpp-to-dict/test/top/fwTypes.fpp b/compiler/tools/fpp-to-dict/test/top/fwTypes.fpp
new file mode 100644
index 000000000..002e3da89
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/fwTypes.fpp
@@ -0,0 +1,5 @@
+type FwEventIdType = U32
+type FwChanIdType = U32
+type FwOpcodeType = U32
+type FwPacketDescriptorType = U32
+type FwTlmPacketizeIdType = U16
diff --git a/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.fpp b/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.fpp
new file mode 100644
index 000000000..9ff7dce6d
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.fpp
@@ -0,0 +1,8 @@
+type FwPacketDescriptorType = U32
+type FwOpcodeType = U32
+type FwChanIdType = U32
+type FwTlmPacketizeIdType = U16
+
+topology T {
+
+}
diff --git a/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.ref.txt b/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.ref.txt
new file mode 100644
index 000000000..91ad5fc0f
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.ref.txt
@@ -0,0 +1,5 @@
+fpp-to-dict
+[ local path prefix ]/tools/fpp-to-dict/test/top/missingFwEventIdType.fpp:6.1
+topology T {
+^
+error: undefined symbol FwEventIdType
diff --git a/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.fpp b/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.fpp
new file mode 100644
index 000000000..71238a213
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.fpp
@@ -0,0 +1,8 @@
+type FwPacketDescriptorType = U32
+type FwEventIdType = U32
+type FwChanIdType = U32
+type FwTlmPacketizeIdType = U16
+
+topology T {
+
+}
diff --git a/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.ref.txt b/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.ref.txt
new file mode 100644
index 000000000..2d5a38108
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.ref.txt
@@ -0,0 +1,5 @@
+fpp-to-dict
+[ local path prefix ]/tools/fpp-to-dict/test/top/missingFwOpcodeType.fpp:6.1
+topology T {
+^
+error: undefined symbol FwOpcodeType
From 03d05e7a28d3862828459ac0415c43e266f6991c Mon Sep 17 00:00:00 2001
From: jawest
Date: Fri, 25 Apr 2025 09:03:59 -0700
Subject: [PATCH 3/7] Add notes to UndefinedSymbol error, update tests
---
.../analysis/CheckSemantics/CheckUses.scala | 7 +++++--
compiler/lib/src/main/scala/util/Error.scala | 10 ++++++++--
.../test/top/missingFwEventIdType.ref.txt | 1 +
.../test/top/missingFwOpcodeType.ref.txt | 1 +
compiler/tools/fpp-to-dict/test/top/run.sh | 20 +++++++++++++++----
compiler/tools/fpp-to-dict/test/top/tests.sh | 2 ++
.../tools/fpp-to-dict/test/top/update-ref.sh | 12 ++++++++---
7 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
index afa53c5ea..61ed4a47e 100644
--- a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
+++ b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
@@ -131,8 +131,11 @@ object CheckUses extends UseAnalyzer {
val mapping = a.nestedScope.get (NameGroup.Type) _
for {
a <- Result.foldLeft (impliedTypeUses) (a) ((a, t) => {
- for (symbol <- helpers.getSymbolForName(mapping)(node1.id, t)) yield {
- a.copy(dictionaryTypeSymbolSet = a.dictionaryTypeSymbolSet + symbol)
+ helpers.getSymbolForName(mapping)(node1.id, t) match {
+ case Left(e: SemanticError.UndefinedSymbol) =>
+ Left(e.copy(notes=e.notes :+ s"Dictionary requires type ${t} to be defined."))
+ case Left(e) => Left(e)
+ case Right(symbol) => Right(a.copy(dictionaryTypeSymbolSet = a.dictionaryTypeSymbolSet + symbol))
}
})
a <- super.defTopologyAnnotatedNode(a, node)
diff --git a/compiler/lib/src/main/scala/util/Error.scala b/compiler/lib/src/main/scala/util/Error.scala
index bfe731d1a..795816654 100644
--- a/compiler/lib/src/main/scala/util/Error.scala
+++ b/compiler/lib/src/main/scala/util/Error.scala
@@ -20,6 +20,11 @@ sealed trait Error {
System.err.println(prevLoc)
}
+ /** Prints a list of notes */
+ def printNotes(notes: List[String]): Unit = {
+ notes.map(n => System.err.println(s"note: ${n}"))
+ }
+
/*** Print the error */
def print: Unit = {
this match {
@@ -296,8 +301,9 @@ sealed trait Error {
System.err.println("for this component instance:")
System.err.println(instanceLoc)
case SemanticError.TypeMismatch(loc, msg) => Error.print (Some(loc)) (msg)
- case SemanticError.UndefinedSymbol(name, loc) =>
+ case SemanticError.UndefinedSymbol(name, loc, notes) =>
Error.print (Some(loc)) (s"undefined symbol ${name}")
+ printNotes(notes)
case SemanticError.UseDefCycle(loc, msg) => Error.print (Some(loc)) (msg)
case XmlError.ParseError(file, msg) => Error.printXml (file) (msg)
case XmlError.SemanticError(file, msg) => Error.printXml (file) (msg)
@@ -681,7 +687,7 @@ object SemanticError {
/** Type mismatch */
final case class TypeMismatch(loc: Location, msg: String) extends Error
/** Undefined symbol */
- final case class UndefinedSymbol(name: String, loc: Location) extends Error
+ final case class UndefinedSymbol(name: String, loc: Location, notes: List[String]=List()) extends Error
/** Use-def cycle */
final case class UseDefCycle(loc: Location, msg: String) extends Error
}
diff --git a/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.ref.txt b/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.ref.txt
index 91ad5fc0f..48cc5e3d0 100644
--- a/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.ref.txt
+++ b/compiler/tools/fpp-to-dict/test/top/missingFwEventIdType.ref.txt
@@ -3,3 +3,4 @@ fpp-to-dict
topology T {
^
error: undefined symbol FwEventIdType
+note: Dictionary requires type FwEventIdType to be defined.
diff --git a/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.ref.txt b/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.ref.txt
index 2d5a38108..ab0b3ec22 100644
--- a/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.ref.txt
+++ b/compiler/tools/fpp-to-dict/test/top/missingFwOpcodeType.ref.txt
@@ -3,3 +3,4 @@ fpp-to-dict
topology T {
^
error: undefined symbol FwOpcodeType
+note: Dictionary requires type FwOpcodeType to be defined.
diff --git a/compiler/tools/fpp-to-dict/test/top/run.sh b/compiler/tools/fpp-to-dict/test/top/run.sh
index e2e604e00..de67f2a25 100644
--- a/compiler/tools/fpp-to-dict/test/top/run.sh
+++ b/compiler/tools/fpp-to-dict/test/top/run.sh
@@ -1,6 +1,6 @@
multipleTops()
{
- run_test "-i builtin.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" multipleTops && \
+ run_test "-i builtin.fpp,fwTypes.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" multipleTops && \
validate_json_schema FirstTop && \
validate_json_schema SecondTop && \
diff_json FirstTop && \
@@ -9,20 +9,32 @@ multipleTops()
dataProducts()
{
- run_test "-i builtin.fpp -p 1.0.0 -f 3.4.3" dataProducts && \
+ run_test "-i builtin.fpp,fwTypes.fpp -p 1.0.0 -f 3.4.3" dataProducts && \
validate_json_schema BasicDp && \
diff_json BasicDp
}
duplicate()
{
- run_test '' duplicate && \
+ run_test '-i fwTypes.fpp' duplicate && \
compare duplicate
}
+missingFwOpcodeType()
+{
+ run_test '' missingFwOpcodeType && \
+ compare missingFwOpcodeType
+}
+
+missingFwEventType()
+{
+ run_test '' missingFwEventType && \
+ compare missingFwEventType
+}
+
unqualifiedComponentInstances()
{
- run_test "-i builtin.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" unqualifiedComponentInstances && \
+ run_test "-i builtin.fpp,fwTypes.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" unqualifiedComponentInstances && \
validate_json_schema QualifiedCompInst && \
validate_json_schema UnqualifiedCompInst && \
diff_json QualifiedCompInst && \
diff --git a/compiler/tools/fpp-to-dict/test/top/tests.sh b/compiler/tools/fpp-to-dict/test/top/tests.sh
index 347daf0d0..db06efd74 100644
--- a/compiler/tools/fpp-to-dict/test/top/tests.sh
+++ b/compiler/tools/fpp-to-dict/test/top/tests.sh
@@ -2,5 +2,7 @@ tests="
multipleTops
dataProducts
duplicate
+missingFwOpcodeType
+missingFwEventIdType
unqualifiedComponentInstances
"
diff --git a/compiler/tools/fpp-to-dict/test/top/update-ref.sh b/compiler/tools/fpp-to-dict/test/top/update-ref.sh
index 2b091d650..31fa4497e 100644
--- a/compiler/tools/fpp-to-dict/test/top/update-ref.sh
+++ b/compiler/tools/fpp-to-dict/test/top/update-ref.sh
@@ -1,19 +1,25 @@
multipleTops()
{
- update "-i builtin.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" multipleTops
+ update "-i builtin.fpp,fwTypes.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" multipleTops
move_json FirstTop
move_json SecondTop
}
dataProducts()
{
- update "-i builtin.fpp -p 1.0.0 -f 3.4.3" dataProducts
+ update "-i builtin.fpp,fwTypes.fpp -p 1.0.0 -f 3.4.3" dataProducts
move_json BasicDp
}
+
+duplicate()
+{
+ update '-i fwTypes.fpp' duplicate
+}
+
unqualifiedComponentInstances()
{
- update "-i builtin.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" unqualifiedComponentInstances
+ update "-i builtin.fpp,fwTypes.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" unqualifiedComponentInstances
move_json QualifiedCompInst
move_json UnqualifiedCompInst
}
From b3997575b5eb778d619966989fe1be3ab7a4e476 Mon Sep 17 00:00:00 2001
From: jawest
Date: Fri, 25 Apr 2025 12:13:44 -0700
Subject: [PATCH 4/7] Add annotated error
---
.../analysis/CheckSemantics/CheckUses.scala | 2 +-
compiler/lib/src/main/scala/util/Error.scala | 21 +++++++++++--------
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
index 61ed4a47e..08ad44111 100644
--- a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
+++ b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
@@ -133,7 +133,7 @@ object CheckUses extends UseAnalyzer {
a <- Result.foldLeft (impliedTypeUses) (a) ((a, t) => {
helpers.getSymbolForName(mapping)(node1.id, t) match {
case Left(e: SemanticError.UndefinedSymbol) =>
- Left(e.copy(notes=e.notes :+ s"Dictionary requires type ${t} to be defined."))
+ Left(AnnotatedError(e, s"Dictionary requires type ${t} to be defined."))
case Left(e) => Left(e)
case Right(symbol) => Right(a.copy(dictionaryTypeSymbolSet = a.dictionaryTypeSymbolSet + symbol))
}
diff --git a/compiler/lib/src/main/scala/util/Error.scala b/compiler/lib/src/main/scala/util/Error.scala
index 795816654..69819ca45 100644
--- a/compiler/lib/src/main/scala/util/Error.scala
+++ b/compiler/lib/src/main/scala/util/Error.scala
@@ -19,12 +19,7 @@ sealed trait Error {
System.err.println("previous occurrence is here:")
System.err.println(prevLoc)
}
-
- /** Prints a list of notes */
- def printNotes(notes: List[String]): Unit = {
- notes.map(n => System.err.println(s"note: ${n}"))
- }
-
+
/*** Print the error */
def print: Unit = {
this match {
@@ -301,17 +296,25 @@ sealed trait Error {
System.err.println("for this component instance:")
System.err.println(instanceLoc)
case SemanticError.TypeMismatch(loc, msg) => Error.print (Some(loc)) (msg)
- case SemanticError.UndefinedSymbol(name, loc, notes) =>
+ case SemanticError.UndefinedSymbol(name, loc) =>
Error.print (Some(loc)) (s"undefined symbol ${name}")
- printNotes(notes)
case SemanticError.UseDefCycle(loc, msg) => Error.print (Some(loc)) (msg)
case XmlError.ParseError(file, msg) => Error.printXml (file) (msg)
case XmlError.SemanticError(file, msg) => Error.printXml (file) (msg)
+ case e: AnnotatedError => e.print
}
}
}
+/** Annotated error for including additional notes */
+case class AnnotatedError(error: Error, note: String) extends Error {
+ override def print: Unit = {
+ error.print
+ System.err.println(s"note: ${note}")
+ }
+}
+
/** A syntax error */
final case class SyntaxError(loc: Location, msg: String) extends Error
@@ -687,7 +690,7 @@ object SemanticError {
/** Type mismatch */
final case class TypeMismatch(loc: Location, msg: String) extends Error
/** Undefined symbol */
- final case class UndefinedSymbol(name: String, loc: Location, notes: List[String]=List()) extends Error
+ final case class UndefinedSymbol(name: String, loc: Location) extends Error
/** Use-def cycle */
final case class UseDefCycle(loc: Location, msg: String) extends Error
}
From b4db78a46c2f55c7f1f94dff096df9567a20f55c Mon Sep 17 00:00:00 2001
From: jawest
Date: Fri, 25 Apr 2025 14:55:53 -0700
Subject: [PATCH 5/7] Add annotateResult function
---
.../src/main/scala/analysis/CheckSemantics/CheckUses.scala | 7 ++++---
compiler/lib/src/main/scala/util/Result.scala | 7 +++++++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
index 08ad44111..acead005d 100644
--- a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
+++ b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
@@ -131,9 +131,10 @@ object CheckUses extends UseAnalyzer {
val mapping = a.nestedScope.get (NameGroup.Type) _
for {
a <- Result.foldLeft (impliedTypeUses) (a) ((a, t) => {
- helpers.getSymbolForName(mapping)(node1.id, t) match {
- case Left(e: SemanticError.UndefinedSymbol) =>
- Left(AnnotatedError(e, s"Dictionary requires type ${t} to be defined."))
+ Result.annotateResult(
+ helpers.getSymbolForName(mapping)(node1.id, t),
+ s"Dictionary requires type ${t} to be defined."
+ ) match {
case Left(e) => Left(e)
case Right(symbol) => Right(a.copy(dictionaryTypeSymbolSet = a.dictionaryTypeSymbolSet + symbol))
}
diff --git a/compiler/lib/src/main/scala/util/Result.scala b/compiler/lib/src/main/scala/util/Result.scala
index d09605858..80d8991c1 100644
--- a/compiler/lib/src/main/scala/util/Result.scala
+++ b/compiler/lib/src/main/scala/util/Result.scala
@@ -4,6 +4,13 @@ package fpp.compiler.util
object Result {
type Result[T] = Either[Error, T]
+
+ /** Wraps error as an AnnotatedError with note */
+ def annotateResult[A](r: Result[A], note: String): Result[A] =
+ r match {
+ case Right(v) => Right(v)
+ case Left(e: Error) => Left(AnnotatedError(e, note))
+ }
/** Left fold with a function that returns a result */
def foldLeft[A,B]
From 389772f44a0b1b64a5662fd3085b0a670497b2a6 Mon Sep 17 00:00:00 2001
From: jawest
Date: Mon, 28 Apr 2025 15:49:30 -0700
Subject: [PATCH 6/7] Cleanup
---
.../scala/analysis/CheckSemantics/CheckUses.scala | 12 +++++-------
compiler/lib/src/main/scala/util/Error.scala | 12 ++++--------
2 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
index acead005d..663fde717 100644
--- a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
+++ b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckUses.scala
@@ -131,13 +131,11 @@ object CheckUses extends UseAnalyzer {
val mapping = a.nestedScope.get (NameGroup.Type) _
for {
a <- Result.foldLeft (impliedTypeUses) (a) ((a, t) => {
- Result.annotateResult(
- helpers.getSymbolForName(mapping)(node1.id, t),
- s"Dictionary requires type ${t} to be defined."
- ) match {
- case Left(e) => Left(e)
- case Right(symbol) => Right(a.copy(dictionaryTypeSymbolSet = a.dictionaryTypeSymbolSet + symbol))
- }
+ for {
+ symbol <- Result.annotateResult(
+ helpers.getSymbolForName(mapping)(node1.id, t),
+ s"Dictionary requires type ${t} to be defined.")
+ } yield a.copy(dictionaryTypeSymbolSet = a.dictionaryTypeSymbolSet + symbol)
})
a <- super.defTopologyAnnotatedNode(a, node)
} yield a
diff --git a/compiler/lib/src/main/scala/util/Error.scala b/compiler/lib/src/main/scala/util/Error.scala
index 69819ca45..523d005a6 100644
--- a/compiler/lib/src/main/scala/util/Error.scala
+++ b/compiler/lib/src/main/scala/util/Error.scala
@@ -301,20 +301,16 @@ sealed trait Error {
case SemanticError.UseDefCycle(loc, msg) => Error.print (Some(loc)) (msg)
case XmlError.ParseError(file, msg) => Error.printXml (file) (msg)
case XmlError.SemanticError(file, msg) => Error.printXml (file) (msg)
- case e: AnnotatedError => e.print
+ case AnnotatedError(error, note) =>
+ error.print
+ System.err.println(s"note: ${note}")
}
}
}
/** Annotated error for including additional notes */
-case class AnnotatedError(error: Error, note: String) extends Error {
- override def print: Unit = {
- error.print
- System.err.println(s"note: ${note}")
- }
-}
-
+final case class AnnotatedError(error: Error, note: String) extends Error
/** A syntax error */
final case class SyntaxError(loc: Location, msg: String) extends Error
From 8c723a7abcd469ad9a428fb7ef65677ba19d99af Mon Sep 17 00:00:00 2001
From: jawest
Date: Mon, 28 Apr 2025 17:55:46 -0700
Subject: [PATCH 7/7] Update user guide, revert spec change
---
docs/fpp-spec.html | 14 +--------
docs/fpp-users-guide.html | 30 ++++++++++++++++++-
docs/index.html | 9 +++---
docs/spec/Specifiers/Command-Specifiers.adoc | 2 --
docs/spec/Specifiers/Event-Specifiers.adoc | 2 --
.../Telemetry-Channel-Specifiers.adoc | 2 --
.../Telemetry-Packet-Specifiers.adoc | 2 --
.../Analyzing-and-Translating-Models.adoc | 17 +++++++++++
8 files changed, 52 insertions(+), 26 deletions(-)
diff --git a/docs/fpp-spec.html b/docs/fpp-spec.html
index 7fabe1eff..87c884860 100644
--- a/docs/fpp-spec.html
+++ b/docs/fpp-spec.html
@@ -5141,9 +5141,6 @@ 7.1.2. Semantics
This specifier is valid only if the kind of the command is async
.
If no specifier appears, then the default behavior is assert
.
-
-Commands have an implied use of the type FwOpcodeType
.
-
@@ -5770,9 +5767,6 @@ 7.5.2. Semantics
Integer and must evaluate to an integer
in the range [0,231).
-
-Events have an implied use of the type FwEventIdType
.
-
@@ -7151,9 +7145,6 @@ 7.15.2. Semantics
-
-Telemetry Channels have an implied use of the type FwChanIdType
.
-
@@ -7382,9 +7373,6 @@ 7.17.2. Semantics
or through
import.
-
-Telemetry Packets have an implied use of the type FwTlmPacketizeIdType
.
-
@@ -11171,7 +11159,7 @@
diff --git a/docs/fpp-users-guide.html b/docs/fpp-users-guide.html
index a610457e5..e10f9f34f 100644
--- a/docs/fpp-users-guide.html
+++ b/docs/fpp-users-guide.html
@@ -14230,6 +14230,34 @@ 14.8. G
documentation.
+
When generating dictionaries with fpp-to-dict
, the following types must be defined
+in FPP (either in the input model itself or in a dependency file):
+
+
+
+-
+
FwChanIdType
+
+-
+
FwEventIdType
+
+-
+
FwOpcodeType
+
+-
+
FwPacketDescriptorType
+
+-
+
FwTlmPacketizeIdType
+
+
+
+
+
Here is a common use case:
@@ -15166,7 +15194,7 @@
15.4. S
diff --git a/docs/index.html b/docs/index.html
index 11deeafad..a8f6ff460 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -140,7 +140,7 @@
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
-#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
+#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
@@ -162,6 +162,7 @@
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
+body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
@@ -327,7 +328,7 @@
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
-sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
+sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
@@ -463,8 +464,8 @@ F Prime Prime (FPP)