Help me spot a problem
Mark Anthony BROWN
dougl at students.cs.mu.oz.au
Fri Mar 14 18:15:59 AEDT 1997
Hello,
Mercury's runtime system is catching seg-faults in some code of mine,
but I can't see why. I am trying to write some predicates that achieve
polymorphism by taking closures in an argument.
Here's my attempt at a simple case. To use the predicate pwrite/4, you
must pass it a closure that has the appropriate type and mode for
printing the other argument.
%%%%%%%%%%%%%%
:- module printable.
:- interface.
:- import_module io.
:- type printable(T) ---> class(pred(T, io:state, io:state)).
:- inst printable_data = bound(class(pred(in, di, uo) is det)).
:- mode printable :: in(printable_data).
:- mode new_printable :: out(printable_data).
:- pred pwrite(printable(T)::printable, T::in, io:state::di, io:state::uo) is det.
:- implementation.
pwrite(C, Data) -->
call(Write, Data),
{ C = class(Write) }.
:- end_module printable.
%%%%%%%%%%%%%%%
% The above module can be used as follows:
:- module test_printable.
:- interface.
:- import_module printable, io.
:- pred main(io:state, io:state).
:- mode main(di, uo) is det.
% This is how we can make a concrete type.
:- func integer = printable(int).
:- mode integer = new_printable is det.
:- implementation.
% This constant function can be used to supply pwrite/4
% Note that by using write_int/4, the compiler will ensure
% that the other argument to pwrite is in fact an int.
integer = class(write_int).
% Real-code usage is now nice and simple
main -->
pwrite(integer, 99).
%%%%%%%%%%%%%%%%
These two modules compile without a problem, and produce the following when run:
*** Mercury runtime: caught segmentation violation ***
cause: address not mapped to object
PC at signal: 4396972367248 (3ffbff9dd90)
address involved: 63
You can get a stack dump by using grade debug
exiting from signal handler
Note: 63 is 99 in hexadecimal; if I change the integer, the violation
moves correspondingly.
Can anybody see the problem? Does it belong to any of these categories:
- compiler bug (eg reporting that program as type-correct when it
isn't)
- implementation (eg have I relied on an aspect of call/N that is
not yet implemented?)
- a mistake, misconception or oversight of mine
Thanks for any advice,
Mark.
P.S. I have other similar examples that _do_ work. The big difference in
this case is that this example passes io:write_string, which uses unique
modes and DCGs.
P.P.S. Is there more obvious way of doing all this?
More information about the users
mailing list