Skip to content

Commit

Permalink
Merge pull request #583 from nasa/tumbar-type-aliases-spec
Browse files Browse the repository at this point in the history
Type alias spec
  • Loading branch information
bocchino authored Jan 31, 2025
2 parents ac7685d + 5201be6 commit a4c51fd
Show file tree
Hide file tree
Showing 9 changed files with 473 additions and 153 deletions.
454 changes: 320 additions & 134 deletions docs/fpp-spec.html

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions docs/spec/Definitions/Alias-Type-Definitions.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
=== Alias Type Definitions

An *alias type definition* associates a name with a type
that is defined elsewhere.

==== Syntax

`type` <<Lexical-Elements_Identifiers,_identifier_>> = <<Type-Names,_type-name_>>

==== Semantics

The identifier is the name _N_ of the type.
The definition associates the name _N_ with
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_.

==== Examples

[source,fpp]
----
# Defines a type A that is an alias of U32
type A = U32
# Defines a struct type B whose member x has type A
struct B {
x: A
y: F32
} default { y = 1 }
----
4 changes: 2 additions & 2 deletions docs/spec/Definitions/Struct-Definitions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ _]_

==== Semantics

The identifier is the name _N_ of the type. The definition associates the name
_N_ with a
The identifier is the name _N_ of the type.
The definition associates the name _N_ with a
<<Types_Struct-Types,struct type>> _T_ representing a structure with named members, each
of the specified type. Each
identifier appearing in the struct type member sequence must be distinct.
Expand Down
1 change: 1 addition & 0 deletions docs/spec/Definitions/defs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ redo-ifchange defs.sh
export FILES="
Introduction.adoc
Abstract-Type-Definitions.adoc
Alias-Type-Definitions.adoc
Array-Definitions.adoc
Component-Definitions.adoc
Component-Instance-Definitions.adoc
Expand Down
13 changes: 13 additions & 0 deletions docs/spec/Type-Checking.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ are both the same

. Each of stem:[T_1] and stem:[T_2]
is an
<<Types_Abstract-Types,abstract type>>,
<<Types_Alias-Types,alias type>>,
<<Types_Array-Types,array type>>,
<<Types_Enum-Types,enum type>>, or
<<Types_Struct-Types,struct type>>,
Expand All @@ -257,6 +259,12 @@ Here are the rules for type conversion:
. stem:[T_1] may be converted to stem:[T_2] if stem:[T_1] and stem:[T_2]
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
type>> of stem:[T_1] may be converted to
the <<Types_Underlying-Types,underlying type>> of stem:[T_2].

. Any <<Types_String-Types,string type>> may be converted
to any other string type.

Expand Down Expand Up @@ -331,6 +339,11 @@ 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
types>>, 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_Internal-Types_Numeric-Types,numeric types>>, then do the following:

Expand Down
1 change: 1 addition & 0 deletions docs/spec/Type-Names.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ A *qualified identifier type name* is a
<<Scoping-of-Names_Qualified-Identifiers,qualified
identifier>> that refers to an
<<Definitions_Abstract-Type-Definitions,abstract type definition>>,
<<Definitions_Alias-Type-Definitions,alias type definition>>,
<<Definitions_Array-Definitions,array definition>>,
<<Definitions_Enum-Definitions,enum definition>>, or
<<Definitions_Struct-Definitions,struct definition>>
Expand Down
11 changes: 11 additions & 0 deletions docs/spec/Type-Options.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ 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
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].
Expand Down Expand Up @@ -53,6 +60,10 @@ 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.
Expand Down
37 changes: 35 additions & 2 deletions docs/spec/Types.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ 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.
Expand Down Expand Up @@ -118,9 +127,25 @@ 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 type is a **displayable type** if it is one of the following:
A *displayable type* is a type that the F Prime ground data system can display.
It is one of the following:

* A <<Types_Primitive-Integer-Types,primitive integer type>>.
* A <<Types_Floating-Point-Types,floating-point type>>.
Expand All @@ -129,10 +154,13 @@ A type is a **displayable type** if 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
type>> is a displayable type.

=== Types with Numeric Members

A type *has numeric members* if it is one of the following:
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>>.

Expand Down Expand Up @@ -192,3 +220,8 @@ struct definitions>> for examples.
<<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>>.
75 changes: 60 additions & 15 deletions docs/spec/Values.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,26 @@ A *value* is one of the following:
* A struct value
Every value belongs to exactly one type.
Every value _v_ belongs to exactly one <<Types_Canonical-Types,canonical type>>
_T_, except as follows:

* Every string value belongs to the type `string` and to
all types `string` _n_, for any _n_.
* Every value that belongs to type _T_ also belongs to every
<<Types_Alias-Types,alias type>> whose
<<Types_Underlying-Types,underlying type>> is _T_.
When a value _v_ belongs to a type _T_, we say that _v_ is a value
*of type _T_*.

In the following subsections, we describe each kind of value and
its associated canonical types.

=== Primitive Integer Values

A *primitive integer value* is an ordinary (mathematical) integer value
together with a
together with its canonical type, which is a
<<Types_Primitive-Integer-Types,primitive integer type>>. Formally, the set of
primitive integer values
is the disjoint union over the integer types of the values
Expand All @@ -43,14 +57,15 @@ stem:[[0, 255\]].
stem:[[-2^(w-1), 2^(w-1)-1\]]. For example, `I8` represents the integers
stem:[[-128, 127\]].

We represent a primitive integer value as an expression followed by a colon and a type.
We represent a primitive integer value as an expression followed by a colon and
a primitive integer type.
For example, we write the value 1 at type `U32` as `1: U32`. The value `1:
U32` is distinct from the value `1: U8`.

=== Integer Values

An *integer value* is an ordinary (mathematical) integer value.
It has type _Integer_.
Its canonical type is _Integer_.
We represent an integer value as an integer number, with no explicit type.
For example, `1` is an integer value.

Expand All @@ -66,25 +81,34 @@ over the types `F32` and `F64` of the values represented by each type:

We write a floating-point values analogously to primitive integer values. For
example, we write the value 1.0 at type `F32` as `1.0: F32`.
The canonical type of a floating-point value is `F32` or `F64`.

=== Boolean Values

A *Boolean value* is one of the values `true` and `false`.
Its type is `bool`.
Its canonical type is `bool`.

=== String Values

A *string value* is a sequence of characters that can be
represented as a <<Expressions_String-Literals,string literal expression>>.
It is written in the same way as a string literal expression,
e.g., `"abc"`.
Its type is `string`.
A string value belongs to the following canonical types:

* `string`

* `string` _n_ for any _n_

=== Abstract Type Values

An *abstract type value* is a value associated with an abstract
type.
There is one value associated with each abstract type stem:[T].
For each abstract type stem:[T], there is one
value with canonical type stem:[T].
This value is not represented explicitly in the model, but it
may be represented in the generated code, e.g., as an object
with default initialization.
We write the value `value of type` stem:[T].

=== Anonymous Array Values
Expand All @@ -93,10 +117,17 @@ An *anonymous array value* is a value associated with an anonymous
array type.
We write an anonymous array value similarly to an
<<Expressions_Array-Expressions,array expression>>:
an anonymous array value has the form `[` stem:[v_1] `,` stem:[...] `,`
an anonymous array value stem:[v] has the form `[` stem:[v_1] `,` stem:[...]
`,`
stem:[v_n] `]`, where for each stem:[i in [1,n]], stem:[v_i] is a value of type
stem:[T] for some stem:[T].
The type of the value is _[_ stem:[n] _]_ stem:[T].
stem:[T] for some <<Types_Canonical-Types,canonical type>> stem:[T].
The canonical type of stem:[v] is _[_ stem:[n] _]_ stem:[T].

Note that for an anonymous array value stem:[v] to be well-formed, the member
values must have identical types.
If an array expression appearing in the source syntax has
member values with non-identical types, then one or more members must be
converted to a different type before forming stem:[v].

=== Array Values

Expand All @@ -116,16 +147,20 @@ that refers to a
with member type stem:[T].

. For each stem:[i in [1,n]], stem:[v_i] is a value of type stem:[T].
Note that stem:[T] need not be a canonical type.
For example, it is permissible for stem:[T] to be `T`, for
`T` to be an alias of `U32`, and for stem:[v] to be the value `[ 1: U32, 2: U32 ]`.
In this case `1: U32` and `2: U32` are values of type `T`, as required.

The type of the value is stem:[Q].
The canonical type of the value is stem:[Q].

=== Enumeration Values

An *enumeration value* is a value associated with an
<<Definitions_Enumerated-Constant-Definitions,enumerated constant definition>>.
It is a pair consisting of the name and the integer value
specified in the enumerated constant definition.
Its type is the type associated with the
Its canonical type is the type associated with the
<<Definitions_Enum-Definitions,enum definition>> in which
the enumerated constant definition appears.

Expand All @@ -139,8 +174,9 @@ We write an anonymous struct value stem:[v] similarly to a
a struct value has the form `{` stem:[m_1] `=` stem:[v_1] `,` stem:[...] `,`
stem:[m_n] `=` stem:[v_n] `}`,
where for each stem:[i in [1,n]], stem:[v_i] is a value of type stem:[T_i].
The type of stem:[v] is _{_ stem:[m_1] _:_ stem:[T_1] _,_ stem:[...] _,_
stem:[m_n] _:_ stem:[T_n] _}_.
Each type stem:[T_i] must be a <<Types_Canonical-Types,canonical type>>.
The canonical type of the value is _{_ stem:[m_1] _:_ stem:[T_1] _,_ stem:[...]
_,_ stem:[m_n] _:_ stem:[T_n] _}_.

=== Struct Values

Expand All @@ -161,8 +197,13 @@ that refers to a
. The members of stem:[Q] are stem:[m_i] `:` stem:[T_i] for stem:[i in [1,n\]].

. For each stem:[i in [1,n]], stem:[v_i] is a value of type stem:[T_i].
Note that stem:[T_i] need not be a canonical type.
For example, it is permissible for stem:[T_1] to be `T`, for
`T` to be an alias of `U32`, and for stem:[v_1] to be the value `1: U32`.
In this case `1: U32` is a value of type `T`, as required.

All the members must be explicitly assigned values.
Each member of the struct value must have an explicit value.
The canonical type of the struct value is stem:[Q].

=== Serialized Sizes

Expand Down Expand Up @@ -200,3 +241,7 @@ the sum of the serialized sizes of the members of _v_
* If _T_ is an
<<Types_Abstract-Types,abstract type>>, then _s_ is not specified in FPP. It
is up to the implementer of _T_ to provide the serialized size.

* If _T_ is a
<<Types_Alias-Types,alias type>>, then apply these rules to its
<<Types_Underlying-Types,underlying type>>.

0 comments on commit a4c51fd

Please sign in to comment.