[m-rev.] for review: implement arg_cc in Mercury
Peter Ross
pro at missioncriticalit.com
Sun Dec 1 02:28:35 AEDT 2002
Hi,
For fjh to review. I also need to code up something similar to make
limited_deconstruct_idcc work, but I want to have this reviewed first before
continuing further.
===================================================================
Estimated hours taken: 4
Branches: main
Implement arg_cc in Mercury using rtti_implementation.
library/deconstruct.m:
Implement univ_arg_idcc as a cc_multi predicate with the
success of the predicate encoded into a maybe type, as it is
impossible to implement is as cc_nondet.
Change the C code version of univ_arg_idcc to match the
Mercury versions behaviour.
Delete the bogus modes of arg/4 and implement them as arg_cc/3
instead.
library/std_util.m:
Introduce a new type maybe_arg which is returned by arg_cc to
return its result.
Change arg_cc to have the correct determinism and type
signature.
Add utility predicates which allow us to construct values of
the maybe type from a foreign language.
runtime/mercury_ml_arg_body.h:
In the MR_NONCANON case this code is used inside a cc_multi
predicate, so setting the SUCCESS_INDICATOR should be
disabled.
tests/hard_coded/deconstruct_arg.m:
Update the test case to test this new functionality.
Index: library/deconstruct.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/deconstruct.m,v
retrieving revision 1.15
diff -u -r1.15 deconstruct.m
--- library/deconstruct.m 30 Nov 2002 08:03:33 -0000 1.15
+++ library/deconstruct.m 30 Nov 2002 15:14:57 -0000
@@ -118,8 +118,12 @@
:- some [ArgT] pred arg(T, noncanon_handling, int, ArgT).
:- mode arg(in, in(do_not_allow), in, out) is semidet.
:- mode arg(in, in(canonicalize), in, out) is semidet.
-:- mode arg(in, in(include_details_cc), in, out) is cc_nondet.
-:- mode arg(in, in, in, out) is cc_nondet.
+:- mode arg(in, in(include_details_cc), in, out) is erroneous.
+:- mode arg(in, in, in, out) is semidet.
+
+ % See the documentation of std_util__arg_cc
+:- pred arg_cc(T, int, std_util__maybe_arg).
+:- mode arg_cc(in, in, out) is cc_multi.
% named_arg(Data, NonCanon, Name, Argument)
%
@@ -225,6 +229,7 @@
:- implementation.
:- import_module int, require, rtti_implementation.
+:- pragma foreign_import_module("C", std_util).
%-----------------------------------------------------------------------------%
@@ -271,10 +276,18 @@
univ_arg_can(Term, Index, Univ)
;
NonCanon = include_details_cc,
- univ_arg_idcc(Term, Index, Univ)
+ error("deconstruct__arg called with include_details_cc")
),
Argument = univ_value(Univ).
+arg_cc(Term, Index, MaybeArg) :-
+ univ_arg_idcc(Term, Index, MaybeUniv),
+ ( MaybeUniv = yes(Univ),
+ MaybeArg = 'new arg'(univ_value(Univ))
+ ; MaybeUniv = no,
+ MaybeArg = std_util__no
+ ).
+
named_arg(Term, NonCanon, Name, Argument) :-
(
NonCanon = do_not_allow,
@@ -298,7 +311,7 @@
univ_arg_can(Term, Index, Univ)
;
NonCanon = include_details_cc,
- univ_arg_idcc(Term, Index, Univ)
+ error("deconstruct__arg called with include_details_cc")
)
->
Argument = univ_value(Univ)
@@ -426,7 +439,7 @@
:- pred univ_arg_dna(T::in, int::in, univ::out) is semidet.
:- pred univ_arg_can(T::in, int::in, univ::out) is semidet.
-:- pred univ_arg_idcc(T::in, int::in, univ::out) is cc_nondet.
+:- pred univ_arg_idcc(T::in, int::in, maybe(univ)::out) is cc_multi.
:- pred univ_named_arg_dna(T::in, string::in, univ::out) is semidet.
:- pred univ_named_arg_can(T::in, string::in, univ::out) is semidet.
@@ -471,22 +484,30 @@
}").
:- pragma foreign_proc("C",
- univ_arg_idcc(Term::in, Index::in, Argument::out),
+ univ_arg_idcc(Term::in, Index::in, MaybeArg::out),
[will_not_call_mercury, thread_safe, promise_pure],
"{
-#define TYPEINFO_ARG TypeInfo_for_T
-#define TERM_ARG Term
-#define SELECTOR_ARG Index
-#define SELECTED_ARG Argument
-#define SELECTED_TYPE_INFO TypeInfo_for_ArgT
-#define NONCANON MR_NONCANON_CC
-#include ""mercury_ml_arg_body.h""
-#undef TYPEINFO_ARG
-#undef TERM_ARG
-#undef SELECTOR_ARG
-#undef SELECTED_ARG
-#undef SELECTED_TYPE_INFO
-#undef NONCANON
+ MR_Word Argument;
+
+ #define TYPEINFO_ARG TypeInfo_for_T
+ #define TERM_ARG Term
+ #define SELECTOR_ARG Index
+ #define SELECTED_ARG Argument
+ #define SELECTED_TYPE_INFO TypeInfo_for_ArgT
+ #define NONCANON MR_NONCANON_CC
+ #include ""mercury_ml_arg_body.h""
+ #undef TYPEINFO_ARG
+ #undef TERM_ARG
+ #undef SELECTOR_ARG
+ #undef SELECTED_ARG
+ #undef SELECTED_TYPE_INFO
+ #undef NONCANON
+
+ if (success) {
+ MaybeArg = ML_construct_maybe_yes((MR_Word) NULL, Argument);
+ } else {
+ MaybeArg = ML_construct_maybe_no((MR_Word) NULL);
+ }
}").
:- pragma foreign_proc("C",
@@ -560,10 +581,14 @@
rtti_implementation__deconstruct(Term,
canonicalize, _Functor, _Arity, Arguments),
list__index0(Arguments, Index, Arg).
-univ_arg_idcc(_Term::in, _Index::in, _Arg::out) :-
- % This version is only used for back-ends for which there is no
- % matching foreign_proc version.
- private_builtin__sorry("univ_arg_idcc/3").
+univ_arg_idcc(Term::in, Index::in, MaybeArg::out) :-
+ rtti_implementation__deconstruct(Term,
+ include_details_cc, _Functor, _Arity, Arguments),
+ ( list__index0(Arguments, Index, Arg) ->
+ MaybeArg = yes(Arg)
+ ;
+ MaybeArg = no
+ ).
univ_named_arg_dna(_Term::in, _Name::in, _Arg::out) :-
% This version is only used for back-ends for which there is no
Index: library/std_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
retrieving revision 1.273
diff -u -r1.273 std_util.m
--- library/std_util.m 8 Nov 2002 00:44:25 -0000 1.273
+++ library/std_util.m 30 Nov 2002 15:14:59 -0000
@@ -563,6 +563,10 @@
%-----------------------------------------------------------------------------%
+:- type maybe_arg
+ ---> some[T] arg(T)
+ ; no.
+
% functor, argument and deconstruct and their variants take any type
% (including univ), and return representation information for that type.
%
@@ -630,7 +634,7 @@
% of a non-canonical type.
%
:- func arg(T::in, int::in) = (ArgT::out) is semidet.
-:- pred arg_cc(T::in, int::in, ArgT::out) is cc_nondet.
+:- pred arg_cc(T::in, int::in, maybe_arg::out) is cc_multi.
:- func argument(T::in, int::in) = (univ::out) is semidet.
:- pred argument_cc(T::in, int::in, univ::out) is cc_nondet.
@@ -789,6 +793,16 @@
Y = no
).
+ % Utility predicates which are useful for constructing values
+ % of the maybe(T) type from foreign code.
+:- func construct_yes(T) = maybe(T).
+:- pragma export(construct_yes(in) = out, "ML_construct_maybe_yes").
+construct_yes(T) = yes(T).
+
+:- func construct_no = maybe(T).
+:- pragma export(construct_no = out, "ML_construct_maybe_no").
+construct_no = no.
+
%-----------------------------------------------------------------------------%
/*
@@ -1606,12 +1620,7 @@
private_builtin__typed_unify(Argument0, Argument).
arg_cc(Term, Index, Argument) :-
- deconstruct__arg(Term, include_details_cc, Index, Argument0),
- ( private_builtin__typed_unify(Argument0, Argument1) ->
- Argument = Argument1
- ;
- error("arg_cc: argument has wrong type")
- ).
+ deconstruct__arg_cc(Term, Index, Argument).
argument(Term, Index) = ArgumentUniv :-
deconstruct__arg(Term, canonicalize, Index, Argument),
Index: runtime/mercury_ml_arg_body.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_ml_arg_body.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_ml_arg_body.h
--- runtime/mercury_ml_arg_body.h 18 Feb 2002 07:01:18 -0000 1.3
+++ runtime/mercury_ml_arg_body.h 30 Nov 2002 15:15:00 -0000
@@ -70,6 +70,8 @@
MR_new_univ_on_hp(SELECTED_ARG, arg_type_info, *argument_ptr);
}
+#ifndef MR_NONCANON_CC
SUCCESS_INDICATOR = success;
+#endif
#undef arg_func
Index: tests/hard_coded/deconstruct_arg.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/deconstruct_arg.m,v
retrieving revision 1.4
diff -u -r1.4 deconstruct_arg.m
--- tests/hard_coded/deconstruct_arg.m 29 Nov 2002 13:26:00 -0000 1.4
+++ tests/hard_coded/deconstruct_arg.m 30 Nov 2002 15:15:00 -0000
@@ -154,7 +154,8 @@
{ string__format("deconstruct argument %d of ", [i(ArgNum)], Str) },
io__write_string(Str),
io__print(T),
- ( { deconstruct__arg(T, include_details_cc, ArgNum, Arg) } ->
+ { deconstruct__arg_cc(T, ArgNum, MaybeArg) },
+ ( { MaybeArg = arg(Arg) } ->
io__write_string(" is "),
io__write(Arg),
io__write_string("\n")
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list