Skip to content

Commit a4c51fd

Browse files
authoredJan 31, 2025··
Merge pull request #583 from nasa/tumbar-type-aliases-spec
Type alias spec
2 parents ac7685d + 5201be6 commit a4c51fd

9 files changed

+473
-153
lines changed
 

‎docs/fpp-spec.html

+320-134
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
=== Alias Type Definitions
2+
3+
An *alias type definition* associates a name with a type
4+
that is defined elsewhere.
5+
6+
==== Syntax
7+
8+
`type` <<Lexical-Elements_Identifiers,_identifier_>> = <<Type-Names,_type-name_>>
9+
10+
==== Semantics
11+
12+
The identifier is the name _N_ of the type.
13+
The definition associates the name _N_ with
14+
the type _T_ specified after the `=` symbol.
15+
Elsewhere in the model, the name _N_ may be used as alias of (i.e., an
16+
alternate name for) the type _T_.
17+
18+
==== Examples
19+
20+
[source,fpp]
21+
----
22+
# Defines a type A that is an alias of U32
23+
type A = U32
24+
25+
# Defines a struct type B whose member x has type A
26+
struct B {
27+
x: A
28+
y: F32
29+
} default { y = 1 }
30+
----

‎docs/spec/Definitions/Struct-Definitions.adoc

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ _]_
2525

2626
==== Semantics
2727

28-
The identifier is the name _N_ of the type. The definition associates the name
29-
_N_ with a
28+
The identifier is the name _N_ of the type.
29+
The definition associates the name _N_ with a
3030
<<Types_Struct-Types,struct type>> _T_ representing a structure with named members, each
3131
of the specified type. Each
3232
identifier appearing in the struct type member sequence must be distinct.

‎docs/spec/Definitions/defs.sh

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ redo-ifchange defs.sh
99
export FILES="
1010
Introduction.adoc
1111
Abstract-Type-Definitions.adoc
12+
Alias-Type-Definitions.adoc
1213
Array-Definitions.adoc
1314
Component-Definitions.adoc
1415
Component-Instance-Definitions.adoc

‎docs/spec/Type-Checking.adoc

+13
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ are both the same
241241

242242
. Each of stem:[T_1] and stem:[T_2]
243243
is an
244+
<<Types_Abstract-Types,abstract type>>,
245+
<<Types_Alias-Types,alias type>>,
244246
<<Types_Array-Types,array type>>,
245247
<<Types_Enum-Types,enum type>>, or
246248
<<Types_Struct-Types,struct type>>,
@@ -257,6 +259,12 @@ Here are the rules for type conversion:
257259
. stem:[T_1] may be converted to stem:[T_2] if stem:[T_1] and stem:[T_2]
258260
are <<Type-Checking_Identical-Types,identical types>>.
259261

262+
. If either stem:[T_1] or stem:[T_2] or both is an
263+
<<Types_Alias-Types,alias type>>, then stem:[T_1]
264+
may be converted to stem:[T_2] if the <<Types_Underlying-Types,underlying
265+
type>> of stem:[T_1] may be converted to
266+
the <<Types_Underlying-Types,underlying type>> of stem:[T_2].
267+
260268
. Any <<Types_String-Types,string type>> may be converted
261269
to any other string type.
262270

@@ -331,6 +339,11 @@ the whole expression):
331339
<<Type-Checking_Identical-Types,identical types>>, then let
332340
stem:[T] be stem:[T_1].
333341

342+
. Otherwise if stem:[T_1] or stem:[T_2] or both are <<Types_Alias-Types,alias
343+
types>>, then replace
344+
each alias type with its <<Types_Underlying-Types,underlying type>>
345+
and reapply these rules.
346+
334347
. Otherwise if stem:[T_1] and stem:[T_2] are both
335348
<<Types_Internal-Types_Numeric-Types,numeric types>>, then do the following:
336349

‎docs/spec/Type-Names.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ A *qualified identifier type name* is a
6262
<<Scoping-of-Names_Qualified-Identifiers,qualified
6363
identifier>> that refers to an
6464
<<Definitions_Abstract-Type-Definitions,abstract type definition>>,
65+
<<Definitions_Alias-Type-Definitions,alias type definition>>,
6566
<<Definitions_Array-Definitions,array definition>>,
6667
<<Definitions_Enum-Definitions,enum definition>>, or
6768
<<Definitions_Struct-Definitions,struct definition>>

‎docs/spec/Type-Options.adoc

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ stem:[O_2] in the following cases.
2121

2222
.. stem:[T_1] and stem:[T_2] are <<Type-Checking_Identical-Types,identical types>>.
2323

24+
.. Either or both of stem:[T_1] and stem:[T_2] is an <<Types_Alias-Types,alias
25+
type>>,
26+
and _Some_ stem:[T'_1] may be converted to _Some_ stem:[T'_2], where
27+
stem:[T'_1] is the <<Types_Underlying-Types,underlying type>> of stem:[T_1],
28+
and
29+
stem:[T'_2] is the <<Types_Underlying-Types,underlying type>> of stem:[T_2].
30+
2431
.. stem:[T_1] and stem:[T_2] are both
2532
<<Types_Primitive-Integer-Types,signed primitive integer types>>,
2633
and stem:[T_2] is at least as wide as stem:[T_1].
@@ -53,6 +60,10 @@ is computed as follows:
5360
.. If stem:[T_1] and stem:[T_2] are <<Type-Checking_Identical-Types,identical types>>,
5461
then let stem:[T] be stem:[T_1].
5562

63+
.. Otherwise if either stem:[T_1] or stem:[T_2] is an <<Types_Alias-Types,alias type>>,
64+
then replace each alias type with its <<Types_Underlying-Types,underlying type>>
65+
and reapply these rules.
66+
5667
.. Otherwise if stem:[T_1] and stem:[T_2] are both
5768
<<Types_Primitive-Integer-Types,signed primitive integer types>>,
5869
then let stem:[T] be the wider of the two types.

‎docs/spec/Types.adoc

+35-2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ An abstract type is written using its
8080
<<Scoping-of-Names_Names-of-Definitions,unique qualified
8181
name>>.
8282

83+
=== Alias Types
84+
85+
An *alias type* is a type associated with an
86+
<<Definitions_Alias-Type-Definitions,alias type definition>>.
87+
There is one alias type per alias type definition.
88+
An alias type is written using its
89+
<<Scoping-of-Names_Names-of-Definitions,unique qualified
90+
name>>.
91+
8392
=== Internal Types
8493

8594
*Internal types* do not have syntactic names in FPP source models.
@@ -118,9 +127,25 @@ The order of the members is not significant.
118127
For example, `{ a: U32, b: F32 }` represents the same
119128
type as `{ b : F32, a: U32 }`.
120129

130+
=== Canonical Types
131+
132+
A type is a *canonical type* if it is not an <<Types_Alias-Types,alias type>>.
133+
134+
=== Underlying Types
135+
136+
The *underlying type* of a type _T_ is the <<Types_Canonical-Types, canonical type>>
137+
associated with _T_.
138+
139+
* If _T_ is a canonical type, then the underlying type of _T_ is _T_.
140+
141+
* Otherwise _T_ is an <<Types_Alias-Types,alias type>>.
142+
In this case, the underlying type of _T_ is the underlying type of the type
143+
associated with _T_ in the definition of _T_.
144+
121145
=== Displayable Types
122146

123-
A type is a **displayable type** if it is one of the following:
147+
A *displayable type* is a type that the F Prime ground data system can display.
148+
It is one of the following:
124149

125150
* A <<Types_Primitive-Integer-Types,primitive integer type>>.
126151
* A <<Types_Floating-Point-Types,floating-point type>>.
@@ -129,10 +154,13 @@ A type is a **displayable type** if it is one of the following:
129154
* An <<Types_Enum-Types,enum type>>.
130155
* An <<Types_Array-Types,array type>> whose member type is a displayable type.
131156
* A <<Types_Struct-Types,struct type>> whose member types are all displayable types.
157+
* An <<Types_Alias-Types,alias type>> whose <<Types_Underlying-Types,underlying
158+
type>> is a displayable type.
132159

133160
=== Types with Numeric Members
134161

135-
A type *has numeric members* if it is one of the following:
162+
A type *has numeric members* if its <<Types_Underlying-Types,underlying type>>
163+
is one of the following:
136164

137165
* A <<Types_Internal-Types_Numeric-Types,numeric type>>.
138166

@@ -192,3 +220,8 @@ struct definitions>> for examples.
192220
<<Values_Abstract-Type-Values,single value associated with _T_>>.
193221
This value is left abstract in the FPP model; the implementation
194222
of _T_ must provide a concrete value.
223+
224+
* The default value associated with an
225+
<<Types_Alias-Types,alias type>> _T_ is the
226+
<<Types_Default-Values,default value>> of its
227+
<<Types_Underlying-Types,underlying type>>.

‎docs/spec/Values.adoc

+60-15
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,26 @@ A *value* is one of the following:
2424
2525
* A struct value
2626
27-
Every value belongs to exactly one type.
27+
Every value _v_ belongs to exactly one <<Types_Canonical-Types,canonical type>>
28+
_T_, except as follows:
29+
30+
* Every string value belongs to the type `string` and to
31+
all types `string` _n_, for any _n_.
32+
33+
* Every value that belongs to type _T_ also belongs to every
34+
<<Types_Alias-Types,alias type>> whose
35+
<<Types_Underlying-Types,underlying type>> is _T_.
36+
37+
When a value _v_ belongs to a type _T_, we say that _v_ is a value
38+
*of type _T_*.
39+
40+
In the following subsections, we describe each kind of value and
41+
its associated canonical types.
2842

2943
=== Primitive Integer Values
3044

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

46-
We represent a primitive integer value as an expression followed by a colon and a type.
60+
We represent a primitive integer value as an expression followed by a colon and
61+
a primitive integer type.
4762
For example, we write the value 1 at type `U32` as `1: U32`. The value `1:
4863
U32` is distinct from the value `1: U8`.
4964

5065
=== Integer Values
5166

5267
An *integer value* is an ordinary (mathematical) integer value.
53-
It has type _Integer_.
68+
Its canonical type is _Integer_.
5469
We represent an integer value as an integer number, with no explicit type.
5570
For example, `1` is an integer value.
5671

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

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

7086
=== Boolean Values
7187

7288
A *Boolean value* is one of the values `true` and `false`.
73-
Its type is `bool`.
89+
Its canonical type is `bool`.
7490

7591
=== String Values
7692

7793
A *string value* is a sequence of characters that can be
7894
represented as a <<Expressions_String-Literals,string literal expression>>.
7995
It is written in the same way as a string literal expression,
8096
e.g., `"abc"`.
81-
Its type is `string`.
97+
A string value belongs to the following canonical types:
98+
99+
* `string`
100+
101+
* `string` _n_ for any _n_
82102

83103
=== Abstract Type Values
84104

85105
An *abstract type value* is a value associated with an abstract
86106
type.
87-
There is one value associated with each abstract type stem:[T].
107+
For each abstract type stem:[T], there is one
108+
value with canonical type stem:[T].
109+
This value is not represented explicitly in the model, but it
110+
may be represented in the generated code, e.g., as an object
111+
with default initialization.
88112
We write the value `value of type` stem:[T].
89113

90114
=== Anonymous Array Values
@@ -93,10 +117,17 @@ An *anonymous array value* is a value associated with an anonymous
93117
array type.
94118
We write an anonymous array value similarly to an
95119
<<Expressions_Array-Expressions,array expression>>:
96-
an anonymous array value has the form `[` stem:[v_1] `,` stem:[...] `,`
120+
an anonymous array value stem:[v] has the form `[` stem:[v_1] `,` stem:[...]
121+
`,`
97122
stem:[v_n] `]`, where for each stem:[i in [1,n]], stem:[v_i] is a value of type
98-
stem:[T] for some stem:[T].
99-
The type of the value is _[_ stem:[n] _]_ stem:[T].
123+
stem:[T] for some <<Types_Canonical-Types,canonical type>> stem:[T].
124+
The canonical type of stem:[v] is _[_ stem:[n] _]_ stem:[T].
125+
126+
Note that for an anonymous array value stem:[v] to be well-formed, the member
127+
values must have identical types.
128+
If an array expression appearing in the source syntax has
129+
member values with non-identical types, then one or more members must be
130+
converted to a different type before forming stem:[v].
100131

101132
=== Array Values
102133

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

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

120-
The type of the value is stem:[Q].
155+
The canonical type of the value is stem:[Q].
121156

122157
=== Enumeration Values
123158

124159
An *enumeration value* is a value associated with an
125160
<<Definitions_Enumerated-Constant-Definitions,enumerated constant definition>>.
126161
It is a pair consisting of the name and the integer value
127162
specified in the enumerated constant definition.
128-
Its type is the type associated with the
163+
Its canonical type is the type associated with the
129164
<<Definitions_Enum-Definitions,enum definition>> in which
130165
the enumerated constant definition appears.
131166

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

145181
=== Struct Values
146182

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

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

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

167208
=== Serialized Sizes
168209

@@ -200,3 +241,7 @@ the sum of the serialized sizes of the members of _v_
200241
* If _T_ is an
201242
<<Types_Abstract-Types,abstract type>>, then _s_ is not specified in FPP. It
202243
is up to the implementer of _T_ to provide the serialized size.
244+
245+
* If _T_ is a
246+
<<Types_Alias-Types,alias type>>, then apply these rules to its
247+
<<Types_Underlying-Types,underlying type>>.

0 commit comments

Comments
 (0)
Please sign in to comment.