Merge branch 'feat/dictionary-specifier' into dictionary-specifier

This commit is contained in:
Rob Bocchino 2025-10-28 16:02:21 -07:00
commit d31670c654
19 changed files with 125 additions and 78 deletions

View File

@ -425,6 +425,7 @@ var IN_GLOBAL_SCOPE = false;
"cpu," +
"default," +
"diagnostic," +
"dictionary," +
"do," +
"drop," +
"else," +

View File

@ -1728,7 +1728,7 @@ Elsewhere in the model, the name <em>N</em> may be used as alias of (i.e., an
alternate name for) the type <em>T</em>.</p>
</div>
<div class="paragraph">
<p>If the optional <code>dictionary</code> keyword is present, then the
<p>If the optional keyword <code>dictionary</code> is present, then the
definition must conform to the rules stated in the
<a href="#Definitions_Dictionary-Definitions">dictionary definitions</a> section.</p>
</div>
@ -1781,7 +1781,9 @@ whose value is greater than zero.
</div>
<div class="paragraph">
<p>The definition associates the name <em>N</em> with a new type <em>T'</em>
that represents an array of <em>n</em> elements of type <em>T</em>.</p>
that represents an array of <em>n</em> elements of type <em>T</em>.
The value <em>n</em> is called the <strong>size</strong> of the array type <em>T'</em>.
The type <em>T</em> is called the <strong>element type</strong> of the array type <em>T'</em>.</p>
</div>
<div class="paragraph">
<p>The expression following the keyword <code>default</code> is optional.
@ -1796,7 +1798,7 @@ 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.</p>
</div>
<div class="paragraph">
<p>If the optional <code>dictionary</code> keyword is present, then the
<p>If the optional keyword <code>dictionary</code> is present, then the
definition must conform to the rules stated in the
<a href="#Definitions_Dictionary-Definitions">dictionary definitions</a> section.</p>
</div>
@ -2554,7 +2556,7 @@ the constant definition according to the
rules for names</a>, you can use <em>Q</em> as a name for <em>v</em>.</p>
</div>
<div class="paragraph">
<p>If the optional <code>dictionary</code> keyword is present, then the
<p>If the optional keyword <code>dictionary</code> is present, then the
definition must conform to the rules stated in the
<a href="#Definitions_Dictionary-Definitions">dictionary definitions</a> section.</p>
</div>
@ -2638,7 +2640,7 @@ with the enum definition.
The type of the expression must be the type of the enum definition.</p>
</div>
<div class="paragraph">
<p>If the optional <code>dictionary</code> keyword is present, then the
<p>If the optional keyword <code>dictionary</code> is present, then the
definition must conform to the rules stated in the
<a href="#Definitions_Dictionary-Definitions">dictionary definitions</a> section.</p>
</div>
@ -3566,7 +3568,7 @@ If the expression specifies a value for a member with size
greater than one, then the value is applied to each element.</p>
</div>
<div class="paragraph">
<p>If the optional <code>dictionary</code> keyword is present, then the
<p>If the optional keyword <code>dictionary</code> is present, then the
definition must conform to the rules stated in the
<a href="#Definitions_Dictionary-Definitions">dictionary definitions</a> section.</p>
</div>
@ -4380,29 +4382,26 @@ to the following rules.</p>
<div class="sect2">
<h3 id="Definitions_Dictionary-Definitions">5.16. Dictionary Definitions</h3>
<div class="paragraph">
<p>If a type definition or a constant definition has the optional
<code>dictionary</code> keyword, then it is called a <strong>dictionary definition</strong>.</p>
<p>If the optional keyword <code>dictionary</code> appears in a type definition or
a constant definition, then that definition is called a
<strong>dictionary definition</strong>.
A dictionary definition instructs the code generator to include
the definition in the ground dictionary.</p>
</div>
<div class="sect3">
<h4 id="Definitions_Dictionary-Definitions_Semantics">5.16.1. Semantics</h4>
<div class="paragraph">
<p>Type definitions that are included in the dictionary must be
<a href="#Types_Displayable-Types">displayable</a>.</p>
<p>If a type definition <em>D</em> is a dictionary definition, then the type
defined by <em>D</em> must be a <a href="#Types_Displayable-Types">displayable type</a>.</p>
</div>
<div class="paragraph">
<p>Constants that are included in the dictionary must be one of
the following:</p>
<p>If a constant definition <em>D</em> is a dictionary definition, then the
expression appearing in <em>D</em> must have one of the following types:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A <a href="#Types_Primitive-Integer-Types">primitive integer type</a>.</p>
</li>
<li>
<p>A <a href="#Types_Floating-Point-Types">floating-point type</a>.</p>
</li>
<li>
<p>A <a href="#Types_The-Boolean-Type">boolean type</a>.</p>
<p>A <a href="#Types_Primitive-Types">primitive type</a>.</p>
</li>
<li>
<p>A <a href="#Types_String-Types">string type</a>.</p>
@ -4419,7 +4418,16 @@ the following:</p>
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">dictionary type T = U32
dictionary array A = [3] string
dictionary constant a = 0</code></pre>
dictionary constant a = 0
enum E { X, Y }
dictionary constant b = E.X
type T1
dictionary type T2 = T1 # Error: T2 is not displayable
# Error: c does not have primitive, string, or enum type
dictionary constant c = { x = U32 }</code></pre>
</div>
</div>
</div>
@ -6705,16 +6713,20 @@ of a <a href="#Definitions">definition</a>.</p>
</ul>
</div>
<div class="paragraph">
<p>A location specifier for a constant or type with the
<code>dictionary</code> keyword is called a <strong>dictionary specifier</strong>.</p>
<p>If the optional keyword <code>dictionary</code> appears in a location specifier <em>S</em>,
then <em>S</em> is called a <strong>dictionary specifier</strong>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifiers_Location-Specifiers_Semantics">7.10.2. Semantics</h4>
<div class="paragraph">
<p>A location specifier <em>S</em> with qualified identifier <em>Q</em> must conform
to the following rules:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The qualified identifier <em>Q</em> is resolved like a
<p><em>Q</em> is resolved like a
<a href="#Definitions-and-Uses_Uses">use</a> that refers to a <a href="#Definitions">definition</a>
as follows:</p>
<div class="olist loweralpha">
@ -6758,13 +6770,19 @@ as follows:</p>
<a href="#Definitions_Module-Definitions">module definition <em>M</em></a>,
<em>Q</em> is implicitly qualified by the
<a href="#Scoping-of-Names_Names-of-Definitions">qualified name</a>
of <em>M</em>.</p>
of <em>M</em>.
This rule allows the resolution to occur during dependency analysis,
before uses have been matched with their definitions.</p>
</li>
<li>
<p><em>Q</em> 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.</p>
or translation.
If <em>Q</em> does refer to a definition <em>D</em>, then <em>S</em>
must be a dictionary specifier if <em>D</em> is a
<a href="#Definitions_Dictionary-Definitions">dictionary definition</a>;
otherwise it must not be.</p>
</li>
<li>
<p>The string literal must specify the path of an FPP source file, relative to the
@ -6778,13 +6796,19 @@ location specifier.</p>
</li>
<li>
<p>Multiple location specifiers for the same definition are allowed in a single
<a href="#Translation-Units-and-Models_Models">model</a>, so long as the locations are all
consistent.</p>
<a href="#Translation-Units-and-Models_Models">model</a>, so long as the following
conditions are met:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>All of the specifiers must be dictionary specifiers, or none of them must
be.</p>
</li>
<li>
<p>If a location specifier is a dictionary specifier and if <em>Q</em> refers to
a constant or type definition, then the definition must be a
<a href="#Definitions_Dictionary-Definitions">dictionary definition</a>.</p>
<p>All the specifiers must have the same locations.</p>
</li>
</ol>
</div>
</li>
</ol>
</div>
@ -12001,7 +12025,7 @@ equivalent.</p>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-10-28 15:38:47 -0700
Last updated 2025-10-28 16:02:16 -0700
</div>
</div>
<script src="code-prettify/run_prettify.js"></script>

View File

@ -15789,7 +15789,7 @@ serialized according to its
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-10-28 15:38:48 -0700
Last updated 2025-10-28 15:59:57 -0700
</div>
</div>
<script src="code-prettify/run_prettify.js"></script>

View File

@ -18,8 +18,8 @@ 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 `dictionary` keyword is present, then the
definition must conform to the rules stated in the
If the optional keyword `dictionary` is present, then the
definition must conform to the rules stated in the
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Examples

View File

@ -26,6 +26,8 @@ _type-name_ names the type _T_ of each array element.
The definition associates the name _N_ with a new type _T'_
that represents an array of _n_ elements of type _T_.
The value _n_ is called the *size* of the array type _T'_.
The type _T_ is called the *element type* of the array type _T'_.
The expression following the keyword `default` is optional.
If present, it specifies the <<Types_Default-Values,default value>> associated
@ -37,8 +39,8 @@ The optional format specifier specifies a <<Format-Strings,format string>>.
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 `dictionary` keyword is present, then the
definition must conform to the rules stated in the
If the optional keyword `dictionary` is present, then the
definition must conform to the rules stated in the
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Examples

View File

@ -24,8 +24,8 @@ the constant definition according to the
<<Scoping-of-Names_Resolution-of-Qualified-Identifiers,scoping
rules for names>>, you can use _Q_ as a name for _v_.
If the optional `dictionary` keyword is present, then the
definition must conform to the rules stated in the
If the optional keyword `dictionary` is present, then the
definition must conform to the rules stated in the
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Examples

View File

@ -1,19 +1,20 @@
=== Dictionary Definitions
If a type definition or a constant definition has the optional
`dictionary` keyword, then it is called a *dictionary definition*.
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.
==== Semantics
Type definitions that are included in the dictionary must be
<<Types_Displayable-Types, displayable>>.
If a type definition _D_ is a dictionary definition, then the type
defined by _D_ must be a <<Types_Displayable-Types, displayable type>>.
Constants that are included in the dictionary must be one of
the following:
If a constant definition _D_ is a dictionary definition, then the
expression appearing in _D_ must have one of the following types:
* A <<Types_Primitive-Integer-Types,primitive integer type>>.
* A <<Types_Floating-Point-Types,floating-point type>>.
* A <<Types_The-Boolean-Type,boolean type>>.
* A <<Types_Primitive-Types,primitive type>>.
* A <<Types_String-Types,string type>>.
* An <<Types_Enum-Types,enum type>>.
@ -24,4 +25,13 @@ the following:
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
# Error: c does not have primitive, string, or enum type
dictionary constant c = { x = U32 }
----

View File

@ -52,8 +52,8 @@ If present, it specifies the <<Types_Default-Values,default value>> associated
with the enum definition.
The type of the expression must be the type of the enum definition.
If the optional `dictionary` keyword is present, then the
definition must conform to the rules stated in the
If the optional keyword `dictionary` is present, then the
definition must conform to the rules stated in the
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Inferred Representation Type

View File

@ -59,8 +59,8 @@ 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 `dictionary` keyword is present, then the
definition must conform to the rules stated in the
If the optional keyword `dictionary` is present, then the
definition must conform to the rules stated in the
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Examples

View File

@ -183,7 +183,7 @@ step are all the matched connections at _I_ `.` stem:[p_2].
.. For each pair stem:[(c_1,c_2)] computed in step c:
... If stem:[c_1] has a port number stem:[n_1] assigned at _I_ `.` stem:[p_1] and
... If stem:[c_1] has a port number stem:[n_1] assigned at _I_ `.` stem:[p_1] and
stem:[c_2] has a port number stem:[n_2] assigned at
_I_ `.` stem:[p_2], then check that stem:[n_1 = n_2].
@ -305,7 +305,7 @@ The only requirement levied here is that, when generating a dictionary,
the FPP implementation must guarantee that all the framework definitions
required by the dictionary specification are available in the model.
Those framework definitions are specified
in the https://fprime.jpl.nasa.gov/latest/docs/reference/fpp-json-dict/[F Prime
in the https://fprime.jpl.nasa.gov/latest/docs/reference/fpp-json-dict/[F Prime
dictionary specification].
==== Examples

View File

@ -1,6 +1,6 @@
=== Array Subscript Expressions
An *array subscript expression* is an expression that selects an element from
An *array subscript expression* is an expression that selects an element from
an array value.
==== Syntax

View File

@ -29,7 +29,7 @@ constant definition according to the
for resolving qualified identifiers>>, then it evaluates to the value
associated with the corresponding <<Definitions,definition>>.
. Otherwise if stem:[e] is an <<Expressions,expression>> of type stem:[T],
. Otherwise if stem:[e] is an <<Expressions,expression>> of type stem:[T],
where
stem:[T] is a <<Types_Struct-Types,struct type>>
or <<Types_Internal-Types_Anonymous-Struct-Types,anonymous struct type>>

View File

@ -97,7 +97,7 @@ stem:[[0,10^6)].
+
+
If a throttle period stem:[p] is specified for event _E_, and the throttle
If a throttle period stem:[p] is specified for event _E_, and the throttle
count
for _E_ goes from zero to nonzero at time stem:[t], and a request
to emit an instance of _E_ occurs at or after time stem:[t + p], then the

View File

@ -16,10 +16,10 @@ A location specifier is one of the following:
<<Scoping-of-Names_Qualified-Identifiers,_qual-ident_>> `at`
<<Expressions_String-Literals,_string-literal_>>
* A *constant location specifier* `locate`
* A *constant location specifier* `locate`
_[_
`dictionary`
_]_
_]_
`constant`
<<Scoping-of-Names_Qualified-Identifiers,_qual-ident_>> `at`
<<Expressions_String-Literals,_string-literal_>>
@ -44,12 +44,15 @@ _]_
<<Scoping-of-Names_Qualified-Identifiers,_qual-ident_>> `at`
<<Expressions_String-Literals,_string-literal_>>
A location specifier for a constant or type with the
`dictionary` keyword is called a *dictionary specifier*.
If the optional keyword `dictionary` appears in a location specifier _S_,
then _S_ is called a *dictionary specifier*.
==== Semantics
. The qualified identifier _Q_ is resolved like a
A location specifier _S_ with qualified identifier _Q_ must conform
to the following rules:
. _Q_ is resolved like a
<<Definitions-and-Uses_Uses,use>> that refers to a <<Definitions,definition>>
as follows:
@ -82,11 +85,17 @@ as follows:
_Q_ is implicitly qualified by the
<<Scoping-of-Names_Names-of-Definitions,qualified name>>
of _M_.
This rule allows the resolution to occur during dependency analysis,
before uses have been matched with their definitions.
. _Q_ need not actually refer to any definition.
This rule allows the specification of dependencies for a larger set
of files than the ones involved in a particular analysis
or translation.
If _Q_ does refer to a definition _D_, then _S_
must be a dictionary specifier if _D_ is a
<<Definitions_Dictionary-Definitions,dictionary definition>>;
otherwise it must not be.
. The string literal must specify the path of an FPP source file, relative to the
<<Translation-Units-and-Models_Locations,location>>
@ -98,12 +107,13 @@ the file must contain the definition referred to in the
location specifier.
. Multiple location specifiers for the same definition are allowed in a single
<<Translation-Units-and-Models_Models,model>>, so long as the locations are all
consistent.
<<Translation-Units-and-Models_Models,model>>, so long as the following
conditions are met:
. If a location specifier is a dictionary specifier and if _Q_ refers to
a constant or type definition, then the definition must be a
<<Definitions_Dictionary-Definitions,dictionary definition>>.
.. All of the specifiers must be dictionary specifiers, or none of them must
be.
.. All the specifiers must have the same locations.
==== Examples

View File

@ -1,7 +1,7 @@
=== Telemetry Packet Set Specifiers
A *telemetry packet set specifier* arranges the telemetry channels of a
topology into a set of <<Specifiers_Telemetry-Packet-Specifiers,telemetry
topology into a set of <<Specifiers_Telemetry-Packet-Specifiers,telemetry
packets>>.
A telemetry packet set specifier is part of a
<<Definitions_Topology-Definitions, topology definition>>.
@ -35,7 +35,7 @@ and the terminating punctuation is a comma.
==== Semantics
FPP recursively resolves any include specifiers in
FPP recursively resolves any include specifiers in
_telemetry-packet-group-member-sequence_.
This action converts _telemetry-packet-group-member-sequence_ to a
list _L_ of telemetry packet specifiers,

View File

@ -151,7 +151,7 @@ with element type stem:[T] and size stem:[n].
. Check that stem:[T_2] <<Type-Checking_Type-Conversion,may be converted to>>
_Integer_.
. Use stem:[T] as the type of the expression.
=== Struct Expressions
@ -295,7 +295,7 @@ are <<Type-Checking_Identical-Types,identical types>>.
. If either stem:[T_1] or stem:[T_2] or both is an
<<Types_Alias-Types,alias type>>, then stem:[T_1]
may be converted to stem:[T_2] if the <<Types_Underlying-Types,underlying
may be converted to stem:[T_2] if the <<Types_Underlying-Types,underlying
type>> of stem:[T_1] may be converted to
the <<Types_Underlying-Types,underlying type>> of stem:[T_2].
@ -373,16 +373,16 @@ the whole expression):
<<Type-Checking_Identical-Types,identical types>>, then let
stem:[T] be stem:[T_1].
. Otherwise if stem:[T_1] or stem:[T_2] or both are <<Types_Alias-Types,alias
. Otherwise if stem:[T_1] or stem:[T_2] or both are <<Types_Alias-Types,alias
types>>, then do the following:
.. Let stem:[L_1] be the <<Types_Alias-Lists,alias list>> of stem:[T_1].
.. Let stem:[L_2] be the <<Types_Alias-Lists,alias list>> of stem:[T_2].
.. If there is no type in stem:[L_1] that is
.. If there is no type in stem:[L_1] that is
<<Type-Checking_Identical-Types,identical>>
to a type in stem:[L_2], then replace each each alias type with its
to a type in stem:[L_2], then replace each each alias type with its
<<Types_Underlying-Types,underlying type>> and reapply these rules.
.. Otherwise let stem:[T] be the first type in stem:[L_2] that is identical

View File

@ -21,10 +21,10 @@ stem:[O_2] in the following cases.
.. stem:[T_1] and stem:[T_2] are <<Type-Checking_Identical-Types,identical types>>.
.. Either or both of stem:[T_1] and stem:[T_2] is an <<Types_Alias-Types,alias
.. Either or both of stem:[T_1] and stem:[T_2] is an <<Types_Alias-Types,alias
type>>,
and _Some_ stem:[T'_1] may be converted to _Some_ stem:[T'_2], where
stem:[T'_1] is the <<Types_Underlying-Types,underlying type>> of stem:[T_1],
stem:[T'_1] is the <<Types_Underlying-Types,underlying type>> of stem:[T_1],
and
stem:[T'_2] is the <<Types_Underlying-Types,underlying type>> of stem:[T_2].

View File

@ -42,7 +42,7 @@ where _n_ is an integer value in the range [1,2^31-1].
There is one string type `string` and one string type `string size` _n_
for each legal value of _n_.
The value _n_, if present, is called the *size* associated with the string
The value _n_, if present, is called the *size* associated with the string
type.
The size provides a maximum string length that the code generator can use
for allocating memory and serializing data.
@ -163,7 +163,7 @@ It is one of the following:
* An <<Types_Enum-Types,enum type>>.
* An <<Types_Array-Types,array type>> whose member type is a displayable type.
* A <<Types_Struct-Types,struct type>> whose member types are all displayable types.
* An <<Types_Alias-Types,alias type>> whose <<Types_Underlying-Types,underlying
* An <<Types_Alias-Types,alias type>> whose <<Types_Underlying-Types,underlying
type>> is a displayable type.
=== Types with Numeric Members

View File

@ -133,7 +133,7 @@ an anonymous array value stem:[v] has the form `[` stem:[v_1] `,` stem:[...]
`,`
stem:[v_{n-1}] `]`, where
. stem:[n] is a positive integer called the *size* of the anonymous array
. stem:[n] is a positive integer called the *size* of the anonymous array
value.
. For each stem:[i in [0,n-1]], stem:[v_i] is a value of type