mirror of
https://github.com/nasa/fpp.git
synced 2025-12-16 21:35:53 -06:00
201 lines
5.3 KiB
Plaintext
201 lines
5.3 KiB
Plaintext
== Defining Enums
|
|
|
|
An FPP model may contain one or more *enum definitions*.
|
|
Enum is short for enumeration.
|
|
An FPP enum is similar to an enum in C or {cpp}.
|
|
It defines a named type called an *enum type* and a set of named constants
|
|
called *enumerated constants*.
|
|
The enumerated constants are the values associated with the type.
|
|
|
|
An enum definition may appear at the top level or inside a
|
|
<<Defining-Modules,module definition>>.
|
|
An enum definition is an
|
|
<<Writing-Comments-and-Annotations_Annotations,annotatable element>>.
|
|
|
|
=== Writing an Enum Definition
|
|
|
|
Here is an example:
|
|
|
|
[source,fpp]
|
|
----
|
|
enum Decision {
|
|
YES
|
|
NO
|
|
MAYBE
|
|
}
|
|
----
|
|
|
|
This code defines an enum type `Decision` with three
|
|
enumerated constants: `YES`, `NO`, and `MAYBE`.
|
|
|
|
In general, to write an enum definition, you write the following:
|
|
|
|
* The keyword `enum`.
|
|
|
|
* The name of the enum.
|
|
|
|
* A sequence of enumerated constants enclosed in curly braces `{` ... `}`.
|
|
|
|
|
|
The enumerated constants form an
|
|
<<Defining-Constants_Multiple-Definitions-and-Element-Sequences,element
|
|
sequence>>
|
|
in which the optional terminating punctuation is a comma.
|
|
For example, this definition is equivalent to the one above:
|
|
|
|
[source,fpp]
|
|
----
|
|
enum Decision { YES, NO, MAYBE }
|
|
----
|
|
|
|
There must be at least one enumerated constant.
|
|
|
|
=== Using an Enum Definition
|
|
|
|
Once you have defined an enum, you can use the enum as a type and the
|
|
enumerated constants as constants of that type.
|
|
The name of each enumerated constant is qualified by the enum name.
|
|
Here is an example:
|
|
|
|
[source,fpp]
|
|
----
|
|
enum State { ON, OFF }
|
|
constant initialState = State.OFF
|
|
----
|
|
|
|
The constant `s` has type `State` and value `State.ON`.
|
|
Here is another example:
|
|
|
|
[source,fpp]
|
|
|
|
----
|
|
enum Decision { YES, NO, MAYBE }
|
|
array Decisions = [3] Decision default Decision.MAYBE
|
|
----
|
|
|
|
Here we have used the enum type as the type of the array member,
|
|
and we have used the value `Decision.MAYBE` as the default
|
|
value of an array member.
|
|
|
|
=== Numeric Values
|
|
|
|
As in C and {cpp}, each enumerated constant has an associated
|
|
numeric value.
|
|
By default, the values start at zero and go up by one.
|
|
For example, in the enum `Decision` defined above,
|
|
`YES` has value 0, `NO` has value 1, and `MAYBE` has value 2.
|
|
|
|
You can optionally assign explicit values to the enumerated
|
|
constants.
|
|
To do this, you write an equals sign and an expression after
|
|
each of the constant definitions.
|
|
Here is an example:
|
|
|
|
[source,fpp]
|
|
----
|
|
enum E { A = 1, B = 2, C = 3 }
|
|
----
|
|
|
|
This definition creates an enum type `E` with three enumerated constants `E.A`,
|
|
`E.B`, and `E.C`. The constants have 1, 2, and 3 as their associated numeric
|
|
values.
|
|
|
|
If you provide an explicit numeric value for any of the enumerated constants,
|
|
then you must do so for all of them.
|
|
For example, this code is not allowed:
|
|
|
|
[source,fpp]
|
|
--------
|
|
# Error: cannot provide a value for just one enumerated constant
|
|
enum E { A = 1, B, C }
|
|
--------
|
|
|
|
Further, the values must be distinct.
|
|
For example, this code is not allowed, because
|
|
the enumerated constants `A` and `B` both have the value 2:
|
|
|
|
[source,fpp]
|
|
--------
|
|
# Error: enumerated constant values must be distinct
|
|
enum E { A = 2, B = 1 + 1 }
|
|
--------
|
|
|
|
You may convert an enumerated constant to its associated numeric value.
|
|
For example, this code is allowed:
|
|
|
|
[source,fpp]
|
|
----
|
|
enum E { A = 5 }
|
|
constant c = E.A + 1
|
|
----
|
|
|
|
The constant `c` has the value 6.
|
|
|
|
However, you may not convert a numeric value to an enumerated constant.
|
|
This is for type safety reasons: a value of enumeration type should have
|
|
one of the numeric values specified in the type.
|
|
Assigning an arbitrary number to an enum type would violate this rule.
|
|
|
|
For example, this code is not allowed:
|
|
|
|
[source,fpp]
|
|
--------
|
|
enum E { A, B, C }
|
|
# Error: cannot assign integer 10 to type E
|
|
array A = [3] E default 10
|
|
--------
|
|
|
|
=== The Representation Type
|
|
|
|
Each enum definition has an associated *representation type*.
|
|
This is the primitive integer type used to represent the numeric
|
|
values associated with the enumerated constants when generating code.
|
|
|
|
If you don't specify a representation type, then the default
|
|
type is `I32`.
|
|
For example, in the enumerations defined in the previous sections,
|
|
the representation type is `I32`.
|
|
To specify an explicit representation type, you write it after
|
|
the enum name, separated from the name by a colon, like this:
|
|
|
|
[source,fpp]
|
|
----
|
|
enum Small : U8 { A, B, C }
|
|
----
|
|
|
|
This code defines an enum `Small` with three enumerated constants
|
|
`Small.A`, `Small.B`, and `Small.C`.
|
|
Each of the enumerated constants is represented as a `U8` value
|
|
in {cpp}.
|
|
|
|
=== The Default Value
|
|
|
|
Every type in FPP has an associated default value.
|
|
For enum types, if you don't specify a default value explicitly,
|
|
then the default value is the first enumerated constant
|
|
in the definition.
|
|
For example, given this definition
|
|
|
|
[source,fpp]
|
|
----
|
|
enum Decision { YES, NO, MAYBE }
|
|
----
|
|
|
|
the default value for the type `Decision` is `Decision.YES`.
|
|
|
|
That may be too permissive, say if `Decision` represents
|
|
a decision on a bank loan.
|
|
Perhaps the default value should be `Decision.MAYBE`.
|
|
To specify an explicit default value, write the keyword `default`
|
|
and the enumerated constant after the enumerated constant
|
|
definitions, like this:
|
|
|
|
[source,fpp]
|
|
----
|
|
enum Decision { YES, NO, MAYBE } default MAYBE
|
|
----
|
|
|
|
Notice that when using the constant `MAYBE` as a default value, we
|
|
don't need to qualify it with the enum name, because the
|
|
use appears inside the enum where it is defined.
|