Skip to content

Commit ddcfd4e

Browse files
author
Mihai Budiu
authored
Merge pull request #777 from p4lang/ser_enum_774
Issue #774: Allow automatic conversions from a serializable enum to a…
2 parents bc50642 + 48a140f commit ddcfd4e

File tree

1 file changed

+66
-7
lines changed

1 file changed

+66
-7
lines changed

p4-16/spec/P4-16-spec.mdk

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,8 +2163,8 @@ target-specific).
21632163
It is also possible to specify an `enum` with an underlying representation.
21642164
These are sometimes called serializable `enum`s, because headers are
21652165
allowed to have fields with such `enum` types.
2166-
This requires the programmer provide both the fixed-width unsigned integer type and an associated
2167-
fixed-width unsigned integer value for each symbolic entry in the enumeration. For example, the
2166+
This requires the programmer provide both the fixed-width unsigned (or signed) integer type and
2167+
an associated integer value for each symbolic entry in the enumeration. For example, the
21682168
declaration
21692169

21702170
~ Begin P4Example
@@ -2189,7 +2189,7 @@ an `enum` with an underlying type can be thought of as being a type derived
21892189
from the underlying type carrying equality, assignment, and casts to/from the
21902190
underlying type.
21912191

2192-
Compiler implementations are expected to raise an error if the fixed-width unsigned integer representation
2192+
Compiler implementations are expected to raise an error if the fixed-width integer representation
21932193
for an enumeration entry falls outside the representation range of the underlying
21942194
type.
21952195

@@ -3046,6 +3046,61 @@ casts `a`, which was initialized to `E.e2` to a `bit<8>`, using the specified
30463046
fixed-width unsigned integer representation for `E.e2`, `1`. The variable `b` is then set to the
30473047
symbolic value `E.e2`, which corresponds to the fixed-width unsigned integer value `1`.
30483048

3049+
Because it is always safe to cast from an `enum` to its underlying fixed-width integer type,
3050+
automatic casting from an `enum` to its fixed-width (signed or unsigned) integer type is also supported:
3051+
3052+
~ Begin P4Example
3053+
bit<8> x = E.e2; // sets x to 1 (E.e2 is automatically casted to bit<8>)
3054+
3055+
E a = E.e2
3056+
bit<8> y = a << 3; // sets y to 8 (a is automatically casted to bit<8> and then shifted)
3057+
~ End P4Example
3058+
3059+
Automatic casting from an underlying fixed-width type to an enum is *not* supported.
3060+
3061+
~ Begin P4Example
3062+
enum bit<8> E1 {
3063+
e1 = 0, e2 = 1, e3 = 2
3064+
}
3065+
3066+
enum bit<8> E2 {
3067+
e1 = 10, e2 = 11, e3 = 12
3068+
}
3069+
E1 a = E1.e1;
3070+
E2 b = E2.e2;
3071+
3072+
a = b; // Error: b is automatically casted to bit<8>,
3073+
// but bit<8> cannot be automatically casted to E1
3074+
3075+
a = (E1) b; // OK
3076+
3077+
a = E1.e1 + 1; // Error: E.e1 is automatically casted to bit<8>,
3078+
// and the right-hand expression has
3079+
// the type bit<8>, which cannot be casted to E automatically.
3080+
3081+
a = (E1)(E1.e1 + 1); // Final explicit casting makes the assinment legal
3082+
3083+
a = E1.e1 + E1.e2; // Error: both arguments to the addition are automatically
3084+
// casted to bit<8>. Thus the addition itself is legal, but
3085+
// the assignment is not
3086+
3087+
a = (E)(E.e1 + E.e2); // Final explicit casting makes the assinment legal
3088+
~ End P4Example
3089+
3090+
A reasonable compiler might generate a warning in cases that involve multiple automatic casts.
3091+
3092+
~ Begin P4Example
3093+
E1 a = E1.e1;
3094+
E2 b = E2.e2;
3095+
bit<8> c;
3096+
3097+
if (a > b) { // Potential warning: two automatic and different casts to bit<8>.
3098+
...
3099+
}
3100+
3101+
c = a + b; // Legal, but a warning would be reasonable
3102+
~ End P4Example
3103+
30493104
Note that while it is always safe to cast from an `enum` to its fixed-width unsigned integer type,
30503105
and vice versa, there may be cases where casting a fixed-width unsigned integer value to
30513106
its related `enum` type produces an unnamed value.
@@ -7183,13 +7238,17 @@ The P4 compiler should provide:
71837238
| | | restrictions on arguments to calls, and modified precedence of |
71847239
| | | bitwise operators. |
71857240
|-----|-----|-----|
7186-
| 1.2.0 | April TBD, 2019 | Added error `ParserInvalidArgument`. |
7241+
| 1.2.0 | October, 2019 | Added error `ParserInvalidArgument`, order of `const` entries, |
7242+
| | | header size methods, 1-bit signed values, signed bit slices, empty |
7243+
| | | tuples, `@deprecated` annotation, free-form annotations, `int` type |
7244+
| | | `table.apply().miss`, `string` type. |
71877245
|-----|-----|-----|
71887246

71897247
## Summary of changes made in version 1.2.0
71907248

7191-
* Added `table.apply().miss`
7192-
* Added `string` type (Section [#sec-string].)
7249+
* Added `table.apply().miss` (Section [#sec-invoke-mau]).
7250+
* Added `string` type (Section [#sec-string]).
7251+
* Implicit casts from enum values (Section [#sec-enum-exprs]).
71937252
* Allow 1-bit signed values
71947253
* Define the type of bit slices from signed and unsigned values to be unsigned.
71957254
* Constrain `default` label position for `switch` statements.
@@ -7198,7 +7257,7 @@ The P4 compiler should provide:
71987257
* Relaxed the structure of annotation bodies.
71997258
* Removed the `@pkginfo` annotation. This is defined by the P4Runtime
72007259
specification.
7201-
* Added `int` type (Section [#sec-infinite-precision-integers].)
7260+
* Added `int` type (Section [#sec-infinite-precision-integers]).
72027261
* Added error `ParserInvalidArgument` (Sections
72037262
[#sec-packet-extract-two], [#sec-skip-bits]).
72047263
* Clarify the significance of order of entries in `const entries`

0 commit comments

Comments
 (0)