[mercury-users] Appreciate some help #3:

Thomas Charles CONWAY conway at cs.mu.OZ.AU
Mon May 25 10:35:48 AEST 1998

tcklnbrg, you write:
> How do I define a new type that has several constraints including not
> being one of several other types?

There isn't a way. Mercury supports only discriminated union types,
not undiscriminated unions, which would be necessary (though not
sufficient on their own) for something like that.

> In particular, I have defined types: keyword; booleanliteral;
> nullliteral, etc. and now I need to define another
> type, identifier, as not a keyword, and not a booleanliteral, and not a
> null literal , and as a string with constraints on
> its form.
> something like:
> :- type keyword ---> <some enumerated words>.
> :- type booleanliteral ---> true; false.
> :- type nullliteral ---> null.
> :- type identifier ---> \+keyword, \+booleanliteral, \+nullliteral, <and
> some other string-related constraints>.

This sounds like tokenizing to me.
What you might want is a type like:

:- type token
	--->	keyword(keyword)
	;	true
	;	false
	;	null
	;	id(string)	% the string is the name of the identifier

> Also, how do I convert types, as in send a string literal into something
> that takes a keyword type?

Well, you can't really - it a predicate expects a keyword as an argument,
then you'd better give it a keyword. What you might need to do is have
a separate predicate or function (which is semidet) that takes a string
and returns a keyword.

Here's some bits from my C tokenizer:

:- type token
	--->	('+')
	;	('-')
	;	('<<=')
	;	('>>=')
	;	id(string)
	;	int(int)
	;	float(float)
	;	string(string)
	;	auto
	;	register
	;	char
	;	extern

Then in the predicate which takes a list of characters and
returns a list of tokens:
		takewhile(char__is_alnum_or_underscore, Cs, WordChars, Rest),
		string__from_char_list([C|WordCars], Word),
		( keyword(Word, KeyWord) ->
			Token = KeyWord
			Token = id(Word)

:- pred keyword(string, token).
:- mode keyword(in, out) is semidet.

keyword("auto", auto).
keyword("char", char).
keyword("const", const).
keyword("extern", extern).

While it's not strictly necessary to convert the list of characters
into a string to do the matching process, the compiler will do more
efficient indexing on strings than lists of chars, and it's easier to

Thomas Conway <conway at cs.mu.oz.au>
Nail here [] for new monitor.  )O+

More information about the users mailing list