Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
408 changes: 349 additions & 59 deletions docs/fpp-spec.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/fpp-users-guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -15716,7 +15716,7 @@ <h3 id="Writing-C-Plus-Plus-Implementations_Serialization-of-FPP-Values">16.4. S
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-10-22 10:13:22 -0700
Last updated 2025-12-02 10:41:57 -0800
</div>
</div>
<script src="code-prettify/run_prettify.js"></script>
Expand Down
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ <h1>F Prime Prime (FPP)</h1>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-01-28 17:09:18 -0800
Last updated 2025-09-26 15:59:43 -0700
</div>
</div>
</body>
Expand Down
4 changes: 4 additions & 0 deletions docs/spec/Definitions/Module-Definitions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ A module member is one of the following:

* A <<Definitions_Topology-Definitions,topology definition>>

* A <<Definitions_Module-Template-Definitions,module template definition>>

* A <<Specifiers_Template-Expansion-Specifiers,template expansion specifier>>

* A <<Specifiers_Location-Specifiers,location specifier>>

* An <<Definitions_Abstract-Type-Definitions,abstract type definition>>
Expand Down
103 changes: 103 additions & 0 deletions docs/spec/Definitions/Module-Template-Definitions.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
=== Module Template Definitions

A *module template definition* defines an FPP template that can
help reduce FPP model code duplication.
A module template is an FPP construct with definitions inside
parameterized with a set of types, constants, and interfaces that
can be expanded into a module.

==== Syntax

`template`
<<Lexical-Elements_Identifiers,_identifier_>>
`(` _parameter-sequence_ `)` `{`
_module-member-sequence_
`}`

The _identifier_ specifies the name of the template.

_parameter-sequence_ is an
<<Element-Sequences,element sequence>> in which the
elements are one of the following and the terminating punctuation
is a comma:

* `constant` <<Lexical-Elements_Identifiers,_identifier_>> `:` <<Type-Names,_type-name_>>
* `interface` <<Lexical-Elements_Identifiers,_identifier_>> `:` <<Scoping-of-Names_Qualified-Identifiers,_qual-ident_>>
* `type` <<Lexical-Elements_Identifiers,_identifier_>>

_module-member-sequence_ is an
<<Element-Sequences,element sequence>> in
which each element is a <<Definitions_Module-Definitions_Syntax,
module member>>, and the terminating punctuation is a semicolon.

. Note that <<Definitions_Module-Template-Definitions,template definition>> defined
as members to template definitions will cause an error.

==== Semantics

Module template definitions define parameterized FPP syntax. A template can be expanded
through a <<Specifiers_Template-Expansion-Specifiers,
template expansion specifier>>.

Templates are expanded with the following algorithm:

. For each template expansion specifier _E_:

.. Create a new empty scope _S_ for _E_.

.. Resolve the module template definition _T_ which _E_
<<Scoping-of-Names_Resolution-of-Qualified-Identifiers,refers to>>.

.. Enter template parameters of _T_ into _S_ with concrete values given in _E_.

.. Duplicate the syntax contained in _T_ into syntax _X_ contained under _E_.

.. Enter symbols discovered in _X_ into _S_.

.. For each template expansion specifier in _X_, apply these rules recursively.

With templates expanded,

==== Example

[source,fpp]
----
template MT(
constant base_id: U32,
interface comDriver: ByteStreamDriver
) {
instance comStub: Svc.ComStub base id \
base_id + 0x0800

toplogy T {
instance comStub

# TODO(tumbar) What is this? Do we need it
# (do we need `instance comStub`?)
instance comDriver

# Connect to the driver from the parameter list
connections Downlink {
# ComStub <-> ComDriver
comStub.drvSendOut -> comDriver.$send
comDriver.sendReturnOut -> comStub.drvSendReturnIn
comDriver.ready -> comStub.drvConnected
}
}
}

instance comDriver: Drv.TcpClient base id 0x10300000 + 0x100

module M {
# Instantiate template with topology inside
# Pass an external component into the topology
expand MT(constant 0x100, interface comDriver)
}

topology T {
import M.T # Imports the instantiated template topology
import MT.T # Error: Cannot reference definitions inside a _template_

instance comDriver
}
----
1 change: 1 addition & 0 deletions docs/spec/Definitions/defs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Constant-Definitions.adoc
Enum-Definitions.adoc
Enumerated-Constant-Definitions.adoc
Module-Definitions.adoc
Module-Template-Definitions.adoc
Port-Definitions.adoc
Port-Interface-Definitions.adoc
State-Machine-Definitions.adoc
Expand Down
21 changes: 18 additions & 3 deletions docs/spec/Scoping-of-Names.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@

A *qualified identifier* is one of the following:

1. _Q_

2. `.` _Q_

where _Q_ is one of the following:

1. An
<<Lexical-Elements_Identifiers,identifier>>.

2. _Q_ `.` _I_, where _Q_ is a qualified identifier and _I_ is an
identifier.
2. _Q_ `.` _I_.

A qualified identifier _Q_ is *scope relative*.
A qualified identifier `.` _Q_ is *absolute*.

Examples:

Expand All @@ -17,6 +25,7 @@ Examples:
a
a.b
a.b.c
.a.b.c
----

=== Names of Definitions
Expand Down Expand Up @@ -267,7 +276,12 @@ associating qualified identifiers with definitions:
stated in the
<<Scoping-of-Names_Resolution-of-Identifiers,previous section>>.

. Otherwise, the qualified identifier has the form _Q_ `.` _I_, where
. If a qualified identifier is of the form `.` _I_, then resolve it as
stated in the
<<Scoping-of-Names_Resolution-of-Identifiers,previous section>> as if _I_ were
appearing at the top level.

. If a qualified identifier is of the form _Q_ `.` _I_, where
_Q_ is a qualified identifier and _I_ is an identifier. Do the
following:

Expand All @@ -284,6 +298,7 @@ _I_.

.. Otherwise the qualified identifier is invalid. Issue an error.


*Example:*

[source,fpp]
Expand Down
73 changes: 73 additions & 0 deletions docs/spec/Specifiers/Template-Expansion-Specifiers.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
=== Template Expansion Specifiers

A *template expansion specifier* takes a
<<Definitions_Module-Template-Definitions,template>> and
applies a set of values to its parameters
to generate concrete definitions.

=== Syntax

`expand`
<<Scoping-of-Names_Qualified-Identifiers,_qual-ident>>
`(` _parameter-sequence_ `)`

_parameter-sequence_ is an
<<Element-Sequences,element sequence>> in
which each element is one of the following:

. `constant` <<Expressions,_expression_>>

. `type` <<Type-Names,_type-name_>>

. `interface` <<Scoping-of-Names_Qualified-Identifiers,_qual-ident_>>

=== Semantics

. The qualified identifier must
<<Scoping-of-Names_Resolution-of-Qualified-Identifiers,refer to>>
a
<<Definitions_Module-Template-Definitions,module template definition _T_>>.

. The parameter sequence is the set of parameters that map to
the template parameters of the template _T_.

==== Checking parameter types

For each template parameter _P_ and its corresponding parameter definition _D_ in _T_:

. If _P_ is `constant`, _D_ must be `constant and the expression is
<<Type-Checking_Type-Conversion,converted to>> the type specified in _D_.

. If _P_ is `type`, _D_ must also be a `type` parameter.

. If _P_ is `interface`, _D_ must also be `interface and the value must be a
<<Scoping-of-Names_Qualified-Identifiers,_qualified-identifier_>> of a
<<Ports_Port-Interface-Instances,port interface instance>>
which is a <<Ports_Sub-Interfaces,sub-interface>> to _I_

=== Examples

[source,fpp]
----
port P

@ A basic template parameterizing an interface port count
template Templ(
constant numPorts: U32
) {
interface I {
output port N[numPorts]: P
}

passive component C {
import I
}
}

@ Instantiate the template giving the parameters concrete values
module M {
expand Templ(constant 30)
}
# M.I => interface { output port N[30]: P }
# M.C => passive component { output port N[30]: P }
----
1 change: 1 addition & 0 deletions docs/spec/Specifiers/defs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ Telemetry-Channel-Specifiers.adoc
Telemetry-Packet-Set-Specifiers.adoc
Telemetry-Packet-Specifiers.adoc
Topology-Port-Instance-Specifiers.adoc
Template-Expansion-Specifiers.adoc
"