[m-dev.] for review: add MC++ implementation of library and runtime

Tyson Dowd trd at cs.mu.OZ.AU
Tue Dec 5 18:54:42 AEDT 2000


Just before I begin:

Lots of review comments have been of the form:

"What happens when ...."

"Why don't you ... "

"Surely there's a class method for ..."

"Can't you just ..."

The answer to all of these is "I don't know" or "This seemed to work
at the time".

I've asked exactly the same questions while I was writing the code.

On average to answer questions like this it has taken 1 hour per
question.  This is because the documentation is often non-existant or so
vacuous that it is useless, the class libraries are written to ad-hoc
specifications (e.g. no attempt at POSIX compatibility or other useful,
"complete" standards) and the runtime system itself gives poor error
messages.

On average I find that this questions come up about once per predicate
that needs to be implemented.

I tried to implement some of them in array.m before I noticed how long
it was taking and gave up.

I have avoided doing anything that will involve writing a lot of code
unless it is absolutely necessary to get some of the samples going.

> What happens with the bounds checking?  I assume that MC++ arrays are bounds
> checked.

Yes, they will throw exceptions if you are out of range.

> > +		[will_not_call_mercury, thread_safe], "
> > +		// XXX need to deep copy it
> > +	Array = Array0;
> >  ").
> >  
> If bad things will happen, I suggest calling SORRY.
> 
> 
> > Index: library/builtin.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/library/builtin.m,v
> > retrieving revision 1.47
> > diff -u -r1.47 builtin.m
> > --- library/builtin.m	2000/12/03 02:22:45	1.47
> > +++ library/builtin.m	2000/12/03 07:23:15
> 
> > +:- pragma foreign_code("MC++", "
> > +	
> > +    static void
> > +    mercury__builtin____Compare____int_0_0(
> > +        MR_Word_Ref result, MR_Integer x, MR_Integer y)
> > +    {
> > +                    MR_COMPARE_LESS);
> > +            MR_newobj(*result, r, 0);
> > +    }
> > +
> 
> Something strange going on here with the floating MR_COMPARE_LESS!

This is bizarre.

My diff files have this in them too, but if I create a new diff of
builtin.m this problem certainly doesn't occur.

Here is a "real" diff of builtin.m (I hope).

Index: builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/builtin.m,v
retrieving revision 1.47
diff -u -r1.47 builtin.m
--- builtin.m	2000/12/03 02:22:45	1.47
+++ builtin.m	2000/12/03 07:23:15
@@ -229,14 +229,22 @@
 :- mode cc_cast(pred(out) is cc_nondet) = out(pred(out) is semidet) is det.
 :- mode cc_cast(pred(out) is cc_multi) = out(pred(out) is det) is det.
 
-:- pragma c_code(cc_cast(X :: (pred(out) is cc_multi)) =
+:- pragma foreign_code("C", cc_cast(X :: (pred(out) is cc_multi)) =
                         (Y :: out(pred(out) is det)),
                 [will_not_call_mercury, thread_safe],
                 "Y = X;").
-:- pragma c_code(cc_cast(X :: (pred(out) is cc_nondet)) =
+:- pragma foreign_code("C", cc_cast(X :: (pred(out) is cc_nondet)) =
                         (Y :: out(pred(out) is semidet)),
                 [will_not_call_mercury, thread_safe],
                 "Y = X;").
+:- pragma foreign_code("MC++", cc_cast(X :: (pred(out) is cc_multi)) =
+                        (Y :: out(pred(out) is det)),
+                [will_not_call_mercury, thread_safe],
+                "Y = X;").
+:- pragma foreign_code("MC++", cc_cast(X :: (pred(out) is cc_nondet)) =
+                        (Y :: out(pred(out) is semidet)),
+                [will_not_call_mercury, thread_safe],
+                "Y = X;").
 
 promise_only_solution_io(Pred, X) -->
 	call(cc_cast_io(Pred), X).
@@ -245,8 +253,14 @@
 :- mode cc_cast_io(pred(out, di, uo) is cc_multi) =
 	out(pred(out, di, uo) is det) is det.
 
-:- pragma c_code(cc_cast_io(X :: (pred(out, di, uo) is cc_multi)) =
-                        (Y :: out(pred(out, di, uo) is det)),
+:- pragma foreign_code("C",
+	cc_cast_io(X :: (pred(out, di, uo) is cc_multi)) = 
+		(Y :: out(pred(out, di, uo) is det)),
+                [will_not_call_mercury, thread_safe],
+                "Y = X;").
+:- pragma foreign_code("MC++", 
+		cc_cast_io(X :: (pred(out, di, uo) is cc_multi)) =
+		(Y :: out(pred(out, di, uo) is det)),
                 [will_not_call_mercury, thread_safe],
                 "Y = X;").
 
@@ -262,9 +276,9 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pragma c_header_code("#include ""mercury_type_info.h""").
+:- pragma foreign_decl("C", "#include ""mercury_type_info.h""").
 
-:- pragma c_code("
+:- pragma foreign_code("C", "
 
 #ifdef MR_HIGHLEVEL_CODE
 void sys_init_builtin_types_module(void); /* suppress gcc warning */
@@ -391,6 +405,483 @@
 }
 
 #endif /* ! HIGHLEVEL_CODE */
+
+").
+
+/*
+
+XXX :- external stops us from using this
+
+:- pragma foreign_code("MC++", compare(Res::uo, X::in, Y::in),
+	[may_call_mercury], "
+
+        MR_TypeInfo             type_info;
+        MR_TypeCtorInfo         type_ctor_info;
+        int                     arity;
+        MR_TypeInfoParams       params;
+        MR_Word                 *args;
+
+        type_info = (MR_TypeInfo) TypeInfo_for_T;
+        type_ctor_info = dynamic_cast<MR_Word> (type_info->GetValue(0));
+
+        if (type_ctor_info == 0) {
+            type_ctor_info = type_info;
+        }
+
+        if (0) {
+            // code for higher order...
+        } else {
+            arity = mr_convert::ToInt32(type_ctor_info->GetValue(0));
+            // params = ???
+        }
+
+        switch(arity) {
+	case 0: 
+        	generic::generic_res_call3(
+			type_ctor_info->GetValue(3),
+			&Res, X, Y);
+	break;
+	case 1:
+                generic::generic_res_call4(
+			type_ctor_info->GetValue(3), 
+			type_info->GetValue(1), 
+			&Res, X, Y);
+        break;
+	case 2:
+		generic::generic_res_call5(
+			type_ctor_info->GetValue(3), 
+			type_info->GetValue(1), 
+			type_info->GetValue(2), 
+			&Res, X, Y);
+	break;
+	case 3:
+		generic::generic_res_call6(
+			type_ctor_info->GetValue(3), 
+			type_info->GetValue(1), 
+			type_info->GetValue(2), 
+			type_info->GetValue(3), 
+			&Res, X, Y);
+	break;
+	case 4:
+		generic::generic_res_call7(
+			type_ctor_info->GetValue(3), 
+			type_info->GetValue(1), 
+			type_info->GetValue(2), 
+			type_info->GetValue(3), 
+			type_info->GetValue(4), 
+			&Res, X, Y);
+	break;
+	case 5:
+		generic::generic_res_call8(
+			type_ctor_info->GetValue(3), 
+			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:
+		MR_Runtime::MR_fatal_error(
+			""compare/3: type arity > 5 not supported"");
+	}
+").
+
+:- pragma foreign_code("MC++", compare(Res::uo, X::ui, Y::ui),
+	[may_call_mercury], "
+	compare_3_p_0(TypeInfo_for_T, &Res, X, Y);
+").
+
+:- pragma foreign_code("MC++", compare(Res::uo, X::ui, Y::in),
+	[may_call_mercury], "
+	compare_3_p_0(TypeInfo_for_T, &Res, X, Y);
+").
+
+:- pragma foreign_code("MC++", compare(Res::uo, X::in, Y::ui),
+	[may_call_mercury], "
+	compare_3_p_0(TypeInfo_for_T, &Res, X, Y);
+").
+
+:- pragma foreign_code("MC++", copy(_X::ui, _Y::uo),
+	[may_call_mercury], "
+	MR_Runtime::SORRY(""foreign code for this function"");
+").
+
+:- pragma foreign_code("MC++", copy(_X::in, _Y::uo),
+	[may_call_mercury], "
+	MR_Runtime::SORRY(""foreign code for this function"");
+").
+
+:- pragma foreign_code("MC++", unify(X::in, Y::in),
+	[may_call_mercury], "
+{
+        MR_TypeInfo             type_info;
+        MR_TypeCtorInfo         type_ctor_info;
+        MR_Box                  tmp;
+        int                     arity;
+        MR_TypeInfoParams       params;
+	
+        type_info = (MR_TypeInfo) TypeInfo_for_T;
+
+        type_ctor_info = dynamic_cast<MR_Word> (type_info->GetValue(0));
+        if (type_ctor_info == 0) {
+            type_ctor_info = type_info;
+        }
+
+        // XXX insert code to handle higher order....
+        if (0) {
+
+        } else {
+            arity = mr_convert::ToInt32(type_ctor_info->GetValue(0));
+            // params = ???
+        }
+
+        // args = params;
+
+	switch(arity) {
+	case 0: 
+                SUCCESS_INDICATOR = generic::generic_call2(
+                	type_ctor_info->GetValue(1),
+			X, Y);
+	break;
+	case 1:
+                SUCCESS_INDICATOR = generic::generic_call3(
+			type_ctor_info->GetValue(1), 
+			type_info->GetValue(1), 
+			X, Y);
+	break;
+	case 2:
+		SUCCESS_INDICATOR = generic::generic_call4(
+			type_ctor_info->GetValue(1), 
+			type_info->GetValue(1), 
+			type_info->GetValue(2), 
+			X, Y);
+	break;
+	case 3:
+		SUCCESS_INDICATOR = generic::generic_call5(
+			type_ctor_info->GetValue(1), 
+			type_info->GetValue(1), 
+			type_info->GetValue(2), 
+			type_info->GetValue(3), 
+			X, Y);
+	break;
+	case 4:
+		SUCCESS_INDICATOR = generic::generic_call6(
+			type_ctor_info->GetValue(1), 
+			type_info->GetValue(1), 
+			type_info->GetValue(2), 
+			type_info->GetValue(3), 
+			type_info->GetValue(4), 
+			X, Y);
+	break;
+	case 5:
+		SUCCESS_INDICATOR = generic::generic_call7(
+			type_ctor_info->GetValue(1), 
+			type_info->GetValue(1), 
+			type_info->GetValue(2), 
+			type_info->GetValue(3), 
+			type_info->GetValue(4), 
+			type_info->GetValue(5), 
+			X, Y);
+	break;
+	default:
+		MR_Runtime::MR_fatal_error(
+			""unify/2: type arity > 5 not supported"");
+	}
+}
+
+").
+
+*/
+
+:- pragma foreign_code("MC++", "
+	
+    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(builtin, int, 0, MR_TYPECTOR_REP_INT) 
+    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(builtin, character, 0,
+        MR_TYPECTOR_REP_CHAR) 
+    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(builtin, string, 0,
+        MR_TYPECTOR_REP_STRING) 
+    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(builtin, c_pointer, 0,
+        MR_TYPECTOR_REP_C_POINTER) 
+    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(builtin, void, 0,
+        MR_TYPECTOR_REP_VOID) 
+    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(builtin, float, 0, 
+       MR_TYPECTOR_REP_FLOAT) 
+    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(builtin, func, 0,
+        MR_TYPECTOR_REP_PRED) 
+    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(builtin, pred, 0,
+        MR_TYPECTOR_REP_PRED) 
+
+    static int
+    mercury__builtin____Unify____int_0_0(MR_Integer x, MR_Integer y)
+    {
+            return x == y;
+    }
+
+    static int
+    mercury__builtin____Unify____string_0_0(MR_String x, MR_String y)
+    {
+            return String::Equals(x, y);
+    }
+
+    static int
+    mercury__builtin____Unify____character_0_0(MR_Char x, MR_Char y)
+    {
+            return x == y;
+    }
+
+    static int
+    mercury__builtin____Unify____float_0_0(MR_Float x, MR_Float y)
+    {
+            /* XXX what should this function do when x and y are both NaNs? */
+            return x == y;
+    }
+
+    static int
+    mercury__builtin____Unify____void_0_0(MR_Word x, MR_Word y)
+    {
+            MR_Runtime::MR_fatal_error(
+                ""called unify for type `void'"");
+            return 0;
+    }
+
+    static int
+    mercury__builtin____Unify____c_pointer_0_0(MR_Word x, MR_Word y)
+    {
+            MR_Runtime::MR_fatal_error(
+                ""called unify for type `c_pointer'"");
+            return 0;
+    }
+
+    static int
+    mercury__builtin____Unify____func_0_0(MR_Word x, MR_Word y)
+    {
+            MR_Runtime::MR_fatal_error(
+                ""called unify for `func' type"");
+            return 0;
+    }
+
+    static int
+    mercury__builtin____Unify____pred_0_0(MR_Word x, MR_Word y)
+    {
+            MR_Runtime::MR_fatal_error(
+                ""called unify for `pred' type"");
+            return 0;
+    }
+
+    static void
+    mercury__builtin____Compare____int_0_0(
+        MR_Word_Ref result, MR_Integer x, MR_Integer y)
+    {
+            int r = (x > y ? MR_COMPARE_GREATER :
+                     x == y ? MR_COMPARE_EQUAL :
+                    MR_COMPARE_LESS);
+            MR_newobj(*result, r, 0);
+    }
+
+    static void
+    mercury__builtin____Compare____float_0_0(
+          MR_Word_Ref result, MR_Float x, MR_Float y)
+    {
+          /* XXX what should this function do when x and y are both NaNs? */
+         int r = (x > y ? MR_COMPARE_GREATER :
+                      x == y ? MR_COMPARE_EQUAL :
+                      x < y ? MR_COMPARE_LESS :
+                              (MR_Runtime::MR_fatal_error(
+                                 ""incomparable floats in compare/3""),
+                              MR_COMPARE_EQUAL)); 
+        MR_newobj(*result, r, 0);
+    }
+
+
+    static void
+    mercury__builtin____Compare____string_0_0(MR_Word_Ref result,
+            MR_String x, MR_String y)
+    {
+        int res = String::Compare(x, y);
+        int r = (res > 0 ? MR_COMPARE_GREATER :
+                  res == 0 ? MR_COMPARE_EQUAL :
+                  MR_COMPARE_LESS);
+        MR_newobj(*result, r, 0);
+    }
+
+    static void
+    mercury__builtin____Compare____character_0_0(
+            MR_Word_Ref result, MR_Char x, MR_Char y)
+    {
+            int r = (x > y ? MR_COMPARE_GREATER :
+                      x == y ? MR_COMPARE_EQUAL :
+                      MR_COMPARE_LESS);
+            MR_newobj(*result, r, 0);
+    }
+
+    static void
+    mercury__builtin____Compare____void_0_0(MR_Word_Ref result,
+        MR_Word x, MR_Word y)
+    {
+        MR_Runtime::MR_fatal_error(
+            ""called compare/3 for type `void'"");
+    }
+
+    static void
+    mercury__builtin____Compare____c_pointer_0_0(
+        MR_Word_Ref result, MR_Word x, MR_Word y)
+    {
+        MR_Runtime::MR_fatal_error(
+            ""called compare/3 for type `c_pointer'"");
+    }
+
+    static void
+    mercury__builtin____Compare____func_0_0(MR_Word_Ref result,
+        MR_Word x, MR_Word y)
+    {
+        MR_Runtime::MR_fatal_error(
+            ""called compare/3 for `func' type"");
+    }
+
+    static void
+    mercury__builtin____Compare____pred_0_0(MR_Word_Ref result,
+        MR_Word x, MR_Word y)
+    {
+        MR_Runtime::MR_fatal_error(
+            ""called compare/3 for `pred' type"");
+    }
+
+/*
+** Unification procedures with the arguments boxed.
+** These are just wrappers which call the unboxed version.
+*/
+
+    static int
+    mercury__builtin__do_unify__int_0_0(MR_Box x, MR_Box y)
+    {
+            return mercury__builtin____Unify____int_0_0(
+                    mr_convert::ToInt32(x), 
+                    mr_convert::ToInt32(y)); 
+    }
+
+    static int
+    mercury__builtin__do_unify__string_0_0(MR_Box x, MR_Box y)
+    {
+            return mercury__builtin____Unify____string_0_0(
+                    dynamic_cast<MR_String>(x), 
+                    dynamic_cast<MR_String>(y));
+    }
+
+    static int
+    mercury__builtin__do_unify__float_0_0(MR_Box x, MR_Box y)
+    {
+            return mercury__builtin____Unify____float_0_0(
+                    mr_convert::ToDouble(x), mr_convert::ToDouble(y));
+    }
+
+    static int
+    mercury__builtin__do_unify__character_0_0(MR_Box x, MR_Box y)
+    {
+            return mercury__builtin____Unify____character_0_0(
+                    mr_convert::ToChar(x),
+                    mr_convert::ToChar(y));
+    }
+
+    static int
+    mercury__builtin__do_unify__void_0_0(MR_Box x, MR_Box y)
+    {
+            MR_Runtime::MR_fatal_error(
+            ""called unify for type `void'"");
+            return 0;
+    }
+
+    static int
+    mercury__builtin__do_unify__c_pointer_0_0(MR_Box x, MR_Box y)
+    {
+            return mercury__builtin____Unify____c_pointer_0_0(
+                dynamic_cast<MR_Word>(x), 
+                dynamic_cast<MR_Word>(y)); 
+    }
+
+    static int
+    mercury__builtin__do_unify__func_0_0(MR_Box x, MR_Box y)
+    {
+            MR_Runtime::MR_fatal_error(
+            ""called unify for `func' type"");
+            return 0;
+    }
+
+    static int
+    mercury__builtin__do_unify__pred_0_0(MR_Box x, MR_Box y)
+    {
+            MR_Runtime::MR_fatal_error(
+            ""called unify for `pred' type"");
+            return 0;
+    }
+
+/*
+** Comparison procedures with the arguments boxed.
+** These are just wrappers which call the unboxed version.
+*/
+
+    static void
+    mercury__builtin__do_compare__int_0_0(MR_Word_Ref result, MR_Box x, MR_Box y)
+    {
+            mercury__builtin____Compare____int_0_0(result,
+                    mr_convert::ToInt32(x),
+                    mr_convert::ToInt32(y));
+    }
+
+    static void
+    mercury__builtin__do_compare__string_0_0(MR_Word_Ref result, MR_Box x, MR_Box y)
+    {
+            mercury__builtin____Compare____string_0_0(result,
+                    dynamic_cast<MR_String>(x),
+                    dynamic_cast<MR_String>(y));
+    }
+
+    static void
+    mercury__builtin__do_compare__float_0_0(MR_Word_Ref result, MR_Box x, MR_Box y)
+    {
+            mercury__builtin____Compare____float_0_0(result,
+                    mr_convert::ToDouble(x), mr_convert::ToDouble(y));
+    }
+
+    static void
+    mercury__builtin__do_compare__character_0_0(
+            MR_Word_Ref result, MR_Box x, MR_Box y)
+    {
+            mercury__builtin____Compare____character_0_0(
+                    result, 
+                    mr_convert::ToChar(x),
+                    mr_convert::ToChar(y));
+    }
+
+    static void
+    mercury__builtin__do_compare__void_0_0(MR_Word_Ref result, MR_Box x, MR_Box y)
+    {
+            MR_Runtime::MR_fatal_error(
+            ""called compare/3 for type `void'"");
+    }
+
+    static void
+    mercury__builtin__do_compare__c_pointer_0_0(
+            MR_Word_Ref result, MR_Box x, MR_Box y)
+    {
+            mercury__builtin____Compare____c_pointer_0_0(
+                    result, 
+                    dynamic_cast<MR_Word>(x),
+                    dynamic_cast<MR_Word>(y));
+    }
+    static void
+    mercury__builtin__do_compare__func_0_0(MR_Word_Ref result, MR_Box x, MR_Box y)
+    {
+            MR_Runtime::MR_fatal_error(
+            ""called compare/3 for func type"");
+    }
+
+    static void
+    mercury__builtin__do_compare__pred_0_0(MR_Word_Ref result, MR_Box x, MR_Box y)
+    {
+            MR_Runtime::MR_fatal_error(
+            ""called compare/3 for pred type"");
+    }
 
 ").
 
> > Index: library/exception.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/library/exception.m,v
> > retrieving revision 1.36
> > diff -u -r1.36 exception.m
> > --- library/exception.m	2000/12/03 02:22:46	1.36
> > +++ library/exception.m	2000/12/03 07:12:49
> > @@ -207,7 +207,7 @@
> >  % the C interface, since Mercury doesn't allow different code for different
> >  % modes.
> >  
> > -:- pragma c_header_code("
> > +:- pragma foreign_decl("C", "
> >  /* The `#ifndef ... #define ... #endif' guards against multiple inclusion */
> >  #ifndef ML_DETERMINISM_GUARD
> >  #define ML_DETERMINISM_GUARD
> > @@ -229,57 +229,140 @@
> 
> ...
> 
> >  
> > +:- pragma foreign_decl("MC++", "
> > +/* The `#ifndef ... #define ... #endif' guards against multiple inclusion */
> 
> Is there a reasone why this isn't done automatically?

Not my code, I just copied it from the C version.

I could probably fix it, but since I didn't really understand why it was
there in the first place...

> > Index: library/io.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/library/io.m,v
> > retrieving revision 1.214
> > diff -u -r1.214 io.m
> > --- library/io.m	2000/11/28 05:50:41	1.214
> > +++ library/io.m	2000/12/03 07:12:50
> > +:- pragma foreign_decl("MC++", "
> > +
> > +__gc struct MR_MercuryFileStruct {
> > +public:
> > +	IO::Stream 	*stream;
> > +	int		line_number;
> > +	int		id;
> > +};
> > +
> > +typedef __gc struct MR_MercuryFileStruct *MR_MercuryFile;
> > +#define MR_DownCast(Cast, Expr) dynamic_cast<Cast>(Expr)
> > +#define MR_UpCast(Cast, Expr) ((Cast) (Expr))
> > +
> 
> These should have ML_ prefixes instead of MR_ prefixes.
> 
> > +
> > +:- pragma foreign_code("MC++", 
> > +	io__putback_char(_File::in, _Character::in, IO0::di, IO::uo),
> > +		may_call_mercury, "{
> > +	MR_Runtime::SORRY(""foreign code for this function"");
> > +	update_io(IO0, IO);
> > +}").
> > +
> 
> This is a pretty important predicate.  I would add an implementation if
> possible.

There are around 100 predicates that come into the pretty important category.

This was one of the ones I wanted to do soon.  But it requires writing
some scaffolding in MC++, so I have put it off.  It will need testing
too.

I'll try to make it early on the list.

> > +
> > +:- pragma foreign_code("MC++", 
> > +	io__write_char(Character::in, IO0::di, IO::uo),
> > +		[may_call_mercury, thread_safe], "
> > +	if (Character == '\\n') {
> > +		mercury_current_text_output->line_number++;
> > +	}
> > +	update_io(IO0, IO);
> > +").
> > +
> 
> This doesn't appear to output a character, have I missed something?
> 

No, I missed it.

This is one of the reasons I started taking a minimalist approach.
To write all these functions correctly, you need test cases for them...
If you write something *without* a test case, then who is to know
whether it really works or not.  Then if your program doesn't work, it
can be very difficult to debug.

> > +
> > +:- pragma foreign_code("MC++",
> > +	io__get_exit_status(ExitStatus::out, IO0::di, IO::uo),
> > +		will_not_call_mercury, "
> > +	ExitStatus = System::Environment::get_ExitCode();
> > +	MR_Runtime::SORRY(""foreign code for this function"");
> > +	update_io(IO0, IO);
> > +").
> > +
> 
> Why the call to SORRY?

That can probably go, I just missed it (again, no test case).

> 
> > +:- pragma foreign_code("MC++",
> > +	io__remove_file_2(FileName::in, RetVal::out, RetStr::out,
> > +		IO0::di, IO::uo), [will_not_call_mercury, thread_safe],
> > +"{
> > +	System::IO::File::Delete(FileName);
> > +	RetVal = 0;
> > +	RetStr = """";
> > +	update_io(IO0, IO);
> > +}").
> > +
> > +
> 
> What happens if an error is reported?

Nothing useful -- an exception is thrown, and halts the program.
I should catch it and set RetVal.  I'll make this into SORRY instead.

> 
> > Index: library/ops.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/library/ops.m,v
> > retrieving revision 1.32
> > diff -u -r1.32 ops.m
> > --- library/ops.m	2000/09/19 04:46:50	1.32
> > +++ library/ops.m	2000/12/01 03:34:04
> > @@ -80,7 +80,8 @@
> >  
> >  :- implementation.
> >  
> > -:- type ops__table ---> ops__table.	% XXX
> > +	% XXX for some reason I get a determinism warning on this one.
> > +:- type ops__table ---> ops__table ; aaa.	% XXX
> >  
> >  :- type ops__category ---> before ; after.
> >  
> 
> What is this for?

roy 18:46 library 0 >mmc --il-only ops.m
ops.m:033: In `__Unify__(in, in)':
ops.m:033:   warning: determinism declaration could be tighter.
ops.m:033:   Declared `semidet', inferred `det'.

I'll get rid of it now, it was just slowing me down while searching for
"real" errors. 

But of course it needs to be fixed before we release, because
--halt-at-warn is set in the library directory.

Thanks for the other comments, I've fixed those problems.

-- 
       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-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list