====== User-defined data types ====== A user-defined data type is defined using ''deftype''. These are classified into two categories: * //data types//, which correspond to representations of the built-in ''int'' and ''bool'' types. * //structures//, which are a collection of data types. ===== Data types ===== A data type corresponds to an integer or Boolean value, even though it could also be a composite construct like a record or structure (from software programming languages). The syntax is similar to a process, and the constraints about declarations/etc. apply here as well. These data types are handled as the underlying built-in ''int'' or ''bool'' that they correspond to at the CHP level of abstraction. Often data types have some additional structure that is not required for a process. In particular, the body of the data type and its type signature provide information that relates a user-defined data type to a previously defined or built-in data type. When a user-defined data type is specified, a method for setting the value of the data type and reading its value must also be specified. If omitted, certain features of data types will not be enabled for the defined type. The following is a simple example of a datatype that creates a dual-rail representation for a Boolean variable. The first line specifies that ''d1of2'' is a new data type, and it implements the built-in type ''int<1>''---a one-bit integer. deftype d1of2 <: int<1> (bool d0,d1) { spec { exclhi(d0,d1) } } The body of the type is similar to a process, except it can only contain connections, ''spec'' bodies, and special //methods//. The following would result in an error: deftype d1of2 <: int<1> (bool d0,d1) { bool p; spec { exclhi(d0,d1) } } -[ERROR]-> Expecting bnf-item `methods_body', got `bool' Port lists for data types can be either built-in data types or user-defined data types. Channels (built-in or user-defined) and processes are not valid types for ports of a data type, since a data type is supposed to represent a circuit structure that is used to represent a data value. ==== Data methods ==== There are two methods that can be specified for a data type: - a //set method//, used to write a value to the type; - a //get method//, used to read the value of the type. One can think of these as type conversion methods invoked automatically to read or write the data type. When a normal data type is used, the special variable ''self'' is implicitly defined to be the built-in type that is implemented by the user-defined data type. deftype d1of2 <: int<1> (bool d0,d1) { spec { exclhi(d0,d1) } methods { set { [self=1->d1-;d0+ [] self=0->d0-;d1+] } get { [d0->self:=1 [] d1->self:=0] } } } In the example above, the ''set'' method says that the way to set a ''d1of2'' data type to the value ''0'' is to set ''d0'' to ''false'' and ''d1'' to ''true''. The special variable ''self'' is used to specify the ''int<1>'' value of the type, and the methods specify conversion operations. The selection statement in the ''get'' method uses the deterministic selection operator ''[]'' (see [[language:langs:hse|the hse sublanguage]]). This is an implicit check that when the ''get'' method is invoked, signals ''d0'' and ''d1'' cannot both be ''true''. We have also made this explicit in the specification body. Also, if both ''d0'' and ''d1'' are false (i.e. an illegal state in which to execute a get operation), the variable ''self'' is not assigned; the operation waits for at least one of ''d0'' or ''d1'' to be true. This is viewed as an error for a data type. (This is different in the case of a channel, where the semantics of the channel permit waiting.) ===== Structures ===== The ''deftype'' syntax can also be used to define structures/record types. These types can be used to group data fields or channel fields together. A structure is defined using ''deftype'', except it is not related to a built-in type as in the examples above. So, for instance: deftype mystruct (int<4> a; int<5> b) { } would declare a structure with two fields: ''a'' and ''b'' of the specified type. If all the fields within a structure are data values, this is a special case of a structure consisting purely of data. The distinction between a structure and another data type is that other data types are implementations of one of the built-in types like ''int'' or ''bool.'' ==== Pure structures ==== A pure structure is one that only contains other pure structures or ''int'' and ''bool'' components. In other words, they are structures that don't include channels. Structures like this correspond to what is normally viewed as a record/struct in a normal software programming language.