[m-rev.] diff: make some erlang deconstruct routines fail on non-du types

Peter Wang novalazy at gmail.com
Tue Sep 4 14:04:02 AEST 2007


Branches: main

library/deconstruct.m:
library/erlang_rtti_implementation.m:
	Make the Erlang implementations of deconstruct_du, functor_number,
	functor_number_cc, fail as required on non-d.u. types.

	Replace int by functor_number_lex and functor_number_ordinal types
	where appropriate.


About the "% XXX force cc_multi" part, which is a workaround for a
problem I only noticed I added after I committed an earlier version of
this.  The C implementation of `functor_number_cc' passes
MR_NONCANON_ALLOW to mercury_ml_functor_body.h.  As far as I can tell,
MR_NONCANON_ALLOW corresponds to the functor `canonicalize' in the type
`noncanon_handling'.  For all routines in deconstruct.m, `canonicalize'
implies determinism `det', not `cc_multi'.  Should the C implementation
of functor_number_cc be passing MR_NONCANON_CC instead, or should
functor_number_cc not be cc_multi?


Index: library/deconstruct.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/deconstruct.m,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- library/deconstruct.m	30 Aug 2007 06:56:37 -0000	1.48
+++ library/deconstruct.m	4 Sep 2007 03:10:50 -0000	1.49
@@ -433,7 +433,7 @@
 
 deconstruct_du(Term, NonCanon, FunctorNumber, Arity, Arguments) :-
     ( erlang_rtti_implementation.is_erlang_backend ->
-        erlang_rtti_implementation.deconstruct(Term, NonCanon, _Functor,
+        erlang_rtti_implementation.deconstruct_du(Term, NonCanon,
             FunctorNumber, Arity, Arguments)
     ;
         deconstruct_du_2(Term, NonCanon, FunctorNumber, Arity, Arguments)
@@ -598,20 +598,15 @@
 
 functor_number(Term::in, FunctorNumber::out, Arity::out) :-
     ( erlang_rtti_implementation.is_erlang_backend ->
-        % XXX should fail for non-du types
-        semidet_succeed,
-        erlang_rtti_implementation.deconstruct(Term, do_not_allow,
-            _Functor, FunctorNumber, Arity, _Args)
+        erlang_rtti_implementation.functor_number(Term, FunctorNumber, Arity)
     ;
         private_builtin.sorry("deconstruct.functor_number")
     ).
 
 functor_number_cc(Term::in, FunctorNumber::out, Arity::out) :-
     ( erlang_rtti_implementation.is_erlang_backend ->
-        % XXX should fail for non-du types
-        semidet_succeed,
-        erlang_rtti_implementation.deconstruct(Term, include_details_cc,
-            _Functor, FunctorNumber, Arity, _Args)
+        erlang_rtti_implementation.functor_number_cc(Term, FunctorNumber,
+            Arity)
     ;
         private_builtin.sorry("deconstruct.functor_number_cc")
     ).
@@ -1047,7 +1042,7 @@
 
 local_deconstruct(T, H, F, A, As) :-
     ( erlang_rtti_implementation.is_erlang_backend ->
-        erlang_rtti_implementation.deconstruct(T, H, F, _FN, A, As)
+        erlang_rtti_implementation.deconstruct(T, H, F, A, As)
     ;
         rtti_implementation.deconstruct(T, H, F, A, As)
     ).
Index: library/erlang_rtti_implementation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/erlang_rtti_implementation.m,v
retrieving revision 1.18
retrieving revision 1.20
diff -u -r1.18 -r1.20
--- library/erlang_rtti_implementation.m	30 Aug 2007 14:03:48 -0000	1.18
+++ library/erlang_rtti_implementation.m	4 Sep 2007 03:47:54 -0000	1.20
@@ -19,11 +19,14 @@
 :- module erlang_rtti_implementation.
 :- interface.
 
+:- import_module construct.
 :- import_module deconstruct.
 :- import_module list.
 :- import_module type_desc.
 :- import_module univ.
 
+%-----------------------------------------------------------------------------%
+
 :- type type_info.
 :- type type_ctor_info.
 :- type type_ctor_info_evaled.
@@ -56,34 +59,51 @@
 :- pred type_ctor_desc_name_and_arity(type_ctor_desc::in,
     string::out, string::out, int::out) is det.
 
-:- pred deconstruct(T, noncanon_handling, string, int, int, list(univ)).
-:- mode deconstruct(in, in(do_not_allow), out, out, out, out) is det.
-:- mode deconstruct(in, in(canonicalize), out, out, out, out) is det.
-:- mode deconstruct(in, in(include_details_cc), out, out, out, out)
+%-----------------------------------------------------------------------------%
+%
+% Implementations for use from deconstruct
+%
+
+:- pred functor_number(T::in, functor_number_lex::out, int::out) is semidet.
+
+:- pred functor_number_cc(T::in, functor_number_lex::out,
+    int::out) is cc_nondet. 
+
+:- pred deconstruct(T, noncanon_handling, string, int, list(univ)).
+:- mode deconstruct(in, in(do_not_allow), out, out, out) is det.
+:- mode deconstruct(in, in(canonicalize), out, out, out) is det.
+:- mode deconstruct(in, in(include_details_cc), out, out, out)
     is cc_multi.
-:- mode deconstruct(in, in, out, out, out, out) is cc_multi.
+:- mode deconstruct(in, in, out, out, out) is cc_multi.
+
+:- pred deconstruct_du(T, noncanon_handling, functor_number_lex,
+    int, list(univ)).
+:- mode deconstruct_du(in, in(do_not_allow), out, out, out) is semidet.
+:- mode deconstruct_du(in, in(include_details_cc), out, out, out) is cc_nondet.
+:- mode deconstruct_du(in, in, out, out, out) is cc_nondet.
 
 %-----------------------------------------------------------------------------%
 %
-% Implementations for use from construct.
+% Implementations for use from construct
+%
 
 :- func num_functors(type_desc.type_desc) = int is semidet.
 
-:- pred get_functor(type_desc.type_desc::in, int::in, string::out, int::out,
-    list(type_desc.type_desc)::out) is semidet.
+:- pred get_functor(type_desc.type_desc::in, functor_number_lex::in,
+    string::out, int::out, list(type_desc.type_desc)::out) is semidet.
 
-:- pred get_functor_with_names(type_desc.type_desc::in, int::in, string::out,
-    int::out, list(type_desc.type_desc)::out, list(string)::out)
+:- pred get_functor_with_names(type_desc.type_desc::in, functor_number_lex::in,
+    string::out, int::out, list(type_desc.type_desc)::out, list(string)::out)
     is semidet.
 
-:- pred get_functor_ordinal(type_desc.type_desc::in, int::in, int::out)
-    is semidet.
+:- pred get_functor_ordinal(type_desc.type_desc::in, functor_number_lex::in,
+    functor_number_ordinal::out) is semidet.
 
-:- pred get_functor_lex(type_desc.type_desc::in, int::in, int::out)
-    is semidet.
+:- pred get_functor_lex(type_desc.type_desc::in, functor_number_ordinal::in,
+    functor_number_lex::out) is semidet.
 
-:- func construct(type_desc::in, int::in, list(univ)::in) = (univ::out)
-    is semidet.
+:- func construct(type_desc::in, functor_number_lex::in, list(univ)::in)
+    = (univ::out) is semidet.
 
 :- func construct_tuple_2(list(univ), list(type_desc), int) = univ.
 
@@ -650,12 +670,50 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-deconstruct(Term, NonCanon, Functor, FunctorNumber, Arity, Arguments) :-
+functor_number(Term, FunctorNumber, Arity) :-
+    TypeInfo = Term ^ type_info,
+    TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
+    TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
+    is_du_type(TypeCtorRep),
+    NonCanon = do_not_allow,
+    deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
+        _Functor, FunctorNumber, Arity, _Arguments).
+
+functor_number_cc(Term, FunctorNumber, Arity) :-
+    TypeInfo = Term ^ type_info,
+    TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
+    TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
+    is_du_type(TypeCtorRep),
+    NonCanon = canonicalize,
+    deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
+        _Functor, FunctorNumber, Arity0, _Arguments),
+    % XXX force cc_multi as required by the interface for functor_number_cc.
+    % It seems wrong since deconstruct(canonicalize) is det.
+    ( Arity = Arity0
+    ; Arity = Arity0
+    ).
+
+deconstruct(Term, NonCanon, Functor, Arity, Arguments) :-
     TypeInfo = Term ^ type_info,
     TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
     TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
     deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
-        Functor, FunctorNumber, Arity, Arguments).
+        Functor, _FunctorNumber, Arity, Arguments).
+
+deconstruct_du(Term, NonCanon, FunctorNumber, Arity, Arguments) :-
+    TypeInfo = Term ^ type_info,
+    TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
+    TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
+    is_du_type(TypeCtorRep),
+    deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
+        _Functor, FunctorNumber, Arity, Arguments).
+
+:- pred is_du_type(erlang_type_ctor_rep::in) is semidet.
+
+is_du_type(etcr_du).
+is_du_type(etcr_dummy).
+is_du_type(etcr_list).
+is_du_type(etcr_tuple).
 
 :- pred deconstruct_2(T, type_info, type_ctor_info_evaled,
     erlang_type_ctor_rep, noncanon_handling, string, int, int, list(univ)).
@@ -672,8 +730,9 @@
     (
         TypeCtorRep = etcr_du,
         FunctorReps = TypeCtorInfo ^ type_ctor_functors,
-        matching_du_functor(FunctorReps, 0, Term, FunctorRep, FunctorNumber),
+        matching_du_functor(FunctorReps, Term, FunctorRep),
         Functor = string.from_char_list(FunctorRep ^ edu_name),
+        FunctorNumber = FunctorRep ^ edu_lex,
         Arity = FunctorRep ^ edu_orig_arity,
         Arguments = list.map(
             get_du_functor_arg(TypeInfo, FunctorRep, Term), 1 .. Arity)
@@ -754,7 +813,7 @@
     ;
         TypeCtorRep = etcr_string,
         det_dynamic_cast(Term, String),
-        Functor = term_io.quoted_string(String),
+        Functor = "\"" ++ String ++ "\"",
         FunctorNumber = 0,
         Arity = 0,
         Arguments = []
@@ -836,22 +895,21 @@
     ).
 
     %
-    % matching_du_functor(FunctorReps, Index, Term, FunctorRep, FunctorNumber)
+    % matching_du_functor(FunctorReps, Term, FunctorRep)
     %
     % finds the erlang_du_functor in the list Functors which describes
     % the given Term.
     %
-:- pred matching_du_functor(list(erlang_du_functor)::in, int::in, T::in,
-    erlang_du_functor::out, int::out) is det.
+:- pred matching_du_functor(list(erlang_du_functor)::in, T::in,
+    erlang_du_functor::out) is det.
 
-matching_du_functor([], _, _, _, _) :-
+matching_du_functor([], _, _) :-
     error(this_file ++ " matching_du_functor/2").
-matching_du_functor([F | Fs], Index, T, Functor, FunctorNumber) :-
+matching_du_functor([F | Fs], T, Functor) :-
     ( matches_du_functor(T, F) ->
-        Functor = F,
-        FunctorNumber = Index
+        Functor = F
     ;
-        matching_du_functor(Fs, Index + 1, T, Functor, FunctorNumber)
+        matching_du_functor(Fs, T, Functor)
     ).
 
     %
@@ -1228,8 +1286,8 @@
         FunctorNum = 0
     ).
 
-:- pred matching_du_ordinal(list(erlang_du_functor)::in, int::in,
-    erlang_du_functor::out) is semidet.
+:- pred matching_du_ordinal(list(erlang_du_functor)::in,
+    functor_number_ordinal::in, erlang_du_functor::out) is semidet.
 
 matching_du_ordinal(Fs, Ordinal, Functor) :-
     list.index0(Fs, Ordinal, Functor),
@@ -1240,8 +1298,8 @@
         error(this_file ++ " matching_du_ordinal/3")
     ).
 
-:- pred matching_du_functor_number(list(erlang_du_functor)::in, int::in,
-    erlang_du_functor::out) is semidet.
+:- pred matching_du_functor_number(list(erlang_du_functor)::in,
+    functor_number_lex::in, erlang_du_functor::out) is semidet.
 
 matching_du_functor_number([F | Fs], FunctorNum, Functor) :-
     ( F ^ edu_lex = FunctorNum ->

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list