// BEGIN:Hash_extern
extern Hash<O> {
/// Constructor
Hash(PNA_HashAlgorithm_t algo);
/// Compute the hash for data.
/// @param data The data over which to calculate the hash.
/// @return The hash value.
O get_hash<D>(in D data);
/// Compute the hash for data, with modulo by max, then add base.
/// @param base Minimum return value.
/// @param data The data over which to calculate the hash.
/// @param max The hash value is divided by max to get modulo.
/// An implementation may limit the largest value supported,
/// e.g. to a value like 32, or 256, and may also only
/// support powers of 2 for this value. P4 developers should
/// limit their choice to such values if they wish to
/// maximize portability.
/// @return (base + (h % max)) where h is the hash value.
O get_hash<T, D>(in T base, in D data, in T max);
}
// END:Hash_extern
And I try to write the following code. Are there any errors? Thanks for your reply.
That looks correct to me, except for one thing: In the P4 language (not only for the PNA archtitecture, but any architecture), all parameters to extern object constructor methods must be compile-time known values, e.g. a literal constant, not the value of a run-time variable.
In addition to @andyfingerhut 's reply, I also want to point out that the current version of the language specification does not allow writing into the action data. In the code you quoted, register_position parameter is directionless, meaning that it is read from the match-action table to be used in the computations. It cannot be written back (see Section 14.1 or the current spec).
I also want to mention that even though the current spec allows instantiating externs inside the actions, many targets do not support that. Instead, it is recommended to instantiate those outside of an action, in the control. The reason is that externs might have their own control plane APIs and instantiating them inside actions makes generating those APIs a lot more problematic.