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.

    5.2.1. Syntax

    -

    type identifier = type-name

    +

    [ +dictionary +] +type identifier = type-name

    @@ -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

    -

    constant +

    [ +dictionary +] +constant identifier = expression

    @@ -2529,6 +2555,11 @@ the constant definition according to the scoping rules for names, you can use Q as a name for v.

    +
    +

    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

    -

    struct identifier +

    [ +dictionary +] +struct identifier { struct-type-member-sequence } [ default expression ]

    @@ -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
    +
    +
    +
    +
    @@ -6578,7 +6680,17 @@ of a definition.

    string-literal

  • -

    A constant location specifier locate constant +

    A constant location specifier locate +[ +dictionary +] +constant +qual-ident at +string-literal

    +
  • +
  • +

    A port interface specifier locate +interface qual-ident at string-literal

  • @@ -6598,54 +6710,70 @@ of a definition.

    string-literal

  • -

    A type location specifier locate type +

    A type location specifier locate +[ +dictionary +] +type qual-ident at string-literal

  • +
    +

    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:

    +
    1. -

      The qualified identifier Q is resolved like a +

      Q is resolved like a use that refers to a definition as follows:

      1. +

        A component instance location specifier refers to a +component instance definition.

        +
      2. +
      3. +

        A component location specifier refers to a +component definition.

        +
      4. +
      5. A constant location specifier refers to a constant definition.

      6. +

        A port interface location specifier refers to a +port interface definition.

        +
      7. +
      8. +

        A port location specifier refers to a +port definition.

        +
      9. +
      10. +

        A state machine location specifier refers to a +state machine definition.

        +
      11. +
      12. +

        A topology location specifier refers to a +topology definition.

        +
      13. +
      14. A type location specifier refers to an array definition, enum definition, struct definition, or abstract type definition.

      15. -
      16. -

        A port location specifier refers to a -port definition.

        -
      17. -
      18. -

        A component location specifier refers to a -component definition.

        -
      19. -
      20. -

        A component instance location specifier refers to a -component instance definition.

        -
      21. -
      22. -

        A topology location specifier refers to a -topology definition.

        -
      23. -
      24. -

        A state machine location specifier refers to a -state machine definition.

        -
    2. @@ -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.

    3. 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.

    4. The string literal must specify the path of an FPP source file, relative to the @@ -6674,8 +6808,19 @@ location specifier.

    5. 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:

      +
      +
        +
      1. +

        All of the specifiers must be dictionary specifiers, or none of them must +be.

        +
      2. +
      3. +

        All the specifiers must have the same locations.

        +
      4. +
      +
    @@ -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:

    +
    +
    +
    +
    constant a = 0
    +
    +
    +
    +

    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.)

    +
    +
    +

    Framework types are like framework +constants: +you typically define them by overriding configuration files +provided by F Prime, and if they are defined, then they must +conform to certain rules. +The +FPP Language Specification has all the details.

    +
    +
    @@ -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:

    +
    +
    +
      +
    1. +

      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.

      +
    2. +
    3. +

      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.

      +
    4. +
    +
    +
    +

    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.

    -

    8.2. Formal Parameters

    +

    9.2. Formal Parameters

    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

    A port definition is an annotatable element. @@ -3701,7 +3920,7 @@ port P(

    -

    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 S1 and S2 be states. If S1 is equal to S2, or S1 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.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.

    -

    10.5.2. Formal Parameters

    +

    11.5.2. Formal Parameters

    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.

    -

    10.6.2. Formal Parameters

    +

    11.6.2. Formal Parameters

    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 {
    -

    10.7.4. Format Strings

    +

    11.7.4. Format Strings

    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

    You can write a constant definition, type definition, @@ -8943,7 +9163,7 @@ We will have more to say about this issue in the section on

    -

    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

    Once you have defined a port interface, you can use it in a component definition. To do this you write a component @@ -9252,7 +9472,7 @@ passive component C {

    -

    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

    After resolving explicit numbering and @@ -11240,7 +11460,7 @@ a.p[1] -> c.p[0]

    -

    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

    When writing a telemetry packet set, you can include code @@ -11913,7 +12133,7 @@ from other files, if you wish.

    -

    14. Specifying Models as Files

    +

    15. Specifying Models as Files

    -

    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

    +
    +
    +
    +
    constant a = 0
    +
    +
    +
    +

    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:

    +
    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 3. Location Specifier Kinds
    KeywordMeaning

    component

    A component definition

    constant

    A constant definition

    instance

    A component instance definition

    interface

    A port interface definition

    port

    A port definition

    state machine

    A state machine definition

    topology

    A topology definition

    type

    A type or enum definition

    +
    +

    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

    As with include specifiers, @@ -12345,7 +12630,7 @@ Then in b.fpp we could write this:

    -

    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:

    +
    +
    +
      +
    1. +

      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.

      +
    2. +
    3. +

      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.

      +
    4. +
    +
    +
    -

    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.

    - +

    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.

    - +@@ -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:

    -

    15.3. Formatting FPP Source

    +

    16.3. Formatting FPP Source

    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.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

    When translating to C++, an abstract type definition @@ -15347,7 +15691,7 @@ the generated C++ may not compile.

    -

    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)
    Table 3. C++ File NamesTable 4. C++ File Names