[m-rev.] for review: semidet C# code

Tyson Dowd trd at cs.mu.OZ.AU
Fri Oct 12 13:16:50 AEST 2001


Hi,

Pete, could you have a look at this diff?

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


Estimated hours taken: 10
Branches: main

Fix semidet C# code to use SUCCESS_INDICATOR.

Represent mlds__native_bool_type as bool, not int32.

In the library, fix incorrect uses of MC++ to implement functions -- these
weren't being caught because they returned int32, and we assumed
this was a semidet return value, not an actual integer.

These incorrect uses were all buggy -- functions don't work in MC++.
The compiler is now catches cases where functions returning int are
implemented in MC++ -- it won't catch cases where
IL's bool type is returned, but that should not be a such a problem.

compiler/ml_code_gen.m:
	Add SUCCESS_INDICATOR to the locals of the MLDS for semidet C# code, 
	copy SUCCESS_INDICATOR into succeeded after the execution of the
	user's code.

compiler/mlds_to_csharp.m:
	Implement assignments (so we can copy SUCCESS_INDICATOR to
	succeeded).

compiler/mlds_to_il.m:
	Copy return values into SUCCESS_INDICATOR for forwarded
	predicates (it will then be copied into succeeded).
	This all gets optimized away in the generated IL anyway.

	Represent native_bool_type as bool, not int32.
	Check for MC++ functions returning bool (not int32).

compiler/mlds_to_mcpp.m:
	Map bool to MR_Bool, not MR_Integer.

library/int.m:
	Implement much of the code in Mercury rather than C# or MC++.
	The more efficient C bindings remain, but for other backends we
	fall back on the Mercury bindings.

library/io.m:
	Implement io__get_stream_id as a pred in MC++.
	It is easier to keep this as MC++ at the moment as that is what
	the rest of the io.m code is implemented in (including the
	Mercury stream data structure).

library/std_util.m:
	Add some missing assignments to SUCCESS_INDICATOR.


Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.100
diff -u -r1.100 ml_code_gen.m
--- compiler/ml_code_gen.m	24 Aug 2001 15:44:49 -0000	1.100
+++ compiler/ml_code_gen.m	11 Oct 2001 07:31:07 -0000
@@ -2308,7 +2308,7 @@
 	% we generate a call to an out-of-line procedure that contains
 	% the user's code.
 
-ml_gen_ordinary_pragma_csharp_proc(_CodeModel, Attributes,
+ml_gen_ordinary_pragma_csharp_proc(CodeModel, Attributes,
 		_PredId, _ProcId, _ArgVars, _ArgDatas, _OrigArgTypes,
 		ForeignCode, Context, MLDS_Decls, MLDS_Statements) -->
 	{ foreign_language(Attributes, ForeignLang) },
@@ -2319,10 +2319,37 @@
 	{ OutlineStmt = outline_foreign_proc(ForeignLang, OutputVarLvals,
 		ForeignCode) },
 
+	{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
+	{ module_info_name(ModuleInfo, ModuleName) },
+	{ MLDSModuleName = mercury_module_name_to_mlds(ModuleName) },
+
+		% If the code is semidet, we should copy SUCCESS_INDICATOR 
+		% out into "suceess".
+	
+	ml_success_lval(SucceededLval),
+
+	{ CodeModel = model_semi ->
+		SuccessIndicatorVarName = var_name("SUCCESS_INDICATOR", no),
+		SuccessIndicatorDecl = ml_gen_mlds_var_decl(
+			var(SuccessIndicatorVarName),
+			mlds__native_bool_type,
+			no_initializer, MLDSContext),
+		SuccessIndicatorLval = var(qual(MLDSModuleName,
+			SuccessIndicatorVarName), mlds__native_bool_type),
+		SuccessIndicatorStatement = ml_gen_assign(SucceededLval,
+			lval(SuccessIndicatorLval), Context),
+		SuccessVarLocals = [SuccessIndicatorDecl],
+		SuccessIndicatorStatements = [SuccessIndicatorStatement]
+	;
+		SuccessVarLocals = [],
+		SuccessIndicatorStatements = []
+	},
+
 	{ MLDS_Statements = [
-		mlds__statement(atomic(OutlineStmt), MLDSContext)
+		mlds__statement(atomic(OutlineStmt), MLDSContext) |
+		SuccessIndicatorStatements
 		] },
-	{ MLDS_Decls = [] }.
+	{ MLDS_Decls = SuccessVarLocals }.
 
 :- pred ml_gen_ordinary_pragma_il_proc(code_model, 
 	pragma_foreign_proc_attributes, pred_id, proc_id, list(prog_var),
Index: compiler/mlds_to_csharp.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_csharp.m,v
retrieving revision 1.16
diff -u -r1.16 mlds_to_csharp.m
--- compiler/mlds_to_csharp.m	24 Aug 2001 15:44:54 -0000	1.16
+++ compiler/mlds_to_csharp.m	11 Oct 2001 07:31:08 -0000
@@ -270,6 +270,13 @@
 			{ sorry(this_file, "multiple return values") }
 		)
 	;
+		{ Statement = atomic(assign(LVal, RVal)) } 
+	->
+		write_csharp_lval(LVal),
+		io__write_string(" = "),
+		write_csharp_rval(RVal),
+		io__write_string(";\n")
+	;
 		{ functor(Statement, SFunctor, _Arity) },
 		{ sorry(this_file, "csharp output for " ++ SFunctor) }
 	).
Index: compiler/mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.84
diff -u -r1.84 mlds_to_il.m
--- compiler/mlds_to_il.m	19 Sep 2001 10:03:11 -0000	1.84
+++ compiler/mlds_to_il.m	11 Oct 2001 07:31:14 -0000
@@ -1756,7 +1756,8 @@
 
 		( { ReturnLvals = [] } ->
 			% If there is a return type, but no return value, it
-			% must be a semidet predicate so put it in succeeded.
+			% must be a semidet predicate so put it in 
+			% SUCCESS_INDICATOR.
 			% XXX it would be better to get the code generator
 			% to tell us this is the case directly
 			{ LoadInstrs = empty },
@@ -1764,7 +1765,7 @@
 				StoreInstrs = empty
 			;
 				StoreInstrs = instr_node(
-					stloc(name("succeeded")))
+					stloc(name("SUCCESS_INDICATOR")))
 			}
 		; { ReturnLvals = [ReturnLval] } ->
 			get_load_store_lval_instrs(ReturnLval,
@@ -1810,7 +1811,7 @@
 			% return a useful value.
 		{ RetType = void ->
 			StoreReturnInstr = empty
-		; RetType = simple_type(int32) ->
+		; RetType = simple_type(bool) ->
 			StoreReturnInstr = instr_node(stloc(name("succeeded")))
 		;
 			sorry(this_file, "functions in MC++")
@@ -2886,8 +2887,7 @@
 mlds_type_to_ilds_type(ILDataRep, mlds__generic_env_ptr_type) =
 	ILDataRep^il_envptr_type.
 
-	% XXX we ought to use the IL bool type
-mlds_type_to_ilds_type(_, mlds__native_bool_type) = ilds__type([], int32).
+mlds_type_to_ilds_type(_, mlds__native_bool_type) = ilds__type([], bool).
 
 mlds_type_to_ilds_type(_, mlds__native_char_type) = ilds__type([], char).
 
Index: compiler/mlds_to_mcpp.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_mcpp.m,v
retrieving revision 1.19
diff -u -r1.19 mlds_to_mcpp.m
--- compiler/mlds_to_mcpp.m	24 Aug 2001 15:44:57 -0000	1.19
+++ compiler/mlds_to_mcpp.m	11 Oct 2001 07:31:15 -0000
@@ -579,7 +579,7 @@
 write_il_simple_type_as_managed_cpp_type(native_float) --> 
 	io__write_string("mercury::MR_Float").
 write_il_simple_type_as_managed_cpp_type(bool) --> 
-	io__write_string("mercury::MR_Integer").
+	io__write_string("mercury::MR_Bool").
 write_il_simple_type_as_managed_cpp_type(char) --> 
 	io__write_string("mercury::MR_Char").
 write_il_simple_type_as_managed_cpp_type(refany) --> 
Index: library/int.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/int.m,v
retrieving revision 1.77
diff -u -r1.77 int.m
--- library/int.m	6 Sep 2001 08:26:46 -0000	1.77
+++ library/int.m	11 Oct 2001 07:31:15 -0000
@@ -477,17 +477,6 @@
 	#define ML_BITS_PER_INT		(sizeof(MR_Integer) * CHAR_BIT)
 ").
 
-:- pragma foreign_decl("MC++", "
-	#include <limits.h>
-
-	// XXX this should work, but it would be nice to have a more robust
-	// technique that used the fact we map to System.Int32 in the compiler.
-
-	#define ML_BITS_PER_INT		(sizeof(MR_Integer) * CHAR_BIT)
-
-").
-
-
 :- pragma foreign_proc("C", int__max_int(Max::out),
 		[will_not_call_mercury, thread_safe], "
 	if (sizeof(MR_Integer) == sizeof(int))
@@ -541,24 +530,20 @@
 
 :- pragma foreign_proc("MC++", int__bits_per_int(Bits::out),
 		[will_not_call_mercury, thread_safe], "
-	Bits = ML_BITS_PER_INT;
+	Bits = 32;
 ").
 
-:- pragma foreign_proc("MC++", int__quot_bits_per_int(Int::in) = (Div::out),
-		[will_not_call_mercury, thread_safe], "
-	Div = Int / ML_BITS_PER_INT;
-").
-
-:- pragma foreign_proc("MC++", int__times_bits_per_int(Int::in) = (Result::out),
-		[will_not_call_mercury, thread_safe], "
-	Result = Int * ML_BITS_PER_INT;
-").
+int__quot_bits_per_int(Int::in) = (Result::out) :-
+	int__bits_per_int(Bits),
+	Result = Int // Bits.
 
-:- pragma foreign_proc("MC++", int__rem_bits_per_int(Int::in) = (Rem::out),
-		[will_not_call_mercury, thread_safe], "
-	Rem = Int % ML_BITS_PER_INT;
-").
+int__times_bits_per_int(Int::in) = (Result::out) :-
+	int__bits_per_int(Bits),
+	Result = Int * Bits.
 
+int__rem_bits_per_int(Int::in) = (Result::out) :-
+	int__bits_per_int(Bits),
+	Result = Int rem Bits.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.233
diff -u -r1.233 io.m
--- library/io.m	25 Sep 2001 09:37:02 -0000	1.233
+++ library/io.m	11 Oct 2001 07:31:15 -0000
@@ -2747,8 +2747,18 @@
 	io__progname(DefaultName, Progname),
 	{ dir__basename(Progname, PrognameBase) }.
 
+
+	% XXX we call a pred version of io__get_stream_id, which is a
+	% bit inelegant.  We should either fix the MC++ interface so you
+	% can implement functions, or implement everything in this
+	% module in C#.
+
+io__get_stream_id(Stream) = Id :- io__get_stream_id(Stream, Id).
+
+:- pred io__get_stream_id(io__stream::in, io__stream_id::out) is det.
+
 :- pragma foreign_proc("C",
-	io__get_stream_id(Stream::in) = (Id::out), 
+	io__get_stream_id(Stream::in, Id::out), 
 		will_not_call_mercury, "
 	/* 
 	** Most of the time, we can just use the pointer to the stream
@@ -2767,7 +2777,7 @@
 ").
 
 :- pragma foreign_proc("MC++",
-	io__get_stream_id(Stream::in) = (Id::out), 
+	io__get_stream_id(Stream::in, Id::out), 
 		will_not_call_mercury, "
 	MR_MercuryFile mf = ML_DownCast(MR_MercuryFile,
 		MR_word_to_c_pointer(Stream));
Index: library/std_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
retrieving revision 1.244
diff -u -r1.244 std_util.m
--- library/std_util.m	11 Oct 2001 07:10:06 -0000	1.244
+++ library/std_util.m	11 Oct 2001 07:31:19 -0000
@@ -1962,11 +1962,13 @@
 }
 ").
 
-:- pragma foreign_proc("MC++", 
+:- pragma foreign_proc("C#", 
 	make_type(_TypeCtorDesc::in, _ArgTypes::in) = (_TypeDesc::out),
 		will_not_call_mercury, "
 {
-	mercury::runtime::Errors::SORRY(""make_type"");
+	mercury.runtime.Errors.SORRY(""make_type"");
+	// XXX this is required to keep the C# compiler quiet
+	SUCCESS_INDICATOR = false;
 }
 ").
 
@@ -2404,9 +2406,6 @@
 		will_not_call_mercury, "
 {
 	mercury.runtime.Errors.SORRY(""foreign code for make_type"");
-	// XXX this is required to keep the C# compiler quiet, but we should 
-	// really fix the interface to semidet C#
-	succeeded = 1;
 }
 ").
 
@@ -2417,10 +2416,12 @@
 		TypeCtorModuleName, TypeCtorName, TypeCtorArity).
 
 
-:- pragma foreign_proc("MC++", num_functors(_TypeInfo::in) = (_Functors::out),
+:- pragma foreign_proc("C#", num_functors(_TypeInfo::in) = (Functors::out),
 	will_not_call_mercury, "
 {
-	mercury::runtime::Errors::SORRY(""foreign code for num_functors"");
+	mercury.runtime.Errors.SORRY(""foreign code for num_functors"");
+	// XXX keep the C# compiler quiet
+	Functors = 0;
 }
 ").
 
@@ -2446,9 +2447,8 @@
 {
 	mercury.runtime.Errors.SORRY(""foreign code for construct"");
 	_Term = null;
-	// XXX this is required to keep the C# compiler quiet, but we should 
-	// really fix the interface to semidet C#
-	succeeded = 1;
+	// XXX this is required to keep the C# compiler quiet
+	SUCCESS_INDICATOR = false;
 }
 ").
 
@@ -3459,9 +3459,8 @@
         will_not_call_mercury, "
 {
 	mercury.runtime.Errors.SORRY(""foreign code for arg"");
-	// XXX this is required to keep the C# compiler quiet, but we should 
-	// really fix the interface to semidet C#
-	succeeded = 1;
+	// XXX this is required to keep the C# compiler quiet
+	SUCCESS_INDICATOR = false;
 }").
 
 :- pragma foreign_proc("C#",
@@ -3469,9 +3468,8 @@
         will_not_call_mercury, "
 {
 	mercury.runtime.Errors.SORRY(""foreign code for argument"");
-	// XXX this is required to keep the C# compiler quiet, but we should 
-	// really fix the interface to semidet C#
-	succeeded = 1;
+	// XXX this is required to keep the C# compiler quiet
+	SUCCESS_INDICATOR = false;
 }").
 
 det_arg(Type, ArgumentIndex) = Argument :-


-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
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