[m-rev.] for review: implement unify and compare for .NET in Mercury

Tyson Dowd trd at miscrit.be
Mon Aug 20 23:37:50 AEST 2001


Hi,


===================================================================


Estimated hours taken: 10
Branches: main

Implement generic unify and compare in (mostly) Mercury instead of MC++.

library/builtin.m:
	Call into rtti_implementation to implement unify and compare for
	the .NET backend.

library/rtti_implementation.m:
	Implement unify and compare in Mercury.



Index: library/builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/builtin.m,v
retrieving revision 1.61
diff -u -r1.61 builtin.m
--- library/builtin.m	16 Aug 2001 15:04:09 -0000	1.61
+++ library/builtin.m	20 Aug 2001 13:37:18 -0000
@@ -428,87 +428,25 @@
 
 ").
 
+
+:- interface.
+:- pred call_rtti_generic_unify(T::in, T::in) is semidet.
+:- pred call_rtti_generic_compare(comparison_result::out, T::in, T::in) is det.
+:- implementation.
+:- use_module rtti_implementation.
+
+call_rtti_generic_unify(X, Y) :-
+	rtti_implementation__generic_unify(X, Y).
+call_rtti_generic_compare(Res, X, Y) :-
+	rtti_implementation__generic_compare(Res, X, Y).
+
 :- pragma foreign_code("MC++", "
 
 static void compare_3(MR_TypeInfo TypeInfo_for_T, MR_Word_Ref Res, 
 		MR_Box X, MR_Box Y) 
 {
-
-        MR_TypeInfo             type_info;
-        MR_TypeCtorInfo         type_ctor_info;
-        int                     arity;
-        MR_TypeInfoParams       params;
-        MR_Word                 *args;
-        MR_Box                  ComparePred;
-
-        type_info = (MR_TypeInfo) TypeInfo_for_T;
-        type_ctor_info = dynamic_cast<MR_Word> (type_info->GetValue(
-		MR_TYPEINFO_TYPE_CTOR_INFO_SLOT));
-
-        if (type_ctor_info == 0) {
-            type_ctor_info = type_info;
-        }
-
-        if (0) {
-            // XXX code for higher order still needs to be written...
-        } else {
-            arity = System::Convert::ToInt32(
-		type_ctor_info->GetValue(MR_TYPE_CTOR_INFO_ARITY_SLOT));
-        }
-
-	ComparePred = type_ctor_info->GetValue(
-		MR_TYPE_CTOR_INFO_COMPARE_PRED_SLOT);
-
-        switch(arity) {
-	case 0: 
-		mercury::runtime::GenericCall::result_call_4(
-			ComparePred,
-			Res, X, Y);
-	break;
-	case 1:
-		mercury::runtime::GenericCall::result_call_5(
-			ComparePred,
-			type_info->GetValue(1), 
-			Res, X, Y);
-	break;
-	case 2:
-		mercury::runtime::GenericCall::result_call_6(
-			ComparePred,
-			type_info->GetValue(1), 
-			type_info->GetValue(2), 
-			Res, X, Y);
-	break;
-	case 3:
-		mercury::runtime::GenericCall::result_call_7(
-			ComparePred,
-			type_info->GetValue(1), 
-			type_info->GetValue(2), 
-			type_info->GetValue(3), 
-			Res, X, Y);
-	break;
-	case 4:
-		mercury::runtime::GenericCall::result_call_8(
-			ComparePred,
-			type_info->GetValue(1), 
-			type_info->GetValue(2), 
-			type_info->GetValue(3), 
-			type_info->GetValue(4), 
-			Res, X, Y);
-	break;
-	case 5:
-		mercury::runtime::GenericCall::result_call_9(
-			ComparePred,
-			type_info->GetValue(1), 
-			type_info->GetValue(2), 
-			type_info->GetValue(3), 
-			type_info->GetValue(4), 
-			type_info->GetValue(5), 
-			Res, X, Y);
-	break; 
-	default:
-		mercury::runtime::Errors::fatal_error(
-			""compare/3: type arity > 5 not supported"");
-	}
+	mercury::builtin::mercury_code::call_rtti_generic_compare_3(
+			TypeInfo_for_T, Res, X, Y);
 }
 
 void compare_3_m1(MR_TypeInfo TypeInfo_for_T, MR_Word_Ref Res, 
@@ -545,95 +483,13 @@
 
 ").
 
+
 :- pragma foreign_code("MC++", "
 
-static MR_Integer unify_2_p(MR_TypeInfo TypeInfo_for_T, MR_Box X, MR_Box Y) 
+static MR_Integer unify_2_p(MR_TypeInfo ti, MR_Box X, MR_Box Y) 
 {
-	int			SUCCESS_INDICATOR;
-        MR_TypeInfo             type_info;
-        MR_TypeCtorInfo         type_ctor_info;
-        MR_Box                  tmp;
-        int                     arity;
-        MR_TypeInfoParams       params;
-        MR_Box       		UnifyPred;
-	
-        type_info = (MR_TypeInfo) TypeInfo_for_T;
-
-        type_ctor_info = dynamic_cast<MR_Word> (type_info->GetValue(
-		MR_TYPEINFO_TYPE_CTOR_INFO_SLOT));
-        if (type_ctor_info == 0) {
-            type_ctor_info = type_info;
-        }
-
-        // XXX insert code to handle higher order....
-        if (0) {
-
-        } else {
-            arity = System::Convert::ToInt32(
-		type_ctor_info->GetValue(MR_TYPE_CTOR_INFO_ARITY_SLOT));
-        }
-
-	UnifyPred = type_ctor_info->GetValue(
-		MR_TYPE_CTOR_INFO_UNIFY_PRED_SLOT);
-
-	switch(arity) {
-	case 0: 
-                SUCCESS_INDICATOR = 
-			mercury::runtime::GenericCall::semidet_call_3(
-				UnifyPred,
-				X, Y);
-	break;
-	case 1:
-                SUCCESS_INDICATOR = 
-			mercury::runtime::GenericCall::semidet_call_4(
-				UnifyPred,
-				type_info->GetValue(1), 
-				X, Y);
-	break;
-	case 2:
-		SUCCESS_INDICATOR = 
-			mercury::runtime::GenericCall::semidet_call_5(
-				UnifyPred,
-				type_info->GetValue(1), 
-				type_info->GetValue(2), 
-				X, Y);
-	break;
-	case 3:
-		SUCCESS_INDICATOR =
-			mercury::runtime::GenericCall::semidet_call_6(
-				UnifyPred,
-				type_info->GetValue(1), 
-				type_info->GetValue(2), 
-				type_info->GetValue(3), 
-				X, Y);
-	break;
-	case 4:
-		SUCCESS_INDICATOR =
-			mercury::runtime::GenericCall::semidet_call_7(
-				UnifyPred,
-				type_info->GetValue(1), 
-				type_info->GetValue(2), 
-				type_info->GetValue(3), 
-				type_info->GetValue(4), 
-				X, Y);
-	break;
-	case 5:
-		SUCCESS_INDICATOR = 
-			mercury::runtime::GenericCall::semidet_call_8(
-				UnifyPred,
-				type_info->GetValue(1), 
-				type_info->GetValue(2), 
-				type_info->GetValue(3), 
-				type_info->GetValue(4), 
-				type_info->GetValue(5), 
-				X, Y);
-	break;
-	default:
-		mercury::runtime::Errors::fatal_error(
-			""unify/2: type arity > 5 not supported"");
-	}
-
-	return SUCCESS_INDICATOR;
+	return mercury::builtin::mercury_code::call_rtti_generic_unify_2_p(
+			ti, X, Y);
 }
 
 ").
Index: library/rtti_implementation.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/rtti_implementation.m,v
retrieving revision 1.2
diff -u -r1.2 rtti_implementation.m
--- library/rtti_implementation.m	17 Aug 2001 13:11:53 -0000	1.2
+++ library/rtti_implementation.m	20 Aug 2001 13:37:18 -0000
@@ -35,6 +35,10 @@
 
 :- func get_type_info(T::unused) = (type_info::out) is det.
 
+:- pred generic_unify(T::in, T::in) is semidet.
+
+:- pred generic_compare(comparison_result::out, T::in, T::in) is det.
+
 :- pred compare_type_infos(comparison_result::out,
 		type_info::in, type_info::in) is det.
 
@@ -43,7 +47,7 @@
 
 :- implementation.
 
-:- import_module require.
+:- import_module require, string.
 
 	% std_util has a lot of types and functions with the same names,
 	% so we prefer to keep the namespace separate.
@@ -109,6 +113,278 @@
 	TypeInfo = TypeInfo_for_T;
 ").
 
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+generic_compare(Res, X, Y) :-
+	TypeInfo = get_type_info(X),
+	TypeCtorInfo = get_type_ctor_info(TypeInfo),
+	TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
+	( 
+		TypeCtorRep = tuple 
+	->
+		compare_tuple(TypeInfo, Res, X, Y)
+	; 	
+		TypeCtorRep = (pred)
+	->
+		error("rtti_implementation.m: unimplemented: higher order comparisons")
+	;	
+		Arity = TypeCtorInfo ^ type_ctor_arity,
+		ComparePred = TypeCtorInfo ^ type_ctor_compare_pred,
+		( Arity = 0 ->
+			result_call_4(ComparePred, Res, X, Y)
+		; Arity = 1 ->
+			result_call_5(ComparePred, Res,
+				TypeInfo ^ index(1), X, Y)
+		; Arity = 2 ->
+			result_call_6(ComparePred, Res,  
+				TypeInfo ^ index(1), TypeInfo ^ index(2), 
+				X, Y)
+		; Arity = 3 ->
+			result_call_7(ComparePred, Res,
+				TypeInfo ^ index(1), TypeInfo ^ index(2), 
+				TypeInfo ^ index(3),
+				X, Y)
+		; Arity = 4 ->
+			result_call_8(ComparePred, Res,
+				TypeInfo ^ index(1), TypeInfo ^ index(2), 
+				TypeInfo ^ index(3), TypeInfo ^ index(4),
+				X, Y)
+		; Arity = 5 ->
+			result_call_9(ComparePred, Res,
+				TypeInfo ^ index(1), TypeInfo ^ index(2), 
+				TypeInfo ^ index(3), TypeInfo ^ index(4),
+				TypeInfo ^ index(5),
+				X, Y)
+		;
+			error("compare/3: type arity > 5 not supported")
+		)
+	).
+
+
+generic_unify(X, Y) :-
+	TypeInfo = get_type_info(X),
+	TypeCtorInfo = get_type_ctor_info(TypeInfo),
+	TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
+	( 
+		TypeCtorRep = tuple 
+	->
+		unify_tuple(TypeInfo, X, Y)
+	; 	
+		TypeCtorRep = (pred)
+	->
+		error("rtti_implementation.m: unimplemented: higher order unifications")
+	;	
+		Arity = TypeCtorInfo ^ type_ctor_arity,
+		UnifyPred = TypeCtorInfo ^ type_ctor_unify_pred,
+		( Arity = 0 ->
+			semidet_call_3(UnifyPred, X, Y)
+		; Arity = 1 ->
+			semidet_call_4(UnifyPred, TypeInfo ^ index(1), X, Y)
+		; Arity = 2 ->
+			semidet_call_5(UnifyPred, 
+				TypeInfo ^ index(1), TypeInfo ^ index(2), 
+				X, Y)
+		; Arity = 3 ->
+			semidet_call_6(UnifyPred, 
+				TypeInfo ^ index(1), TypeInfo ^ index(2), 
+				TypeInfo ^ index(3),
+				X, Y)
+		; Arity = 4 ->
+			semidet_call_7(UnifyPred, 
+				TypeInfo ^ index(1), TypeInfo ^ index(2), 
+				TypeInfo ^ index(3), TypeInfo ^ index(4),
+				X, Y)
+		; Arity = 5 ->
+			semidet_call_8(UnifyPred, 
+				TypeInfo ^ index(1), TypeInfo ^ index(2), 
+				TypeInfo ^ index(3), TypeInfo ^ index(4),
+				TypeInfo ^ index(5),
+				X, Y)
+		;
+			error("unify/2: type arity > 5 not supported")
+		)
+	).
+
+	% check for tuple and higher order cases
+
+:- pred unify_tuple(type_info::in, T::in, T::in) is semidet.
+
+unify_tuple(_, _, _) :- 
+	semidet_unimplemented("tuple unifications").
+
+:- pred compare_tuple(type_info::in, comparison_result::out, T::in, T::in)
+	is det.
+
+compare_tuple(_, (=), _, _) :- 
+	det_unimplemented("tuple comparisons").
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+	% Implement generic calls -- we could use call/N but then we would
+	% have to create a real closure.
+	%
+	% We first give "unimplemented" definitions in Mercury, which will be
+	% used by default.
+
+:- pred semidet_call_3(P::in, T::in, U::in) is semidet.
+semidet_call_3(_::in, _::in, _::in) :-
+	semidet_unimplemented("semidet_call_3").
+
+:- pred semidet_call_4(P::in, A::in, T::in, U::in) is semidet.
+semidet_call_4(_::in, _::in, _::in, _::in) :-
+	semidet_unimplemented("semidet_call_4").
+
+:- pred semidet_call_5(P::in, A::in, B::in, T::in, U::in) is semidet.
+semidet_call_5(_::in, _::in, _::in, _::in, _::in) :-
+	semidet_unimplemented("semidet_call_5").
+
+:- pred semidet_call_6(P::in, A::in, B::in, C::in, T::in, U::in) is semidet.
+semidet_call_6(_::in, _::in, _::in, _::in, _::in, _::in) :-
+	semidet_unimplemented("semidet_call_6").
+
+:- pred semidet_call_7(P::in, A::in, B::in, C::in, D::in, T::in, U::in)
+	is semidet.
+semidet_call_7(_::in, _::in, _::in, _::in, _::in, _::in, _::in) :-
+	semidet_unimplemented("semidet_call_7").
+
+:- pred semidet_call_8(P::in, A::in, B::in, C::in, D::in, E::in, T::in, U::in)
+	is semidet.
+semidet_call_8(_::in, _::in, _::in, _::in, _::in, _::in, _::in, _::in) :-
+	semidet_unimplemented("semidet_call_8").
+
+
+:- pred result_call_4(P::in, comparison_result::out,
+		T::in, U::in) is det.
+result_call_4(_::in, (=)::out, _::in, _::in) :-
+	det_unimplemented("result_call_4").
+
+:- pred result_call_5(P::in, comparison_result::out,
+		A::in, T::in, U::in) is det.
+result_call_5(_::in, (=)::out, _::in, _::in, _::in) :-
+	det_unimplemented("comparison_result").
+
+:- pred result_call_6(P::in, comparison_result::out,
+		A::in, B::in, T::in, U::in) is det.
+result_call_6(_::in, (=)::out, _::in, _::in, _::in, _::in) :-
+	det_unimplemented("comparison_result").
+
+:- pred result_call_7(P::in, comparison_result::out,
+		A::in, B::in, C::in, T::in, U::in) is det.
+result_call_7(_::in, (=)::out, _::in, _::in, _::in, _::in, _::in) :-
+	det_unimplemented("comparison_result").
+
+:- pred result_call_8(P::in, comparison_result::out,
+		A::in, B::in, C::in, D::in, T::in, U::in) is det.
+result_call_8(_::in, (=)::out, _::in, _::in, _::in, _::in, _::in, _::in) :-
+	det_unimplemented("comparison_result").
+
+:- pred result_call_9(P::in, comparison_result::out,
+		A::in, B::in, C::in, D::in, E::in, T::in, U::in) is det.
+result_call_9(_::in, (=)::out, _::in, _::in, _::in, _::in, _::in,
+		_::in, _::in) :-
+	det_unimplemented("result_call_9").
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+
+	% We override the above definitions in the .NET backend.
+
+:- pragma foreign_proc("MC++",
+	semidet_call_3(Pred::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	SUCCESS_INDICATOR =
+		mercury::runtime::GenericCall::semidet_call_3(Pred, X, Y);
+").
+:- pragma foreign_proc("MC++",
+	semidet_call_4(Pred::in, A::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	SUCCESS_INDICATOR =
+		mercury::runtime::GenericCall::semidet_call_4(Pred, A, X, Y);
+").
+:- pragma foreign_proc("MC++",
+	semidet_call_5(Pred::in, A::in, B::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	SUCCESS_INDICATOR =
+		mercury::runtime::GenericCall::semidet_call_5(Pred, A, B, X, Y);
+").
+:- pragma foreign_proc("MC++",
+	semidet_call_6(Pred::in, A::in, B::in, C::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	SUCCESS_INDICATOR =
+		mercury::runtime::GenericCall::semidet_call_6(Pred, A, B, C,
+			X, Y);
+").
+:- pragma foreign_proc("MC++",
+	semidet_call_7(Pred::in, A::in, B::in, C::in, D::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	SUCCESS_INDICATOR =
+		mercury::runtime::GenericCall::semidet_call_7(Pred, A, B, C, D,
+			X, Y);
+").
+:- pragma foreign_proc("MC++",
+	semidet_call_8(Pred::in, A::in, B::in, C::in, D::in, E::in,
+		X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	SUCCESS_INDICATOR =
+		mercury::runtime::GenericCall::semidet_call_8(Pred, A, B, C, D,
+			E, X, Y);
+").
+
+
+
+:- pragma foreign_proc("C#",
+	result_call_4(Pred::in, Res::out, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	mercury.runtime.GenericCall.result_call_4(Pred, ref Res, X, Y);
+").
+
+:- pragma foreign_proc("C#",
+	result_call_5(Pred::in, Res::out, A::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	mercury.runtime.GenericCall.result_call_5(Pred, A, ref Res, X, Y);
+").
+:- pragma foreign_proc("C#",
+	result_call_6(Pred::in, Res::out, A::in, B::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	mercury.runtime.GenericCall.result_call_6(Pred, A, B, ref Res, X, Y);
+").
+:- pragma foreign_proc("C#",
+	result_call_7(Pred::in, Res::out, A::in, B::in, C::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	mercury.runtime.GenericCall.result_call_7(Pred, A, B, C, ref Res, X, Y);
+").
+:- pragma foreign_proc("C#",
+	result_call_8(Pred::in, Res::out, A::in, B::in, C::in, D::in, X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	mercury.runtime.GenericCall.result_call_8(Pred, A, B, C, D,
+		ref Res, X, Y);
+").
+:- pragma foreign_proc("C#",
+	result_call_9(Pred::in, Res::out, A::in, B::in, C::in, D::in, E::in,
+		X::in, Y::in), 
+		[will_not_call_mercury, thread_safe],
+"
+	mercury.runtime.GenericCall.result_call_9(Pred, 
+		A, B, C, D, E, ref Res, X, Y);
+").
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
 compare_type_infos(Res, TypeInfo1, TypeInfo2) :-
 	( same_pointer_value(TypeInfo1, TypeInfo2) ->
 		Res = (=)
@@ -125,8 +401,8 @@
 :- pred compare_collapsed_type_infos(comparison_result::out,
 		type_info::in, type_info::in) is det.
 compare_collapsed_type_infos(Res, TypeInfo1, TypeInfo2) :-
-	get_type_ctor_info(TypeInfo1, TypeCtorInfo1),
-	get_type_ctor_info(TypeInfo2, TypeCtorInfo2),
+	TypeCtorInfo1 = get_type_ctor_info(TypeInfo1),
+	TypeCtorInfo2 = get_type_ctor_info(TypeInfo2),
 
 		% The comparison here is arbitrary.
 		% In the past we just compared pointers of the type_c
@@ -144,12 +420,11 @@
 			; TypeCtorInfo1 ^ type_ctor_name = "func" 
 			)
 		->
+			% XXX code to handle tuples and higher order
 			error("rtti_implementation.m: unimplemented: tuples and higher order type comparisons")
 		;
 			true
 		)
-
-		% XXX code to handle tuples and higher order
 	;
 		Res = NameRes
 	).
@@ -165,7 +440,7 @@
 
 :- func collapse_equivalences(type_info) = type_info.
 collapse_equivalences(TypeInfo) = NewTypeInfo :-
-	get_type_ctor_info(TypeInfo, TypeCtorInfo),
+	TypeCtorInfo = get_type_ctor_info(TypeInfo),
 	( 
 		( 
 		  TypeCtorInfo ^ type_ctor_rep = equiv_ground 
@@ -183,7 +458,7 @@
 %
 % XXX we have only implemented the .NET backend for the low-level data case.
 
-:- pred get_type_ctor_info(type_info::in, type_ctor_info::out) is det.
+:- func get_type_ctor_info(type_info) = type_ctor_info is det.
 
 :- pragma foreign_code("C#", "
 
@@ -191,18 +466,22 @@
 	// Fill this in as you add new field accessors.
 
 	enum type_ctor_info_field_nums {
+		type_ctor_arity = 0,
+		type_ctor_unify_pred = 1,
+		type_ctor_compare_pred = 3,
 		type_ctor_rep = 4,
 		type_ctor_module_name = 7,
 		type_ctor_name = 8,
-		type_layout = 11
+		type_functors = 10,
+		type_layout = 11,
+		type_ctor_num_functors = 12,
+		type_ctor_num_ptags = 13
 	}
 
 ").
 
-
-
 :- pragma foreign_proc("C#",
-	get_type_ctor_info(TypeInfo::in, TypeCtorInfo::out), [],
+	get_type_ctor_info(TypeInfo::in) = (TypeCtorInfo::out), [],
 "
 	try {
 		TypeCtorInfo = (object[]) TypeInfo[0];
@@ -212,7 +491,7 @@
 ").
 
 :- pragma foreign_proc("C",
-	get_type_ctor_info(TypeInfo::in, TypeCtorInfo::out), [],
+	get_type_ctor_info(TypeInfo::in) = (TypeCtorInfo::out), [],
 "
 	TypeCtorInfo = (MR_Word) MR_TYPEINFO_GET_TYPE_CTOR_INFO(
 		(MR_TypeInfo) TypeInfo);
@@ -231,6 +510,74 @@
 ").
 
 %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- func index(int, type_info) = type_info.
+:- pragma foreign_proc("C#",
+	index(X::in, TypeInfo::in) = (TypeInfoAtIndex::out), [], "
+	TypeInfoAtIndex = (object[]) TypeInfo[X];
+").
+
+index(_::in, TypeInfo::in) = (TypeInfo::out) :- 
+	det_unimplemented("index").
+
+
+:- pred semidet_unimplemented(string::in) is semidet.
+semidet_unimplemented(S) :-
+	( std_util__semidet_succeed ->
+		error("unimplemented: " ++ S)
+	;
+		std_util__semidet_succeed
+	).
+
+:- pred det_unimplemented(string::in) is det.
+det_unimplemented(S) :-
+	( std_util__semidet_succeed ->
+		error("unimplemented: " ++ S)
+	;
+		true
+	).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- func type_ctor_arity(type_ctor_info) = int.
+:- pragma foreign_proc("C#",
+	type_ctor_arity(TypeCtorInfo::in) = (Arity::out), [], "
+	Arity = (int) TypeCtorInfo[
+			(int) type_ctor_info_field_nums.type_ctor_arity];
+").
+:- pragma foreign_proc("C",
+	type_ctor_arity(TypeCtorInfo::in) = (Arity::out), [], "
+	MR_TypeCtorInfo tci = (MR_TypeCtorInfo) TypeCtorInfo;
+	Arity = tci->arity;
+").
+
+:- some [P] func type_ctor_unify_pred(type_ctor_info) = P.
+:- pragma foreign_proc("C#",
+	type_ctor_unify_pred(TypeCtorInfo::in) = (UnifyPred::out), [], "
+	UnifyPred = TypeCtorInfo[
+			(int) type_ctor_info_field_nums.type_ctor_unify_pred];
+").
+:- pragma foreign_proc("C",
+	type_ctor_unify_pred(TypeCtorInfo::in) = (UnifyPred::out), [], "
+	MR_TypeCtorInfo tci = (MR_TypeCtorInfo) TypeCtorInfo;
+	UnifyPred = (MR_Integer) tci->unify_pred;
+").
+
+:- some [P] func type_ctor_compare_pred(type_ctor_info) = P.
+:- pragma foreign_proc("C#",
+	type_ctor_compare_pred(TypeCtorInfo::in) = (UnifyPred::out), [], "
+	UnifyPred = TypeCtorInfo[
+			(int) type_ctor_info_field_nums.type_ctor_compare_pred];
+").
+:- pragma foreign_proc("C",
+	type_ctor_compare_pred(TypeCtorInfo::in) = (UnifyPred::out), [], "
+	MR_TypeCtorInfo tci = (MR_TypeCtorInfo) TypeCtorInfo;
+	UnifyPred = (MR_Integer) tci->compare_pred;
+").
+
+
 
 :- func type_ctor_rep(type_ctor_info) = type_ctor_rep.
 :- pragma foreign_proc("C#",
--------------------------------------------------------------------------
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