[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