fpp/docs/spec/Type-Options.adoc
2025-10-28 16:00:06 -07:00

100 lines
3.3 KiB
Plaintext

== Type Options
A *type option* is one of the following:
. _Some_ stem:[T], representing a value of type stem:[T].
. _None_, representing no value.
Type options are used to specify the optional types associated with
signals, actions, and guards in <<Definitions_State-Machine-Definitions,state
machine definitions>>.
=== Conversion of Type Options
We say that a type option stem:[O_1] *may be converted to* another type option
stem:[O_2] in the following cases.
. Any type option may be converted to _None_.
. _Some_ stem:[T_1] may be converted to _Some_ stem:[T_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
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],
and
stem:[T'_2] is the <<Types_Underlying-Types,underlying type>> of stem:[T_2].
.. stem:[T_1] and stem:[T_2] are both
<<Types_Primitive-Integer-Types,signed primitive integer types>>,
and stem:[T_2] is at least as wide as stem:[T_1].
.. stem:[T_1] and stem:[T_2] are both
<<Types_Primitive-Integer-Types,unsigned primitive integer types>>,
and stem:[T_2] is at least as wide as stem:[T_1].
.. stem:[T_1] and stem:[T_2] are both
<<Types_Floating-Point-Types,floating-point types>>,
and stem:[T_2] is at least as wide as stem:[T_1].
.. stem:[T_1] and stem:[T_2] are both <<Types_String-Types,string types>>.
=== Computing a Common Type Option
==== Pairs of Type Options
Here are the rules for resolving two type options stem:[O_1] and stem:[O_2] to
a common type option stem:[O]:
. If either or both of stem:[O_1] and stem:[O_2] is _None_, then
let stem:[O] be _None_.
. Otherwise let stem:[O_1] be _Some_ stem:[T_1], and let
stem:[O_2] be _Some_ stem:[T_2].
Let stem:[O] be _Some_ stem:[T], where stem:[T]
is computed as follows:
.. If stem:[T_1] and stem:[T_2] are <<Type-Checking_Identical-Types,identical types>>,
then let stem:[T] be stem:[T_1].
.. Otherwise if either stem:[T_1] or stem:[T_2] is an <<Types_Alias-Types,alias type>>,
then replace each alias type with its <<Types_Underlying-Types,underlying type>>
and reapply these rules.
.. Otherwise if stem:[T_1] and stem:[T_2] are both
<<Types_Primitive-Integer-Types,signed primitive integer types>>,
then let stem:[T] be the wider of the two types.
.. Otherwise if stem:[T_1] and stem:[T_2] are both
<<Types_Primitive-Integer-Types,unsigned primitive integer types>>,
then let stem:[T] be the wider of the two types.
.. Otherwise if stem:[T_1] and stem:[T_2] are both
<<Types_Floating-Point-Types,floating-point types>>,
then let stem:[T] be the wider of the two types.
.. Otherwise if stem:[T_1] and stem:[T_2] are both
<<Types_String-Types,string types>>, then
then let stem:[T] be `string`.
.. Otherwise the attempted resolution is invalid.
Throw an error.
==== Lists of Type Options
To compute a common type for a list of type options
stem:[O_1, ... , O_n], do the following:
. Check that stem:[n > 0]. If not, then throw an error.
. Let stem:[O'_1] be stem:[O_1].
. For each stem:[i in [2,n]], compute the
<<Type-Checking_Computing-a-Common-Type,common type>> stem:[O'_i] of
stem:[O'_(i-1)] and stem:[O_i].
. Use stem:[O'_n] as the common type of the list.