[mercury-users] Re: integer enumerations

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Jul 26 13:03:51 AEST 2000


On 26-Jul-2000, Michael Day <mcda at students.cs.mu.OZ.AU> wrote:
> 
> Has any work been done in Mercury to allow integer types limited to a
> fixed set of values,

If the set of values is reasonably small, then you can encode
this as a subtype using the mode system:
	
	:- inst my_int_subtype == bound(1 ; 2 ; 3).

	:- func xyz(int) = int.
	:- mode xyz(in(my_int_subtype)) = out(my_int_subtype) is det.

	xyz(1) = 2.
	xyz(2) = 3.
	xyz(3) = 1.

> or a fixed range of values?

Not to my knowledge.

> Alternatively, how about a pragma hack for discriminated union types for
> easy interfacing with C libraries...
> 
> :- type some_c_enum
> 	--->	foo	= some hack to set value to 1
> 	;	bar	= some hack to set value to 2
> 	;	baz	= some hack to set value to 17
> 	.

Ada has standard pragmas for that kind of thing.

One difficulty, though, is that there's a fundamental incompatibility
between Mercury enumerations and C enumerations: C allows enumerations
to have values which are not members of the enumeration.  For example,
if you have

	enum some_c_enum { foo = 1, bar = 2, baz = 17 };

then according to the C standard `foo | bar' and `31' are both valid
values of the type `enum some_c_enum'.

For enumerations where the enumeration values have been explicitly specified
in the C code, it's probably best not to map them to Mercury enums.
Instead, you can map them to `int' plus a set of constants in Mercury,
e.g.

	:- type some_c_enum == int.

	:- func foo = some_c_enum.
	:- func bar = some_c_enum.
	:- func baz = some_c_enum.
	foo = 1.
	bar = 2.
	baz = 17.

or you can use a Mercury enum type and some conversion routines:

	:- type some_c_enum ---> foo ; bar ; baz.
	:- type some_c_enum_rep == int.

	:- func from_enum(some_c_enum) = some_c_enum_rep.
	:- mode from_enum(in) = out is det.
	:- mode from_enum(out) = in is semidet.
	from_enum(foo) = 1.
	from_enum(bar) = 2.
	from_enum(baz) = 17.

	:- func to_enum(some_c_enum_rep) = some_c_enum.
	to_enum(X) = Y :- X = from_enum(Y).

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list