diff --git a/compiler/README.adoc b/compiler/README.adoc
index 294173f5b..9961b04a1 100644
--- a/compiler/README.adoc
+++ b/compiler/README.adoc
@@ -2,8 +2,30 @@
== Requirements
-* A Unix environment, such as Linux, Mac OS, or the Windows Subsystem for Linux.
-* The https://www.scala-sbt.org[Simple Build Tool (sbt)] for Scala.
+. A Unix environment, such as Linux, Mac OS, or the Windows Subsystem for Linux.
+
+. The https://www.scala-sbt.org[Simple Build Tool (sbt)] for Scala.
+
+. Version 11 of the Java Development Kit (JDK).
+If you have a different version of Java installed on your system, then
+you can do the following:
+
+.. Install version 11 of the JDK.
+For example, in MacPorts you can run
++
+[source,bash]
+----
+% sudo port install openjdk11-graalvm
+----
+
+.. Set the environment variable `JAVA_HOME` to the home directory associated
+with the installation.
+For example, on Mac OS:
++
+[source,bash]
+----
+% export JAVA_HOME=/Library/Java/JavaVirtualMachines/openjdk11-graalvm/Contents/Home
+----
== Installing
@@ -117,7 +139,7 @@ For example, on Mac OS:
+
[source,bash]
----
-% export GRAALVM_JAVA_HOME=Library/Java/JavaVirtualMachines/openjdk11-graalvm/Contents/Home
+% export GRAALVM_JAVA_HOME=/Library/Java/JavaVirtualMachines/openjdk11-graalvm/Contents/Home
----
. Run `sudo $GRAALVM_JAVA_HOME/bin/gu install native-image`
diff --git a/compiler/lib/src/main/resources/META-INF/native-image/reflect-config.json b/compiler/lib/src/main/resources/META-INF/native-image/reflect-config.json
index 156622b36..774ceccab 100644
--- a/compiler/lib/src/main/resources/META-INF/native-image/reflect-config.json
+++ b/compiler/lib/src/main/resources/META-INF/native-image/reflect-config.json
@@ -8,6 +8,9 @@
{
"name":"[Lio.circe.Encoder;"
},
+{
+ "name":"[Ljava.io.File;"
+},
{
"name":"[Ljava.lang.String;"
},
@@ -1259,42 +1262,6 @@
"name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1909",
"fields":[{"name":"0bitmap$1769"}]
},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1910",
- "fields":[{"name":"0bitmap$1768"}]
-},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1911",
- "fields":[{"name":"0bitmap$1760"}]
-},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1912",
- "fields":[{"name":"0bitmap$1761"}]
-},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1913",
- "fields":[{"name":"0bitmap$1762"}]
-},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1914",
- "fields":[{"name":"0bitmap$1763"}]
-},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1915",
- "fields":[{"name":"0bitmap$1764"}]
-},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1916",
- "fields":[{"name":"0bitmap$1765"}]
-},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1917",
- "fields":[{"name":"0bitmap$1766"}]
-},
-{
- "name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$1918",
- "fields":[{"name":"0bitmap$1767"}]
-},
{
"name":"fpp.compiler.codegen.AnalysisJsonEncoder$$anon$192",
"fields":[{"name":"0bitmap$183"}]
diff --git a/compiler/lib/src/main/scala/analysis/Analysis.scala b/compiler/lib/src/main/scala/analysis/Analysis.scala
index 23757e4f0..e1af788af 100644
--- a/compiler/lib/src/main/scala/analysis/Analysis.scala
+++ b/compiler/lib/src/main/scala/analysis/Analysis.scala
@@ -22,7 +22,7 @@ case class Analysis(
/** The set of files included when parsing input */
includedFileSet: Set[File] = Set(),
/** A map from pairs (spec loc kind, qualified name) to spec locs. */
- locationSpecifierMap: Map[(Ast.SpecLoc.Kind, Name.Qualified), Ast.SpecLoc] = Map(),
+ locationSpecifierMap: Map[(Ast.SpecLoc.Kind, Name.Qualified), AstNode[Ast.SpecLoc]] = Map(),
/** A list of unqualified names representing the enclosing scope names,
* with the innermost name at the head of the list. For exapmle, inside
* module B where B is inside A and A is at the top level, the module name
@@ -80,7 +80,9 @@ case class Analysis(
/** Whether dictionary generation is required */
dictionaryGeneration: Boolean = false,
/** The mapping from nodes to implied uses */
- impliedUseMap: Map[AstNode.Id, ImpliedUse.Uses] = Map()
+ impliedUseMap: Map[AstNode.Id, ImpliedUse.Uses] = Map(),
+ /** The set of symbols defined with a dictionary specifier */
+ dictionarySymbolSet: Set[Symbol] = Set()
) {
/** Gets the qualified name of a symbol */
@@ -394,6 +396,9 @@ case class Analysis(
s"\n\n${Locations.get(id)}\nbecause this type is not displayable$reason"
}
this.typeMap(id) match {
+ case a: Type.AliasType =>
+ val id = a.node._2.data.typeName.id
+ getElementReason(id)
case a: Type.Array =>
val id = a.node._2.data.eltType.id
getElementReason(id)
diff --git a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckDictionaryDefs.scala b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckDictionaryDefs.scala
new file mode 100644
index 000000000..a4bff03f5
--- /dev/null
+++ b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckDictionaryDefs.scala
@@ -0,0 +1,55 @@
+package fpp.compiler.analysis
+
+import fpp.compiler.ast._
+import fpp.compiler.util._
+
+/** Check dictionary definitions */
+object CheckDictionaryDefs
+ extends Analyzer
+ with ModuleAnalyzer
+{
+
+ def checkConstantDef(a: Analysis, s: Symbol.Constant) =
+ if !s.isDictionaryDef
+ then Right(a)
+ else
+ val id = s.getNodeId
+ val t = a.typeMap(id)
+ def result =
+ val a1 = a.copy(dictionarySymbolSet = a.dictionarySymbolSet + s)
+ Right(a1)
+ def error =
+ val loc = Locations.get(id)
+ val msg = "dictionary constant must have a numeric, Boolean, string, or enum type"
+ Left(SemanticError.InvalidType(loc, msg))
+ t match
+ case _: Type.String | Type.Boolean | _: Type.Enum => result
+ case _ => if t.isNumeric then result else error
+
+ def checkTypeDef(a: Analysis, s: Symbol) =
+ if s.isDictionaryDef
+ then
+ for {
+ _ <- a.checkDisplayableType(
+ s.getNodeId,
+ "dictionary type is not displayable"
+ )
+ } yield a.copy(dictionarySymbolSet = a.dictionarySymbolSet + s)
+ else Right(a)
+
+ override def defAliasTypeAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefAliasType]]) =
+ checkTypeDef(a, Symbol.AliasType(aNode))
+
+ override def defArrayAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefArray]]) =
+ checkTypeDef(a, Symbol.Array(aNode))
+
+ override def defEnumAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefEnum]]) =
+ checkTypeDef(a, Symbol.Enum(aNode))
+
+ override def defStructAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefStruct]]) =
+ checkTypeDef(a, Symbol.Struct(aNode))
+
+ override def defConstantAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefConstant]]) =
+ checkConstantDef(a, Symbol.Constant(aNode))
+
+}
diff --git a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSemantics.scala b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSemantics.scala
index 94809538a..57bdd22f6 100644
--- a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSemantics.scala
+++ b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSemantics.scala
@@ -33,9 +33,10 @@ object CheckSemantics {
_ <- CheckComponentInstanceDefs.checkIdRanges(a)
a <- CheckStateMachineDefs.visitList(a, tul, CheckStateMachineDefs.transUnit)
a <- CheckTopologyDefs.visitList(a, tul, CheckTopologyDefs.transUnit)
- a <- ConstructDictionaryMap.visitList(a, tul, ConstructDictionaryMap.transUnit)
a <- BuildSpecLocMap.visitList(a, tul, BuildSpecLocMap.transUnit)
a <- CheckSpecLocs.visitList(a, tul, CheckSpecLocs.transUnit)
+ a <- CheckDictionaryDefs.visitList(a, tul, CheckDictionaryDefs.transUnit)
+ a <- ConstructDictionaryMap.visitList(a, tul, ConstructDictionaryMap.transUnit)
}
yield a
}
diff --git a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSpecLocs.scala b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSpecLocs.scala
index e0267e3f3..0398386c3 100644
--- a/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSpecLocs.scala
+++ b/compiler/lib/src/main/scala/analysis/CheckSemantics/CheckSpecLocs.scala
@@ -9,58 +9,116 @@ object CheckSpecLocs
with ModuleAnalyzer
{
- override def defAbsTypeAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefAbsType]]) = {
- val (_, node, _) = aNode
- val name = node.data.name
- checkSpecLoc(a, Ast.SpecLoc.Type, name, node)
- }
+ override def defAbsTypeAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefAbsType]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Type, Symbol.AbsType(aNode))
- override def defArrayAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefArray]]) = {
- val (_, node, _) = aNode
- val name = node.data.name
- checkSpecLoc(a, Ast.SpecLoc.Type, name, node)
- }
+ override def defAliasTypeAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefAliasType]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Type, Symbol.AliasType(aNode))
- override def defConstantAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefConstant]]) = {
- val (_, node, _) = aNode
- val name = node.data.name
- checkSpecLoc(a, Ast.SpecLoc.Constant, name, node)
- }
+ override def defArrayAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefArray]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Type, Symbol.Array(aNode))
- override def defEnumAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefEnum]]) = {
- val (_, node, _) = aNode
- val name = node.data.name
- checkSpecLoc(a, Ast.SpecLoc.Type, name, node)
- }
+ override def defComponentAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefComponent]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Component, Symbol.Component(aNode))
- override def defPortAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefPort]]) = {
- val (_, node, _) = aNode
- val name = node.data.name
- checkSpecLoc(a, Ast.SpecLoc.Port, name, node)
- }
+ override def defComponentInstanceAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefComponentInstance]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.ComponentInstance, Symbol.ComponentInstance(aNode))
- override def defStructAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefStruct]]) = {
- val (_, node, _) = aNode
- val name = node.data.name
- checkSpecLoc(a, Ast.SpecLoc.Type, name, node)
- }
+ override def defConstantAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefConstant]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Constant, Symbol.Constant(aNode))
- private def checkSpecLoc[T](
+ override def defEnumAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefEnum]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Type, Symbol.Enum(aNode))
+
+ override def defInterfaceAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefInterface]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Interface, Symbol.Interface(aNode))
+
+ override def defPortAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefPort]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Port, Symbol.Port(aNode))
+
+ override def defStructAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefStruct]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Type, Symbol.Struct(aNode))
+
+ override def defTopologyAnnotatedNode(
+ a: Analysis,
+ aNode: Ast.Annotated[AstNode[Ast.DefTopology]]
+ ) = checkSpecLoc(a, Ast.SpecLoc.Topology, Symbol.Topology(aNode))
+
+ private def checkSpecLoc(
a: Analysis,
kind: Ast.SpecLoc.Kind,
- name: Name.Unqualified,
- node: AstNode[T]
+ symbol: Symbol
+ ) = for {
+ a <- checkPath(a, kind, symbol)
+ a <- checkDictionarySpecifier(a, kind, symbol)
+ } yield a
+
+ private def checkPath[T](
+ a: Analysis,
+ kind: Ast.SpecLoc.Kind,
+ symbol: Symbol
): Result = {
+ val name = symbol.getUnqualifiedName
+ val id = symbol.getNodeId
val qualifiedName = Name.Qualified(a.scopeNameList.reverse, name)
- val actualLoc = Locations.get(node.id).tuLocation
+ val actualLoc = Locations.get(id).tuLocation
a.locationSpecifierMap.get((kind, qualifiedName)) match {
- case Some(specLoc) => {
+ case Some(node) => {
+ val specLoc = node.data
val specifierLoc = Locations.get(specLoc.file.id)
- val specifiedJavaPath = specifierLoc.getRelativePath(specLoc.file.data)
+ val specifiedJavaPath =
+ specifierLoc.getRelativePath(specLoc.file.data)
val specifiedPath = File.Path(specifiedJavaPath).toString
val actualPath = actualLoc.file.toString
if (specifiedPath == actualPath) Right(a)
- else Left(SemanticError.IncorrectSpecLoc(specifierLoc, specifiedPath, actualLoc))
+ else Left(
+ SemanticError.IncorrectLocationPath(
+ specifierLoc,
+ specifiedPath,
+ actualLoc
+ )
+ )
+ }
+ case None => Right(a)
+ }
+ }
+
+ private def checkDictionarySpecifier(
+ a: Analysis,
+ kind: Ast.SpecLoc.Kind,
+ symbol: Symbol
+ ) = {
+ val name = a.getQualifiedName(symbol)
+ val id = symbol.getNodeId
+ val defLoc = Locations.get(id)
+ a.locationSpecifierMap.get((kind, name)) match {
+ case Some(node) => {
+ val specifierLoc = Locations.get(node.id)
+ if symbol.isDictionaryDef == node.data.isDictionaryDef
+ then Right(a)
+ else Left(
+ SemanticError.IncorrectDictionarySpecifier(specifierLoc, defLoc)
+ )
}
case None => Right(a)
}
diff --git a/compiler/lib/src/main/scala/analysis/ComputeDependencies/BuildSpecLocMap.scala b/compiler/lib/src/main/scala/analysis/ComputeDependencies/BuildSpecLocMap.scala
index 3e948d766..8e32cfba4 100644
--- a/compiler/lib/src/main/scala/analysis/ComputeDependencies/BuildSpecLocMap.scala
+++ b/compiler/lib/src/main/scala/analysis/ComputeDependencies/BuildSpecLocMap.scala
@@ -17,14 +17,34 @@ object BuildSpecLocMap extends ModuleAnalyzer {
val key = (spec.kind, qualifiedName)
a.locationSpecifierMap.get(key) match {
case None => {
- val map = a.locationSpecifierMap + (key -> spec)
+ val map = a.locationSpecifierMap + (key -> specNode)
Right(a.copy(locationSpecifierMap = map))
}
- case Some(spec1) =>
- for { _ <- checkPathConsistency(spec, spec1) } yield a
+ case Some(specNode1) =>
+ for {
+ _ <- checkPathConsistency(spec, specNode1.data)
+ _ <- checkDictionarySpecifierConsistency(specNode, specNode1)
+ } yield a
}
}
+ private def checkDictionarySpecifierConsistency(
+ specNode1: AstNode[Ast.SpecLoc],
+ specNode2: AstNode[Ast.SpecLoc]
+ ): Result.Result[Unit] = {
+ val spec1 = specNode1.data
+ val spec2 = specNode2.data
+ if(spec1.isDictionaryDef == spec2.isDictionaryDef) then
+ Right(())
+ else
+ Left(
+ SemanticError.InconsistentDictionarySpecifier(
+ Locations.get(specNode1.id),
+ Locations.get(specNode2.id),
+ )
+ )
+ }
+
private def checkPathConsistency(
spec1: Ast.SpecLoc,
spec2: Ast.SpecLoc
@@ -34,7 +54,7 @@ object BuildSpecLocMap extends ModuleAnalyzer {
if (path1 == path2)
Right(())
else Left(
- SemanticError.InconsistentSpecLoc(
+ SemanticError.InconsistentLocationPath(
Locations.get(spec1.file.id),
path1,
Locations.get(spec2.file.id),
diff --git a/compiler/lib/src/main/scala/analysis/ComputeDependencies/ComputeDependencies.scala b/compiler/lib/src/main/scala/analysis/ComputeDependencies/ComputeDependencies.scala
index 4a763797d..f9cec8992 100644
--- a/compiler/lib/src/main/scala/analysis/ComputeDependencies/ComputeDependencies.scala
+++ b/compiler/lib/src/main/scala/analysis/ComputeDependencies/ComputeDependencies.scala
@@ -23,6 +23,7 @@ object ComputeDependencies {
a <- BuildSpecLocMap.visitList(a, tul, BuildSpecLocMap.transUnit)
a <- ConstructImpliedUseMap.visitList(a, tul, ConstructImpliedUseMap.transUnit)
a <- MapUsesToLocs.visitList(a, tul, MapUsesToLocs.transUnit)
+ a <- Right(addDictionaryDependencies(a))
}
yield {
val includedFileSet = a.includedFileSet
@@ -31,4 +32,16 @@ object ComputeDependencies {
}
}
+ // Adds the dictionary dependencies to the dependency file set
+ private def addDictionaryDependencies(a: Analysis) = {
+ val dfs = a.locationSpecifierMap.foldLeft (a.dependencyFileSet) {
+ case (s, (_, node)) => {
+ if node.data.isDictionaryDef
+ then s + Locations.get(node.data.file.id).file
+ else s
+ }
+ }
+ a.copy(dependencyFileSet = dfs)
+ }
+
}
diff --git a/compiler/lib/src/main/scala/analysis/ComputeDependencies/MapUsesToLocs.scala b/compiler/lib/src/main/scala/analysis/ComputeDependencies/MapUsesToLocs.scala
index d0f59d124..505c63d9e 100644
--- a/compiler/lib/src/main/scala/analysis/ComputeDependencies/MapUsesToLocs.scala
+++ b/compiler/lib/src/main/scala/analysis/ComputeDependencies/MapUsesToLocs.scala
@@ -60,7 +60,7 @@ object MapUsesToLocs extends BasicUseAnalyzer {
nameList match {
case Nil => None
case head :: tail => a.locationSpecifierMap.get((kind, head)) match {
- case specLoc @ Some(_) => specLoc
+ case opt @ Some(_) => opt.map(_.data)
case None => findLocation(tail)
}
}
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 27241591a..ff462d54b 100644
--- a/compiler/lib/src/main/scala/analysis/Semantics/ConstructDictionary/DictionaryUsedSymbols.scala
+++ b/compiler/lib/src/main/scala/analysis/Semantics/ConstructDictionary/DictionaryUsedSymbols.scala
@@ -9,39 +9,47 @@ final case class DictionaryUsedSymbols(a: Analysis, t: Topology) {
d.copy(usedSymbolSet = getUsedSymbolSet)
private def getUsedSymbolSet: Set[Symbol] =
- t.instanceMap.keys.toSet.flatMap(getUsedSymbolsForInstance) ++
- a.getImpliedUses(ImpliedUse.Kind.Type, t.aNode._2.id).map(iu => a.useDefMap(iu.id)) ++
- a.getImpliedUses(ImpliedUse.Kind.Constant, t.aNode._2.id).map(iu => a.useDefMap(iu.id))
+ val kinds = Set(ImpliedUse.Kind.Type, ImpliedUse.Kind.Constant)
+ val impliedUses = kinds.flatMap(
+ k => a.getImpliedUses(k, t.aNode._2.id).map(iu => a.useDefMap(iu.id))
+ )
+ val ss = Set.concat(
+ t.instanceMap.keys.toSet.flatMap(getUsedSymbolsForInstance),
+ impliedUses,
+ a.dictionarySymbolSet
+ )
+ UsedSymbols.resolveUses(a, ss)
private def getUsedSymbolsForInstance(ci: ComponentInstance) = {
val component = ci.component
+ val a1 = a.copy(usedSymbolSet = Set())
val commandSymbols = getUsedSymbolsForSpecifier(
component.commandMap,
{
case Command.NonParam(aNode, _) =>
- UsedSymbols.specCommandAnnotatedNode(a, aNode)
+ UsedSymbols.specCommandAnnotatedNode(a1, aNode)
case _ => Right(a.copy(usedSymbolSet = Set()))
}
)
val eventSymbols = getUsedSymbolsForSpecifier(
component.eventMap,
- event => UsedSymbols.specEventAnnotatedNode(a, event.aNode)
+ event => UsedSymbols.specEventAnnotatedNode(a1, event.aNode)
)
val tlmChannelSymbols = getUsedSymbolsForSpecifier(
component.tlmChannelMap,
- channel => UsedSymbols.specTlmChannelAnnotatedNode(a, channel.aNode)
+ channel => UsedSymbols.specTlmChannelAnnotatedNode(a1, channel.aNode)
)
val paramSymbols = getUsedSymbolsForSpecifier(
component.paramMap,
- param => UsedSymbols.specParamAnnotatedNode(a, param.aNode)
+ param => UsedSymbols.specParamAnnotatedNode(a1, param.aNode)
)
val recordSymbols = getUsedSymbolsForSpecifier(
component.recordMap,
- record => UsedSymbols.specRecordAnnotatedNode(a, record.aNode)
+ record => UsedSymbols.specRecordAnnotatedNode(a1, record.aNode)
)
val containerSymbols = getUsedSymbolsForSpecifier(
component.containerMap,
- container => UsedSymbols.specContainerAnnotatedNode(a, container.aNode)
+ container => UsedSymbols.specContainerAnnotatedNode(a1, container.aNode)
)
Set.concat(
commandSymbols,
@@ -57,11 +65,11 @@ final case class DictionaryUsedSymbols(a: Analysis, t: Topology) {
map: Map[BigInt, Specifier],
usedSymbols: Specifier => Result.Result[Analysis]
): Set[Symbol] =
- map.values.toSet.flatMap {
+ map.values.toSet.flatMap (
specifier => {
val Right(a) = usedSymbols(specifier)
- UsedSymbols.resolveUses(a, a.usedSymbolSet)
+ a.usedSymbolSet
}
- }
+ )
}
diff --git a/compiler/lib/src/main/scala/analysis/Semantics/Symbol.scala b/compiler/lib/src/main/scala/analysis/Semantics/Symbol.scala
index ed01ffe89..e9e88fa0b 100644
--- a/compiler/lib/src/main/scala/analysis/Semantics/Symbol.scala
+++ b/compiler/lib/src/main/scala/analysis/Semantics/Symbol.scala
@@ -4,7 +4,9 @@ import fpp.compiler.ast._
import fpp.compiler.util._
/** A data structure that represents a definition */
-sealed trait Symbol extends SymbolInterface
+sealed trait Symbol extends SymbolInterface {
+ def isDictionaryDef = false
+}
object Symbol {
@@ -13,10 +15,12 @@ object Symbol {
override def getUnqualifiedName = node._2.data.name
}
final case class AliasType(node: Ast.Annotated[AstNode[Ast.DefAliasType]]) extends Symbol {
+ override def isDictionaryDef = node._2.data.isDictionaryDef
override def getNodeId = node._2.id
override def getUnqualifiedName = node._2.data.name
}
final case class Array(node: Ast.Annotated[AstNode[Ast.DefArray]]) extends Symbol {
+ override def isDictionaryDef = node._2.data.isDictionaryDef
override def getNodeId = node._2.id
override def getUnqualifiedName = node._2.data.name
}
@@ -29,10 +33,12 @@ object Symbol {
override def getUnqualifiedName = node._2.data.name
}
final case class Constant(node: Ast.Annotated[AstNode[Ast.DefConstant]]) extends Symbol {
+ override def isDictionaryDef = node._2.data.isDictionaryDef
override def getNodeId = node._2.id
override def getUnqualifiedName = node._2.data.name
}
final case class Enum(node: Ast.Annotated[AstNode[Ast.DefEnum]]) extends Symbol {
+ override def isDictionaryDef = node._2.data.isDictionaryDef
override def getNodeId = node._2.id
override def getUnqualifiedName = node._2.data.name
}
@@ -57,6 +63,7 @@ object Symbol {
override def getUnqualifiedName = node._2.data.name
}
final case class Struct(node: Ast.Annotated[AstNode[Ast.DefStruct]]) extends Symbol {
+ override def isDictionaryDef = node._2.data.isDictionaryDef
override def getNodeId = node._2.id
override def getUnqualifiedName = node._2.data.name
}
diff --git a/compiler/lib/src/main/scala/analysis/Semantics/Type.scala b/compiler/lib/src/main/scala/analysis/Semantics/Type.scala
index 6ceaa4b76..c90c852c9 100644
--- a/compiler/lib/src/main/scala/analysis/Semantics/Type.scala
+++ b/compiler/lib/src/main/scala/analysis/Semantics/Type.scala
@@ -189,7 +189,6 @@ object Type {
case class AliasType(
/** The AST node giving the definition */
node: Ast.Annotated[AstNode[Ast.DefAliasType]],
-
/** Type that this typedef points to */
aliasType: Type
) extends Type {
diff --git a/compiler/lib/src/main/scala/analysis/UsedSymbols.scala b/compiler/lib/src/main/scala/analysis/UsedSymbols.scala
index 58bf4e8e8..d9653852c 100644
--- a/compiler/lib/src/main/scala/analysis/UsedSymbols.scala
+++ b/compiler/lib/src/main/scala/analysis/UsedSymbols.scala
@@ -3,9 +3,38 @@ package fpp.compiler.analysis
import fpp.compiler.ast.*
import fpp.compiler.util.*
-/** Compute used symbols */
+/**
+ * Compute used symbols
+ *
+ * There are two forms of resolution:
+ *
+ * 1. Shallow resolution (don't follow uses from uses). This is used to
+ * generate header files. You get this by calling a visitor method
+ * of UsedSymbols.
+ *
+ * 2. Deep resolution (follow uses from uses). This is used to generate
+ * dictionary symbols. You get this by calling UsedSymbols.resolveUses.
+ */
object UsedSymbols extends UseAnalyzer {
+ // When resolving uses, if the default value of an enum definition is an enum
+ // constant, then don't visit it. In this case the symbol is ignored (for
+ // shallow resolution) or converted to a use of this enum (for deep resolution).
+ // So it adds nothing to the resolution.
+ override def defEnumAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefEnum]]) = {
+ val (_, node1, _) = node
+ val data = node1.data
+ for
+ a <- opt(typeNameNode)(a, data.typeName)
+ a <- visitList(a, data.constants, defEnumConstantAnnotatedNode)
+ a <- node._2.data.default match
+ case Some(en) => a.useDefMap(en.id) match
+ case _: Symbol.EnumConstant => Right(a)
+ case _ => opt(exprNode)(a, data.default)
+ case None => Right(a)
+ yield a
+ }
+
override def componentUse(
a: Analysis,
node: AstNode[Ast.QualIdent],
@@ -47,7 +76,7 @@ object UsedSymbols extends UseAnalyzer {
node: AstNode[Ast.TypeName],
use: Name.Qualified
) = addSymbol(a, node)
-
+
override def portUse(
a: Analysis,
node: AstNode[Ast.QualIdent],
@@ -55,14 +84,30 @@ object UsedSymbols extends UseAnalyzer {
) = addSymbol(a, node)
private def addSymbol[T](a: Analysis, node: AstNode[T]) = {
+ // We could convert enum constant symbols to enum symbols here.
+ // This would convert E.A to a use of E in shallow resolution.
+ // Currently we don't do this, because we convert E.A to a numeric
+ // constant in the generated code, so we don't need the dependency
+ // on E.
val symbol = a.useDefMap(node.id)
Right(a.copy(usedSymbolSet = a.usedSymbolSet + symbol))
}
- /** Resolves used symbols recursively */
+ /** Deep resolution of used symbols
+ * Replaces uses of enum constants with uses of the corresponding enums */
def resolveUses(a: Analysis, ss: Set[Symbol]): Set[Symbol] = {
+ // When resolving uses, convert an enum constant symbol to the corresponding
+ // enum symbol. For example, the use E.A becomes a use of E. This is what
+ // we want, because E provides the definition of E.A.
+ def resolveEnumConstant(s: Symbol) =
+ s match
+ case Symbol.EnumConstant(node) =>
+ val t @ Type.Enum(enumNode, _, _) = a.typeMap(node._2.id)
+ Symbol.Enum(enumNode)
+ case _ => s
+ // Helper function for recursive resolution
val a1: Analysis = a.copy(usedSymbolSet = Set())
- def helper(s: Symbol): Set[Symbol] = {
+ def resolveNode(s: Symbol): Set[Symbol] = {
val Right(a2) = s match {
case Symbol.AbsType(node) => defAbsTypeAnnotatedNode(a1, node)
case Symbol.AliasType(node) => defAliasTypeAnnotatedNode(a1, node)
@@ -79,9 +124,9 @@ object UsedSymbols extends UseAnalyzer {
case Symbol.Struct(node) => defStructAnnotatedNode(a1, node)
case Symbol.Topology(node) => defTopologyAnnotatedNode(a1, node)
}
- a2.usedSymbolSet.flatMap(helper) + s
+ a2.usedSymbolSet.flatMap(resolveNode) + resolveEnumConstant(s)
}
- ss.flatMap(helper)
+ ss.flatMap(resolveNode)
}
}
diff --git a/compiler/lib/src/main/scala/ast/Ast.scala b/compiler/lib/src/main/scala/ast/Ast.scala
index d00814613..e286ef362 100644
--- a/compiler/lib/src/main/scala/ast/Ast.scala
+++ b/compiler/lib/src/main/scala/ast/Ast.scala
@@ -78,7 +78,8 @@ object Ast {
/* Aliased type definition */
final case class DefAliasType(
name: Ident,
- typeName: AstNode[TypeName]
+ typeName: AstNode[TypeName],
+ isDictionaryDef: Boolean
)
/* Array definition */
@@ -87,7 +88,8 @@ object Ast {
size: AstNode[Expr],
eltType: AstNode[TypeName],
default: Option[AstNode[Expr]],
- format: Option[AstNode[String]]
+ format: Option[AstNode[String]],
+ isDictionaryDef: Boolean
)
/** Component definition */
@@ -112,14 +114,19 @@ object Ast {
)
/** Constant definition */
- final case class DefConstant(name: Ident, value: AstNode[Expr])
+ final case class DefConstant(
+ name: Ident,
+ value: AstNode[Expr],
+ isDictionaryDef: Boolean
+)
/** Enum definition */
final case class DefEnum(
name: Ident,
typeName: Option[AstNode[TypeName]],
constants: List[Annotated[AstNode[DefEnumConstant]]],
- default: Option[AstNode[Expr]]
+ default: Option[AstNode[Expr]],
+ isDictionaryDef: Boolean
)
/** Enum constant definition */
@@ -279,7 +286,8 @@ object Ast {
final case class DefStruct(
name: Ident,
members: List[Annotated[AstNode[StructTypeMember]]],
- default: Option[AstNode[Expr]]
+ default: Option[AstNode[Expr]],
+ isDictionaryDef: Boolean
)
/** Expression */
@@ -578,7 +586,8 @@ object Ast {
final case class SpecLoc(
kind: SpecLoc.Kind,
symbol: AstNode[QualIdent],
- file: AstNode[String]
+ file: AstNode[String],
+ isDictionaryDef: Boolean
)
object SpecLoc {
/** Location specifier kind */
diff --git a/compiler/lib/src/main/scala/ast/AstVisitor.scala b/compiler/lib/src/main/scala/ast/AstVisitor.scala
index 057e64a7e..ebd9b54cb 100644
--- a/compiler/lib/src/main/scala/ast/AstVisitor.scala
+++ b/compiler/lib/src/main/scala/ast/AstVisitor.scala
@@ -11,18 +11,16 @@ trait AstVisitor {
def defAbsTypeAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefAbsType]]): Out = default(in)
- def defAliasTypeAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefAliasType]]): Out = default(in)
-
def defActionAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefAction]]): Out = default(in)
+ def defAliasTypeAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefAliasType]]): Out = default(in)
+
def defArrayAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefArray]]): Out = default(in)
def defChoiceAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefChoice]]): Out = default(in)
def defComponentAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefComponent]]): Out = default(in)
- def defInterfaceAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefInterface]]): Out = default(in)
-
def defComponentInstanceAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefComponentInstance]]): Out = default(in)
def defConstantAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefConstant]]): Out = default(in)
@@ -31,6 +29,8 @@ trait AstVisitor {
def defGuardAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefGuard]]): Out = default(in)
+ def defInterfaceAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefInterface]]): Out = default(in)
+
def defModuleAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefModule]]): Out = default(in)
def defPortAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefPort]]): Out = default(in)
diff --git a/compiler/lib/src/main/scala/codegen/AstWriter.scala b/compiler/lib/src/main/scala/codegen/AstWriter.scala
index b33af65f3..8ef2ca16d 100644
--- a/compiler/lib/src/main/scala/codegen/AstWriter.scala
+++ b/compiler/lib/src/main/scala/codegen/AstWriter.scala
@@ -16,7 +16,7 @@ object AstWriter extends AstVisitor with LineUtils {
in: Unit,
aNode: Ast.Annotated[AstNode[Ast.DefAliasType]]): Out = {
val (_, node, _) = aNode
- lines("def alias type") ++ (
+ prefixWithDictionary("def alias type", node.data.isDictionaryDef) ++ (
ident(node.data.name) ++
typeNameNode(node.data.typeName)
).map(indentIn)
@@ -49,7 +49,7 @@ object AstWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines("def array") ++
+ prefixWithDictionary("def array", data.isDictionaryDef) ++
List.concat(
ident(data.name),
addPrefix("size", exprNode) (data.size),
@@ -128,8 +128,10 @@ object AstWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines("def constant") ++
- (ident(data.name) ++ exprNode(data.value)).map(indentIn)
+ prefixWithDictionary("def constant", data.isDictionaryDef) ++ (
+ ident(data.name) ++
+ exprNode(data.value)
+ ).map(indentIn)
}
override def defEnumAnnotatedNode(
@@ -138,7 +140,7 @@ object AstWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines("def enum") ++
+ prefixWithDictionary("def enum", data.isDictionaryDef) ++
List.concat(
ident(data.name),
linesOpt(typeNameNode, data.typeName),
@@ -229,7 +231,7 @@ object AstWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines("def struct") ++
+ prefixWithDictionary("def struct", data.isDictionaryDef) ++
(
ident(data.name) ++
data.members.flatMap(annotateNode(structTypeMember)) ++
@@ -949,4 +951,9 @@ object AstWriter extends AstVisitor with LineUtils {
private def visibility(v: Ast.Visibility) = v.toString
+ private def prefixWithDictionary(s: String, isDictionaryDef: Boolean) =
+ if isDictionaryDef then
+ lines(s"dictionary $s")
+ else
+ lines(s)
}
diff --git a/compiler/lib/src/main/scala/codegen/FppWriter.scala b/compiler/lib/src/main/scala/codegen/FppWriter.scala
index 9c3f924ae..b45f988f7 100644
--- a/compiler/lib/src/main/scala/codegen/FppWriter.scala
+++ b/compiler/lib/src/main/scala/codegen/FppWriter.scala
@@ -124,7 +124,7 @@ object FppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines(s"type ${ident(data.name)} = ").
+ lines(prefixWithDictionary(s"type ${ident(data.name)} = ", data.isDictionaryDef)).
join("") (typeNameNode(data.typeName))
}
@@ -153,7 +153,7 @@ object FppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines(s"array ${ident(data.name)} = [").
+ lines(prefixWithDictionary(s"array ${ident(data.name)} = [", data.isDictionaryDef)).
join ("") (exprNode(data.size)).
join ("] ") (typeNameNode(data.eltType)).
joinOpt (data.default) (" default ") (exprNode).
@@ -223,7 +223,8 @@ object FppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines(s"constant ${ident(data.name)}").join (" = ") (exprNode(data.value))
+ lines(prefixWithDictionary(s"constant ${ident(data.name)}", data.isDictionaryDef)).
+ join (" = ") (exprNode(data.value))
}
override def defEnumAnnotatedNode(
@@ -232,7 +233,7 @@ object FppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines(s"enum ${ident(data.name)}").
+ lines(prefixWithDictionary(s"enum ${ident(data.name)}", data.isDictionaryDef)).
joinOpt (data.typeName) (": ") (typeNameNode).
joinNoIndent (" ") (
addBraces(data.constants.flatMap(annotateNode(defEnumConstant)))
@@ -320,7 +321,7 @@ object FppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- lines(s"struct ${ident(data.name)}").
+ lines(prefixWithDictionary(s"struct ${ident(data.name)}", data.isDictionaryDef)).
joinNoIndent (" ") (
addBraces(data.members.flatMap(annotateNode(structTypeMember)))
).
@@ -537,7 +538,7 @@ object FppWriter extends AstVisitor with LineUtils {
val (_, node, _) = aNode
val data = node.data
val kind = data.kind.toString
- lines(s"locate ${kind}").
+ lines(s"locate ${prefixWithDictionary(kind, data.isDictionaryDef)}").
join (" ") (qualIdent(data.symbol.data)).
join (" at ") (string(data.file.data))
}
@@ -896,4 +897,9 @@ object FppWriter extends AstVisitor with LineUtils {
private def unop(op: Ast.Unop) = op.toString
+ private def prefixWithDictionary(s: String, isDictionaryDef: Boolean) =
+ if isDictionaryDef then
+ s"dictionary $s"
+ else
+ s
}
diff --git a/compiler/lib/src/main/scala/codegen/JsonEncoder/AnalysisJsonEncoder.scala b/compiler/lib/src/main/scala/codegen/JsonEncoder/AnalysisJsonEncoder.scala
index 1928883cb..f3d43aada 100644
--- a/compiler/lib/src/main/scala/codegen/JsonEncoder/AnalysisJsonEncoder.scala
+++ b/compiler/lib/src/main/scala/codegen/JsonEncoder/AnalysisJsonEncoder.scala
@@ -314,7 +314,7 @@ object AnalysisJsonEncoder extends JsonEncoder{
Encoder.instance(_.toList.asJson)
private implicit val locationSpecifierMapEncoder:
- Encoder[Map[(Ast.SpecLoc.Kind, Name.Qualified), Ast.SpecLoc]] =
+ Encoder[Map[(Ast.SpecLoc.Kind, Name.Qualified), AstNode[Ast.SpecLoc]]] =
Encoder.instance(_.toList.asJson)
private implicit val portNumberMapEncoder: Encoder[Map[Connection, Int]] =
@@ -353,7 +353,8 @@ object AnalysisJsonEncoder extends JsonEncoder{
"typeMap" -> a.typeMap.asJson,
"useDefMap" -> a.useDefMap.asJson,
"valueMap" -> a.valueMap.asJson,
- "stateMachineMap" -> a.stateMachineMap.asJson
+ "stateMachineMap" -> a.stateMachineMap.asJson,
+ "dictionarySymbolSet" -> a.dictionarySymbolSet.asJson
)
}
diff --git a/compiler/lib/src/main/scala/codegen/LocateDefsFppWriter.scala b/compiler/lib/src/main/scala/codegen/LocateDefsFppWriter.scala
index 2518e7bc1..bd904cd58 100644
--- a/compiler/lib/src/main/scala/codegen/LocateDefsFppWriter.scala
+++ b/compiler/lib/src/main/scala/codegen/LocateDefsFppWriter.scala
@@ -36,7 +36,7 @@ object LocateDefsFppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- writeSpecLoc(s, Ast.SpecLoc.Type, data.name, node)
+ writeSpecLoc(s, Ast.SpecLoc.Type, data.name, node, data.isDictionaryDef)
}
override def defArrayAnnotatedNode(
@@ -45,7 +45,7 @@ object LocateDefsFppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- writeSpecLoc(s, Ast.SpecLoc.Type, data.name, node)
+ writeSpecLoc(s, Ast.SpecLoc.Type, data.name, node, data.isDictionaryDef)
}
override def defComponentAnnotatedNode(
@@ -92,7 +92,7 @@ object LocateDefsFppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- writeSpecLoc(s, Ast.SpecLoc.Constant, data.name, node)
+ writeSpecLoc(s, Ast.SpecLoc.Constant, data.name, node, data.isDictionaryDef)
}
override def defEnumAnnotatedNode(
@@ -101,7 +101,7 @@ object LocateDefsFppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- writeSpecLoc(s, Ast.SpecLoc.Type, data.name, node)
+ writeSpecLoc(s, Ast.SpecLoc.Type, data.name, node, data.isDictionaryDef)
}
override def defModuleAnnotatedNode(
@@ -129,7 +129,7 @@ object LocateDefsFppWriter extends AstVisitor with LineUtils {
) = {
val (_, node, _) = aNode
val data = node.data
- writeSpecLoc(s, Ast.SpecLoc.Type, data.name, node)
+ writeSpecLoc(s, Ast.SpecLoc.Type, data.name, node, data.isDictionaryDef)
}
override def defTopologyAnnotatedNode(
@@ -148,7 +148,8 @@ object LocateDefsFppWriter extends AstVisitor with LineUtils {
s: State,
kind: Ast.SpecLoc.Kind,
name: String,
- node: AstNode[T]
+ node: AstNode[T],
+ isDictionaryDef: Boolean = false
): Out = {
val loc = Locations.get(node.id).tuLocation
loc.file match {
@@ -162,7 +163,7 @@ object LocateDefsFppWriter extends AstVisitor with LineUtils {
val baseDirPath = java.nio.file.Paths.get(baseDir).toAbsolutePath
val relativePath = baseDirPath.relativize(path)
val fileNode = AstNode.create(relativePath.normalize.toString)
- val specLocNode = AstNode.create(Ast.SpecLoc(kind, qualIdentNode, fileNode))
+ val specLocNode = AstNode.create(Ast.SpecLoc(kind, qualIdentNode, fileNode, isDictionaryDef))
val specLocAnnotatedNode = (Nil, specLocNode, Nil)
FppWriter.specLocAnnotatedNode((), specLocAnnotatedNode)
}
diff --git a/compiler/lib/src/main/scala/codegen/XmlFppWriter/ArrayXmlFppWriter.scala b/compiler/lib/src/main/scala/codegen/XmlFppWriter/ArrayXmlFppWriter.scala
index 37d7e3145..2fe993052 100644
--- a/compiler/lib/src/main/scala/codegen/XmlFppWriter/ArrayXmlFppWriter.scala
+++ b/compiler/lib/src/main/scala/codegen/XmlFppWriter/ArrayXmlFppWriter.scala
@@ -59,7 +59,8 @@ object ArrayXmlFppWriter extends LineUtils {
AstNode.create(Ast.ExprLiteralInt(xmlSize.text)),
AstNode.create(eltType),
fppDefaultsOpt,
- fppFormatOpt.map(AstNode.create(_))
+ fppFormatOpt.map(AstNode.create(_)),
+ false
)
(note ++ comment, node, Nil)
}
diff --git a/compiler/lib/src/main/scala/codegen/XmlFppWriter/EnumXmlFppWriter.scala b/compiler/lib/src/main/scala/codegen/XmlFppWriter/EnumXmlFppWriter.scala
index 7d6be240c..2b0967649 100644
--- a/compiler/lib/src/main/scala/codegen/XmlFppWriter/EnumXmlFppWriter.scala
+++ b/compiler/lib/src/main/scala/codegen/XmlFppWriter/EnumXmlFppWriter.scala
@@ -31,7 +31,7 @@ object EnumXmlFppWriter extends LineUtils {
yield {
val repType = FppBuilder.repType(file)
val default = FppBuilder.default(file)
- Ast.DefEnum(name, repType, constants, default)
+ Ast.DefEnum(name, repType, constants, default, false)
}
def defEnumConstant(
diff --git a/compiler/lib/src/main/scala/codegen/XmlFppWriter/StructXmlFppWriter.scala b/compiler/lib/src/main/scala/codegen/XmlFppWriter/StructXmlFppWriter.scala
index c1a276b56..0849f10b7 100644
--- a/compiler/lib/src/main/scala/codegen/XmlFppWriter/StructXmlFppWriter.scala
+++ b/compiler/lib/src/main/scala/codegen/XmlFppWriter/StructXmlFppWriter.scala
@@ -99,7 +99,7 @@ object StructXmlFppWriter extends LineUtils {
structName <- file.getAttribute(file.elem, "name")
members <- structTypeMemberAnnotatedNodeList(file)
}
- yield (comment, Ast.DefStruct(structName, members, None), Nil)
+ yield (comment, Ast.DefStruct(structName, members, None, false), Nil)
}
diff --git a/compiler/lib/src/main/scala/codegen/XmlFppWriter/XmlFppWriter.scala b/compiler/lib/src/main/scala/codegen/XmlFppWriter/XmlFppWriter.scala
index df5e68028..8ac1beb4d 100644
--- a/compiler/lib/src/main/scala/codegen/XmlFppWriter/XmlFppWriter.scala
+++ b/compiler/lib/src/main/scala/codegen/XmlFppWriter/XmlFppWriter.scala
@@ -370,7 +370,7 @@ object XmlFppWriter extends LineUtils {
name <- file.getAttribute(node, "name")
constants <- defEnumConstantNodeAnnotatedList(file)(node)
}
- yield (Nil, Ast.DefEnum(name, None, constants, None), Nil)
+ yield (Nil, Ast.DefEnum(name, None, constants, None, false), Nil)
/** Translates an enum if present in the node */
def defEnumAnnotatedOpt(file: XmlFppWriter.File)(node: scala.xml.Node):
diff --git a/compiler/lib/src/main/scala/syntax/Lexer.scala b/compiler/lib/src/main/scala/syntax/Lexer.scala
index 2b066a6c3..3dda69324 100644
--- a/compiler/lib/src/main/scala/syntax/Lexer.scala
+++ b/compiler/lib/src/main/scala/syntax/Lexer.scala
@@ -47,6 +47,7 @@ object Lexer {
("cpu", CPU),
("default", DEFAULT),
("diagnostic", DIAGNOSTIC),
+ ("dictionary", DICTIONARY),
("do", DO),
("drop", DROP),
("else", ELSE),
@@ -239,6 +240,7 @@ object Lexer {
case CPU => Token.CPU()
case DEFAULT => Token.DEFAULT()
case DIAGNOSTIC => Token.DIAGNOSTIC()
+ case DICTIONARY => Token.DICTIONARY()
case DO => Token.DO()
case DOT => Token.DOT()
case DROP => Token.DROP()
diff --git a/compiler/lib/src/main/scala/syntax/Parser.scala b/compiler/lib/src/main/scala/syntax/Parser.scala
index 42ac1f8f2..356604370 100644
--- a/compiler/lib/src/main/scala/syntax/Parser.scala
+++ b/compiler/lib/src/main/scala/syntax/Parser.scala
@@ -74,9 +74,10 @@ object Parser extends Parsers {
}
}
- private def defAliasType: Parser[Ast.DefAliasType] = {
- ((typeToken ~> ident) ~ (equals ~> node(typeName))) ^^ {
- case ident ~ typeName => Ast.DefAliasType(ident, typeName)
+ def defAliasType: Parser[Ast.DefAliasType] = {
+ (opt(dictionary) ~ (typeToken ~> ident) ~ (equals ~> node(typeName))) ^^ {
+ case dictionary ~ ident ~ typeName =>
+ Ast.DefAliasType(ident, typeName, dictionary.isDefined)
}
}
@@ -91,12 +92,12 @@ object Parser extends Parsers {
}
def defArray: Parser[Ast.DefArray] = {
- (array ~>! ident <~! equals) ~!
+ opt(dictionary) ~ (array ~>! ident <~! equals) ~!
index ~! node(typeName) ~!
opt(default ~>! exprNode) ~!
opt(format ~>! node(literalString)) ^^ {
- case name ~ size ~ eltType ~ default ~ format =>
- Ast.DefArray(name, size, eltType, default, format)
+ case dictionary ~ name ~ size ~ eltType ~ default ~ format =>
+ Ast.DefArray(name, size, eltType, default, format, dictionary.isDefined)
}
}
@@ -172,8 +173,9 @@ object Parser extends Parsers {
}
def defConstant: Parser[Ast.DefConstant] = {
- (constant ~>! ident) ~! (equals ~>! exprNode) ^^ { case id ~ e =>
- Ast.DefConstant(id, e)
+ opt(dictionary) ~ (constant ~>! ident) ~! (equals ~>! exprNode) ^^ {
+ case dictionary ~ id ~ e =>
+ Ast.DefConstant(id, e, dictionary.isDefined)
}
}
@@ -182,12 +184,12 @@ object Parser extends Parsers {
def constants = annotatedElementSequence(node(defEnumConstant), comma, id)
- (enumeration ~>! ident) ~!
+ opt(dictionary) ~ (enumeration ~>! ident) ~!
opt(colon ~>! node(typeName)) ~!
(lbrace ~>! constants <~! rbrace) ~!
opt(default ~>! exprNode) ^^ {
- case name ~ typeName ~ constants ~ default =>
- Ast.DefEnum(name, typeName, constants, default)
+ case dictionary ~ name ~ typeName ~ constants ~ default =>
+ Ast.DefEnum(name, typeName, constants, default, dictionary.isDefined)
}
}
@@ -241,10 +243,10 @@ object Parser extends Parsers {
def members = annotatedElementSequence(node(structTypeMember), comma, id)
- (struct ~>! ident) ~! (lbrace ~>! members <~! rbrace) ~! opt(
+ opt(dictionary) ~ (struct ~>! ident) ~! (lbrace ~>! members <~! rbrace) ~! opt(
default ~>! exprNode
- ) ^^ { case name ~ members ~ default =>
- Ast.DefStruct(name, members, default)
+ ) ^^ { case dictionary ~ name ~ members ~ default =>
+ Ast.DefStruct(name, members, default, dictionary.isDefined)
}
}
@@ -668,24 +670,33 @@ object Parser extends Parsers {
}
}
- def specLoc: Parser[Ast.SpecLoc] = {
- def kind = {
+ def specLoc: Parser[Ast.SpecLoc] =
+ def maybeDictKind =
+ constant ^^ (_ => Ast.SpecLoc.Constant) |
+ typeToken ^^ (_ => Ast.SpecLoc.Type)
+ def nonDictKind =
component ^^ (_ => Ast.SpecLoc.Component) |
- constant ^^ (_ => Ast.SpecLoc.Constant) |
- instance ^^ (_ => Ast.SpecLoc.ComponentInstance) |
- port ^^ (_ => Ast.SpecLoc.Port) |
- state ~! machine ^^ (_ => Ast.SpecLoc.StateMachine) |
- topology ^^ (_ => Ast.SpecLoc.Topology) |
- typeToken ^^ (_ => Ast.SpecLoc.Type) |
- interface ^^ (_ => Ast.SpecLoc.Interface) |
- failure("location kind expected")
+ instance ^^ (_ => Ast.SpecLoc.ComponentInstance) |
+ port ^^ (_ => Ast.SpecLoc.Port) |
+ state ~! machine ^^ (_ => Ast.SpecLoc.StateMachine) |
+ topology ^^ (_ => Ast.SpecLoc.Topology) |
+ interface ^^ (_ => Ast.SpecLoc.Interface)
+ def maybeDictPair =
+ opt(dictionary) ~ maybeDictKind ^^ {
+ case dictOpt ~ kind => (dictOpt.isDefined, kind)
+ }
+ def nonDictPair =
+ nonDictKind ^^ { case kind => (false, kind) }
+ def isDictAndKind =
+ maybeDictPair |
+ nonDictPair |
+ failure("dictionary specifier or location kind expected")
+ (locate ~>! isDictAndKind) ~! node(qualIdent) ~! (at ~>! node(literalString)) ^^ {
+ case (isDict, kind) ~ symbol ~ file => {
+ Ast.SpecLoc(kind, symbol, file, isDict)
+ }
}
- (locate ~>! kind) ~! node(qualIdent) ~! (at ~>! node(literalString)) ^^ {
- case kind ~ symbol ~ file => Ast.SpecLoc(kind, symbol, file)
- }
- }
-
def specParam: Parser[Ast.SpecParam] = {
opt(external) ~ (param ~>! ident) ~ (colon ~>! node(typeName)) ~!
opt(default ~>! exprNode) ~!
@@ -1111,6 +1122,8 @@ object Parser extends Parsers {
private def diagnostic =
accept("diagnostic", { case t: Token.DIAGNOSTIC => t })
+ private def dictionary = accept("dictionary", { case t: Token.DICTIONARY => t })
+
private def doToken = accept("do", { case t: Token.DO => t })
private def dot = accept(".", { case t: Token.DOT => t })
diff --git a/compiler/lib/src/main/scala/syntax/Token.scala b/compiler/lib/src/main/scala/syntax/Token.scala
index b6d44dd27..1b46e1837 100644
--- a/compiler/lib/src/main/scala/syntax/Token.scala
+++ b/compiler/lib/src/main/scala/syntax/Token.scala
@@ -30,6 +30,7 @@ object Token {
final case class CPU() extends Token
final case class DEFAULT() extends Token
final case class DIAGNOSTIC() extends Token
+ final case class DICTIONARY() extends Token
final case class DO() extends Token
final case class DOT() extends Token
final case class DROP() extends Token
@@ -180,6 +181,7 @@ enum TokenId {
case CPU
case DEFAULT
case DIAGNOSTIC
+ case DICTIONARY
case DO
case DROP
case ELSE
diff --git a/compiler/lib/src/main/scala/util/Error.scala b/compiler/lib/src/main/scala/util/Error.scala
index 0eff45de6..028965d72 100644
--- a/compiler/lib/src/main/scala/util/Error.scala
+++ b/compiler/lib/src/main/scala/util/Error.scala
@@ -146,11 +146,20 @@ sealed trait Error {
System.err.println(matchingLoc)
System.err.println("conflicting connection is here:")
System.err.println(prevLoc)
- case SemanticError.InconsistentSpecLoc(loc, path, prevLoc, prevPath) =>
+ case SemanticError.InconsistentDictionarySpecifier(loc, prevLoc) =>
+ Error.print (Some(loc)) (s"inconsistent location specifier")
+ printPrevLoc(prevLoc)
+ printNote("one specifies dictionary and one does not")
+ case SemanticError.InconsistentLocationPath(loc, path, prevLoc, prevPath) =>
Error.print (Some(loc)) (s"inconsistent location path ${path}")
- System.err.println(prevLoc)
+ printPrevLoc(prevLoc)
System.err.println(s"previous path is ${prevPath}")
- case SemanticError.IncorrectSpecLoc(loc, specifiedPath, actualLoc) =>
+ case SemanticError.IncorrectDictionarySpecifier(loc, defLoc) =>
+ Error.print (Some(loc)) (s"incorrect location specifier")
+ System.err.println(s"actual definition is here:")
+ System.err.println(defLoc)
+ printNote("one specifies dictionary and one does not")
+ case SemanticError.IncorrectLocationPath(loc, specifiedPath, actualLoc) =>
Error.print (Some(loc)) (s"incorrect location path ${specifiedPath}")
System.err.println(s"actual location is ${actualLoc}")
case SemanticError.InvalidArraySize(loc, size) =>
@@ -514,15 +523,25 @@ object SemanticError {
matchingLoc: Location,
prevLoc: Location
) extends Error
+ /** Inconsistent dictionary specifiers in location specifiers */
+ final case class InconsistentDictionarySpecifier(
+ loc: Location,
+ prevLoc: Location,
+ ) extends Error
/** Inconsistent location specifiers */
- final case class InconsistentSpecLoc(
+ final case class InconsistentLocationPath(
loc: Location,
path: String,
prevLoc: Location,
prevPath: String
) extends Error
+ /** Incorrect dictionary specifier in location specifier */
+ final case class IncorrectDictionarySpecifier(
+ loc: Location,
+ defLoc: Location
+ ) extends Error
/** Incorrect location specifiers */
- final case class IncorrectSpecLoc(
+ final case class IncorrectLocationPath(
loc: Location,
specifiedPath: String,
actualLoc: Location
diff --git a/compiler/lib/src/test/scala/semantics/Types.scala b/compiler/lib/src/test/scala/semantics/Types.scala
index cddf5392d..70772e78e 100644
--- a/compiler/lib/src/test/scala/semantics/Types.scala
+++ b/compiler/lib/src/test/scala/semantics/Types.scala
@@ -19,7 +19,7 @@ object Types {
def aliasType(name: Ast.Ident, ty: Type, id: AstNode.Id = 0): AliasType = {
val typeNameNode = AstNode.create(Ast.TypeNameInt(Ast.U32()), id)
- val d = Ast.DefAliasType(name, typeNameNode)
+ val d = Ast.DefAliasType(name, typeNameNode, false)
val anode = annotatedNode(d, id)
AliasType(anode, ty)
}
@@ -27,19 +27,19 @@ object Types {
def array(name: Ast.Ident, anonArray: AnonArray = AnonArray(None, U32), id: AstNode.Id = 0): Array = {
val size = AstNode.create(Ast.ExprLiteralInt("1"))
val eltType = AstNode.create(Ast.TypeNameInt(Ast.U32()))
- val d = Ast.DefArray(name, size, eltType, None, None)
+ val d = Ast.DefArray(name, size, eltType, None, None, false)
val anode = annotatedNode(d, id)
Array(anode, anonArray)
}
def enumeration(name: Ast.Ident, repType: Type.PrimitiveInt = I32, id: AstNode.Id = 0): Enum = {
- val d = Ast.DefEnum(name, None, List(), None)
+ val d = Ast.DefEnum(name, None, List(), None, false)
val anode = annotatedNode(d, id)
Enum(anode, repType)
}
def struct(name: Ast.Ident, anonStruct: AnonStruct = AnonStruct(Map()), id: AstNode.Id = 0): Struct = {
- val d = Ast.DefStruct(name, List(), None)
+ val d = Ast.DefStruct(name, List(), None, false)
val anode = annotatedNode(d, id)
Struct(anode, anonStruct)
}
diff --git a/compiler/lib/src/test/scala/syntax/Parser.scala b/compiler/lib/src/test/scala/syntax/Parser.scala
index cc56243ed..f6cff7f9b 100644
--- a/compiler/lib/src/test/scala/syntax/Parser.scala
+++ b/compiler/lib/src/test/scala/syntax/Parser.scala
@@ -57,6 +57,17 @@ class ParserSpec extends AnyWordSpec {
)
}
+ "def alias type OK" should {
+ parseAllOK(
+ Parser.defAliasType,
+ List(
+ "type a = U32",
+ "type a = F32",
+ "dictionary type a = string"
+ )
+ )
+ }
+
"def array OK" should {
parseAllOK(
Parser.defArray,
@@ -64,6 +75,7 @@ class ParserSpec extends AnyWordSpec {
"array a = [10] U32",
"array a = [10] U32 default 0",
"array a = [10] U32 default 0 format \"{} counts\"",
+ "dictionary array a = [10] U32"
)
)
}
@@ -122,6 +134,7 @@ class ParserSpec extends AnyWordSpec {
Parser.defConstant,
List(
"constant a = 0",
+ "dictionary constant a = 0"
)
)
}
@@ -138,6 +151,7 @@ class ParserSpec extends AnyWordSpec {
@ Pre
Y = 1 @< Post
}""",
+ "dictionary enum E { X = 0 }"
)
)
}
@@ -206,6 +220,7 @@ class ParserSpec extends AnyWordSpec {
@ Pre
y: F32 @< Post
}""",
+ "dictionary struct S { x: [3] U32 }"
)
)
}
@@ -491,6 +506,8 @@ class ParserSpec extends AnyWordSpec {
"locate port a.b at \"c.fpp\"",
"locate topology a.b at \"c.fpp\"",
"locate type a.b at \"c.fpp\"",
+ "locate dictionary type a.b at \"c.fpp\"",
+ "locate dictionary constant a.b at \"c.fpp\"",
)
)
}
diff --git a/compiler/tools/fpp-check/test/array/dictionary_not_displayable.fpp b/compiler/tools/fpp-check/test/array/dictionary_not_displayable.fpp
new file mode 100644
index 000000000..3826e73ef
--- /dev/null
+++ b/compiler/tools/fpp-check/test/array/dictionary_not_displayable.fpp
@@ -0,0 +1,2 @@
+type T
+dictionary array A = [3] T
diff --git a/compiler/tools/fpp-check/test/array/dictionary_not_displayable.ref.txt b/compiler/tools/fpp-check/test/array/dictionary_not_displayable.ref.txt
new file mode 100644
index 000000000..d7971aefe
--- /dev/null
+++ b/compiler/tools/fpp-check/test/array/dictionary_not_displayable.ref.txt
@@ -0,0 +1,15 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/array/dictionary_not_displayable.fpp:2.1
+dictionary array A = [3] T
+^
+error: dictionary type is not displayable
+
+[ local path prefix ]/compiler/tools/fpp-check/test/array/dictionary_not_displayable.fpp:2.26
+dictionary array A = [3] T
+ ^
+because this type is not displayable
+
+[ local path prefix ]/compiler/tools/fpp-check/test/array/dictionary_not_displayable.fpp:1.1
+type T
+^
+Type is defined here
diff --git a/compiler/tools/fpp-check/test/array/dictionary_ok.fpp b/compiler/tools/fpp-check/test/array/dictionary_ok.fpp
new file mode 100644
index 000000000..25a2f05a9
--- /dev/null
+++ b/compiler/tools/fpp-check/test/array/dictionary_ok.fpp
@@ -0,0 +1 @@
+dictionary array A = [3] U32
diff --git a/compiler/tools/fpp-check/test/array/dictionary_ok.ref.txt b/compiler/tools/fpp-check/test/array/dictionary_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/array/tests.sh b/compiler/tools/fpp-check/test/array/tests.sh
index 572f4c371..dcdd8d9ee 100644
--- a/compiler/tools/fpp-check/test/array/tests.sh
+++ b/compiler/tools/fpp-check/test/array/tests.sh
@@ -3,6 +3,8 @@ array_default_error
array_default_ok
array_no_default_ok
default_ok
+dictionary_not_displayable
+dictionary_ok
enum_default_error
enum_default_ok
enum_no_default_ok
diff --git a/compiler/tools/fpp-check/test/constant/dictionary_error.fpp b/compiler/tools/fpp-check/test/constant/dictionary_error.fpp
new file mode 100644
index 000000000..d78f1f949
--- /dev/null
+++ b/compiler/tools/fpp-check/test/constant/dictionary_error.fpp
@@ -0,0 +1 @@
+dictionary constant c = { x = 0, y = 1 }
diff --git a/compiler/tools/fpp-check/test/constant/dictionary_error.ref.txt b/compiler/tools/fpp-check/test/constant/dictionary_error.ref.txt
new file mode 100644
index 000000000..ccdf4ce76
--- /dev/null
+++ b/compiler/tools/fpp-check/test/constant/dictionary_error.ref.txt
@@ -0,0 +1,5 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/constant/dictionary_error.fpp:1.1
+dictionary constant c = { x = 0, y = 1 }
+^
+error: dictionary constant must have a numeric, Boolean, string, or enum type
diff --git a/compiler/tools/fpp-check/test/constant/dictionary_ok.fpp b/compiler/tools/fpp-check/test/constant/dictionary_ok.fpp
new file mode 100644
index 000000000..0ea2f0d3e
--- /dev/null
+++ b/compiler/tools/fpp-check/test/constant/dictionary_ok.fpp
@@ -0,0 +1 @@
+dictionary constant c = 42
diff --git a/compiler/tools/fpp-check/test/constant/dictionary_ok.ref.txt b/compiler/tools/fpp-check/test/constant/dictionary_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/constant/tests.sh b/compiler/tools/fpp-check/test/constant/tests.sh
index f118e3b9e..e0049f47b 100644
--- a/compiler/tools/fpp-check/test/constant/tests.sh
+++ b/compiler/tools/fpp-check/test/constant/tests.sh
@@ -1,6 +1,8 @@
tests="
array_index_negative
array_index_out_of_bounds
+dictionary_error
+dictionary_ok
invalid_array_index_type
invalid_array_type
undef_1
diff --git a/compiler/tools/fpp-check/test/enum/dictionary_ok.fpp b/compiler/tools/fpp-check/test/enum/dictionary_ok.fpp
new file mode 100644
index 000000000..8ee0693dd
--- /dev/null
+++ b/compiler/tools/fpp-check/test/enum/dictionary_ok.fpp
@@ -0,0 +1 @@
+dictionary enum E { A, B }
diff --git a/compiler/tools/fpp-check/test/enum/dictionary_ok.ref.txt b/compiler/tools/fpp-check/test/enum/dictionary_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/enum/tests.sh b/compiler/tools/fpp-check/test/enum/tests.sh
index 493d66f0c..b7fcf864f 100644
--- a/compiler/tools/fpp-check/test/enum/tests.sh
+++ b/compiler/tools/fpp-check/test/enum/tests.sh
@@ -5,6 +5,7 @@ bad_constant
bad_default
bad_rep_type
default_ok
+dictionary_ok
duplicate_value
explicit
implied
diff --git a/compiler/tools/fpp-check/test/spec_loc/abs_type_dictionary_error.fpp b/compiler/tools/fpp-check/test/spec_loc/abs_type_dictionary_error.fpp
new file mode 100644
index 000000000..df7a9e5fe
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/abs_type_dictionary_error.fpp
@@ -0,0 +1,2 @@
+locate dictionary type T at "abs_type_dictionary_error.fpp"
+type T
diff --git a/compiler/tools/fpp-check/test/spec_loc/abs_type_dictionary_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/abs_type_dictionary_error.ref.txt
new file mode 100644
index 000000000..bde6b72b6
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/abs_type_dictionary_error.ref.txt
@@ -0,0 +1,10 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/abs_type_dictionary_error.fpp:1.1
+locate dictionary type T at "abs_type_dictionary_error.fpp"
+^
+error: incorrect location specifier
+actual definition is here:
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/abs_type_dictionary_error.fpp:2.1
+type T
+^
+note: one specifies dictionary and one does not
diff --git a/compiler/tools/fpp-check/test/spec_loc/abs_type_error.fpp b/compiler/tools/fpp-check/test/spec_loc/abs_type_path_error.fpp
similarity index 100%
rename from compiler/tools/fpp-check/test/spec_loc/abs_type_error.fpp
rename to compiler/tools/fpp-check/test/spec_loc/abs_type_path_error.fpp
diff --git a/compiler/tools/fpp-check/test/spec_loc/abs_type_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/abs_type_path_error.ref.txt
similarity index 81%
rename from compiler/tools/fpp-check/test/spec_loc/abs_type_error.ref.txt
rename to compiler/tools/fpp-check/test/spec_loc/abs_type_path_error.ref.txt
index 7c0747b1d..ebb7e73a7 100644
--- a/compiler/tools/fpp-check/test/spec_loc/abs_type_error.ref.txt
+++ b/compiler/tools/fpp-check/test/spec_loc/abs_type_path_error.ref.txt
@@ -1,8 +1,8 @@
fpp-check
-[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/abs_type_error.fpp:1.18
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/abs_type_path_error.fpp:1.18
locate type T at "incorrect.fpp"
^
error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
-actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/abs_type_error.fpp:2.1
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/abs_type_path_error.fpp:2.1
type T
^
diff --git a/compiler/tools/fpp-check/test/spec_loc/alias_type_dictionary_error.fpp b/compiler/tools/fpp-check/test/spec_loc/alias_type_dictionary_error.fpp
new file mode 100644
index 000000000..ae6e5feb1
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/alias_type_dictionary_error.fpp
@@ -0,0 +1,2 @@
+locate type T at "alias_type_dictionary_error.fpp"
+dictionary type T = U32
diff --git a/compiler/tools/fpp-check/test/spec_loc/alias_type_dictionary_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/alias_type_dictionary_error.ref.txt
new file mode 100644
index 000000000..e2945385e
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/alias_type_dictionary_error.ref.txt
@@ -0,0 +1,10 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/alias_type_dictionary_error.fpp:1.1
+locate type T at "alias_type_dictionary_error.fpp"
+^
+error: incorrect location specifier
+actual definition is here:
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/alias_type_dictionary_error.fpp:2.1
+dictionary type T = U32
+^
+note: one specifies dictionary and one does not
diff --git a/compiler/tools/fpp-check/test/spec_loc/alias_type_ok.fpp b/compiler/tools/fpp-check/test/spec_loc/alias_type_ok.fpp
new file mode 100644
index 000000000..4d4964cbc
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/alias_type_ok.fpp
@@ -0,0 +1,2 @@
+locate type T at "alias_type_ok.fpp"
+type T = U32
diff --git a/compiler/tools/fpp-check/test/spec_loc/alias_type_ok.ref.txt b/compiler/tools/fpp-check/test/spec_loc/alias_type_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/spec_loc/alias_type_path_error.fpp b/compiler/tools/fpp-check/test/spec_loc/alias_type_path_error.fpp
new file mode 100644
index 000000000..b069ee476
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/alias_type_path_error.fpp
@@ -0,0 +1,2 @@
+locate type T at "incorrect.fpp"
+type T = U32
diff --git a/compiler/tools/fpp-check/test/spec_loc/alias_type_path_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/alias_type_path_error.ref.txt
new file mode 100644
index 000000000..97b816cc5
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/alias_type_path_error.ref.txt
@@ -0,0 +1,8 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/alias_type_path_error.fpp:1.18
+locate type T at "incorrect.fpp"
+ ^
+error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/alias_type_path_error.fpp:2.1
+type T = U32
+^
diff --git a/compiler/tools/fpp-check/test/spec_loc/array_dictionary_error.fpp b/compiler/tools/fpp-check/test/spec_loc/array_dictionary_error.fpp
new file mode 100644
index 000000000..e0393f557
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/array_dictionary_error.fpp
@@ -0,0 +1,2 @@
+locate dictionary type A at "array_dictionary_error.fpp"
+array A = [3] U32
diff --git a/compiler/tools/fpp-check/test/spec_loc/array_dictionary_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/array_dictionary_error.ref.txt
new file mode 100644
index 000000000..b088850b8
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/array_dictionary_error.ref.txt
@@ -0,0 +1,10 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/array_dictionary_error.fpp:1.1
+locate dictionary type A at "array_dictionary_error.fpp"
+^
+error: incorrect location specifier
+actual definition is here:
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/array_dictionary_error.fpp:2.1
+array A = [3] U32
+^
+note: one specifies dictionary and one does not
diff --git a/compiler/tools/fpp-check/test/spec_loc/array_error.fpp b/compiler/tools/fpp-check/test/spec_loc/array_path_error.fpp
similarity index 100%
rename from compiler/tools/fpp-check/test/spec_loc/array_error.fpp
rename to compiler/tools/fpp-check/test/spec_loc/array_path_error.fpp
diff --git a/compiler/tools/fpp-check/test/spec_loc/array_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/array_path_error.ref.txt
similarity index 83%
rename from compiler/tools/fpp-check/test/spec_loc/array_error.ref.txt
rename to compiler/tools/fpp-check/test/spec_loc/array_path_error.ref.txt
index 002f94367..3e7ab48e1 100644
--- a/compiler/tools/fpp-check/test/spec_loc/array_error.ref.txt
+++ b/compiler/tools/fpp-check/test/spec_loc/array_path_error.ref.txt
@@ -1,8 +1,8 @@
fpp-check
-[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/array_error.fpp:1.18
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/array_path_error.fpp:1.18
locate type A at "incorrect.fpp"
^
error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
-actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/array_error.fpp:2.1
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/array_path_error.fpp:2.1
array A = [3] U32
^
diff --git a/compiler/tools/fpp-check/test/spec_loc/component_instance_ok.fpp b/compiler/tools/fpp-check/test/spec_loc/component_instance_ok.fpp
new file mode 100644
index 000000000..4730fab2d
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/component_instance_ok.fpp
@@ -0,0 +1,7 @@
+locate instance i at "component_instance_ok.fpp"
+
+passive component C {
+
+}
+
+instance i: C base id 0x100
diff --git a/compiler/tools/fpp-check/test/spec_loc/component_instance_ok.ref.txt b/compiler/tools/fpp-check/test/spec_loc/component_instance_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/spec_loc/component_instance_path_error.fpp b/compiler/tools/fpp-check/test/spec_loc/component_instance_path_error.fpp
new file mode 100644
index 000000000..10b33f49c
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/component_instance_path_error.fpp
@@ -0,0 +1,7 @@
+locate instance i at "incorrect.fpp"
+
+passive component C {
+
+}
+
+instance i: C base id 0x100
diff --git a/compiler/tools/fpp-check/test/spec_loc/component_instance_path_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/component_instance_path_error.ref.txt
new file mode 100644
index 000000000..f483eb0a6
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/component_instance_path_error.ref.txt
@@ -0,0 +1,8 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/component_instance_path_error.fpp:1.22
+locate instance i at "incorrect.fpp"
+ ^
+error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/component_instance_path_error.fpp:7.1
+instance i: C base id 0x100
+^
diff --git a/compiler/tools/fpp-check/test/spec_loc/component_ok.fpp b/compiler/tools/fpp-check/test/spec_loc/component_ok.fpp
new file mode 100644
index 000000000..1e2969757
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/component_ok.fpp
@@ -0,0 +1,4 @@
+locate component C at "component_ok.fpp"
+passive component C {
+
+}
diff --git a/compiler/tools/fpp-check/test/spec_loc/component_ok.ref.txt b/compiler/tools/fpp-check/test/spec_loc/component_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/spec_loc/component_path_error.fpp b/compiler/tools/fpp-check/test/spec_loc/component_path_error.fpp
new file mode 100644
index 000000000..ef0bfa7e9
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/component_path_error.fpp
@@ -0,0 +1,4 @@
+locate component C at "incorrect.fpp"
+passive component C {
+
+}
diff --git a/compiler/tools/fpp-check/test/spec_loc/component_path_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/component_path_error.ref.txt
new file mode 100644
index 000000000..fbb9f630a
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/component_path_error.ref.txt
@@ -0,0 +1,8 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/component_path_error.fpp:1.23
+locate component C at "incorrect.fpp"
+ ^
+error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/component_path_error.fpp:2.1
+passive component C {
+^
diff --git a/compiler/tools/fpp-check/test/spec_loc/constant_dictionary_error.fpp b/compiler/tools/fpp-check/test/spec_loc/constant_dictionary_error.fpp
new file mode 100644
index 000000000..44ff37caf
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/constant_dictionary_error.fpp
@@ -0,0 +1,2 @@
+locate constant c at "constant_dictionary_error.fpp"
+dictionary constant c = 0
diff --git a/compiler/tools/fpp-check/test/spec_loc/constant_dictionary_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/constant_dictionary_error.ref.txt
new file mode 100644
index 000000000..c9e85943d
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/constant_dictionary_error.ref.txt
@@ -0,0 +1,10 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/constant_dictionary_error.fpp:1.1
+locate constant c at "constant_dictionary_error.fpp"
+^
+error: incorrect location specifier
+actual definition is here:
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/constant_dictionary_error.fpp:2.1
+dictionary constant c = 0
+^
+note: one specifies dictionary and one does not
diff --git a/compiler/tools/fpp-check/test/spec_loc/constant_error.fpp b/compiler/tools/fpp-check/test/spec_loc/constant_path_error.fpp
similarity index 100%
rename from compiler/tools/fpp-check/test/spec_loc/constant_error.fpp
rename to compiler/tools/fpp-check/test/spec_loc/constant_path_error.fpp
diff --git a/compiler/tools/fpp-check/test/spec_loc/constant_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/constant_path_error.ref.txt
similarity index 82%
rename from compiler/tools/fpp-check/test/spec_loc/constant_error.ref.txt
rename to compiler/tools/fpp-check/test/spec_loc/constant_path_error.ref.txt
index 5ef2bfd2d..ad9da443a 100644
--- a/compiler/tools/fpp-check/test/spec_loc/constant_error.ref.txt
+++ b/compiler/tools/fpp-check/test/spec_loc/constant_path_error.ref.txt
@@ -1,8 +1,8 @@
fpp-check
-[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/constant_error.fpp:1.22
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/constant_path_error.fpp:1.22
locate constant c at "incorrect.fpp"
^
error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
-actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/constant_error.fpp:2.1
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/constant_path_error.fpp:2.1
constant c = 0
^
diff --git a/compiler/tools/fpp-check/test/spec_loc/enum_dictionary_error.fpp b/compiler/tools/fpp-check/test/spec_loc/enum_dictionary_error.fpp
new file mode 100644
index 000000000..1c3f10c7e
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/enum_dictionary_error.fpp
@@ -0,0 +1,2 @@
+locate dictionary type E at "enum_dictionary_error.fpp"
+enum E { X }
diff --git a/compiler/tools/fpp-check/test/spec_loc/enum_dictionary_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/enum_dictionary_error.ref.txt
new file mode 100644
index 000000000..71a653e49
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/enum_dictionary_error.ref.txt
@@ -0,0 +1,10 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/enum_dictionary_error.fpp:1.1
+locate dictionary type E at "enum_dictionary_error.fpp"
+^
+error: incorrect location specifier
+actual definition is here:
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/enum_dictionary_error.fpp:2.1
+enum E { X }
+^
+note: one specifies dictionary and one does not
diff --git a/compiler/tools/fpp-check/test/spec_loc/enum_error.fpp b/compiler/tools/fpp-check/test/spec_loc/enum_path_error.fpp
similarity index 100%
rename from compiler/tools/fpp-check/test/spec_loc/enum_error.fpp
rename to compiler/tools/fpp-check/test/spec_loc/enum_path_error.fpp
diff --git a/compiler/tools/fpp-check/test/spec_loc/enum_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/enum_path_error.ref.txt
similarity index 83%
rename from compiler/tools/fpp-check/test/spec_loc/enum_error.ref.txt
rename to compiler/tools/fpp-check/test/spec_loc/enum_path_error.ref.txt
index be7489ad2..88dd0af30 100644
--- a/compiler/tools/fpp-check/test/spec_loc/enum_error.ref.txt
+++ b/compiler/tools/fpp-check/test/spec_loc/enum_path_error.ref.txt
@@ -1,8 +1,8 @@
fpp-check
-[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/enum_error.fpp:1.18
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/enum_path_error.fpp:1.18
locate type E at "incorrect.fpp"
^
error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
-actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/enum_error.fpp:2.1
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/enum_path_error.fpp:2.1
enum E { X }
^
diff --git a/compiler/tools/fpp-check/test/spec_loc/interface_ok.fpp b/compiler/tools/fpp-check/test/spec_loc/interface_ok.fpp
new file mode 100644
index 000000000..842482dbd
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/interface_ok.fpp
@@ -0,0 +1,5 @@
+locate interface I at "interface_ok.fpp"
+
+interface I {
+
+}
diff --git a/compiler/tools/fpp-check/test/spec_loc/interface_ok.ref.txt b/compiler/tools/fpp-check/test/spec_loc/interface_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/spec_loc/interface_path_error.fpp b/compiler/tools/fpp-check/test/spec_loc/interface_path_error.fpp
new file mode 100644
index 000000000..6df4ebd8d
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/interface_path_error.fpp
@@ -0,0 +1,5 @@
+locate interface I at "incorrect.fpp"
+
+interface I {
+
+}
diff --git a/compiler/tools/fpp-check/test/spec_loc/interface_path_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/interface_path_error.ref.txt
new file mode 100644
index 000000000..8f2b32e13
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/interface_path_error.ref.txt
@@ -0,0 +1,8 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/interface_path_error.fpp:1.23
+locate interface I at "incorrect.fpp"
+ ^
+error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/interface_path_error.fpp:3.1
+interface I {
+^
diff --git a/compiler/tools/fpp-check/test/spec_loc/port_error.fpp b/compiler/tools/fpp-check/test/spec_loc/port_path_error.fpp
similarity index 100%
rename from compiler/tools/fpp-check/test/spec_loc/port_error.fpp
rename to compiler/tools/fpp-check/test/spec_loc/port_path_error.fpp
diff --git a/compiler/tools/fpp-check/test/spec_loc/port_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/port_path_error.ref.txt
similarity index 83%
rename from compiler/tools/fpp-check/test/spec_loc/port_error.ref.txt
rename to compiler/tools/fpp-check/test/spec_loc/port_path_error.ref.txt
index 5c2ab3d85..b73f003e8 100644
--- a/compiler/tools/fpp-check/test/spec_loc/port_error.ref.txt
+++ b/compiler/tools/fpp-check/test/spec_loc/port_path_error.ref.txt
@@ -1,8 +1,8 @@
fpp-check
-[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/port_error.fpp:1.18
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/port_path_error.fpp:1.18
locate port P at "incorrect.fpp"
^
error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
-actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/port_error.fpp:3.1
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/port_path_error.fpp:3.1
port P
^
diff --git a/compiler/tools/fpp-check/test/spec_loc/struct_dictionary_error.fpp b/compiler/tools/fpp-check/test/spec_loc/struct_dictionary_error.fpp
new file mode 100644
index 000000000..cca5ca8fd
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/struct_dictionary_error.fpp
@@ -0,0 +1,3 @@
+locate type S at "struct_dictionary_error.fpp"
+
+dictionary struct S { x: U32 }
diff --git a/compiler/tools/fpp-check/test/spec_loc/struct_dictionary_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/struct_dictionary_error.ref.txt
new file mode 100644
index 000000000..4fc035c3b
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/struct_dictionary_error.ref.txt
@@ -0,0 +1,10 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/struct_dictionary_error.fpp:1.1
+locate type S at "struct_dictionary_error.fpp"
+^
+error: incorrect location specifier
+actual definition is here:
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/struct_dictionary_error.fpp:3.1
+dictionary struct S { x: U32 }
+^
+note: one specifies dictionary and one does not
diff --git a/compiler/tools/fpp-check/test/spec_loc/struct_error.fpp b/compiler/tools/fpp-check/test/spec_loc/struct_path_error.fpp
similarity index 100%
rename from compiler/tools/fpp-check/test/spec_loc/struct_error.fpp
rename to compiler/tools/fpp-check/test/spec_loc/struct_path_error.fpp
diff --git a/compiler/tools/fpp-check/test/spec_loc/struct_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/struct_path_error.ref.txt
similarity index 82%
rename from compiler/tools/fpp-check/test/spec_loc/struct_error.ref.txt
rename to compiler/tools/fpp-check/test/spec_loc/struct_path_error.ref.txt
index 280e52904..7cc73242d 100644
--- a/compiler/tools/fpp-check/test/spec_loc/struct_error.ref.txt
+++ b/compiler/tools/fpp-check/test/spec_loc/struct_path_error.ref.txt
@@ -1,8 +1,8 @@
fpp-check
-[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/struct_error.fpp:1.18
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/struct_path_error.fpp:1.18
locate type S at "incorrect.fpp"
^
error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
-actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/struct_error.fpp:3.1
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/struct_path_error.fpp:3.1
struct S { x: U32 }
^
diff --git a/compiler/tools/fpp-check/test/spec_loc/tests.sh b/compiler/tools/fpp-check/test/spec_loc/tests.sh
index 3df4d6671..8a5a793bc 100644
--- a/compiler/tools/fpp-check/test/spec_loc/tests.sh
+++ b/compiler/tools/fpp-check/test/spec_loc/tests.sh
@@ -1,15 +1,31 @@
tests="
-abs_type_error
+abs_type_dictionary_error
abs_type_ok
-array_error
+abs_type_path_error
+alias_type_dictionary_error
+alias_type_ok
+alias_type_path_error
+array_dictionary_error
array_ok
-constant_error
+array_path_error
+component_instance_ok
+component_instance_path_error
+component_ok
+component_path_error
+constant_dictionary_error
constant_ok
-enum_error
+constant_path_error
+enum_dictionary_error
enum_ok
+enum_path_error
include_ok
-port_error
+interface_ok
+interface_path_error
port_ok
-struct_error
+port_path_error
+struct_dictionary_error
struct_ok
+struct_path_error
+topology_ok
+topology_path_error
"
diff --git a/compiler/tools/fpp-check/test/spec_loc/topology_ok.fpp b/compiler/tools/fpp-check/test/spec_loc/topology_ok.fpp
new file mode 100644
index 000000000..4cf8c04a4
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/topology_ok.fpp
@@ -0,0 +1,5 @@
+locate topology T at "topology_ok.fpp"
+
+topology T {
+
+}
diff --git a/compiler/tools/fpp-check/test/spec_loc/topology_ok.ref.txt b/compiler/tools/fpp-check/test/spec_loc/topology_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/spec_loc/topology_path_error.fpp b/compiler/tools/fpp-check/test/spec_loc/topology_path_error.fpp
new file mode 100644
index 000000000..94696869b
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/topology_path_error.fpp
@@ -0,0 +1,5 @@
+locate topology T at "incorrect.fpp"
+
+topology T {
+
+}
diff --git a/compiler/tools/fpp-check/test/spec_loc/topology_path_error.ref.txt b/compiler/tools/fpp-check/test/spec_loc/topology_path_error.ref.txt
new file mode 100644
index 000000000..b98b4b7bd
--- /dev/null
+++ b/compiler/tools/fpp-check/test/spec_loc/topology_path_error.ref.txt
@@ -0,0 +1,8 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/topology_path_error.fpp:1.22
+locate topology T at "incorrect.fpp"
+ ^
+error: incorrect location path [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/incorrect.fpp
+actual location is [ local path prefix ]/compiler/tools/fpp-check/test/spec_loc/topology_path_error.fpp:3.1
+topology T {
+^
diff --git a/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.fpp b/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.fpp
new file mode 100644
index 000000000..9f4d0b862
--- /dev/null
+++ b/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.fpp
@@ -0,0 +1,2 @@
+type T
+dictionary struct S { x: T }
diff --git a/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.ref.txt b/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.ref.txt
new file mode 100644
index 000000000..d190389a1
--- /dev/null
+++ b/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.ref.txt
@@ -0,0 +1,15 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.fpp:2.1
+dictionary struct S { x: T }
+^
+error: dictionary type is not displayable
+
+[ local path prefix ]/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.fpp:2.26
+dictionary struct S { x: T }
+ ^
+because this type is not displayable
+
+[ local path prefix ]/compiler/tools/fpp-check/test/struct/dictionary_not_displayable.fpp:1.1
+type T
+^
+Type is defined here
diff --git a/compiler/tools/fpp-check/test/struct/dictionary_ok.fpp b/compiler/tools/fpp-check/test/struct/dictionary_ok.fpp
new file mode 100644
index 000000000..c34fbec55
--- /dev/null
+++ b/compiler/tools/fpp-check/test/struct/dictionary_ok.fpp
@@ -0,0 +1 @@
+dictionary struct S { x: U32 }
diff --git a/compiler/tools/fpp-check/test/struct/dictionary_ok.ref.txt b/compiler/tools/fpp-check/test/struct/dictionary_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/struct/tests.sh b/compiler/tools/fpp-check/test/struct/tests.sh
index 83436e7c8..68c65497e 100644
--- a/compiler/tools/fpp-check/test/struct/tests.sh
+++ b/compiler/tools/fpp-check/test/struct/tests.sh
@@ -1,6 +1,8 @@
tests="
default_error
default_ok
+dictionary_not_displayable
+dictionary_ok
duplicate_names
format_alias_not_numeric
format_alias_numeric
diff --git a/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.fpp b/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.fpp
new file mode 100644
index 000000000..6b67de2a1
--- /dev/null
+++ b/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.fpp
@@ -0,0 +1,2 @@
+type T1
+dictionary type T2 = T1
diff --git a/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.ref.txt b/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.ref.txt
new file mode 100644
index 000000000..f56516e7b
--- /dev/null
+++ b/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.ref.txt
@@ -0,0 +1,15 @@
+fpp-check
+[ local path prefix ]/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.fpp:2.1
+dictionary type T2 = T1
+^
+error: dictionary type is not displayable
+
+[ local path prefix ]/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.fpp:2.22
+dictionary type T2 = T1
+ ^
+because this type is not displayable
+
+[ local path prefix ]/compiler/tools/fpp-check/test/type/alias_dictionary_not_displayable.fpp:1.1
+type T1
+^
+Type is defined here
diff --git a/compiler/tools/fpp-check/test/type/alias_dictionary_ok.fpp b/compiler/tools/fpp-check/test/type/alias_dictionary_ok.fpp
new file mode 100644
index 000000000..4da5875bc
--- /dev/null
+++ b/compiler/tools/fpp-check/test/type/alias_dictionary_ok.fpp
@@ -0,0 +1 @@
+dictionary type T = U32
diff --git a/compiler/tools/fpp-check/test/type/alias_dictionary_ok.ref.txt b/compiler/tools/fpp-check/test/type/alias_dictionary_ok.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-check/test/type/tests.sh b/compiler/tools/fpp-check/test/type/tests.sh
index ed22dd524..f6fd06586 100644
--- a/compiler/tools/fpp-check/test/type/tests.sh
+++ b/compiler/tools/fpp-check/test/type/tests.sh
@@ -1,4 +1,6 @@
tests="
+alias_dictionary_not_displayable
+alias_dictionary_ok
alias_type_ok
string_size_negative
string_size_not_numeric
diff --git a/compiler/tools/fpp-depend/test/def_alias.fpp b/compiler/tools/fpp-depend/test/def_alias.fpp
index c543b7362..24dbc9c5c 100644
--- a/compiler/tools/fpp-depend/test/def_alias.fpp
+++ b/compiler/tools/fpp-depend/test/def_alias.fpp
@@ -1,5 +1,8 @@
locate type T at "T.fpp"
locate type C.T at "C.fpp"
+locate dictionary type T2 at "T2.fpp"
+locate type T3 at "T3.fpp"
type A1 = T
type A2 = C.T
+type A3 = T2
diff --git a/compiler/tools/fpp-depend/test/def_alias.ref.txt b/compiler/tools/fpp-depend/test/def_alias.ref.txt
index e4176abdd..69465a08c 100644
--- a/compiler/tools/fpp-depend/test/def_alias.ref.txt
+++ b/compiler/tools/fpp-depend/test/def_alias.ref.txt
@@ -1,2 +1,4 @@
[ local path prefix ]/compiler/tools/fpp-depend/test/C.fpp
[ local path prefix ]/compiler/tools/fpp-depend/test/T.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/T2.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/def_alias.fpp
diff --git a/compiler/tools/fpp-depend/test/def_array.fpp b/compiler/tools/fpp-depend/test/def_array.fpp
index bef66342b..e2b09087d 100644
--- a/compiler/tools/fpp-depend/test/def_array.fpp
+++ b/compiler/tools/fpp-depend/test/def_array.fpp
@@ -1,9 +1,12 @@
locate constant a at "a.fpp"
locate constant b at "b.fpp"
locate constant c at "c.fpp"
+locate dictionary constant d at "d.fpp"
locate type T at "T.fpp"
locate type C.T at "C.fpp"
+locate dictionary type T2 at "T2.fpp"
array A1 = [a] T default b
array A2 = [a] C.T
+dictionary array A3 = [d] T2
diff --git a/compiler/tools/fpp-depend/test/def_array.ref.txt b/compiler/tools/fpp-depend/test/def_array.ref.txt
index a528aa1d8..bf865efb2 100644
--- a/compiler/tools/fpp-depend/test/def_array.ref.txt
+++ b/compiler/tools/fpp-depend/test/def_array.ref.txt
@@ -1,4 +1,7 @@
[ local path prefix ]/compiler/tools/fpp-depend/test/C.fpp
[ local path prefix ]/compiler/tools/fpp-depend/test/T.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/T2.fpp
[ local path prefix ]/compiler/tools/fpp-depend/test/a.fpp
[ local path prefix ]/compiler/tools/fpp-depend/test/b.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/d.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/def_array.fpp
diff --git a/compiler/tools/fpp-depend/test/def_constant.fpp b/compiler/tools/fpp-depend/test/def_constant.fpp
index b403302cf..d601f1fee 100644
--- a/compiler/tools/fpp-depend/test/def_constant.fpp
+++ b/compiler/tools/fpp-depend/test/def_constant.fpp
@@ -1,3 +1,6 @@
locate constant a at "a.fpp"
+locate dictionary constant c at "c.fpp"
+locate constant e at "e.fpp"
constant b = a
+constant d = c
diff --git a/compiler/tools/fpp-depend/test/def_constant.ref.txt b/compiler/tools/fpp-depend/test/def_constant.ref.txt
index 699b4f65d..8ed50de21 100644
--- a/compiler/tools/fpp-depend/test/def_constant.ref.txt
+++ b/compiler/tools/fpp-depend/test/def_constant.ref.txt
@@ -1 +1,3 @@
[ local path prefix ]/compiler/tools/fpp-depend/test/a.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/c.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/def_constant.fpp
diff --git a/compiler/tools/fpp-depend/test/def_enum.fpp b/compiler/tools/fpp-depend/test/def_enum.fpp
index d11b726a0..7ddd782ba 100644
--- a/compiler/tools/fpp-depend/test/def_enum.fpp
+++ b/compiler/tools/fpp-depend/test/def_enum.fpp
@@ -1,4 +1,7 @@
locate type T at "T.fpp"
locate constant a at "a.fpp"
+locate dictionary type T2 at "T2.fpp"
+locate constant b at "b.fpp"
enum E : T { x = a }
+dictionary enum E2 : T2 { x = a }
diff --git a/compiler/tools/fpp-depend/test/def_enum.ref.txt b/compiler/tools/fpp-depend/test/def_enum.ref.txt
index a37d8451a..090044fdf 100644
--- a/compiler/tools/fpp-depend/test/def_enum.ref.txt
+++ b/compiler/tools/fpp-depend/test/def_enum.ref.txt
@@ -1,2 +1,4 @@
[ local path prefix ]/compiler/tools/fpp-depend/test/T.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/T2.fpp
[ local path prefix ]/compiler/tools/fpp-depend/test/a.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/def_enum.fpp
diff --git a/compiler/tools/fpp-depend/test/def_struct.fpp b/compiler/tools/fpp-depend/test/def_struct.fpp
index c350ac10d..af2f2c79e 100644
--- a/compiler/tools/fpp-depend/test/def_struct.fpp
+++ b/compiler/tools/fpp-depend/test/def_struct.fpp
@@ -1,4 +1,7 @@
locate type T at "T.fpp"
locate constant a at "a.fpp"
+locate dictionary type T2 at "T2.fpp"
+locate constant b at "b.fpp"
struct S { x: T } default a
+dictionary struct S2 { x: T2 } default a
diff --git a/compiler/tools/fpp-depend/test/def_struct.ref.txt b/compiler/tools/fpp-depend/test/def_struct.ref.txt
index a37d8451a..8f502f7c5 100644
--- a/compiler/tools/fpp-depend/test/def_struct.ref.txt
+++ b/compiler/tools/fpp-depend/test/def_struct.ref.txt
@@ -1,2 +1,4 @@
[ local path prefix ]/compiler/tools/fpp-depend/test/T.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/T2.fpp
[ local path prefix ]/compiler/tools/fpp-depend/test/a.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/def_struct.fpp
diff --git a/compiler/tools/fpp-depend/test/enum_constant.fpp b/compiler/tools/fpp-depend/test/enum_constant.fpp
index 61e69b1ac..6a7dfcf8c 100644
--- a/compiler/tools/fpp-depend/test/enum_constant.fpp
+++ b/compiler/tools/fpp-depend/test/enum_constant.fpp
@@ -1,3 +1,5 @@
locate type E at "E.fpp"
+locate dictionary type E2 at "E2.fpp"
constant c = E.X
+dictionary constant c = E2.Y
diff --git a/compiler/tools/fpp-depend/test/enum_constant.ref.txt b/compiler/tools/fpp-depend/test/enum_constant.ref.txt
index 7d65fb5f3..0f904ede6 100644
--- a/compiler/tools/fpp-depend/test/enum_constant.ref.txt
+++ b/compiler/tools/fpp-depend/test/enum_constant.ref.txt
@@ -1 +1,3 @@
[ local path prefix ]/compiler/tools/fpp-depend/test/E.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/E2.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/enum_constant.fpp
diff --git a/compiler/tools/fpp-depend/test/locate_constant_inconsistent.ref.txt b/compiler/tools/fpp-depend/test/locate_constant_inconsistent.ref.txt
index a975fb52f..6330d5484 100644
--- a/compiler/tools/fpp-depend/test/locate_constant_inconsistent.ref.txt
+++ b/compiler/tools/fpp-depend/test/locate_constant_inconsistent.ref.txt
@@ -3,6 +3,7 @@ fpp-depend
locate constant c at "b.fpp"
^
error: inconsistent location path [ local path prefix ]/compiler/tools/fpp-depend/test/b.fpp
+previous occurrence is here:
[ local path prefix ]/compiler/tools/fpp-depend/test/locate_constant_inconsistent.fpp:1.22
locate constant c at "a.fpp"
^
diff --git a/compiler/tools/fpp-depend/test/locate_constant_modules_1.fpp b/compiler/tools/fpp-depend/test/locate_constant_modules_1.fpp
index 7fd0b7131..4b82887ed 100644
--- a/compiler/tools/fpp-depend/test/locate_constant_modules_1.fpp
+++ b/compiler/tools/fpp-depend/test/locate_constant_modules_1.fpp
@@ -1,10 +1,12 @@
locate constant M.N.c at "c.fpp"
+locate dictionary constant M.N.c2 at "c2.fpp"
module M {
module N {
constant x = c
+ dictionary constant x2 = c2
}
diff --git a/compiler/tools/fpp-depend/test/locate_constant_modules_1.ref.txt b/compiler/tools/fpp-depend/test/locate_constant_modules_1.ref.txt
index d74fc6f6b..a54d82932 100644
--- a/compiler/tools/fpp-depend/test/locate_constant_modules_1.ref.txt
+++ b/compiler/tools/fpp-depend/test/locate_constant_modules_1.ref.txt
@@ -1 +1,3 @@
[ local path prefix ]/compiler/tools/fpp-depend/test/c.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/c2.fpp
+[ local path prefix ]/compiler/tools/fpp-depend/test/locate_constant_modules_1.fpp
diff --git a/compiler/tools/fpp-format/test/dictionary_specifier.ref.txt b/compiler/tools/fpp-format/test/dictionary_specifier.ref.txt
new file mode 100644
index 000000000..c1e224811
--- /dev/null
+++ b/compiler/tools/fpp-format/test/dictionary_specifier.ref.txt
@@ -0,0 +1,17 @@
+dictionary type T = U32
+
+dictionary array A = [2] F32
+
+dictionary struct S {
+ x: [3] U32
+ y: F32
+ z: string
+}
+
+dictionary enum E {
+ X
+ Y
+ Z
+} default X
+
+dictionary constant C = 1
diff --git a/compiler/tools/fpp-format/test/run b/compiler/tools/fpp-format/test/run
index 66a5ee706..19a34bf37 100755
--- a/compiler/tools/fpp-format/test/run
+++ b/compiler/tools/fpp-format/test/run
@@ -62,4 +62,11 @@ state_machine()
$fpp_syntax state_machine.out.txt
}
+
+dictionary_specifier()
+{
+ run_test '' ../../fpp-syntax/test/dictionary-specifier dictionary_specifier && \
+ $fpp_syntax dictionary_specifier.out.txt
+}
+
run_suite $tests
diff --git a/compiler/tools/fpp-format/test/tests.sh b/compiler/tools/fpp-format/test/tests.sh
index ca25f6c37..f2df8859d 100644
--- a/compiler/tools/fpp-format/test/tests.sh
+++ b/compiler/tools/fpp-format/test/tests.sh
@@ -7,4 +7,5 @@ interface
kwd_names
no_include
state_machine
+dictionary_specifier
"
diff --git a/compiler/tools/fpp-format/test/update-ref b/compiler/tools/fpp-format/test/update-ref
index 0b185dd44..a9f64f56b 100755
--- a/compiler/tools/fpp-format/test/update-ref
+++ b/compiler/tools/fpp-format/test/update-ref
@@ -60,6 +60,11 @@ state_machine()
update '' ../../fpp-syntax/test/state-machine state_machine
}
+dictionary_specifier()
+{
+ update '' ../../fpp-syntax/test/dictionary-specifier dictionary_specifier
+}
+
for t in $tests
do
echo "updating ref output for $t"
diff --git a/compiler/tools/fpp-locate-defs/test/defs.ref.txt b/compiler/tools/fpp-locate-defs/test/defs.ref.txt
index 9b71fcdf9..6015f9c79 100644
--- a/compiler/tools/fpp-locate-defs/test/defs.ref.txt
+++ b/compiler/tools/fpp-locate-defs/test/defs.ref.txt
@@ -4,6 +4,11 @@ locate constant C.a at "defs/defs-1.fpp"
locate constant M.C.a at "defs/defs-2.fpp"
locate constant M.a at "defs/defs-2.fpp"
locate constant a at "defs/defs-1.fpp"
+locate dictionary constant a2 at "defs/defs-1.fpp"
+locate dictionary type Alias2 at "defs/defs-1.fpp"
+locate dictionary type C.A2 at "defs/defs-1.fpp"
+locate dictionary type M.C.E2 at "defs/defs-2.fpp"
+locate dictionary type M.C.S2 at "defs/defs-2.fpp"
locate instance M.c at "defs/defs-2.fpp"
locate instance c at "defs/defs-1.fpp"
locate interface I at "defs/defs-1.fpp"
diff --git a/compiler/tools/fpp-locate-defs/test/defs/defs-1.fpp b/compiler/tools/fpp-locate-defs/test/defs/defs-1.fpp
index 05f0dbe4b..ed6904b41 100644
--- a/compiler/tools/fpp-locate-defs/test/defs/defs-1.fpp
+++ b/compiler/tools/fpp-locate-defs/test/defs/defs-1.fpp
@@ -2,12 +2,16 @@ array A = [3] U32
constant a = 0
+dictionary constant a2 = 1
+
enum E { X, Y, Z }
type T
type Alias = T
+dictionary type Alias2 = U32
+
struct S { x: U32 }
port P
@@ -20,6 +24,7 @@ passive component C {
type T
type Alias = T
array A = [3] U32
+ dictionary array A2 = [3] U32
constant a = 0
enum E { X, Y, Z }
struct S { x: U32 }
diff --git a/compiler/tools/fpp-locate-defs/test/defs/defs-2.fpp b/compiler/tools/fpp-locate-defs/test/defs/defs-2.fpp
index dc29548e6..6c153e970 100644
--- a/compiler/tools/fpp-locate-defs/test/defs/defs-2.fpp
+++ b/compiler/tools/fpp-locate-defs/test/defs/defs-2.fpp
@@ -22,7 +22,9 @@ module M {
array A = [3] U32
constant a = 0
enum E { X, Y, Z }
+ dictionary enum E2 { A, B, C }
struct S { x: U32 }
+ dictionary struct S2 { a: U32 }
state machine S
}
diff --git a/compiler/tools/fpp-locate-defs/test/defs_dir.ref.txt b/compiler/tools/fpp-locate-defs/test/defs_dir.ref.txt
index ac6ce86e2..2861932a4 100644
--- a/compiler/tools/fpp-locate-defs/test/defs_dir.ref.txt
+++ b/compiler/tools/fpp-locate-defs/test/defs_dir.ref.txt
@@ -4,6 +4,11 @@ locate constant C.a at "defs-1.fpp"
locate constant M.C.a at "defs-2.fpp"
locate constant M.a at "defs-2.fpp"
locate constant a at "defs-1.fpp"
+locate dictionary constant a2 at "defs-1.fpp"
+locate dictionary type Alias2 at "defs-1.fpp"
+locate dictionary type C.A2 at "defs-1.fpp"
+locate dictionary type M.C.E2 at "defs-2.fpp"
+locate dictionary type M.C.S2 at "defs-2.fpp"
locate instance M.c at "defs-2.fpp"
locate instance c at "defs-1.fpp"
locate interface I at "defs-1.fpp"
diff --git a/compiler/tools/fpp-locate-uses/test/defs.fpp b/compiler/tools/fpp-locate-uses/test/defs.fpp
index 89940d893..e75fdea15 100644
--- a/compiler/tools/fpp-locate-uses/test/defs.fpp
+++ b/compiler/tools/fpp-locate-uses/test/defs.fpp
@@ -15,7 +15,7 @@ module Fw {
port Tlm
}
-array A = [3] U32
+dictionary array A = [3] U32
constant a = 0
enum E { X, Y }
enum Phases { setup, teardown }
@@ -26,7 +26,7 @@ constant t = {seconds=10,useconds=20}
module M {
array A = [3] U32
- constant a = 0
+ dictionary constant a = 0
enum E { X, Y }
struct S { x: U32 }
type T
@@ -40,7 +40,7 @@ active component C1 {
array A = [3] U32
constant a = 0
enum E { X, Y }
- struct S { x: U32 }
+ dictionary struct S { x: U32 }
type T
state machine S
}
@@ -60,7 +60,7 @@ module M {
passive component C1 {
array A = [3] U32
constant a = 0
- enum E { X, Y }
+ dictionary enum E { X, Y }
struct S { x: U32 }
type T
state machine S
@@ -80,8 +80,8 @@ constant stack_size_def = 10
constant priority_def = 10
constant cpu_def = 0
constant record_id = 0
-array RecordType = [3] U32
-constant container_id = 0
+dictionary array RecordType = [3] U32
+dictionary constant container_id = 0
constant container_priority = 0
constant product_recv_priority = 0
diff --git a/compiler/tools/fpp-locate-uses/test/stdin.ref.txt b/compiler/tools/fpp-locate-uses/test/stdin.ref.txt
index cd03947a7..78cf21ca3 100644
--- a/compiler/tools/fpp-locate-uses/test/stdin.ref.txt
+++ b/compiler/tools/fpp-locate-uses/test/stdin.ref.txt
@@ -1,11 +1,9 @@
locate component C1 at "defs.fpp"
locate component M.C1 at "defs.fpp"
locate constant C1.a at "defs.fpp"
-locate constant M.a at "defs.fpp"
locate constant SignalConstant at "defs.fpp"
locate constant a at "defs.fpp"
locate constant base_id_def at "defs.fpp"
-locate constant container_id at "defs.fpp"
locate constant container_priority at "defs.fpp"
locate constant cpu_def at "defs.fpp"
locate constant priority_def at "defs.fpp"
@@ -16,6 +14,11 @@ locate constant stack_size_def at "defs.fpp"
locate constant t at "defs.fpp"
locate constant tlm_packet_group at "defs.fpp"
locate constant tlm_packet_id at "defs.fpp"
+locate dictionary constant M.a at "defs.fpp"
+locate dictionary constant container_id at "defs.fpp"
+locate dictionary type A at "defs.fpp"
+locate dictionary type C1.S at "defs.fpp"
+locate dictionary type RecordType at "defs.fpp"
locate instance M.c11 at "defs.fpp"
locate instance c11 at "defs.fpp"
locate port Fw.Cmd at "defs.fpp"
@@ -37,11 +40,9 @@ locate state machine M.S at "defs.fpp"
locate state machine S at "defs.fpp"
locate topology M.T1 at "defs.fpp"
locate topology T1 at "defs.fpp"
-locate type A at "defs.fpp"
locate type ActionType at "defs.fpp"
locate type C1.A at "defs.fpp"
locate type C1.E at "defs.fpp"
-locate type C1.S at "defs.fpp"
locate type C1.T at "defs.fpp"
locate type E at "defs.fpp"
locate type GuardType at "defs.fpp"
@@ -50,7 +51,6 @@ locate type M.E at "defs.fpp"
locate type M.S at "defs.fpp"
locate type M.T at "defs.fpp"
locate type Phases at "defs.fpp"
-locate type RecordType at "defs.fpp"
locate type S at "defs.fpp"
locate type SignalType at "defs.fpp"
locate type T at "defs.fpp"
diff --git a/compiler/tools/fpp-locate-uses/test/uses.ref.txt b/compiler/tools/fpp-locate-uses/test/uses.ref.txt
index 142652ab9..cd0c0de6b 100644
--- a/compiler/tools/fpp-locate-uses/test/uses.ref.txt
+++ b/compiler/tools/fpp-locate-uses/test/uses.ref.txt
@@ -1,11 +1,9 @@
locate component C1 at "defs.fpp"
locate component M.C1 at "defs.fpp"
locate constant C1.a at "defs.fpp"
-locate constant M.a at "defs.fpp"
locate constant SignalConstant at "defs.fpp"
locate constant a at "defs.fpp"
locate constant base_id_def at "defs.fpp"
-locate constant container_id at "defs.fpp"
locate constant container_priority at "defs.fpp"
locate constant cpu_def at "defs.fpp"
locate constant priority_def at "defs.fpp"
@@ -16,6 +14,11 @@ locate constant stack_size_def at "defs.fpp"
locate constant t at "defs.fpp"
locate constant tlm_packet_group at "defs.fpp"
locate constant tlm_packet_id at "defs.fpp"
+locate dictionary constant M.a at "defs.fpp"
+locate dictionary constant container_id at "defs.fpp"
+locate dictionary type A at "defs.fpp"
+locate dictionary type C1.S at "defs.fpp"
+locate dictionary type RecordType at "defs.fpp"
locate instance M.c11 at "defs.fpp"
locate instance c11 at "defs.fpp"
locate interface I at "uses/uses.fpp"
@@ -38,11 +41,9 @@ locate state machine M.S at "defs.fpp"
locate state machine S at "defs.fpp"
locate topology M.T1 at "defs.fpp"
locate topology T1 at "defs.fpp"
-locate type A at "defs.fpp"
locate type ActionType at "defs.fpp"
locate type C1.A at "defs.fpp"
locate type C1.E at "defs.fpp"
-locate type C1.S at "defs.fpp"
locate type C1.T at "defs.fpp"
locate type E at "defs.fpp"
locate type GuardType at "defs.fpp"
@@ -51,7 +52,6 @@ locate type M.E at "defs.fpp"
locate type M.S at "defs.fpp"
locate type M.T at "defs.fpp"
locate type Phases at "defs.fpp"
-locate type RecordType at "defs.fpp"
locate type S at "defs.fpp"
locate type SignalType at "defs.fpp"
locate type T at "defs.fpp"
diff --git a/compiler/tools/fpp-locate-uses/test/uses_dir.ref.txt b/compiler/tools/fpp-locate-uses/test/uses_dir.ref.txt
index 8003b9c60..8c205e9d3 100644
--- a/compiler/tools/fpp-locate-uses/test/uses_dir.ref.txt
+++ b/compiler/tools/fpp-locate-uses/test/uses_dir.ref.txt
@@ -1,11 +1,9 @@
locate component C1 at "../defs.fpp"
locate component M.C1 at "../defs.fpp"
locate constant C1.a at "../defs.fpp"
-locate constant M.a at "../defs.fpp"
locate constant SignalConstant at "../defs.fpp"
locate constant a at "../defs.fpp"
locate constant base_id_def at "../defs.fpp"
-locate constant container_id at "../defs.fpp"
locate constant container_priority at "../defs.fpp"
locate constant cpu_def at "../defs.fpp"
locate constant priority_def at "../defs.fpp"
@@ -16,6 +14,11 @@ locate constant stack_size_def at "../defs.fpp"
locate constant t at "../defs.fpp"
locate constant tlm_packet_group at "../defs.fpp"
locate constant tlm_packet_id at "../defs.fpp"
+locate dictionary constant M.a at "../defs.fpp"
+locate dictionary constant container_id at "../defs.fpp"
+locate dictionary type A at "../defs.fpp"
+locate dictionary type C1.S at "../defs.fpp"
+locate dictionary type RecordType at "../defs.fpp"
locate instance M.c11 at "../defs.fpp"
locate instance c11 at "../defs.fpp"
locate interface I at "uses.fpp"
@@ -38,11 +41,9 @@ locate state machine M.S at "../defs.fpp"
locate state machine S at "../defs.fpp"
locate topology M.T1 at "../defs.fpp"
locate topology T1 at "../defs.fpp"
-locate type A at "../defs.fpp"
locate type ActionType at "../defs.fpp"
locate type C1.A at "../defs.fpp"
locate type C1.E at "../defs.fpp"
-locate type C1.S at "../defs.fpp"
locate type C1.T at "../defs.fpp"
locate type E at "../defs.fpp"
locate type GuardType at "../defs.fpp"
@@ -51,7 +52,6 @@ locate type M.E at "../defs.fpp"
locate type M.S at "../defs.fpp"
locate type M.T at "../defs.fpp"
locate type Phases at "../defs.fpp"
-locate type RecordType at "../defs.fpp"
locate type S at "../defs.fpp"
locate type SignalType at "../defs.fpp"
locate type T at "../defs.fpp"
diff --git a/compiler/tools/fpp-syntax/test/dictionary-specifier.fpp b/compiler/tools/fpp-syntax/test/dictionary-specifier.fpp
new file mode 100644
index 000000000..fb1a010d6
--- /dev/null
+++ b/compiler/tools/fpp-syntax/test/dictionary-specifier.fpp
@@ -0,0 +1,5 @@
+dictionary type T = U32
+dictionary array A = [2] F32
+dictionary struct S { x: [3] U32, y: F32, z: string }
+dictionary enum E { X, Y, Z } default X
+dictionary constant C = 1
diff --git a/compiler/tools/fpp-syntax/test/dictionary-specifier.ref.txt b/compiler/tools/fpp-syntax/test/dictionary-specifier.ref.txt
new file mode 100644
index 000000000..eec06922c
--- /dev/null
+++ b/compiler/tools/fpp-syntax/test/dictionary-specifier.ref.txt
@@ -0,0 +1,31 @@
+dictionary def alias type
+ ident T
+ type name U32
+dictionary def array
+ ident A
+ size literal int 2
+ type name F32
+dictionary def struct
+ ident S
+ struct type member
+ ident x
+ array size literal int 3
+ type name U32
+ struct type member
+ ident y
+ type name F32
+ struct type member
+ ident z
+ type name string
+dictionary def enum
+ ident E
+ def enum constant
+ ident X
+ def enum constant
+ ident Y
+ def enum constant
+ ident Z
+ default ident X
+dictionary def constant
+ ident C
+ literal int 1
diff --git a/compiler/tools/fpp-syntax/test/run b/compiler/tools/fpp-syntax/test/run
index 4b453ed15..d05b6a688 100755
--- a/compiler/tools/fpp-syntax/test/run
+++ b/compiler/tools/fpp-syntax/test/run
@@ -135,6 +135,11 @@ two_input_files()
diff -u two-input-files.ref.txt two-input-files.out.txt > two-input-files.diff.txt 2>&1
}
+dictionary_specifier()
+{
+ run_test -a dictionary-specifier
+}
+
tests="
comments
embedded_tab
@@ -159,6 +164,7 @@ syntax_include_ast
syntax_kwd_names
syntax_stdin
two_input_files
+dictionary_specifier
"
run_suite $tests
diff --git a/compiler/tools/fpp-syntax/test/update-ref b/compiler/tools/fpp-syntax/test/update-ref
index 54c08f84d..b39447258 100755
--- a/compiler/tools/fpp-syntax/test/update-ref
+++ b/compiler/tools/fpp-syntax/test/update-ref
@@ -29,6 +29,7 @@ update "" illegal-character
update "" parse-error
update "" syntax
update "" syntax-kwd-names
+update -a dictionary-specifier
update -a state-machine
update -a empty
update -a escaped-strings
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 6141ad5a5..7e86f84ed 100644
--- a/compiler/tools/fpp-to-dict/test/top/BasicDpTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/BasicDpTopologyDictionary.ref.json
@@ -85,23 +85,7 @@
},
{
"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" : "FwSizeType",
+ "qualifiedName" : "BaseIdType",
"type" : {
"name" : "U32",
"kind" : "integer",
@@ -134,12 +118,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpIdType",
+ "qualifiedName" : "FwEventIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -193,22 +175,6 @@
"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",
@@ -228,12 +194,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpPriorityType",
+ "qualifiedName" : "FwPacketDescriptorType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -244,12 +208,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwOpcodeType",
+ "qualifiedName" : "FwDpIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -262,10 +224,50 @@
"kind" : "alias",
"qualifiedName" : "FwChanIdType",
"type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
"name" : "U32",
"kind" : "integer",
"size" : 32,
"signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwDpPriorityType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwSizeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
diff --git a/compiler/tools/fpp-to-dict/test/top/BasicTopologyDictionary.ref.json b/compiler/tools/fpp-to-dict/test/top/BasicTopologyDictionary.ref.json
index 0e1e85839..78c5f01de 100644
--- a/compiler/tools/fpp-to-dict/test/top/BasicTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/BasicTopologyDictionary.ref.json
@@ -54,23 +54,7 @@
},
{
"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" : "FwSizeType",
+ "qualifiedName" : "BaseIdType",
"type" : {
"name" : "U32",
"kind" : "integer",
@@ -103,12 +87,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpIdType",
+ "qualifiedName" : "FwEventIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -166,10 +148,8 @@
"kind" : "alias",
"qualifiedName" : "FwPacketDescriptorType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -180,12 +160,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpPriorityType",
+ "qualifiedName" : "FwDpIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -213,12 +191,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwOpcodeType",
+ "qualifiedName" : "FwChanIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -229,12 +205,38 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwChanIdType",
+ "qualifiedName" : "FwOpcodeType",
"type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
"name" : "U32",
"kind" : "integer",
"size" : 32,
"signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwDpPriorityType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwSizeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
diff --git a/compiler/tools/fpp-to-dict/test/top/DictionaryDefsTopologyDictionary.ref.json b/compiler/tools/fpp-to-dict/test/top/DictionaryDefsTopologyDictionary.ref.json
new file mode 100644
index 000000000..d6233c5ed
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/DictionaryDefsTopologyDictionary.ref.json
@@ -0,0 +1,456 @@
+{
+ "metadata" : {
+ "deploymentName" : "DictionaryDefs",
+ "projectVersion" : "1.0.0",
+ "frameworkVersion" : "3.4.3",
+ "libraryVersions" : [
+ "lib1-1.0.0",
+ "lib2-2.0.0"
+ ],
+ "dictionarySpecVersion" : "1.0.0"
+ },
+ "typeDefinitions" : [
+ {
+ "kind" : "array",
+ "qualifiedName" : "A",
+ "size" : 3,
+ "elementType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "default" : [
+ 0,
+ 0,
+ 0
+ ]
+ },
+ {
+ "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" : "Fw.DpState",
+ "representationType" : {
+ "name" : "U8",
+ "kind" : "integer",
+ "size" : 8,
+ "signed" : false
+ },
+ "enumeratedConstants" : [
+ {
+ "name" : "UNTRANSMITTED",
+ "value" : 0,
+ "annotation" : "The untransmitted state"
+ },
+ {
+ "name" : "PARTIAL",
+ "value" : 1,
+ "annotation" : "The partially transmitted state\nA data product is in this state from the start of transmission\nuntil transmission is complete."
+ },
+ {
+ "name" : "TRANSMITTED",
+ "value" : 2,
+ "annotation" : "The transmitted state"
+ }
+ ],
+ "default" : "Fw.DpState.UNTRANSMITTED"
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "BaseIdType",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "struct",
+ "qualifiedName" : "S",
+ "members" : {
+ "X" : {
+ "type" : {
+ "name" : "string",
+ "kind" : "string",
+ "size" : 80
+ },
+ "index" : 0
+ },
+ "Y" : {
+ "type" : {
+ "name" : "A2",
+ "kind" : "qualifiedIdentifier"
+ },
+ "index" : 1
+ },
+ "Z" : {
+ "type" : {
+ "name" : "S2",
+ "kind" : "qualifiedIdentifier"
+ },
+ "index" : 2
+ }
+ },
+ "default" : {
+ "X" : "",
+ "Y" : [
+ 0,
+ 0,
+ 0
+ ],
+ "Z" : {
+ "X" : 0
+ }
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwEventIdType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "enum",
+ "qualifiedName" : "E",
+ "representationType" : {
+ "name" : "I32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : true
+ },
+ "enumeratedConstants" : [
+ {
+ "name" : "A",
+ "value" : 0
+ },
+ {
+ "name" : "B",
+ "value" : 1
+ },
+ {
+ "name" : "C",
+ "value" : 2
+ }
+ ],
+ "default" : "E.A"
+ },
+ {
+ "kind" : "enum",
+ "qualifiedName" : "Fw.DpCfg.ProcType",
+ "representationType" : {
+ "name" : "U8",
+ "kind" : "integer",
+ "size" : 8,
+ "signed" : false
+ },
+ "enumeratedConstants" : [
+ {
+ "name" : "PROC_TYPE_ZERO",
+ "value" : 1,
+ "annotation" : "Processing type 0"
+ },
+ {
+ "name" : "PROC_TYPE_ONE",
+ "value" : 2,
+ "annotation" : "Processing type 1"
+ },
+ {
+ "name" : "PROC_TYPE_TWO",
+ "value" : 4,
+ "annotation" : "Processing type 2"
+ }
+ ],
+ "default" : "Fw.DpCfg.ProcType.PROC_TYPE_ZERO",
+ "annotation" : "A bit mask for selecting the type of processing to perform on\na container before writing it to disk."
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwSizeStoreType",
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "enum",
+ "qualifiedName" : "E2",
+ "representationType" : {
+ "name" : "I32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : true
+ },
+ "enumeratedConstants" : [
+ {
+ "name" : "A",
+ "value" : 0
+ }
+ ],
+ "default" : "E2.A"
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwDpIdType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwChanIdType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwTimeContextStoreType",
+ "type" : {
+ "name" : "U8",
+ "kind" : "integer",
+ "size" : 8,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U8",
+ "kind" : "integer",
+ "size" : 8,
+ "signed" : false
+ },
+ "annotation" : "The type used to serialize a time context value"
+ },
+ {
+ "kind" : "struct",
+ "qualifiedName" : "S2",
+ "members" : {
+ "X" : {
+ "type" : {
+ "name" : "T",
+ "kind" : "qualifiedIdentifier"
+ },
+ "index" : 0
+ }
+ },
+ "default" : {
+ "X" : 0
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "T2",
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwPacketDescriptorType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwDpPriorityType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwSizeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "array",
+ "qualifiedName" : "A2",
+ "size" : 3,
+ "elementType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "default" : [
+ 0,
+ 0,
+ 0
+ ]
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "T",
+ "type" : {
+ "name" : "T2",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwTimeBaseStoreType",
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "underlyingType" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "annotation" : "The type used to serialize a time base value"
+ }
+ ],
+ "constants" : [
+ {
+ "kind" : "constant",
+ "qualifiedName" : "C2",
+ "type" : {
+ "name" : "E",
+ "kind" : "qualifiedIdentifier"
+ },
+ "value" : "E.A"
+ },
+ {
+ "kind" : "constant",
+ "qualifiedName" : "C",
+ "type" : {
+ "name" : "E2",
+ "kind" : "qualifiedIdentifier"
+ },
+ "value" : "E2.A"
+ },
+ {
+ "kind" : "constant",
+ "qualifiedName" : "Fw.DpCfg.CONTAINER_USER_DATA_SIZE",
+ "type" : {
+ "name" : "U64",
+ "kind" : "integer",
+ "size" : 64,
+ "signed" : false
+ },
+ "value" : 32,
+ "annotation" : "The container user data size"
+ }
+ ],
+ "commands" : [
+ ],
+ "parameters" : [
+ ],
+ "events" : [
+ ],
+ "telemetryChannels" : [
+ ],
+ "records" : [
+ ],
+ "containers" : [
+ ],
+ "telemetryPacketSets" : [
+ ]
+}
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 c323c9ae8..94734c064 100644
--- a/compiler/tools/fpp-to-dict/test/top/FirstTopTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/FirstTopTopologyDictionary.ref.json
@@ -12,23 +12,7 @@
"typeDefinitions" : [
{
"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" : "FwSizeType",
+ "qualifiedName" : "BaseIdType",
"type" : {
"name" : "U32",
"kind" : "integer",
@@ -77,110 +61,19 @@
"annotation" : "Alias of type U32"
},
{
- "kind" : "struct",
- "qualifiedName" : "Module1.ScalarStruct",
- "members" : {
- "u32" : {
- "type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
- },
- "index" : 6
- },
- "f64" : {
- "type" : {
- "name" : "F64",
- "kind" : "float",
- "size" : 64
- },
- "index" : 9
- },
- "f32" : {
- "type" : {
- "name" : "F32",
- "kind" : "float",
- "size" : 32
- },
- "index" : 8
- },
- "i8" : {
- "type" : {
- "name" : "I8",
- "kind" : "integer",
- "size" : 8,
- "signed" : true
- },
- "index" : 0
- },
- "i16" : {
- "type" : {
- "name" : "I16",
- "kind" : "integer",
- "size" : 16,
- "signed" : true
- },
- "index" : 1
- },
- "u8" : {
- "type" : {
- "name" : "U8",
- "kind" : "integer",
- "size" : 8,
- "signed" : false
- },
- "index" : 4
- },
- "u64" : {
- "type" : {
- "name" : "U64",
- "kind" : "integer",
- "size" : 64,
- "signed" : false
- },
- "index" : 7
- },
- "i64" : {
- "type" : {
- "name" : "I64",
- "kind" : "integer",
- "size" : 64,
- "signed" : true
- },
- "index" : 3
- },
- "i32" : {
- "type" : {
- "name" : "I32",
- "kind" : "integer",
- "size" : 32,
- "signed" : true
- },
- "index" : 2
- },
- "u16" : {
- "type" : {
- "name" : "U16",
- "kind" : "integer",
- "size" : 16,
- "signed" : false
- },
- "index" : 5
- }
+ "kind" : "alias",
+ "qualifiedName" : "Module1.AliasT2",
+ "type" : {
+ "name" : "Module1.AliasT1",
+ "kind" : "qualifiedIdentifier"
},
- "default" : {
- "u32" : 0,
- "f64" : 0.0,
- "f32" : 0.0,
- "i8" : 0,
- "i16" : 0,
- "u8" : 0,
- "u64" : 0,
- "i64" : 0,
- "i32" : 0,
- "u16" : 0
- }
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "annotation" : "Alias of type AliasT1 (with underlying type U32)"
},
{
"kind" : "enum",
@@ -228,12 +121,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwPacketDescriptorType",
+ "qualifiedName" : "FwDpIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -244,26 +135,24 @@
},
{
"kind" : "alias",
- "qualifiedName" : "Module1.AliasT3",
+ "qualifiedName" : "FwChanIdType",
"type" : {
- "name" : "string",
- "kind" : "string",
- "size" : 20
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
- "name" : "string",
- "kind" : "string",
- "size" : 20
- }
- },
- {
- "kind" : "alias",
- "qualifiedName" : "FwDpPriorityType",
- "type" : {
"name" : "U32",
"kind" : "integer",
"size" : 32,
"signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -442,12 +331,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpIdType",
+ "qualifiedName" : "FwEventIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -457,19 +344,110 @@
}
},
{
- "kind" : "alias",
- "qualifiedName" : "Module1.AliasT2",
- "type" : {
- "name" : "Module1.AliasT1",
- "kind" : "qualifiedIdentifier"
+ "kind" : "struct",
+ "qualifiedName" : "Module1.ScalarStruct",
+ "members" : {
+ "u32" : {
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "index" : 6
+ },
+ "f64" : {
+ "type" : {
+ "name" : "F64",
+ "kind" : "float",
+ "size" : 64
+ },
+ "index" : 9
+ },
+ "f32" : {
+ "type" : {
+ "name" : "F32",
+ "kind" : "float",
+ "size" : 32
+ },
+ "index" : 8
+ },
+ "i8" : {
+ "type" : {
+ "name" : "I8",
+ "kind" : "integer",
+ "size" : 8,
+ "signed" : true
+ },
+ "index" : 0
+ },
+ "i16" : {
+ "type" : {
+ "name" : "I16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : true
+ },
+ "index" : 1
+ },
+ "u8" : {
+ "type" : {
+ "name" : "U8",
+ "kind" : "integer",
+ "size" : 8,
+ "signed" : false
+ },
+ "index" : 4
+ },
+ "u64" : {
+ "type" : {
+ "name" : "U64",
+ "kind" : "integer",
+ "size" : 64,
+ "signed" : false
+ },
+ "index" : 7
+ },
+ "i64" : {
+ "type" : {
+ "name" : "I64",
+ "kind" : "integer",
+ "size" : 64,
+ "signed" : true
+ },
+ "index" : 3
+ },
+ "i32" : {
+ "type" : {
+ "name" : "I32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : true
+ },
+ "index" : 2
+ },
+ "u16" : {
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "index" : 5
+ }
},
- "underlyingType" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
- },
- "annotation" : "Alias of type AliasT1 (with underlying type U32)"
+ "default" : {
+ "u32" : 0,
+ "f64" : 0.0,
+ "f32" : 0.0,
+ "i8" : 0,
+ "i16" : 0,
+ "u8" : 0,
+ "u64" : 0,
+ "i64" : 0,
+ "i32" : 0,
+ "u16" : 0
+ }
},
{
"kind" : "struct",
@@ -518,12 +496,24 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwOpcodeType",
+ "qualifiedName" : "Module1.AliasT3",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "string",
+ "kind" : "string",
+ "size" : 20
+ },
+ "underlyingType" : {
+ "name" : "string",
+ "kind" : "string",
+ "size" : 20
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwPacketDescriptorType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -534,12 +524,24 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwChanIdType",
+ "qualifiedName" : "FwDpPriorityType",
"type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
"name" : "U32",
"kind" : "integer",
"size" : 32,
"signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwSizeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
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 77e0c8d3b..b776559b4 100644
--- a/compiler/tools/fpp-to-dict/test/top/QualifiedCompInstTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/QualifiedCompInstTopologyDictionary.ref.json
@@ -81,23 +81,7 @@
},
{
"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" : "FwSizeType",
+ "qualifiedName" : "BaseIdType",
"type" : {
"name" : "U32",
"kind" : "integer",
@@ -130,12 +114,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpIdType",
+ "qualifiedName" : "FwEventIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -193,10 +175,8 @@
"kind" : "alias",
"qualifiedName" : "FwPacketDescriptorType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -207,12 +187,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpPriorityType",
+ "qualifiedName" : "FwDpIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -240,12 +218,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwOpcodeType",
+ "qualifiedName" : "FwChanIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -256,12 +232,38 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwChanIdType",
+ "qualifiedName" : "FwOpcodeType",
"type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
"name" : "U32",
"kind" : "integer",
"size" : 32,
"signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwDpPriorityType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwSizeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
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 f3b873787..182a6e89c 100644
--- a/compiler/tools/fpp-to-dict/test/top/SecondTopTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/SecondTopTopologyDictionary.ref.json
@@ -12,23 +12,7 @@
"typeDefinitions" : [
{
"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" : "FwSizeType",
+ "qualifiedName" : "BaseIdType",
"type" : {
"name" : "U32",
"kind" : "integer",
@@ -77,110 +61,19 @@
"annotation" : "Alias of type U32"
},
{
- "kind" : "struct",
- "qualifiedName" : "Module1.ScalarStruct",
- "members" : {
- "u32" : {
- "type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
- },
- "index" : 6
- },
- "f64" : {
- "type" : {
- "name" : "F64",
- "kind" : "float",
- "size" : 64
- },
- "index" : 9
- },
- "f32" : {
- "type" : {
- "name" : "F32",
- "kind" : "float",
- "size" : 32
- },
- "index" : 8
- },
- "i8" : {
- "type" : {
- "name" : "I8",
- "kind" : "integer",
- "size" : 8,
- "signed" : true
- },
- "index" : 0
- },
- "i16" : {
- "type" : {
- "name" : "I16",
- "kind" : "integer",
- "size" : 16,
- "signed" : true
- },
- "index" : 1
- },
- "u8" : {
- "type" : {
- "name" : "U8",
- "kind" : "integer",
- "size" : 8,
- "signed" : false
- },
- "index" : 4
- },
- "u64" : {
- "type" : {
- "name" : "U64",
- "kind" : "integer",
- "size" : 64,
- "signed" : false
- },
- "index" : 7
- },
- "i64" : {
- "type" : {
- "name" : "I64",
- "kind" : "integer",
- "size" : 64,
- "signed" : true
- },
- "index" : 3
- },
- "i32" : {
- "type" : {
- "name" : "I32",
- "kind" : "integer",
- "size" : 32,
- "signed" : true
- },
- "index" : 2
- },
- "u16" : {
- "type" : {
- "name" : "U16",
- "kind" : "integer",
- "size" : 16,
- "signed" : false
- },
- "index" : 5
- }
+ "kind" : "alias",
+ "qualifiedName" : "Module1.AliasT2",
+ "type" : {
+ "name" : "Module1.AliasT1",
+ "kind" : "qualifiedIdentifier"
},
- "default" : {
- "u32" : 0,
- "f64" : 0.0,
- "f32" : 0.0,
- "i8" : 0,
- "i16" : 0,
- "u8" : 0,
- "u64" : 0,
- "i64" : 0,
- "i32" : 0,
- "u16" : 0
- }
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "annotation" : "Alias of type AliasT1 (with underlying type U32)"
},
{
"kind" : "enum",
@@ -228,12 +121,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwPacketDescriptorType",
+ "qualifiedName" : "FwDpIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -244,26 +135,24 @@
},
{
"kind" : "alias",
- "qualifiedName" : "Module1.AliasT3",
+ "qualifiedName" : "FwChanIdType",
"type" : {
- "name" : "string",
- "kind" : "string",
- "size" : 20
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
- "name" : "string",
- "kind" : "string",
- "size" : 20
- }
- },
- {
- "kind" : "alias",
- "qualifiedName" : "FwDpPriorityType",
- "type" : {
"name" : "U32",
"kind" : "integer",
"size" : 32,
"signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwOpcodeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -442,12 +331,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpIdType",
+ "qualifiedName" : "FwEventIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -457,19 +344,110 @@
}
},
{
- "kind" : "alias",
- "qualifiedName" : "Module1.AliasT2",
- "type" : {
- "name" : "Module1.AliasT1",
- "kind" : "qualifiedIdentifier"
+ "kind" : "struct",
+ "qualifiedName" : "Module1.ScalarStruct",
+ "members" : {
+ "u32" : {
+ "type" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ },
+ "index" : 6
+ },
+ "f64" : {
+ "type" : {
+ "name" : "F64",
+ "kind" : "float",
+ "size" : 64
+ },
+ "index" : 9
+ },
+ "f32" : {
+ "type" : {
+ "name" : "F32",
+ "kind" : "float",
+ "size" : 32
+ },
+ "index" : 8
+ },
+ "i8" : {
+ "type" : {
+ "name" : "I8",
+ "kind" : "integer",
+ "size" : 8,
+ "signed" : true
+ },
+ "index" : 0
+ },
+ "i16" : {
+ "type" : {
+ "name" : "I16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : true
+ },
+ "index" : 1
+ },
+ "u8" : {
+ "type" : {
+ "name" : "U8",
+ "kind" : "integer",
+ "size" : 8,
+ "signed" : false
+ },
+ "index" : 4
+ },
+ "u64" : {
+ "type" : {
+ "name" : "U64",
+ "kind" : "integer",
+ "size" : 64,
+ "signed" : false
+ },
+ "index" : 7
+ },
+ "i64" : {
+ "type" : {
+ "name" : "I64",
+ "kind" : "integer",
+ "size" : 64,
+ "signed" : true
+ },
+ "index" : 3
+ },
+ "i32" : {
+ "type" : {
+ "name" : "I32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : true
+ },
+ "index" : 2
+ },
+ "u16" : {
+ "type" : {
+ "name" : "U16",
+ "kind" : "integer",
+ "size" : 16,
+ "signed" : false
+ },
+ "index" : 5
+ }
},
- "underlyingType" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
- },
- "annotation" : "Alias of type AliasT1 (with underlying type U32)"
+ "default" : {
+ "u32" : 0,
+ "f64" : 0.0,
+ "f32" : 0.0,
+ "i8" : 0,
+ "i16" : 0,
+ "u8" : 0,
+ "u64" : 0,
+ "i64" : 0,
+ "i32" : 0,
+ "u16" : 0
+ }
},
{
"kind" : "struct",
@@ -518,12 +496,24 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwOpcodeType",
+ "qualifiedName" : "Module1.AliasT3",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "string",
+ "kind" : "string",
+ "size" : 20
+ },
+ "underlyingType" : {
+ "name" : "string",
+ "kind" : "string",
+ "size" : 20
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwPacketDescriptorType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -534,12 +524,24 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwChanIdType",
+ "qualifiedName" : "FwDpPriorityType",
"type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
"name" : "U32",
"kind" : "integer",
"size" : 32,
"signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwSizeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
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 a644937c3..e3dc5a93b 100644
--- a/compiler/tools/fpp-to-dict/test/top/UnqualifiedCompInstTopologyDictionary.ref.json
+++ b/compiler/tools/fpp-to-dict/test/top/UnqualifiedCompInstTopologyDictionary.ref.json
@@ -81,23 +81,7 @@
},
{
"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" : "FwSizeType",
+ "qualifiedName" : "BaseIdType",
"type" : {
"name" : "U32",
"kind" : "integer",
@@ -130,12 +114,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpIdType",
+ "qualifiedName" : "FwEventIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -193,10 +175,8 @@
"kind" : "alias",
"qualifiedName" : "FwPacketDescriptorType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -207,12 +187,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwDpPriorityType",
+ "qualifiedName" : "FwDpIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -240,12 +218,10 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwOpcodeType",
+ "qualifiedName" : "FwChanIdType",
"type" : {
- "name" : "U32",
- "kind" : "integer",
- "size" : 32,
- "signed" : false
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
@@ -256,12 +232,38 @@
},
{
"kind" : "alias",
- "qualifiedName" : "FwChanIdType",
+ "qualifiedName" : "FwOpcodeType",
"type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
"name" : "U32",
"kind" : "integer",
"size" : 32,
"signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwDpPriorityType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
+ },
+ "underlyingType" : {
+ "name" : "U32",
+ "kind" : "integer",
+ "size" : 32,
+ "signed" : false
+ }
+ },
+ {
+ "kind" : "alias",
+ "qualifiedName" : "FwSizeType",
+ "type" : {
+ "name" : "BaseIdType",
+ "kind" : "qualifiedIdentifier"
},
"underlyingType" : {
"name" : "U32",
diff --git a/compiler/tools/fpp-to-dict/test/top/config.fpp b/compiler/tools/fpp-to-dict/test/top/config.fpp
index 38c254a52..fe89508a8 100644
--- a/compiler/tools/fpp-to-dict/test/top/config.fpp
+++ b/compiler/tools/fpp-to-dict/test/top/config.fpp
@@ -1,11 +1,12 @@
-type FwChanIdType = U32
-type FwDpIdType = U32
-type FwDpPriorityType = U32
-type FwEventIdType = U32
-type FwOpcodeType = U32
-type FwPacketDescriptorType = U32
+type BaseIdType = U32
+type FwChanIdType = BaseIdType
+type FwDpIdType = BaseIdType
+type FwDpPriorityType = BaseIdType
+type FwEventIdType = BaseIdType
+type FwOpcodeType = BaseIdType
+type FwPacketDescriptorType = BaseIdType
type FwTlmPacketizeIdType = U16
-type FwSizeType = U32
+type FwSizeType = BaseIdType
type FwSizeStoreType = U16
@ The type used to serialize a time base value
diff --git a/compiler/tools/fpp-to-dict/test/top/dictionaryDefs.fpp b/compiler/tools/fpp-to-dict/test/top/dictionaryDefs.fpp
new file mode 100644
index 000000000..f3cc67093
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/dictionaryDefs.fpp
@@ -0,0 +1,45 @@
+# Dictionary definitions (included in the dictionary)
+dictionary type T = T2
+dictionary array A = [3] U32
+dictionary enum E {
+ A
+ B
+ C
+} default C2
+
+dictionary struct S {
+ X: string,
+ Y: A2,
+ Z: S2
+}
+
+dictionary constant C = E2.A
+
+# Defintions that are uses of dictionary definitions (included in the dictionary)
+type T2 = U32
+array A2 = [3] U32
+enum E2 {
+ A
+} default C
+
+struct S2 {
+ X: T
+}
+constant C2 = E.A
+
+# Non dictionary definitions (not included in the dictionary)
+type T3 = F32
+array A3 = [3] string
+enum E3 {
+ X
+}
+
+struct S3 {
+ X: string
+}
+
+constant C3 = 1
+
+topology DictionaryDefs {
+
+}
diff --git a/compiler/tools/fpp-to-dict/test/top/dictionaryDefs.ref.txt b/compiler/tools/fpp-to-dict/test/top/dictionaryDefs.ref.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/compiler/tools/fpp-to-dict/test/top/invalidDictDefConstant.fpp b/compiler/tools/fpp-to-dict/test/top/invalidDictDefConstant.fpp
new file mode 100644
index 000000000..c47642320
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/invalidDictDefConstant.fpp
@@ -0,0 +1,8 @@
+dictionary constant C = {
+ X = 0,
+ Y = 1
+}
+
+topology T {
+
+}
diff --git a/compiler/tools/fpp-to-dict/test/top/invalidDictDefConstant.ref.txt b/compiler/tools/fpp-to-dict/test/top/invalidDictDefConstant.ref.txt
new file mode 100644
index 000000000..a3001be0e
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/invalidDictDefConstant.ref.txt
@@ -0,0 +1,5 @@
+fpp-to-dict
+[ local path prefix ]/tools/fpp-to-dict/test/top/invalidDictDefConstant.fpp:1.1
+dictionary constant C = {
+^
+error: dictionary constant must have a numeric, Boolean, string, or enum type
diff --git a/compiler/tools/fpp-to-dict/test/top/invalidDictDefType.fpp b/compiler/tools/fpp-to-dict/test/top/invalidDictDefType.fpp
new file mode 100644
index 000000000..aa5f4a47f
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/invalidDictDefType.fpp
@@ -0,0 +1,6 @@
+type A
+dictionary type A2 = A
+
+topology T {
+
+}
diff --git a/compiler/tools/fpp-to-dict/test/top/invalidDictDefType.ref.txt b/compiler/tools/fpp-to-dict/test/top/invalidDictDefType.ref.txt
new file mode 100644
index 000000000..ac69e4108
--- /dev/null
+++ b/compiler/tools/fpp-to-dict/test/top/invalidDictDefType.ref.txt
@@ -0,0 +1,15 @@
+fpp-to-dict
+[ local path prefix ]/tools/fpp-to-dict/test/top/invalidDictDefType.fpp:2.1
+dictionary type A2 = A
+^
+error: dictionary type is not displayable
+
+[ local path prefix ]/tools/fpp-to-dict/test/top/invalidDictDefType.fpp:2.22
+dictionary type A2 = A
+ ^
+because this type is not displayable
+
+[ local path prefix ]/tools/fpp-to-dict/test/top/invalidDictDefType.fpp:1.1
+type A
+^
+Type is defined here
diff --git a/compiler/tools/fpp-to-dict/test/top/run.sh b/compiler/tools/fpp-to-dict/test/top/run.sh
index 705b9e57e..a431fd7b7 100644
--- a/compiler/tools/fpp-to-dict/test/top/run.sh
+++ b/compiler/tools/fpp-to-dict/test/top/run.sh
@@ -47,3 +47,22 @@ unqualifiedComponentInstances()
diff_json QualifiedCompInst && \
diff_json UnqualifiedCompInst
}
+
+invalidDictDefConstant()
+{
+ run_test "-i builtin.fpp,config.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" invalidDictDefConstant && \
+ compare invalidDictDefConstant
+}
+
+invalidDictDefType()
+{
+ run_test "-i builtin.fpp,config.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" invalidDictDefType && \
+ compare invalidDictDefType
+}
+
+dictionaryDefs()
+{
+ run_test "-i builtin.fpp,config.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" dictionaryDefs && \
+ validate_json_schema DictionaryDefs && \
+ diff_json DictionaryDefs
+}
diff --git a/compiler/tools/fpp-to-dict/test/top/tests.sh b/compiler/tools/fpp-to-dict/test/top/tests.sh
index 2753e8283..ad520ef6b 100644
--- a/compiler/tools/fpp-to-dict/test/top/tests.sh
+++ b/compiler/tools/fpp-to-dict/test/top/tests.sh
@@ -7,4 +7,7 @@ missingFwOpcodeType
missingUserDataSizeConstant
invalidUserDataSizeConstant
unqualifiedComponentInstances
+invalidDictDefConstant
+invalidDictDefType
+dictionaryDefs
"
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 654a2aaa4..c83b28409 100644
--- a/compiler/tools/fpp-to-dict/test/top/update-ref.sh
+++ b/compiler/tools/fpp-to-dict/test/top/update-ref.sh
@@ -28,3 +28,19 @@ unqualifiedComponentInstances()
move_json QualifiedCompInst
move_json UnqualifiedCompInst
}
+
+invalidDictDefConstant()
+{
+ update "-i builtin.fpp,config.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" invalidDictDefConstant
+}
+
+invalidDictDefType()
+{
+ update "-i builtin.fpp,config.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" invalidDictDefType
+}
+
+dictionaryDefs()
+{
+ update "-i builtin.fpp,config.fpp -p 1.0.0 -f 3.4.3 -l lib1-1.0.0,lib2-2.0.0" dictionaryDefs
+ move_json DictionaryDefs
+}
diff --git a/compiler/tools/fpp-to-json/test/activeComponents.ref.txt b/compiler/tools/fpp-to-json/test/activeComponents.ref.txt
index 721732fbe..e815a2033 100644
--- a/compiler/tools/fpp-to-json/test/activeComponents.ref.txt
+++ b/compiler/tools/fpp-to-json/test/activeComponents.ref.txt
@@ -543,7 +543,8 @@
},
"id" : 139
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 140
}
@@ -596,7 +597,8 @@
},
"id" : 151
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 152
}
@@ -2936,5 +2938,7 @@
}
}
}
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/commands.ref.txt b/compiler/tools/fpp-to-json/test/commands.ref.txt
index 560b88301..1df825d76 100644
--- a/compiler/tools/fpp-to-json/test/commands.ref.txt
+++ b/compiler/tools/fpp-to-json/test/commands.ref.txt
@@ -1131,5 +1131,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/constTypesComponents.ref.txt b/compiler/tools/fpp-to-json/test/constTypesComponents.ref.txt
index dde43098d..7cee090ed 100644
--- a/compiler/tools/fpp-to-json/test/constTypesComponents.ref.txt
+++ b/compiler/tools/fpp-to-json/test/constTypesComponents.ref.txt
@@ -62,7 +62,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : false
},
"id" : 4
}
@@ -1062,5 +1063,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/constants.ref.txt b/compiler/tools/fpp-to-json/test/constants.ref.txt
index f1ab106f4..dabb615a8 100644
--- a/compiler/tools/fpp-to-json/test/constants.ref.txt
+++ b/compiler/tools/fpp-to-json/test/constants.ref.txt
@@ -19,7 +19,8 @@
},
"id" : 0
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 1
}
@@ -47,7 +48,8 @@
},
"id" : 2
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 3
}
@@ -75,7 +77,8 @@
},
"id" : 4
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 5
}
@@ -134,7 +137,8 @@
},
"id" : 9
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 10
}
@@ -183,7 +187,8 @@
},
"id" : 13
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 14
}
@@ -274,7 +279,8 @@
},
"id" : 21
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 22
}
@@ -321,7 +327,8 @@
},
"id" : 25
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 26
}
@@ -387,7 +394,8 @@
},
"id" : 31
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 32
}
@@ -474,7 +482,8 @@
},
"id" : 39
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 40
}
@@ -503,7 +512,8 @@
},
"id" : 41
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 42
}
@@ -608,7 +618,8 @@
},
"id" : 51
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 52
}
@@ -636,7 +647,8 @@
},
"id" : 53
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 54
}
@@ -664,7 +676,8 @@
},
"id" : 55
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 56
}
@@ -706,7 +719,8 @@
},
"id" : 58
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 59
}
@@ -758,7 +772,8 @@
},
"id" : 62
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 63
}
@@ -795,7 +810,8 @@
},
"id" : 65
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 66
}
@@ -827,7 +843,8 @@
},
"id" : 67
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 68
}
@@ -859,7 +876,8 @@
},
"id" : 69
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 70
}
@@ -889,7 +907,8 @@
},
"id" : 73
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 74
}
@@ -2739,5 +2758,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/dataProducts.ref.txt b/compiler/tools/fpp-to-json/test/dataProducts.ref.txt
index 5892dfd02..3257f8ade 100644
--- a/compiler/tools/fpp-to-json/test/dataProducts.ref.txt
+++ b/compiler/tools/fpp-to-json/test/dataProducts.ref.txt
@@ -1093,5 +1093,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/enums.ref.txt b/compiler/tools/fpp-to-json/test/enums.ref.txt
index 86626294c..4989d8619 100644
--- a/compiler/tools/fpp-to-json/test/enums.ref.txt
+++ b/compiler/tools/fpp-to-json/test/enums.ref.txt
@@ -58,7 +58,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : false
},
"id" : 5
}
@@ -101,7 +102,8 @@
},
"id" : 8
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 9
}
@@ -201,7 +203,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : false
},
"id" : 20
}
@@ -268,7 +271,8 @@
},
"id" : 25
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 26
}
@@ -361,7 +365,8 @@
"id" : 33
}
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 34
}
@@ -1398,5 +1403,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/events.ref.txt b/compiler/tools/fpp-to-json/test/events.ref.txt
index 984650e6c..a64401704 100644
--- a/compiler/tools/fpp-to-json/test/events.ref.txt
+++ b/compiler/tools/fpp-to-json/test/events.ref.txt
@@ -2900,5 +2900,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/importedTopologies.ref.txt b/compiler/tools/fpp-to-json/test/importedTopologies.ref.txt
index 6f4b07084..952d4c9fa 100644
--- a/compiler/tools/fpp-to-json/test/importedTopologies.ref.txt
+++ b/compiler/tools/fpp-to-json/test/importedTopologies.ref.txt
@@ -8281,5 +8281,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/interfaces.ref.txt b/compiler/tools/fpp-to-json/test/interfaces.ref.txt
index 639424bdb..6821d7676 100644
--- a/compiler/tools/fpp-to-json/test/interfaces.ref.txt
+++ b/compiler/tools/fpp-to-json/test/interfaces.ref.txt
@@ -1946,5 +1946,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/internalPorts.ref.txt b/compiler/tools/fpp-to-json/test/internalPorts.ref.txt
index 385863b99..2a029f37b 100644
--- a/compiler/tools/fpp-to-json/test/internalPorts.ref.txt
+++ b/compiler/tools/fpp-to-json/test/internalPorts.ref.txt
@@ -481,5 +481,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/matchedPorts.ref.txt b/compiler/tools/fpp-to-json/test/matchedPorts.ref.txt
index ebe59b5c0..906ef3e4b 100644
--- a/compiler/tools/fpp-to-json/test/matchedPorts.ref.txt
+++ b/compiler/tools/fpp-to-json/test/matchedPorts.ref.txt
@@ -20,7 +20,8 @@
},
"id" : 0
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 1
}
@@ -744,5 +745,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/modules.ref.txt b/compiler/tools/fpp-to-json/test/modules.ref.txt
index f830f1298..0d82fb24f 100644
--- a/compiler/tools/fpp-to-json/test/modules.ref.txt
+++ b/compiler/tools/fpp-to-json/test/modules.ref.txt
@@ -30,7 +30,8 @@
},
"id" : 0
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 1
}
@@ -58,7 +59,8 @@
},
"id" : 2
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 3
}
@@ -101,7 +103,8 @@
},
"id" : 14
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 15
}
@@ -154,7 +157,8 @@
},
"id" : 19
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 20
}
@@ -192,7 +196,8 @@
},
"id" : 25
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 26
}
@@ -240,7 +245,8 @@
},
"id" : 32
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 33
}
@@ -298,7 +304,8 @@
},
"id" : 53
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 54
}
@@ -376,7 +383,8 @@
},
"id" : 61
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 62
}
@@ -1161,5 +1169,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/parameters.ref.txt b/compiler/tools/fpp-to-json/test/parameters.ref.txt
index f08b43055..51bfe86b4 100644
--- a/compiler/tools/fpp-to-json/test/parameters.ref.txt
+++ b/compiler/tools/fpp-to-json/test/parameters.ref.txt
@@ -36,7 +36,8 @@
}
},
"default" : "None",
- "format" : "None"
+ "format" : "None",
+ "isDictionaryDef" : false
},
"id" : 2
}
@@ -2146,5 +2147,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/passiveComponent.ref.txt b/compiler/tools/fpp-to-json/test/passiveComponent.ref.txt
index eb64730ee..308cf86c8 100644
--- a/compiler/tools/fpp-to-json/test/passiveComponent.ref.txt
+++ b/compiler/tools/fpp-to-json/test/passiveComponent.ref.txt
@@ -1332,5 +1332,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/patternedConnections.ref.txt b/compiler/tools/fpp-to-json/test/patternedConnections.ref.txt
index b0715ab69..ba467b412 100644
--- a/compiler/tools/fpp-to-json/test/patternedConnections.ref.txt
+++ b/compiler/tools/fpp-to-json/test/patternedConnections.ref.txt
@@ -6302,5 +6302,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/ports.ref.txt b/compiler/tools/fpp-to-json/test/ports.ref.txt
index 3236f8835..7147854d6 100644
--- a/compiler/tools/fpp-to-json/test/ports.ref.txt
+++ b/compiler/tools/fpp-to-json/test/ports.ref.txt
@@ -255,7 +255,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : false
},
"id" : 24
}
@@ -480,7 +481,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : false
},
"id" : 54
}
@@ -2406,5 +2408,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/queuedComponents.ref.txt b/compiler/tools/fpp-to-json/test/queuedComponents.ref.txt
index 01e6fb7e4..56bc0aace 100644
--- a/compiler/tools/fpp-to-json/test/queuedComponents.ref.txt
+++ b/compiler/tools/fpp-to-json/test/queuedComponents.ref.txt
@@ -1618,5 +1618,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/simpleComponents.ref.txt b/compiler/tools/fpp-to-json/test/simpleComponents.ref.txt
index 8f9132450..eec49b533 100644
--- a/compiler/tools/fpp-to-json/test/simpleComponents.ref.txt
+++ b/compiler/tools/fpp-to-json/test/simpleComponents.ref.txt
@@ -567,7 +567,8 @@
},
"id" : 59
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 60
}
@@ -1789,5 +1790,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/simpleTopology.ref.txt b/compiler/tools/fpp-to-json/test/simpleTopology.ref.txt
index fc63639b1..78e8e0fd3 100644
--- a/compiler/tools/fpp-to-json/test/simpleTopology.ref.txt
+++ b/compiler/tools/fpp-to-json/test/simpleTopology.ref.txt
@@ -3167,5 +3167,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/specialPorts.ref.txt b/compiler/tools/fpp-to-json/test/specialPorts.ref.txt
index 95d69efd3..333643c5f 100644
--- a/compiler/tools/fpp-to-json/test/specialPorts.ref.txt
+++ b/compiler/tools/fpp-to-json/test/specialPorts.ref.txt
@@ -1712,5 +1712,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/stateMachine.ref.txt b/compiler/tools/fpp-to-json/test/stateMachine.ref.txt
index 34a00bfce..0664e288b 100644
--- a/compiler/tools/fpp-to-json/test/stateMachine.ref.txt
+++ b/compiler/tools/fpp-to-json/test/stateMachine.ref.txt
@@ -3196,5 +3196,7 @@
}
}
}
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/telemetry.ref.txt b/compiler/tools/fpp-to-json/test/telemetry.ref.txt
index da8eb158f..14e09eaf1 100644
--- a/compiler/tools/fpp-to-json/test/telemetry.ref.txt
+++ b/compiler/tools/fpp-to-json/test/telemetry.ref.txt
@@ -2408,5 +2408,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/telemetryPackets.ref.txt b/compiler/tools/fpp-to-json/test/telemetryPackets.ref.txt
index 5071245d6..4deaaffff 100644
--- a/compiler/tools/fpp-to-json/test/telemetryPackets.ref.txt
+++ b/compiler/tools/fpp-to-json/test/telemetryPackets.ref.txt
@@ -2224,5 +2224,7 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ ]
}
diff --git a/compiler/tools/fpp-to-json/test/types.fpp b/compiler/tools/fpp-to-json/test/types.fpp
index 61a0e6f58..6653477e6 100644
--- a/compiler/tools/fpp-to-json/test/types.fpp
+++ b/compiler/tools/fpp-to-json/test/types.fpp
@@ -1,4 +1,4 @@
-constant numElements = 3
+dictionary constant numElements = 3
array A = [numElements] string size 40 default [ "1", "2", "3" ] format "{} RPM"
array B = [3] A
@@ -18,7 +18,7 @@ type T # T is an abstract type
array arr = [3] T # A is an array of 3 values of type T
# struct with identifier that is a reserved word
-struct SignalInfo {
+dictionary struct SignalInfo {
$type: SignalType
history: SignalSet
pairHistory: SignalPairSet
@@ -31,11 +31,14 @@ struct SignalPair {
array SignalPairSet = [4] SignalPair
-array SignalSet = [4] F32 format "{f}"
+dictionary array SignalSet = [4] F32 format "{f}"
-enum SignalType {
+dictionary enum SignalType {
TRIANGLE
SQUARE
SINE
NOISE
}
+
+dictionary type Alias1 = U32
+type Alias2 = U32
diff --git a/compiler/tools/fpp-to-json/test/types.ref.txt b/compiler/tools/fpp-to-json/test/types.ref.txt
index 1227e2467..1fb9ed9d2 100644
--- a/compiler/tools/fpp-to-json/test/types.ref.txt
+++ b/compiler/tools/fpp-to-json/test/types.ref.txt
@@ -19,7 +19,8 @@
},
"id" : 0
}
- }
+ },
+ "isDictionaryDef" : true
},
"id" : 1
}
@@ -119,7 +120,8 @@
"id" : 9
}
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 10
}
@@ -168,7 +170,8 @@
}
},
"default" : "None",
- "format" : "None"
+ "format" : "None",
+ "isDictionaryDef" : false
},
"id" : 15
}
@@ -250,7 +253,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : false
},
"id" : 33
}
@@ -316,7 +320,8 @@
},
"id" : 38
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 39
}
@@ -404,7 +409,8 @@
"id" : 48
}
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 49
}
@@ -492,7 +498,8 @@
"id" : 58
}
}
- }
+ },
+ "isDictionaryDef" : false
},
"id" : 59
}
@@ -559,7 +566,8 @@
}
},
"default" : "None",
- "format" : "None"
+ "format" : "None",
+ "isDictionaryDef" : false
},
"id" : 65
}
@@ -685,7 +693,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : true
},
"id" : 86
}
@@ -780,7 +789,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : false
},
"id" : 99
}
@@ -829,7 +839,8 @@
}
},
"default" : "None",
- "format" : "None"
+ "format" : "None",
+ "isDictionaryDef" : false
},
"id" : 104
}
@@ -880,7 +891,8 @@
"id" : 107
}
}
- }
+ },
+ "isDictionaryDef" : true
},
"id" : 108
}
@@ -962,7 +974,8 @@
]
]
],
- "default" : "None"
+ "default" : "None",
+ "isDictionaryDef" : true
},
"id" : 115
}
@@ -971,6 +984,72 @@
},
[
]
+ ],
+ [
+ [
+ ],
+ {
+ "DefAliasType" : {
+ "node" : {
+ "AstNode" : {
+ "data" : {
+ "name" : "Alias1",
+ "typeName" : {
+ "AstNode" : {
+ "data" : {
+ "TypeNameInt" : {
+ "name" : {
+ "U32" : {
+
+ }
+ }
+ }
+ },
+ "id" : 116
+ }
+ },
+ "isDictionaryDef" : true
+ },
+ "id" : 117
+ }
+ }
+ }
+ },
+ [
+ ]
+ ],
+ [
+ [
+ ],
+ {
+ "DefAliasType" : {
+ "node" : {
+ "AstNode" : {
+ "data" : {
+ "name" : "Alias2",
+ "typeName" : {
+ "AstNode" : {
+ "data" : {
+ "TypeNameInt" : {
+ "name" : {
+ "U32" : {
+
+ }
+ }
+ }
+ },
+ "id" : 118
+ }
+ },
+ "isDictionaryDef" : false
+ },
+ "id" : 119
+ }
+ }
+ }
+ },
+ [
+ ]
]
]
}
@@ -978,7 +1057,7 @@
{
"0" : {
"file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
- "pos" : "1.24",
+ "pos" : "1.35",
"includingLoc" : "None"
},
"1" : {
@@ -1503,17 +1582,17 @@
},
"105" : {
"file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
- "pos" : "34.20",
+ "pos" : "34.31",
"includingLoc" : "None"
},
"106" : {
"file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
- "pos" : "34.23",
+ "pos" : "34.34",
"includingLoc" : "None"
},
"107" : {
"file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
- "pos" : "34.34",
+ "pos" : "34.45",
"includingLoc" : "None"
},
"108" : {
@@ -1555,6 +1634,26 @@
"file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
"pos" : "36.1",
"includingLoc" : "None"
+ },
+ "116" : {
+ "file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
+ "pos" : "43.26",
+ "includingLoc" : "None"
+ },
+ "117" : {
+ "file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
+ "pos" : "43.1",
+ "includingLoc" : "None"
+ },
+ "118" : {
+ "file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
+ "pos" : "44.15",
+ "includingLoc" : "None"
+ },
+ "119" : {
+ "file" : "[ local path prefix ]/compiler/tools/fpp-to-json/test/types.fpp",
+ "pos" : "44.1",
+ "includingLoc" : "None"
}
}
{
@@ -1649,117 +1748,11 @@
}
}
},
- "33" : {
- "Struct" : {
- "node" : {
- "astNodeId" : 33
- },
- "anonStruct" : {
- "members" : {
- "x" : {
- "Int" : {
- "PrimitiveInt" : {
- "kind" : {
- "U32" : {
-
- }
- }
- }
- }
- },
- "y" : {
- "String" : {
- "size" : "None"
- }
- }
- }
- },
- "default" : {
- "Some" : {
- "anonStruct" : {
- "members" : {
- "x" : {
- "PrimitiveInt" : {
- "value" : 0,
- "kind" : {
- "U32" : {
-
- }
- }
- }
- },
- "y" : {
- "String" : {
- "value" : ""
- }
- }
- }
- },
- "t" : {
- "node" : {
- "astNodeId" : 33
- },
- "anonStruct" : {
- "members" : {
- "x" : {
- "Int" : {
- "PrimitiveInt" : {
- "kind" : {
- "U32" : {
-
- }
- }
- }
- }
- },
- "y" : {
- "String" : {
- "size" : "None"
- }
- }
- }
- },
- "default" : "None",
- "sizes" : {
-
- },
- "formats" : {
-
- }
- }
- }
- },
- "sizes" : {
-
- },
- "formats" : {
-
- }
- }
- },
"56" : {
"String" : {
"size" : "None"
}
},
- "48" : {
- "AnonStruct" : {
- "members" : {
- "x" : {
- "Int" : {
- "Integer" : {
-
- }
- }
- },
- "y" : {
- "String" : {
- "size" : "None"
- }
- }
- }
- }
- },
"106" : {
"Primitive" : {
"Float" : {
@@ -1806,6 +1799,35 @@
}
}
},
+ "118" : {
+ "Int" : {
+ "PrimitiveInt" : {
+ "kind" : {
+ "U32" : {
+
+ }
+ }
+ }
+ }
+ },
+ "119" : {
+ "AliasType" : {
+ "node" : {
+ "astNodeId" : 119
+ },
+ "aliasType" : {
+ "Int" : {
+ "PrimitiveInt" : {
+ "kind" : {
+ "U32" : {
+
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"84" : {
"Array" : {
"node" : {
@@ -2814,6 +2836,112 @@
"format" : "None"
}
},
+ "33" : {
+ "Struct" : {
+ "node" : {
+ "astNodeId" : 33
+ },
+ "anonStruct" : {
+ "members" : {
+ "x" : {
+ "Int" : {
+ "PrimitiveInt" : {
+ "kind" : {
+ "U32" : {
+
+ }
+ }
+ }
+ }
+ },
+ "y" : {
+ "String" : {
+ "size" : "None"
+ }
+ }
+ }
+ },
+ "default" : {
+ "Some" : {
+ "anonStruct" : {
+ "members" : {
+ "x" : {
+ "PrimitiveInt" : {
+ "value" : 0,
+ "kind" : {
+ "U32" : {
+
+ }
+ }
+ }
+ },
+ "y" : {
+ "String" : {
+ "value" : ""
+ }
+ }
+ }
+ },
+ "t" : {
+ "node" : {
+ "astNodeId" : 33
+ },
+ "anonStruct" : {
+ "members" : {
+ "x" : {
+ "Int" : {
+ "PrimitiveInt" : {
+ "kind" : {
+ "U32" : {
+
+ }
+ }
+ }
+ }
+ },
+ "y" : {
+ "String" : {
+ "size" : "None"
+ }
+ }
+ }
+ },
+ "default" : "None",
+ "sizes" : {
+
+ },
+ "formats" : {
+
+ }
+ }
+ }
+ },
+ "sizes" : {
+
+ },
+ "formats" : {
+
+ }
+ }
+ },
+ "117" : {
+ "AliasType" : {
+ "node" : {
+ "astNodeId" : 117
+ },
+ "aliasType" : {
+ "Int" : {
+ "PrimitiveInt" : {
+ "kind" : {
+ "U32" : {
+
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"50" : {
"Int" : {
"PrimitiveInt" : {
@@ -3239,6 +3367,35 @@
}
}
},
+ "48" : {
+ "AnonStruct" : {
+ "members" : {
+ "x" : {
+ "Int" : {
+ "Integer" : {
+
+ }
+ }
+ },
+ "y" : {
+ "String" : {
+ "size" : "None"
+ }
+ }
+ }
+ }
+ },
+ "116" : {
+ "Int" : {
+ "PrimitiveInt" : {
+ "kind" : {
+ "U32" : {
+
+ }
+ }
+ }
+ }
+ },
"65" : {
"Array" : {
"node" : {
@@ -6066,5 +6223,37 @@
},
"stateMachineMap" : {
- }
+ },
+ "dictionarySymbolSet" : [
+ {
+ "Constant" : {
+ "nodeId" : 1,
+ "unqualifiedName" : "numElements"
+ }
+ },
+ {
+ "Enum" : {
+ "nodeId" : 115,
+ "unqualifiedName" : "SignalType"
+ }
+ },
+ {
+ "AliasType" : {
+ "nodeId" : 117,
+ "unqualifiedName" : "Alias1"
+ }
+ },
+ {
+ "Struct" : {
+ "nodeId" : 86,
+ "unqualifiedName" : "SignalInfo"
+ }
+ },
+ {
+ "Array" : {
+ "nodeId" : 108,
+ "unqualifiedName" : "SignalSet"
+ }
+ }
+ ]
}
diff --git a/compiler/tools/fpp/src/main/scala/fpp-locate-uses.scala b/compiler/tools/fpp/src/main/scala/fpp-locate-uses.scala
index e987be4b0..84d5ae023 100644
--- a/compiler/tools/fpp/src/main/scala/fpp-locate-uses.scala
+++ b/compiler/tools/fpp/src/main/scala/fpp-locate-uses.scala
@@ -84,7 +84,15 @@ object FPPLocateUses {
case _: Symbol.Struct => Ast.SpecLoc.Type
case _: Symbol.Topology => Ast.SpecLoc.Topology
}
- val specLocNode = AstNode.create(Ast.SpecLoc(kind, qualIdentNode, fileNode))
+ val isDictionaryDef = s match {
+ case Symbol.Array(aNode) => aNode._2.data.isDictionaryDef
+ case Symbol.AliasType(aNode) => aNode._2.data.isDictionaryDef
+ case Symbol.Struct(aNode) => aNode._2.data.isDictionaryDef
+ case Symbol.Enum(aNode) => aNode._2.data.isDictionaryDef
+ case Symbol.Constant(aNode) => aNode._2.data.isDictionaryDef
+ case _ => false
+ }
+ val specLocNode = AstNode.create(Ast.SpecLoc(kind, qualIdentNode, fileNode, isDictionaryDef))
val specLocAnnotatedNode = (Nil, specLocNode, Nil)
FppWriter.specLocAnnotatedNode((), specLocAnnotatedNode)
}
diff --git a/docs/code-prettify/run_prettify.js b/docs/code-prettify/run_prettify.js
index 4984f8849..d823d8105 100644
--- a/docs/code-prettify/run_prettify.js
+++ b/docs/code-prettify/run_prettify.js
@@ -425,6 +425,7 @@ var IN_GLOBAL_SCOPE = false;
"cpu," +
"default," +
"diagnostic," +
+ "dictionary," +
"do," +
"drop," +
"else," +
diff --git a/docs/fpp-spec.html b/docs/fpp-spec.html
index 7101bd891..7b2fb0c44 100644
--- a/docs/fpp-spec.html
+++ b/docs/fpp-spec.html
@@ -567,6 +567,12 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
5.15.2. Type Definitions
+5.16. Dictionary Definitions
+
+
6. State Machine Behavior Elements
@@ -1177,6 +1183,7 @@ container
cpu
default
diagnostic
+dictionary
do
drop
else
@@ -1705,7 +1712,10 @@ that is defined elsewhere.
@@ -1717,6 +1727,11 @@ the type T specified after the = symbol.
Elsewhere in the model, the name N may be used as alias of (i.e., an
alternate name for) the type T .
+
+
If the optional keyword dictionary is present, then the
+definition must conform to the rules stated in the
+dictionary definitions section.
+
5.2.3. Examples
@@ -1743,7 +1758,10 @@ it.
5.3.1. Syntax
-
array identifier =
+
[
+dictionary
+]
+array identifier =
[ expression ] type-name
[
default expression
@@ -1779,6 +1797,11 @@ The type of the expression must be
When displaying the array, the format is applied to each element of the array.
There is one argument to the format string, which is an array member.
+
+
If the optional keyword dictionary is present, then the
+definition must conform to the rules stated in the
+dictionary definitions section.
+
5.3.3. Examples
@@ -2512,7 +2535,10 @@ model.
5.6.1. Syntax
+
+
If the optional keyword dictionary is present, then the
+definition must conform to the rules stated in the
+dictionary definitions section.
+
5.6.3. Examples
@@ -2567,7 +2598,10 @@ constants.
5.7.1. Syntax
-
enum identifier
+
[
+dictionary
+]
+enum identifier
[ : type-name ]
{ enum-constant-sequence }
[
@@ -2605,6 +2639,11 @@ If present, it specifies the default value a
with the enum definition.
The type of the expression must be the type of the enum definition.
+
+
If the optional keyword dictionary is present, then the
+definition must conform to the rules stated in the
+dictionary definitions section.
+
5.7.3. Inferred Representation Type
@@ -3467,7 +3506,10 @@ with it.
5.13.1. Syntax
@@ -3525,6 +3567,11 @@ The type of the expression must be
If the expression specifies a value for a member with size
greater than one, then the value is applied to each element.
+
+
If the optional keyword dictionary is present, then the
+definition must conform to the rules stated in the
+dictionary definitions section.
+
5.13.3. Examples
@@ -4332,6 +4379,61 @@ to the following rules.
+
+
5.16. Dictionary Definitions
+
+
If the optional keyword dictionary appears in a type definition or
+a constant definition, then that definition is called a
+dictionary definition .
+A dictionary definition instructs the code generator to include
+the definition in the ground dictionary.
+
+
+
5.16.1. Semantics
+
+
If a constant definition D is a dictionary definition, then the
+expression appearing in D must have one of the following types:
+
+
+
+
If a type definition D is a dictionary definition, then the type
+defined by D must be a displayable type .
+
+
+
+
5.16.2. Examples
+
+
+
dictionary type T = U32
+dictionary array A = [3] string
+dictionary constant a = 0
+
+enum E { X, Y }
+dictionary constant b = E.X
+
+type T1
+dictionary type T2 = T1 # Error: T2 is not displayable
+
+dictionary constant c = { x = U32 } # Error: struct type is not allowed
+
+
+
+
+
+
If the optional keyword dictionary appears in a location specifier S ,
+then S is called a dictionary specifier .
+
7.10.2. Semantics
+
+
A location specifier S with qualified identifier Q must conform
+to the following rules:
+
-The qualified identifier Q is resolved like a
+
Q is resolved like a
use that refers to a definition
as follows:
@@ -6654,13 +6782,19 @@ as follows:
module definition M ,
Q is implicitly qualified by the
qualified name
-of M .
+of M .
+This rule allows the resolution to occur during dependency analysis,
+before uses have been matched with their definitions.
Q need not actually refer to any definition.
This rule allows the specification of dependencies for a larger set
of files than the ones involved in a particular analysis
-or translation.
+or translation.
+If Q does refer to a definition D , then S
+must be a dictionary specifier if D is a
+dictionary definition ;
+otherwise it must not be.
The string literal must specify the path of an FPP source file, relative to the
@@ -6674,8 +6808,19 @@ location specifier.
Multiple location specifiers for the same definition are allowed in a single
-model , so long as the locations are all
-consistent.
+model , so long as the following
+conditions are met:
+
+
+
+All of the specifiers must be dictionary specifiers, or none of them must
+be.
+
+
+All the specifiers must have the same locations.
+
+
+
@@ -11892,7 +12037,7 @@ equivalent.
diff --git a/docs/fpp-users-guide.html b/docs/fpp-users-guide.html
index 10d13b19a..09febae9e 100644
--- a/docs/fpp-users-guide.html
+++ b/docs/fpp-users-guide.html
@@ -467,6 +467,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
3.4. Multiple Definitions and Element Sequences
3.5. Multiline Definitions
+3.6. Framework Constants
4. Writing Comments and Annotations
@@ -500,6 +501,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
6.3. Abstract Type Definitions
6.4. Alias Type Definitions
+6.5. Framework Types
7. Defining Enums
@@ -511,257 +513,260 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
7.5. The Default Value
-8. Defining Ports
+8. Dictionary Definitions
+9. Defining Ports
-9. Defining State Machines
+10. Defining State Machines
-10. Defining Components
+11. Defining Components
-11. Defining and Using Port Interfaces
+12. Defining and Using Port Interfaces
-12. Defining Component Instances
+13. Defining Component Instances
-13. Defining Topologies
+14. Defining Topologies
-14. Specifying Models as Files
+15. Specifying Models as Files
-15. Analyzing and Translating Models
+16. Analyzing and Translating Models
-16. Writing C Plus Plus Implementations
+17. Writing C Plus Plus Implementations
@@ -1822,6 +1827,111 @@ is not legal:
+
+
3.6. Framework Constants
+
+
Certain constants defined in FPP have a special meaning in the
+F Prime framework.
+These constants are called framework constants .
+For example, the constant Fw.DpCfg.CONTAINER_USER_DATA_SIZE
+defines the size of the user data field in a data product container.
+(Data products are an F Prime feature that we describe
+in a later section of this manual .)
+You typically set these constants by overriding configuration
+files provided in the directory default/config in the F Prime repository.
+For example, the file default/config/DpCfg.fpp provides a default value for
+Fw.DpCfg.CONTAINER_USER_DATA_SIZE.
+You can override this default value by providing your own version of
+the file DpCfg.fpp.
+The
+F
+Prime User Manual
+explains how to do this configuration.
+
+
+
The FPP analyzer does not require that framework constants be defined
+unless they are used.
+For example, the following model is valid, because it neither defines nor users
+Fw.DpCfg.CONTAINER_USER_DATA_SIZE:
+
+
+
+
The following model is valid because it defines and uses Fw.DpCfg.CONTAINER_USER_DATA_SIZE:
+
+
+
+
module Fw {
+
+ module DpCfg {
+
+ constant CONTAINER_USER_DATA_SIZE = 10
+
+ }
+
+}
+
+constant a = Fw.DpCfg.CONTAINER_USER_DATA_SIZE
+
+
+
+
The following model is invalid, because it uses Fw.DpCfg.CONTAINER_USER_DATA_SIZE
+without defining it:
+
+
+
+
constant a = Fw.DpCfg.CONTAINER_USER_DATA_SIZE
+
+
+
+
If framework constants are defined in the FPP model, then
+then they must conform to certain rules.
+These rules are spelled out in detail in the
+The
+FPP Language Specification .
+For example, Fw.DpCfg.CONTAINER_USER_DATA_SIZE must have an integer type.
+So this model is invalid:
+
+
+
+
module Fw {
+
+ module DpCfg {
+
+ constant CONTAINER_USER_DATA_SIZE = "abc"
+
+ }
+
+}
+
+
+
+
Here is what happens when you run this model through fpp-check:
+
+
+
+
% fpp-check
+module Fw {
+
+ module DpCfg {
+
+ constant CONTAINER_USER_DATA_SIZE = "abc"
+
+ }
+
+}
+^D
+fpp-check
+stdin:5.5
+ constant CONTAINER_USER_DATA_SIZE = "abc"
+ ^
+error: the F Prime framework constant Fw.DpCfg.CONTAINER_USER_DATA_SIZE must have an integer type
+
+
+
@@ -2920,6 +3030,27 @@ configure the framework.
These types are defined in the file config/FpConfig.fpp.
+
+
6.5. Framework Types
+
+
Certain types defined in FPP have a special meaning in the F Prime
+framework.
+These types are called framework types .
+For example, the type FwOpcodeType defines the type of
+a command opcode.
+(Commands are an F Prime feature that we describe
+in a later section of this manual .)
+
+
+
@@ -3163,7 +3294,95 @@ use appears inside the enum where it is defined.
-
8. Defining Ports
+
8. Dictionary Definitions
+
+
+
One of the artifacts generated from an FPP model is a dictionary
+that tells the ground data system how to interpret and display
+the data produced by the FSW.
+By default, the dictionary contains representations of the following
+types and constants defined in FPP:
+
+
+
+
+Types and constants that are known to the framework and that are
+needed by every dictionary, e.g., FwOpcodeType.
+
+
+Types and constants that appear in the definitions of the data produced
+by the FSW, e.g., event specifiers or telemetry specifiers.
+(In later sections of this manual we will explain how to define
+event reports and
+telemetry channels .)
+
+
+
+
+
Sometimes you will need the dictionary to include the definition of a type or
+constant
+that does not satisfy either of these conditions.
+For example, a downlink configuration parameter may be
+shared by the FSW implementation and the GDS and may be otherwise unused
+in the FPP model.
+
+
+
In this case you can mark a type or constant definition as a dictionary
+definition .
+A dictionary definition tells the FPP analyzer that
+whenever a dictionary is generated from the model,
+the definition should be included in the dictionary.
+
+
+
To write a dictionary definition, you write the keyword dictionary
+before the definition.
+You can do this for a constant definition, a type definition,
+or an enum definition.
+For example:
+
+
+
+
dictionary constant a = 1
+dictionary array A = [3] U32
+dictionary struct S { x: U32, y: F32 }
+dictionary type T = S
+dictionary enum E { A, B }
+
+
+
+
Each dictionary definition must observe the following rules:
+
+
+
+
+A dictionary constant definition must have a numeric value (integer or
+floating point),
+a Boolean value (true or false), a string value such as "abc", or an
+enumerated constant value such as E.A.
+
+
+A dictionary type definition must define a displayable type , i.e., a
+type that the F Prime ground data system knows how to display.
+For example, the type may not be an
+abstract type .
+Nor may it be an array or struct type that has an abstract type
+as a member type.
+
+
+
+
+
For example, the following dictionary definitions are invalid:
+
+
+
+
dictionary constant a = { x = 1, y = 2.0 } # Error: a has struct type
+dictionary type T # Error: T is an abstract type
+
+
+
+
+
+
9. Defining Ports
A port definition defines an F Prime port.
@@ -3177,7 +3396,7 @@ carried
on the port, and (3) an optional return type.
-
8.1. Port Names
+
9.1. Port Names
The simplest port definition consists of the keyword port followed
by a name.
@@ -3195,7 +3414,7 @@ This kind of port can be useful for sending or receiving a triggering event.
-
+
More often, a port will carry data.
To specify the data, you write formal parameters
@@ -3246,7 +3465,7 @@ port P(
-
8.3. Handler Functions
+
9.3. Handler Functions
As discussed further in the sections on
defining components
@@ -3432,7 +3651,7 @@ consisting of the first 40 characters of the original string.
-
8.4. Reference Parameters
+
9.4. Reference Parameters
You may write the keyword ref in front of any formal parameter p
of a port definition.
@@ -3491,7 +3710,7 @@ We discuss this pattern in the section on
-
8.5. Returning Values
+
9.5. Returning Values
Optionally, you can give a port definition a return type.
To do this you write an arrow -> and a type
@@ -3612,7 +3831,7 @@ port P(ref result: U32) -> Status
-
8.6. Pass-by-Reference Semantics
+
9.6. Pass-by-Reference Semantics
Whenever a C++ formal parameter p enables sharing of data between
an invoking component and a handler function pIn_handler,
@@ -3679,7 +3898,7 @@ reference and transfer ownership from A to B and vice
-
8.7. Annotating a Port Definition
+
9.7. Annotating a Port Definition
-
9. Defining State Machines
+
10. Defining State Machines
A hierarchical state machine (state machine for short)
@@ -3766,7 +3985,7 @@ The component also provides the functions that are called when
the state machine does actions and evaluates guards.
-
9.1. Writing a State Machine Definition
+
10.1. Writing a State Machine Definition
External state machines:
To define an external state machine, you write the keywords
@@ -3815,7 +4034,7 @@ Prime design documentation.
-
9.2. States, Signals, and Transitions
+
10.2. States, Signals, and Transitions
In this and the following sections, we explain how to define
internal state machines, i.e., state machines that are fully
@@ -4017,7 +4236,7 @@ state machine Device {
-
9.3. Actions
+
10.3. Actions
An action is a function that a state machine calls at a
specified point in its behavior.
@@ -4028,7 +4247,7 @@ When a state machine instance calls the function associated with
an action A , we say that it does A .
-
9.3.1. Actions in Transitions
+
10.3.1. Actions in Transitions
To define an action, you write the keyword action followed
by the name of the action.
@@ -4134,7 +4353,7 @@ terminating punctuation.
-
9.3.2. Entry and Exit Actions
+
10.3.2. Entry and Exit Actions
In addition to doing actions on transitions, a state machine
can do actions on entry to or exit from a state.
@@ -4253,7 +4472,7 @@ exit specifier.
-
9.3.3. Typed Signals and Actions
+
10.3.3. Typed Signals and Actions
Optionally, signals and actions may carry data values.
To specify that a signal or action carries a data value,
@@ -4362,7 +4581,7 @@ In this case the value is ignored when doing the action.
-
9.3.4. Atomicity of Signal Handling
+
10.3.4. Atomicity of Signal Handling
When an FPP state machine receives a signal, the handling of
that signal is atomic .
@@ -4404,14 +4623,14 @@ Prime design documentation.
-
9.4. More on State Transitions
+
10.4. More on State Transitions
In this section, we provide more details on how to write
state transitions
in FPP state machines.
-
9.4.1. Guarded Transitions
+
10.4.1. Guarded Transitions
Sometimes it is useful to specify that a transition should occur
only if a certain condition is true.
@@ -4537,7 +4756,7 @@ it passes in the value as an argument to the function.
-
9.4.2. Self Transitions
+
10.4.2. Self Transitions
When a state transition has the same state S as its source
and its target, and S has no substates, we call the transition
@@ -4654,7 +4873,7 @@ it receives a cmdReset signal, the following behavior occurs:
-
9.4.3. Internal Transitions
+
10.4.3. Internal Transitions
An internal transition is like a
self transition ,
@@ -4751,7 +4970,7 @@ carry data of a compatible type.
-
9.5. Choices
+
10.5. Choices
A choice definition is a state machine member that
defines a branch point for one or more transitions.
@@ -5050,7 +5269,7 @@ go to C3, and C3 to go to C1.
-
9.6. Hierarchy
+
10.6. Hierarchy
As with UML state machines, FPP state machines can have hierarchy .
That is, we can do the following:
@@ -5096,7 +5315,7 @@ In the following subsections, we explain how to define
hierarchical state machines in FPP.
-
9.6.1. Substates
+
10.6.1. Substates
In this section we explain how to define and use substates.
@@ -5304,7 +5523,7 @@ In particular,
M is the root node of the hierarchy tree.
-
9.6.2. Inherited Transitions
+
10.6.2. Inherited Transitions
In general, when a transition T is defined in a parent state S ,
T behaves as if it were defined in each of the
@@ -5493,7 +5712,7 @@ by behavioral polymorphism.
-
9.6.3. Entry and Exit Actions
+
10.6.3. Entry and Exit Actions
In previous sections on
entry and exit actions and on
@@ -5539,10 +5758,10 @@ order of the traversal, do the entry actions of S' , if any.
For example, suppose that M has a state A with substates
B and C , B has substate D , and C has substate E .
-Suppose that T goes from C to E .
+Suppose that T goes from D to E .
Then least common ancestor is A , and the following actions
would be done, in the following order:
-the exit actions of C , the exit actions of B ,
+the exit actions of D , the exit actions of B ,
the actions of T , the entry actions of C , and the
entry actions of E .
@@ -5590,7 +5809,7 @@ reenter
S .
-
+
Let S 1 and S 2 be states.
If S 1 is equal to S2 , or S 1 is an ancestor of S2 , or S2
@@ -5716,7 +5935,7 @@ be overridden.
-
9.6.5. Choices
+
10.6.5. Choices
Like state definitions, choice definitions are hierarchical.
That is, you may define a choice inside a state.
@@ -5834,7 +6053,7 @@ entry actions of B' .
-
10. Defining Components
+
11. Defining Components
In F Prime, the component is the basic unit of FSW function.
@@ -5857,7 +6076,7 @@ A passive component has no thread of control and no
message queue; it is like a non-threaded function library.
-
10.1. Component Definitions
+
11.1. Component Definitions
An FPP component definition defines an F Prime component.
To write a component definition, you write the following:
@@ -5904,7 +6123,7 @@ except for importing port interfaces, which we describe in
-
10.2. Port Instances
+
11.2. Port Instances
A port instance is a component member that specifies an instance of an FPP
port used by the instances of the component.
@@ -5920,7 +6139,7 @@ as the name of the instance and the direction of invocation
(input or output).
-
10.2.1. Basic Port Instances
+
11.2.1. Basic Port Instances
The simplest port instance specifies a kind, a name, and a type.
The kind is one of the following:
@@ -6029,7 +6248,7 @@ of type
F32Value.
-
10.2.2. Rules for Port Instances
+
11.2.2. Rules for Port Instances
The port instances appearing in a component definition must
satisfy certain rules.
@@ -6112,7 +6331,7 @@ active component Error {
-
10.2.3. Arrays of Port Instances
+
11.2.3. Arrays of Port Instances
When you specify a port instance as part of an FPP component, you
are actually specifying an array of port instances.
@@ -6157,7 +6376,7 @@ passive component F32Adder {
-
10.2.4. Priority
+
11.2.4. Priority
For async input ports, you may specify a priority.
The priority specification is not allowed for other kinds of ports.
@@ -6197,7 +6416,7 @@ from the message queue.
-
10.2.5. Queue Full Behavior
+
11.2.5. Queue Full Behavior
By default, if an invocation of an async input port causes
a message queue to overflow, then a FSW assertion fails.
@@ -6265,7 +6484,7 @@ for async input ports.
-
10.2.6. Serial Port Instances
+
11.2.6. Serial Port Instances
When writing a port instance, instead of specifying a named port type,
you may write the keyword serial.
@@ -6312,7 +6531,7 @@ the F Prime User M
-
10.3. Special Port Instances
+
11.3. Special Port Instances
A special port instance is a port instance that has a special
behavior in F Prime.
@@ -6328,7 +6547,7 @@ commands, events, telemetry, parameters, time,
and data products.
-
10.3.1. Command Ports
+
11.3.1. Command Ports
A command is an instruction to the spacecraft to perform an action.
Each component instance C that specifies commands has the following
@@ -6450,7 +6669,7 @@ response, and implementing command handlers, see the
-
10.3.2. Event Ports
+
11.3.2. Event Ports
An event is a report that something happened, for example,
that a file was successfully uplinked.
@@ -6531,7 +6750,7 @@ simplified definitions of these ports:
-
10.3.3. Telemetry Ports
+
11.3.3. Telemetry Ports
Telemetry is data regarding the state of the system.
A telemetry port allows a component to emit telemetry.
@@ -6580,7 +6799,7 @@ simplified definition of this port:
-
10.3.4. Parameter Ports
+
11.3.4. Parameter Ports
A parameter is a configurable constant that may be updated
from the ground.
@@ -6665,7 +6884,7 @@ simplified definitions of these ports:
-
10.3.5. Time Get Ports
+
11.3.5. Time Get Ports
A time get port allows a component to get the system time from a
time component.
@@ -6715,7 +6934,7 @@ simplified definition of this port:
-
10.3.6. Data Product Ports
+
11.3.6. Data Product Ports
A data product is a collection of data that can be stored to an
onboard file system, given a priority, and downlinked in priority
@@ -6840,7 +7059,7 @@ Prime design documentation.
-
10.4. Internal Ports
+
11.4. Internal Ports
An internal port is a port that a component can use to send a
message to itself.
@@ -6966,7 +7185,7 @@ Try it and see.
-
10.5. Commands
+
11.5. Commands
When defining an F Prime component, you may specify one or more commands.
When you are operating the FSW, you use the F Prime Ground Data System
@@ -6983,7 +7202,7 @@ handling, see the
Here we concentrate on how to specify commands in FPP.
-
10.5.1. Basic Commands
+
11.5.1. Basic Commands
The simplest command consists of a kind followed by the keyword
command and a name.
@@ -7081,7 +7300,7 @@ running the result through fpp-check.
-
+
When specifying a command, you may specify one or more
formal parameters.
@@ -7102,7 +7321,8 @@ for the following:
reference parameter .
-Each parameter must have a displayable type , i.e., a
+
Each parameter must have a displayable type , i.e.,
+a
type that the F Prime ground data system knows how to display.
For example, the type may not be an
abstract type .
@@ -7167,7 +7387,7 @@ stubs for the special command ports that are required by
-
10.5.3. Opcodes
+
11.5.3. Opcodes
Every command in an F Prime FSW application has an opcode .
The opcode is a number that uniquely identifies the command.
@@ -7277,7 +7497,7 @@ active component DuplicateOpcode {
-
10.5.4. Priority and Queue Full Behavior
+
11.5.4. Priority and Queue Full Behavior
When specifying an async command, you may specify
priority and
@@ -7331,7 +7551,7 @@ to sync and see what fpp-check has to say about it.
-
10.6. Events
+
11.6. Events
When defining an F Prime component, you may specify one or more events.
The F Prime framework converts each event into a C++
@@ -7346,7 +7566,7 @@ handling, see the
Here we concentrate on how to specify events in FPP.
-
10.6.1. Basic Events
+
11.6.1. Basic Events
The simplest event consists of the keyword event, a name, a severity,
and a format string.
@@ -7434,7 +7654,7 @@ code above and running the result through fpp-check.
-
+
When specifying an event, you may specify one or more
formal parameters.
@@ -7511,7 +7731,7 @@ passive component EventParameters {
-
10.6.3. Identifiers
+
11.6.3. Identifiers
Every event in an F Prime FSW application has a unique
numeric identifier.
@@ -7582,7 +7802,7 @@ passive component EventIdentifiers {
-
10.6.4. Throttling
+
11.6.4. Throttling
Sometimes it is necessary to throttle events, to ensure that
they do not flood the system.
@@ -7701,7 +7921,7 @@ emit the event until the throttle is cleared through FSW command. For details, s
-
10.7. Telemetry
+
11.7. Telemetry
When defining an F Prime component, you may specify one or more
telemetry channels .
@@ -7721,7 +7941,7 @@ handling, see the
Here we concentrate on how to specify telemetry channels in FPP.
-
10.7.1. Basic Telemetry
+
11.7.1. Basic Telemetry
The simplest telemetry channel consists of the keyword telemetry,
a name, and a data type.
@@ -7778,7 +7998,7 @@ Both ports are required for any component that has telemetry.
-
10.7.2. Identifiers
+
11.7.2. Identifiers
Every telemetry channel in an F Prime FSW application has a unique
numeric identifier.
@@ -7843,7 +8063,7 @@ passive component TlmIdentifiers {
-
10.7.3. Update Frequency
+
11.7.3. Update Frequency
You can specify how often the telemetry is emitted on a channel C .
There are two possibilities:
@@ -7924,7 +8144,7 @@ passive component TlmUpdate {
-
+
You may specify how a telemetry channel is formatted in the
ground display.
@@ -7976,7 +8196,7 @@ passive component TlmFormat {
-
10.7.5. Limits
+
11.7.5. Limits
You may specify limits , or bounds, on the expected values
carried on a telemetry channel.
@@ -8063,7 +8283,7 @@ condition (2).
-
10.8. Parameters
+
11.8. Parameters
When defining an F Prime component, you may specify one or more
parameters .
@@ -8081,7 +8301,7 @@ For complete information about F Prime parameters, see the
Here we concentrate on how to specify parameters in FPP.
-
10.8.1. Basic Parameters
+
11.8.1. Basic Parameters
The simplest parameter consists of the keyword param,
a name, and a data type.
@@ -8158,7 +8378,7 @@ above and see what fpp-check does.
-
10.8.2. Default Values
+
11.8.2. Default Values
You can specify a default value for any parameter.
This is the value that F Prime will use if no value is
@@ -8219,7 +8439,7 @@ passive component ParamDefaults {
-
10.8.3. Identifiers
+
11.8.3. Identifiers
Every parameter in an F Prime FSW application has a unique
numeric identifier.
@@ -8295,7 +8515,7 @@ passive component ParamIdentifiers {
-
10.8.4. Set and Save Opcodes
+
11.8.4. Set and Save Opcodes
Each parameter that you specify has two implied commands: one
for setting the value bound to the parameter locally in the
@@ -8396,7 +8616,7 @@ passive component ParamOpcodes {
-
10.8.5. External Parameters
+
11.8.5. External Parameters
In the default case, when you specify a parameter P in a component
C , the FPP code generator produces code for storing
@@ -8465,7 +8685,7 @@ Prime User Manual explains how to do this.
-
10.9. Data Products
+
11.9. Data Products
When defining an F Prime component, you may specify the data products
produced by that component.
@@ -8480,7 +8700,7 @@ For more information about these F Prime features, see the
Prime User Manual.
-
10.9.1. Basic Data Products
+
11.9.1. Basic Data Products
In F Prime, a data product is represented as a container .
One container holds one data product, and each data product
@@ -8585,7 +8805,7 @@ specifier, and vice versa.
-
10.9.2. Identifiers
+
11.9.2. Identifiers
Every record in an F Prime FSW application has a unique
numeric identifier.
@@ -8666,7 +8886,7 @@ and the container identifiers must be unique.
-
10.9.3. Array Records
+
11.9.3. Array Records
In the basic form of a record described above, each record that
does not have
@@ -8733,7 +8953,7 @@ it is provided when the record is serialized into a container.
-
10.10. State Machine Instances
+
11.10. State Machine Instances
A state machine instance is a component member that instantiates
an FPP state machine .
@@ -8804,7 +9024,7 @@ Prime design documentation.
-
10.11. Constants, Types, Enums, and State Machines
+
11.11. Constants, Types, Enums, and State Machines
-
10.12. Include Specifiers
+
11.12. Include Specifiers
Component definitions can become long, especially when there
are many commands, events, telemetry channels, and parameters.
@@ -8996,7 +9216,7 @@ We discuss include specifiers further in the section on
-
10.13. Matched Ports
+
11.13. Matched Ports
Some F Prime components employ the following pattern:
@@ -9090,7 +9310,7 @@ queued component Health {
-
11. Defining and Using Port Interfaces
+
12. Defining and Using Port Interfaces
A common pattern in F Prime is to use an identical set of
@@ -9104,7 +9324,7 @@ FPP has special support for defining and using port interfaces,
which we describe in this section.
-
11.1. Defining Port Interfaces
+
12.1. Defining Port Interfaces
A port interface definition defines a port interface.
To write a port interface definition, you write the following:
@@ -9181,7 +9401,7 @@ is used in a component, as described in the next section.
-
11.2. Using Port Interfaces in Component Definitions
+
12.2. Using Port Interfaces in Component Definitions
-
11.3. Using Port Interfaces in Interface Definitions
+
12.3. Using Port Interfaces in Interface Definitions
You can import a port interface into another interface.
For example:
@@ -9291,7 +9511,7 @@ interface I2 {
-
12. Defining Component Instances
+
13. Defining Component Instances
As discussed in the section on defining-components ,
@@ -9303,14 +9523,14 @@ In the next section, we will explain how to
construct topologies.
-
12.1. Component Instance Definitions
+
13.1. Component Instance Definitions
To instantiate a component, you write a component instance definition .
The form of a component instance definition depends on the kind
of the component you are instantiating: passive, queued, or active.
-
12.1.1. Passive Components
+
13.1.1. Passive Components
To instantiate a passive component, you write the following:
@@ -9463,7 +9683,7 @@ identifier range for
leftEngineTemp, which goes from
-
12.1.2. Queued Components
+
13.1.2. Queued Components
Instantiating a queued component is just like instantiating
a passive component, except that you must also specify
@@ -9522,7 +9742,7 @@ In the component instance definition, we have specified a queue size of 10.
-
12.1.3. Active Components
+
13.1.3. Active Components
Instantiating an active component is like instantiating a queued
component, except that you may specify additional parameters
@@ -9648,7 +9868,7 @@ associated with the instance should run on CPU 0.
-
12.2. Specifying the Implementation
+
13.2. Specifying the Implementation
When you define a component instance I , the FPP translator needs
to know the following information about the C++ implementation of I :
@@ -9782,7 +10002,7 @@ file
../../Svc/LinuxTime/LinuxTime.hpp.
-
12.3. Init Specifiers
+
13.3. Init Specifiers
In an F Prime FSW application, each component instance I
has some associated C++ code
@@ -9813,7 +10033,7 @@ However, most of the code is in fact initialization code,
and so FPP uses "init" as a shorthand name.)
-
12.3.1. Execution Phases
+
13.3.1. Execution Phases
The FPP translator uses init specifiers when it generates
code for an F Prime topology.
@@ -10028,7 +10248,7 @@ instance needs to deallocate memory or release resources on program exit.
-
12.3.2. Writing Init Specifiers
+
13.3.2. Writing Init Specifiers
You may write one or more init specifiers as part of a component
instance definition.
@@ -10167,7 +10387,7 @@ use the state value that we just mentioned.
-
12.4. Generation of Names
+
13.4. Generation of Names
FPP uses the following rules to generate the names associated with
component instances.
@@ -10230,7 +10450,7 @@ according to the previous paragraph.
-
13. Defining Topologies
+
14. Defining Topologies
In F Prime, a topology or connection graph is the
@@ -10251,7 +10471,7 @@ C++ code.
In this section we explain how to define a topology in FPP.
-
13.1. A Simple Example
+
14.1. A Simple Example
We begin with a simple example that shows how many of the pieces
fit together.
@@ -10381,7 +10601,7 @@ terminating punctuation is a semicolon.
-
13.2. Connection Graphs
+
14.2. Connection Graphs
In general, an FPP topology consists of a list of instances
and a set of named connection graphs.
@@ -10389,7 +10609,7 @@ There are two ways to specify connection graphs:
direct graph specifiers and pattern graph specifiers .
-
13.2.1. Direct Graph Specifiers
+
14.2.1. Direct Graph Specifiers
A direct graph specifier provides a name and a list
of connections.
@@ -10510,7 +10730,7 @@ then the port type of P may not specify a
-
13.2.2. Pattern Graph Specifiers
+
14.2.2. Pattern Graph Specifiers
A few connection patterns are so common in F Prime that they
get special treatment in FPP.
@@ -10832,7 +11052,7 @@ each on its own line, or you can separate them with commas:
-
13.3. Port Numbering
+
14.3. Port Numbering
As discussed in the
section on defining components ,
@@ -10845,7 +11065,7 @@ In FPP, there are three ways to specify port numbers:
explicit numbering, matched numbering, and general numbering.
-
13.3.1. Explicit Numbering
+
14.3.1. Explicit Numbering
To use explicit numbering, you provide an explicit port number
for a connection endpoint.
@@ -10992,7 +11212,7 @@ For example, this is what we did in the section on
-
13.3.2. Matched Numbering
+
14.3.2. Matched Numbering
Automatic matching:
After resolving
@@ -11185,7 +11405,7 @@ and use that twice to do the matching by hand.
-
13.3.3. General Numbering
+
14.3.3. General Numbering
-
13.4. Importing Topologies
+
14.4. Importing Topologies
It is often useful to decompose a flight software project
into several topologies.
@@ -11276,7 +11496,7 @@ one topology into another one.
In this section of the User Guide, we explain how to do that.
-
13.4.1. Importing Instances and Connections
+
14.4.1. Importing Instances and Connections
To import a topology A into a topology B, you write
import A inside topology B, like this:
@@ -11388,7 +11608,7 @@ connections of
B.
-
13.4.2. Private Instances
+
14.4.2. Private Instances
Often when importing topology A into topology B, you
want to include one or more instances in A that exist just
@@ -11460,7 +11680,7 @@ the connection is imported into B.
-
13.4.3. Multiple Imports
+
14.4.3. Multiple Imports
Multiple imports are allowed.
For example:
@@ -11498,7 +11718,7 @@ For example, this is incorrect:
-
13.4.4. Transitive Imports
+
14.4.4. Transitive Imports
In general, transitive imports are allowed.
For example, topology A may import topology B,
@@ -11515,7 +11735,7 @@ and C imports A, you will get an error.
-
13.5. Include Specifiers
+
14.5. Include Specifiers
You can include code from another file in a topology definition.
You do this by writing an include specifier .
@@ -11539,7 +11759,7 @@ below.
-
13.6. Telemetry Packets
+
14.6. Telemetry Packets
When defining a topology, you may (but are not required to)
specify how the telemetry channels
@@ -11552,7 +11772,7 @@ individual channels.
In this section we explain how to specify telemetry packets in FPP.
-
13.6.1. Telemetry Packet Sets
+
14.6.1. Telemetry Packet Sets
To group the channels of a topology T into packets, you write a
telemetry packet set as part of the definition of T .
@@ -11707,7 +11927,7 @@ channel M.c1.T instead of channel c1.T.
-
13.6.2. Telemetry Packet Identifiers
+
14.6.2. Telemetry Packet Identifiers
Within a telemetry packet set, every packet has a unique numeric identifier.
Typically the identifiers start at zero and count up by one.
@@ -11743,7 +11963,7 @@ packet P2 id 1 group 1 {
-
13.6.3. Omitting Channels
+
14.6.3. Omitting Channels
By default, every telemetry channel in the topology must appear
in at least one telemetry packet.
@@ -11808,7 +12028,7 @@ packet and also to appear in the omitted list.
-
13.6.4. Specifying Multiple Telemetry Packet Sets
+
14.6.4. Specifying Multiple Telemetry Packet Sets
You may specify more than one telemetry packet set in a topology.
Each telemetry packet set must have a distinct name.
@@ -11867,7 +12087,7 @@ telemetry packet set to use to decode the packets.
-
13.6.5. Include Specifiers
+
14.6.5. Include Specifiers
-
14. Specifying Models as Files
+
15. Specifying Models as Files
The previous sections have explained the syntactic and semantic elements
@@ -11932,7 +12152,7 @@ For more comprehensive coverage, see
the FPP wiki .
-
14.1. Dividing Models into Files
+
15.1. Dividing Models into Files
FPP does not require any particular division of model
elements into files.
@@ -12008,7 +12228,7 @@ multiple blocks
-
14.2. Include Specifiers
+
15.2. Include Specifiers
As part of an FPP model, you can write one or more include specifiers .
An include specifier is an instruction to include FPP source elements
@@ -12159,7 +12379,7 @@ error: identifier expected
-
14.3. Dependencies
+
15.3. Dependencies
Whenever a model spans two or more files, one file F may use
one or more definitions appearing in other files.
@@ -12256,7 +12476,7 @@ the CMake build process included in the F Prime distribution.
-
14.4. Location Specifiers
+
15.4. Location Specifiers
A location specifier is a unit of syntax in an FPP model.
It specifies the location of a definition used in the model.
@@ -12270,12 +12490,25 @@ in the section on
loc
definitions .
-
14.4.1. Syntax
+
15.4.1. Syntax
-
A location specifier consists of the keyword locate, a kind of definition,
+
In general, a location specifier consists of the keyword locate, a kind of
+definition,
the name of a definition, and a string representing a file path.
-For example, to locate the definition of constant a at a.fpp,
-we would write
+For type and constant specifiers, there is also an optional
dictionary
+specifier, which we will describe
+
below .
+
+
+
For example, to locate the definition
+
+
+
+
appearing in the file a.fpp, we would write
@@ -12284,9 +12517,58 @@ locate constant a at "a.fpp"
-
For the current version of FPP, the kind of definition can be constant,
-type, or port.
-To locate a type T in a file T.fpp, we would write the following:
+
The kind of definition must be one of the following:
+
+
+
+
As a further example, to locate a type T in a file T.fpp, we would write the
+following:
@@ -12314,9 +12596,12 @@ constants are then implied:
locate type E at "E.fpp"
+
+
The other kinds operate similarly.
+
-
14.4.2. Path Names
+
15.4.2. Path Names
-
14.4.3. Definition Names
+
15.4.3. Definition Names
The definition name appearing after the keyword locate
may be a qualified name.
@@ -12392,7 +12677,7 @@ definitions and their uses.
-
14.4.4. Included Files
+
15.4.4. Included Files
When you write a file that contains definitions and you
include that file in another file ,
@@ -12405,9 +12690,68 @@ When analyzing b.fpp, the location of the definition of the constan
is b.fpp, not a.fppi.
+
+
15.4.5. Dictionary Definitions
+
+
For type and constant specifiers only, if the definition being located
+is a
+dictionary definition , then you must
+write the keyword dictionary after the keyword locate
+and before the definition kind.
+For example, to locate the dictionary definition
+
+
+
+
dictionary constant b = 1
+
+
+
+
appearing in the file b.fpp, we would write
+
+
+
+
# Locating a dictionary constant definition
+locate dictionary constant b at "b.fpp"
+
+
+
+
The dictionary keyword tells the analyzer that the definition is a dictionary
+definition and so should be included in the dependency files of the model,
+regardless of whether the definition is used in the model.
+
+
+
If a definition is a dictionary definition and the corresponding location
+specifier does not specify dictionary (or vice versa), then the analyzer
+will report an error.
+
+
+
+
15.4.6. Repeated Location Specifiers
+
+
An FPP model may contain any number of location specifiers for the same
+definition, so long as the following conditions are met:
+
+
+
+
+All the specifiers must be consistent.
+This means that all the specifiers for the same definition
+provide the same location, and either they all specify dictionary
+or none of them does.
+
+
+All the specifiers must agree with the definition, if it exists
+in the model.
+This means that the location specifiers specify the location
+of the definition, and the specifiers specify dictionary
+if and only if the definition is a dictionary definition.
+
+
+
+
-
14.5. Locating Definitions
+
15.5. Locating Definitions
Given a collection of FPP source files F , you can generate location specifiers
for all the definitions in F .
@@ -12419,7 +12763,7 @@ When analyzing other files that use the constants, you can use the location
specifiers to discover dependencies on individual files within Constants.
-
14.5.1. Running fpp-locate-defs
+
15.5.1. Running fpp-locate-defs
To locate definitions, do the following:
@@ -12456,7 +12800,7 @@ Running
-
14.5.2. Location Paths
+
15.5.2. Location Paths
By default, the location path is relative to the current
directory.
@@ -12478,7 +12822,7 @@ For example, running
-
14.5.3. Included Definitions
+
15.5.3. Included Definitions
Consider the case where you write a definition in one file and
include that file in another file via an
@@ -12534,7 +12878,7 @@ If your main FPP files end with .fpp and your included FPP files en
-
14.6. Computing Dependencies
+
15.6. Computing Dependencies
Given files F and location specifiers L that locate the definitions used in
F , you can
@@ -12542,7 +12886,7 @@ generate the dependencies of F .
The tool for doing this is called fpp-depend.
-
14.6.1. Running fpp-depend
+
15.6.1. Running fpp-depend
To run fpp-depend, you pass it as input (1) files F that you want to
analyze
@@ -12614,7 +12958,7 @@ So the following is equivalent:
-
14.6.2. Transitive Dependencies
+
15.6.2. Transitive Dependencies
fpp-depend computes dependencies transitively.
This means that if A depends on B and B
@@ -12673,7 +13017,7 @@ produces both dependencies:
-
14.6.3. Missing Dependencies
+
15.6.3. Missing Dependencies
Suppose we construct the files locations.fpp and a.fpp, b.fpp, and c.fpp
as described in the previous section, but then we temporarily remove b.fpp.
@@ -12736,7 +13080,7 @@ the dependency [path-prefix]/b.fpp to standard output.
-
14.6.4. Included Files
+
15.6.4. Included Files
Suppose file a.fpp contains the
include specifier
@@ -12802,7 +13146,7 @@ to the output plus the contents of file .
-
14.6.5. Dependencies Between Build Modules
+
15.6.5. Dependencies Between Build Modules
As discussed
above , the standard output of fpp-depend reports transitive dependencies.
@@ -12896,7 +13240,7 @@ included files are already present in direct.txt.
-
14.6.6. Framework Dependencies
+
15.6.6. Framework Dependencies
Certain FPP constructs imply dependencies on parts of the F Prime framework
that may not be available on all platforms.
@@ -12932,7 +13276,7 @@ be provided to the linker.
-
14.7. Locating Uses
+
15.7. Locating Uses
Given a collection of files F and their dependencies D , you can generate
the locations of the definitions appearing in D and used in F .
@@ -13012,7 +13356,7 @@ for the location specifiers.
-
14.8. Path Name Aliases
+
15.8. Path Name Aliases
Because FPP associates locations with symbols, and the locations
are path names, care is required when using path names that are
@@ -13021,7 +13365,7 @@ There are two issues to consider:
relative paths and unique locations.
-
14.8.1. Relative Paths and Symbolic Links
+
15.8.1. Relative Paths and Symbolic Links
A relative path is a path that does not start with a slash and is
relative to the current directory path, which is
@@ -13087,7 +13431,7 @@ See that section for details, and for suggested workarounds.
-
14.8.2. Unique Locations
+
15.8.2. Unique Locations
The FPP analyzers assume that each symbol s has
a unique path defining the location of the source file where
@@ -13111,7 +13455,7 @@ time, after resolving relative paths as described above.
-
15. Analyzing and Translating Models
+
16. Analyzing and Translating Models
The previous section explained how to specify an FPP model
@@ -13123,7 +13467,7 @@ translation on part or all of an FPP model, after specifying
the model and computing its dependencies.
-
15.1. Checking Models
+
16.1. Checking Models
It is often useful to check a model for correctness, without
doing any translation.
@@ -13293,7 +13637,7 @@ even though c.Out has two ports and only one of them is connected.<
-
15.2. Generating C Plus Plus
+
16.2. Generating C Plus Plus
This section describes how to generate C++ from FPP.
@@ -13375,7 +13719,7 @@ for
fpp-check<
translated to C++ files.
-Table 3. C++ File Names
+Table 4. C++ File Names
@@ -13515,7 +13859,7 @@ type T3 = A # A is not C-compatible
C programs and the .hpp header in your C++ programs.
-
15.2.1. Constant Definitions
+
16.2.1. Constant Definitions
fpp-to-cpp extracts constant definitions
from the source files F .
@@ -13785,7 +14129,7 @@ an automatic default of 80.
-
15.2.2. Types, Ports, State Machines, and Components
+
16.2.2. Types, Ports, State Machines, and Components
Generating code:
To generate code for type, port, state machine, and component definitions, you
@@ -13836,7 +14180,7 @@ Prime design documentation.
-
15.2.3. Component Implementation and Unit Test Code
+
16.2.3. Component Implementation and Unit Test Code
fpp-to-cpp has options -t and -u for generating component “templates”
or
@@ -13939,7 +14283,7 @@ build system does it for you.
-
15.2.4. Topology Definitions
+
16.2.4. Topology Definitions
fpp-to-cpp also extracts topology definitions
from the source files.
@@ -13995,7 +14339,7 @@ the include guard prefix comes from the name of the topology.
-
15.2.5. Compiling the Generated Code
+
16.2.5. Compiling the Generated Code
The generated C++ is intended to compile with the following gcc
and clang compiler flags:
@@ -14025,7 +14369,7 @@ and clang compiler flags:
-
+
The tool fpp-format accepts FPP source files as input
and rewrites them as formatted output.
@@ -14099,7 +14443,7 @@ annotations back to comments.
-
15.4. Visualizing Topologies
+
16.4. Visualizing Topologies
FPP provides a tool called fpp-to-layout for generating files
that you can use to visualize topologies.
@@ -14216,7 +14560,7 @@ repository for more details.
-
15.5. Generating Ground Dictionaries
+
16.5. Generating Ground Dictionaries
A ground dictionary specifies all the commands,
events, telemetry, parameters, and data products in a FSW
@@ -14355,7 +14699,7 @@ in the project.
-
15.6. Identifying Generated Files
+
16.6. Identifying Generated Files
-
15.6.1. Using fpp-filenames
+
16.6.1. Using fpp-filenames
Like fpp-check, fpp-filenames reads the files
provided as command-line arguments if there are any;
@@ -14472,7 +14816,7 @@ CTester.hpp
-
15.6.2. Using fpp-depend
+
16.6.2. Using fpp-depend
Alternatively, you can use
fpp-depend
@@ -14547,7 +14891,7 @@ needed during dependency analysis.
-
15.7. Generating JSON Models
+
16.7. Generating JSON Models
FPP provides a tool called fpp-to-json for converting FPP models to
JavaScript Object Notation (JSON) format.
@@ -14730,7 +15074,7 @@ a complete or semantically correct FPP model to the tool.
-
15.8. Translating Older XML to FPP
+
16.8. Translating Older XML to FPP
Previous versions of F Prime used XML to represent model
elements such as components and ports.
@@ -15129,7 +15473,7 @@ to Commands.fppi.
-
16. Writing C Plus Plus Implementations
+
17. Writing C Plus Plus Implementations
When constructing an F Prime deployment in C++, there are generally
@@ -15173,7 +15517,7 @@ We also discuss serialization of data values, i.e., representin
FPP data values as binary data for storage and transmission.
-
16.1. Implementing Abstract Types
+
17.1. Implementing Abstract Types
-
16.2. Implementing External State Machines
+
17.2. Implementing External State Machines
An external state machine refers to a state machine implementation
supplied outside the FPP model.
@@ -15365,7 +15709,7 @@ see FppTest/state_machine in the F Prime repository.
-
16.3. Implementing Deployments
+
17.3. Implementing Deployments
At the highest level of an F Prime implementation, you write
two units of C++ code:
@@ -15386,7 +15730,7 @@ topology code.
We describe each of these code units below.
-
16.3.1. Application-Specific Definitions
+
17.3.1. Application-Specific Definitions
As discussed in the section on
generating C++ topology definitions , when you translate an FPP
@@ -15568,7 +15912,7 @@ The corresponding link-time symbol is defined in SystemReferenceTopologyDe
-
16.3.2. The Main Function
+
17.3.2. The Main Function
You must write a main function that performs application-specific
and system-specific tasks such as parsing command-line arguments,
@@ -15652,7 +15996,7 @@ F Prime system reference repository.
-
16.3.3. Public Symbols
+
17.3.3. Public Symbols
The header file T TopologyAc.hpp declares several public
symbols that you can use when writing your main function.
@@ -15715,7 +16059,7 @@ function, you may.
-
16.4. Serialization of FPP Values
+
17.4. Serialization of FPP Values
Every value represented in FPP can be serialized , i.e., converted into a
machine-independent sequence of bytes.
@@ -15844,7 +16188,7 @@ serialized according to its
diff --git a/docs/index.html b/docs/index.html
index 033d2808c..11deeafad 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -4,7 +4,7 @@
-
+
F Prime Prime (FPP)