Files
fpp/docs/spec/Types.adoc
2026-03-17 13:50:46 -07:00

310 lines
10 KiB
Plaintext

== Types
A *type* is a set of <<Values,values>>.
=== Primitive Integer Types
The *primitive integer types* correspond to the
<<Type-Names_Primitive-Integer-Type-Names,primitive integer type names>>
and are written in the same way, e.g., `U32`.
The primitive integer types whose names start with `I` are *signed*.
The primitive integer types whose names start with `U` are *unsigned*.
=== Floating-Point Types
The *floating-point types* correspond to the
<<Type-Names_Floating-Point-Type-Names,floating-point type names>>
and are written in the same way, e.g., `F64`.
=== Primitive Numeric Types
The <<Types_Primitive-Integer-Types,primitive integer types>>
together with the <<Types_Floating-Point-Types,floating-point types>> are
called the *primitive numeric types*.
=== The Boolean Type
The *Boolean type* corresponds to the
<<Type-Names_The-Boolean-Type-Name,Boolean type name>>.
It is written `bool`.
=== Primitive Types
Together, the <<Types_Primitive-Numeric-Types,primitive numeric types>>
and the
<<Types_The-Boolean-Type,Boolean type>>
are called the *primitive types*.
=== String Types
The *string types* correspond to the
<<Type-Names_String-Type-Names,string type names>>.
A string type is written `string` or `string size` _n_,
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 string type names map to the string types in the following way:
* The type name `string` maps to the type `string`.
* The type name `string` `size` _e_ maps to the type `string` `size` _n_,
after evaluating the expression _e_ to the value _n_.
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 uses
for allocating memory and serializing data.
If no size is present, then the code generator uses
the <<Definitions_Framework-Definitions_Constant-Definitions,
framework definition>> `FW_FIXED_LENGTH_STRING_SIZE` as the
maximum string length.
=== Array Types
An *array type* is a type associated with an
<<Definitions_Array-Definitions,array definition>>.
There is one array type per array definition.
Each array type is computed after resolving constants,
so an array type has a constant integer value for its size.
An array type is written using its
<<Scoping-of-Names_Names-of-Definitions,unique qualified
name>>.
=== Enum Types
An *enum type* is a type associated with an
<<Definitions_Enum-Definitions,enum definition>>.
There is one enum type per enum definition.
An enum type is written using its
<<Scoping-of-Names_Names-of-Definitions,unique qualified
name>>.
=== Struct Types
A *struct type* is a type associated with a
<<Definitions_Struct-Definitions,struct definition>>.
There is one struct type per struct definition.
A struct type is written using its
<<Scoping-of-Names_Names-of-Definitions,unique qualified
name>>.
=== Abstract Types
An *abstract type* is a type associated with an
<<Definitions_Abstract-Type-Definitions,abstract type definition>>.
There is is one abstract type per abstract type definition.
An abstract type is written using its
<<Scoping-of-Names_Names-of-Definitions,unique qualified
name>>.
=== Alias Types
An *alias type* is a type associated with an
<<Definitions_Alias-Type-Definitions,alias type definition>>.
There is one alias type per alias type definition.
An alias type is written using its
<<Scoping-of-Names_Names-of-Definitions,unique qualified
name>>.
=== Internal Types
*Internal types* do not have syntactic names in FPP source models.
The compiler assigns these types to expressions during type checking.
==== Integer
The type _Integer_ represents all integer values, without regard
to bit width.
==== Integer Types
<<Types_Internal-Types_Integer,_Integer_>> together with the
<<Types_Primitive-Integer-Types,primitive integer types>> are called
the *integer types*.
==== Numeric Types
<<Types_Internal-Types_Integer,_Integer_>> together with the
<<Types_Primitive-Numeric-Types,primitive numeric types>> are called
the *numeric types*.
==== Anonymous Array Types
The type _[_ _n_ _]_ _T_, where _n_
is an integer and _T_ is a type, represents an array of _n_ elements,
each of type _T_.
The type _T_ is called the *element type* of the
anonymous array type.
The integer _n_ is called the *size* of the anonymous array type.
==== Anonymous Struct Types
The type _{_ stem:[m_1] _:_ stem:[T_1, ...,] stem:[m_n] _:_ stem:[T_n] _}_,
where each stem:[m_i] is an identifier and each stem:[T_i] is a type,
represents a struct with members stem:[m_i] _:_ stem:[T_i].
The order of the members is not significant.
For example, `{ a: U32, b: F32 }` represents the same
type as `{ b : F32, a: U32 }`.
=== Canonical Types
A type is a *canonical type* if it is not an <<Types_Alias-Types,alias type>>.
=== Underlying Types
The *underlying type* of a type _T_ is the <<Types_Canonical-Types, canonical type>>
associated with _T_.
* If _T_ is a canonical type, then the underlying type of _T_ is _T_.
* Otherwise _T_ is an <<Types_Alias-Types,alias type>>.
In this case, the underlying type of _T_ is the underlying type of the type
associated with _T_ in the definition of _T_.
=== Displayable Types
A *displayable type* is a type that the F Prime ground data system can display.
It is one of the following:
* A <<Types_Primitive-Numeric-Types,primitive numeric type>>.
* A <<Types_The-Boolean-Type,boolean type>>.
* A <<Types_String-Types,string type>>.
* 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
type>> is a displayable type.
=== Types with Numeric Members
A type *has numeric members* if its <<Types_Underlying-Types,underlying type>>
is one of the following:
* A <<Types_Internal-Types_Numeric-Types,numeric type>>.
* An <<Types_Array-Types,array type>> or
<<Types_Internal-Types_Anonymous-Array-Types,anonymous array type>> whose
member type has numeric members.
* A <<Types_Struct-Types,struct type>> or
<<Types_Internal-Types_Anonymous-Struct-Types,anonymous struct type>> whose
member types all have numeric members.
=== Alias Lists
The *alias list* of a type stem:[T] is a list stem:[L] defined as follows:
. The head of stem:[L] is stem:[T].
. If stem:[T] is not an <<Types_Alias-Types,alias type>>, then the
tail of stem:[L] is the empty list.
. Otherwise the tail of stem:[T] is the alias list of the type
stem:[T'] that appears in the definition of stem:[T].
=== Default Values
Every type _T_ with a syntactic name in FPP has an associated *default
value*.
In generated C++ code, this is the value that is used to initialize a variable
of type _T_
when no other initializer is specified.
Default values are important, because they ensure that in generated code,
every variable is initialized when it is created.
* The default value associated with each
<<Types_Primitive-Numeric-Types,primitive numeric type>> is zero.
* The default value associated with
<<Types_The-Boolean-Type,`bool`>> is `false`.
* The default value associated with any
<<Types_String-Types,string type>> is the empty string.
* The default value associated with an
<<Types_Array-Types,array type>> _T_ is (1)
the default value specified in the array definition,
if one is given; otherwise (2) the unique value
of type _T_ that has the default value of the member type
of _T_ at each member.
See the section on <<Definitions_Array-Definitions,
array definitions>> for examples.
* The default value associated with an
<<Types_Enum-Types,enum type>> is (1) the default value
specified in the enum definition, if one is given;
otherwise (2) the first
enumerated constant appearing in the enum definition.
* The default value associated with a
<<Types_Struct-Types,struct type>> _T_ is (1)
the default value specified in the struct definition,
if one is given; otherwise (2) the unique value of type
_T_ that has the default value of the member type stem:[T_i]
for each member stem:[m_i] `:` stem:[T_i] of _T_.
See the section on <<Definitions_Struct-Definitions,
struct definitions>> for examples.
* The default value associated with an
<<Types_Abstract-Types,abstract type>> _T_ is the
<<Values_Abstract-Type-Values,single value associated with _T_>>.
This value is left abstract in the FPP model; the implementation
of _T_ must provide a concrete value.
* The default value associated with an
<<Types_Alias-Types,alias type>> _T_ is the
<<Types_Default-Values,default value>> of its
<<Types_Underlying-Types,underlying type>>.
=== Serialized Sizes
Every <<Types_Displayable-Types,displayable type>>
has a *serialized size*. This is the maximum number of bytes required to
represent a <<Values,value>> _v_ of type _T_ in
the standard F Prime serialized format.
The serialized size _s_ of a type _T_ is defined as follows:
* If _T_ is a
<<Types_Primitive-Numeric-Types,primitive numeric type>>, then _s_ is the byte
width of the type. For example, the serialized size of a value of type `F64`
is 8.
* If _T_ is
<<Types_The-Boolean-Type,`bool`>>, then _s_ is 1.
* If _T_ is a
<<Types_String-Types,string type>>, then _s_ is the sum of the following two numbers:
** The serialized size of the
<<Definitions_Framework-Definitions_Type-Definitions,framework type>>
`FwSizeStoreType`.
This is the space used to store the length of the string.
** The size _n_ specified in _T_, if it exists; otherwise the
<<Definitions_Framework-Definitions_Constant-Definitions,framework constant>>
`FW_FIXED_LENGTH_STRING_SIZE`.
This is the maximum space required to store the characters of the string.
* If _T_ is an
<<Types_Array-Types,array type>> with element type _T'_ and size _n_, then _s_
is _n_ times the serialized size of _T'_.
* If _T_ is an
<<Types_Enum-Types,enum type>>, then _s_ is the serialized size of the
representation type of _T_.
* If _T_ is a
<<Types_Struct-Types,struct type>>, then _s_
the sum of the serialized sizes of the members of _T_.
For each member _m_ with type stem:[T_m]:
** If _m_ has size _n_, then the serialized size of
_m_ is _n_ times the serialized size of stem:[T_m].
** Otherwise the serialized size of _m_ is the serialized size of stem:[T_m].
* If _T_ is an
<<Types_Alias-Types,alias type>>, then _s_ is the serialized size of the
<<Types_Underlying-Types,underlying type>> of _T_.