Merge pull request #827 from jwest115/spec/dictionary-specifier

Spec updates for dictionary specifier
This commit is contained in:
Rob Bocchino 2025-10-07 08:18:30 -07:00 committed by GitHub
commit 0f79e9a5be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 260 additions and 25 deletions

View File

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

View File

@ -567,6 +567,12 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
<li><a href="#Definitions_Framework-Definitions_Type-Definitions">5.15.2. Type Definitions</a></li>
</ul>
</li>
<li><a href="#Definitions_Dictionary-Definitions">5.16. Dictionary Definitions</a>
<ul class="sectlevel3">
<li><a href="#Definitions_Dictionary-Definitions_Semantics">5.16.1. Semantics</a></li>
<li><a href="#Definitions_Dictionary-Definitions_Examples">5.16.2. Examples</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#State-Machine-Behavior-Elements">6. State Machine Behavior Elements</a>
@ -1177,6 +1183,7 @@ container
cpu
default
diagnostic
dictionary
do
drop
else
@ -1704,7 +1711,10 @@ that is defined elsewhere.</p>
<div class="sect3">
<h4 id="Definitions_Alias-Type-Definitions_Syntax">5.2.1. Syntax</h4>
<div class="paragraph">
<p><code>type</code> <a href="#Lexical-Elements_Identifiers"><em>identifier</em></a> = <a href="#Type-Names"><em>type-name</em></a></p>
<p><em>[</em>
<code>dictionary</code>
<em>]</em>
<code>type</code> <a href="#Lexical-Elements_Identifiers"><em>identifier</em></a> = <a href="#Type-Names"><em>type-name</em></a></p>
</div>
</div>
<div class="sect3">
@ -1716,6 +1726,11 @@ the type <em>T</em> specified after the <code>=</code> symbol.
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 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>
</div>
<div class="sect3">
<h4 id="Definitions_Alias-Type-Definitions_Examples">5.2.3. Examples</h4>
@ -1742,7 +1757,10 @@ it.</p>
<div class="sect3">
<h4 id="Definitions_Array-Definitions_Syntax">5.3.1. Syntax</h4>
<div class="paragraph">
<p><code>array</code> <a href="#Lexical-Elements_Identifiers"><em>identifier</em></a> <code>=</code>
<p><em>[</em>
<code>dictionary</code>
<em>]</em>
<code>array</code> <a href="#Lexical-Elements_Identifiers"><em>identifier</em></a> <code>=</code>
<code>[</code> <a href="#Expressions"><em>expression</em></a> <code>]</code> <a href="#Type-Names"><em>type-name</em></a>
<em>[</em>
<code>default</code> <a href="#Expressions"><em>expression</em></a>
@ -1778,6 +1796,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.</p>
</div>
<div class="paragraph">
<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>
</div>
<div class="sect3">
<h4 id="Definitions_Array-Definitions_Examples">5.3.3. Examples</h4>
@ -2511,7 +2534,10 @@ model.</p>
<div class="sect3">
<h4 id="Definitions_Constant-Definitions_Syntax">5.6.1. Syntax</h4>
<div class="paragraph">
<p><code>constant</code>
<p><em>[</em>
<code>dictionary</code>
<em>]</em>
<code>constant</code>
<a href="#Lexical-Elements_Identifiers"><em>identifier</em></a>
<code>=</code>
<a href="#Expressions"><em>expression</em></a></p>
@ -2528,6 +2554,11 @@ the constant definition according to the
<a href="#Scoping-of-Names_Resolution-of-Qualified-Identifiers">scoping
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 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>
</div>
<div class="sect3">
<h4 id="Definitions_Constant-Definitions_Examples">5.6.3. Examples</h4>
@ -2566,7 +2597,10 @@ constants.</p>
<div class="sect3">
<h4 id="Definitions_Enum-Definitions_Syntax">5.7.1. Syntax</h4>
<div class="paragraph">
<p><code>enum</code> <a href="#Lexical-Elements_Identifiers"><em>identifier</em></a>
<p><em>[</em>
<code>dictionary</code>
<em>]</em>
<code>enum</code> <a href="#Lexical-Elements_Identifiers"><em>identifier</em></a>
<em>[</em> <code>:</code> <a href="#Type-Names"><em>type-name</em></a> <em>]</em>
<code>{</code> <em>enum-constant-sequence</em> <code>}</code>
<em>[</em>
@ -2604,6 +2638,11 @@ If present, it specifies the <a href="#Types_Default-Values">default value</a> a
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 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>
</div>
<div class="sect3">
<h4 id="Definitions_Enum-Definitions_Inferred-Representation-Type">5.7.3. Inferred Representation Type</h4>
@ -3466,7 +3505,10 @@ with it.</p>
<div class="sect3">
<h4 id="Definitions_Struct-Definitions_Syntax">5.13.1. Syntax</h4>
<div class="paragraph">
<p><code>struct</code> <a href="#Lexical-Elements_Identifiers"><em>identifier</em></a>
<p><em>[</em>
<code>dictionary</code>
<em>]</em>
<code>struct</code> <a href="#Lexical-Elements_Identifiers"><em>identifier</em></a>
<code>{</code> <em>struct-type-member-sequence</em> <code>}</code>
<em>[</em> <code>default</code> <a href="#Expressions"><em>expression</em></a> <em>]</em></p>
</div>
@ -3524,6 +3566,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.</p>
</div>
<div class="paragraph">
<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>
</div>
<div class="sect3">
<h4 id="Definitions_Struct-Definitions_Examples">5.13.3. Examples</h4>
@ -4331,6 +4378,59 @@ to the following rules.</p>
</table>
</div>
</div>
<div class="sect2">
<h3 id="Definitions_Dictionary-Definitions">5.16. Dictionary Definitions</h3>
<div class="paragraph">
<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>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>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-Types">primitive type</a>.</p>
</li>
<li>
<p>A <a href="#Types_String-Types">string type</a>.</p>
</li>
<li>
<p>An <a href="#Types_Enum-Types">enum type</a>.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="Definitions_Dictionary-Definitions_Examples">5.16.2. Examples</h4>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">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 }</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
@ -6507,7 +6607,11 @@ of a <a href="#Definitions">definition</a>.</p>
<a href="#Expressions_String-Literals"><em>string-literal</em></a></p>
</li>
<li>
<p>A <strong>constant location specifier</strong> <code>locate</code> <code>constant</code>
<p>A <strong>constant location specifier</strong> <code>locate</code>
<em>[</em>
<code>dictionary</code>
<em>]</em>
<code>constant</code>
<a href="#Scoping-of-Names_Qualified-Identifiers"><em>qual-ident</em></a> <code>at</code>
<a href="#Expressions_String-Literals"><em>string-literal</em></a></p>
</li>
@ -6527,19 +6631,31 @@ of a <a href="#Definitions">definition</a>.</p>
<a href="#Expressions_String-Literals"><em>string-literal</em></a></p>
</li>
<li>
<p>A <strong>type location specifier</strong> <code>locate</code> <code>type</code>
<p>A <strong>type location specifier</strong> <code>locate</code>
<em>[</em>
<code>dictionary</code>
<em>]</em>
<code>type</code>
<a href="#Scoping-of-Names_Qualified-Identifiers"><em>qual-ident</em></a> <code>at</code>
<a href="#Expressions_String-Literals"><em>string-literal</em></a></p>
</li>
</ul>
</div>
<div class="paragraph">
<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">
@ -6583,13 +6699,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
@ -6603,8 +6725,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>If any of the specifiers is a dictionary specifier, then all of them must be
dictionary specifiers.</p>
</li>
<li>
<p>All the specifiers must have the same locations.</p>
</li>
</ol>
</div>
</li>
</ol>
</div>
@ -11821,7 +11954,7 @@ equivalent.</p>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-09-29 08:20:16 -0700
Last updated 2025-10-06 17:44:48 -0700
</div>
</div>
<script src="code-prettify/run_prettify.js"></script>

View File

@ -15783,7 +15783,7 @@ serialized according to its
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-09-29 08:18:11 -0700
Last updated 2025-10-06 16:54:41 -0700
</div>
</div>
<script src="code-prettify/run_prettify.js"></script>

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.20">
<meta name="generator" content="Asciidoctor 2.0.23">
<title>F Prime Prime (FPP)</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
@ -140,7 +140,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
@ -162,6 +162,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
@ -327,7 +328,7 @@ a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
@ -463,7 +464,7 @@ generated code.</p>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-02-18 09:43:03 -0800
Last updated 2025-02-14 13:29:20 -0800
</div>
</div>
</body>

View File

@ -5,6 +5,9 @@ that is defined elsewhere.
==== Syntax
_[_
`dictionary`
_]_
`type` <<Lexical-Elements_Identifiers,_identifier_>> = <<Type-Names,_type-name_>>
==== Semantics
@ -15,6 +18,10 @@ 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
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Examples
[source,fpp]

View File

@ -5,6 +5,9 @@ it.
==== Syntax
_[_
`dictionary`
_]_
`array` <<Lexical-Elements_Identifiers,_identifier_>> `=`
`[` <<Expressions,_expression_>> `]` <<Type-Names,_type-name_>>
_[_
@ -36,6 +39,10 @@ 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 keyword `dictionary` is present, then the
definition must conform to the rules stated in the
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Examples
[source,fpp]

View File

@ -6,6 +6,9 @@ model.
==== Syntax
_[_
`dictionary`
_]_
`constant`
<<Lexical-Elements_Identifiers,_identifier_>>
`=`
@ -21,6 +24,10 @@ 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 keyword `dictionary` is present, then the
definition must conform to the rules stated in the
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Examples
[source,fpp]

View File

@ -0,0 +1,37 @@
=== 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.
==== Semantics
If a type definition _D_ is a dictionary definition, then the type
defined by _D_ must be a <<Types_Displayable-Types, displayable type>>.
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-Types,primitive type>>.
* A <<Types_String-Types,string type>>.
* An <<Types_Enum-Types,enum type>>.
==== Examples
[source,fpp]
----
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

@ -16,6 +16,9 @@ constants.
==== Syntax
_[_
`dictionary`
_]_
`enum` <<Lexical-Elements_Identifiers,_identifier_>>
_[_ `:` <<Type-Names,_type-name_>> _]_
`{` _enum-constant-sequence_ `}`
@ -49,6 +52,10 @@ 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 keyword `dictionary` is present, then the
definition must conform to the rules stated in the
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Inferred Representation Type
If _type-name_ does not appear after the identifier, then

View File

@ -5,6 +5,9 @@ with it.
==== Syntax
_[_
`dictionary`
_]_
`struct` <<Lexical-Elements_Identifiers,_identifier_>>
`{` _struct-type-member-sequence_ `}`
_[_ `default` <<Expressions,_expression_>> _]_
@ -56,6 +59,10 @@ 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
<<Definitions_Dictionary-Definitions,dictionary definitions>> section.
==== Examples
[source,fpp]

View File

@ -23,4 +23,5 @@ State-Machine-Definitions.adoc
Struct-Definitions.adoc
Topology-Definitions.adoc
Framework-Definitions.adoc
Dictionary-Definitions.adoc
"

View File

@ -62,6 +62,7 @@ container
cpu
default
diagnostic
dictionary
do
drop
else

View File

@ -16,7 +16,11 @@ 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` `constant`
* A *constant location specifier* `locate`
_[_
`dictionary`
_]_
`constant`
<<Scoping-of-Names_Qualified-Identifiers,_qual-ident_>> `at`
<<Expressions_String-Literals,_string-literal_>>
@ -32,13 +36,23 @@ A location specifier is one of the following:
<<Scoping-of-Names_Qualified-Identifiers,_qual-ident_>> `at`
<<Expressions_String-Literals,_string-literal_>>
* A *type location specifier* `locate` `type`
* A *type location specifier* `locate`
_[_
`dictionary`
_]_
`type`
<<Scoping-of-Names_Qualified-Identifiers,_qual-ident_>> `at`
<<Expressions_String-Literals,_string-literal_>>
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:
@ -71,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>>
@ -87,8 +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:
.. 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

@ -42,8 +42,8 @@
(defconst fpp-mode-keywords
'("action" "active" "activity" "always" "assert"
"at" "base" "block" "change" "choice" "command"
"connections" "cpu" "default" "diagnostic" "do"
"drop" "else" "entry" "event" "exit" "external"
"connections" "cpu" "default" "diagnostic" "dictionary"
"do" "drop" "else" "entry" "event" "exit" "external"
"false" "fatal" "format" "get" "guard"
"guarded" "health" "high" "hook" "id" "if" "import"
"include" "initial" "input" "interface" "internal"

View File

@ -28,6 +28,7 @@ syn keyword fppKeyword container
syn keyword fppKeyword cpu
syn keyword fppKeyword default
syn keyword fppKeyword diagnostic
syn keyword fppKeyword dictionary
syn keyword fppKeyword do
syn keyword fppKeyword drop
syn keyword fppKeyword else