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

Peter Ross peter.ross at miscrit.be
Tue Dec 5 02:53:13 AEDT 2000


On Mon, Dec 04, 2000 at 11:32:26PM +1100, Tyson Dowd wrote:
> 
> 
> ===================================================================
> 
> 
> Estimated hours taken: 80
> 
> First implementation of the standard library in managed C++.
> 
> configure.in:
> 	Autodetect the .NET SDK, and set MSNETSDKDIR based on it.
> 	Find the IL assembler, and set ILASM.
> 
> library/*.m:
> 	Add pragma foreign_code for MC++.
> 	Rename pragma c_code as pragma foreign_code("C", ...).
> 	Only a fraction of the predicates are implemented, everything
> 	else simply throws and exception when called.
> 	Implementations of predicates marked with :- external are
> 	provided as pragma foreign_code, but are commented out.
> 
> library/Mmakefile:
> runtime/Mmakefile:
> 	Add targets for building the dlls for the library.
> 
> runtime/mercury_cpp.cpp:
> 	Implementation of the runtime.
> 
> runtime/mercury_il.il:
> 	This file mainly implements things that can't be written in
> 	managed C++ (e.g. function pointers).
> 
> scripts/Mmake.rules:
> scripts/Mmake.vars.in:
> 	Add rules for generating .dlls and .exes from .ils and .cpps.
> 
> 
> 

...

> Index: library/array.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/array.m,v
> retrieving revision 1.79
> diff -u -r1.79 array.m
> --- library/array.m	2000/12/03 02:22:44	1.79
> +++ library/array.m	2000/12/03 07:12:48
> @@ -473,55 +512,114 @@

...

>  
> +:- pragma foreign_code("MC++", 
> +		array__init(Size::in, Item::in, Array::array_uo),
> +		[will_not_call_mercury, thread_safe], "
> +		// XXX still need to do init
> +	Array = (MR_Word) Array::CreateInstance(Item->GetType(), Size);
> +").

I suggest fixing this XXX or calling MR_Runtime::SORRY.

> @@ -567,9 +667,22 @@
>  	Item = array->elements[Index];
>  }").
>  
> +:- pragma foreign_code("MC++",
> +		array__lookup(Array::array_ui, Index::in, Item::out),
> +		[will_not_call_mercury, thread_safe], "{
> +	Item = Array->GetValue(Index);
> +}").
> +:- pragma foreign_code("MC++",
> +		array__lookup(Array::in, Index::in, Item::out),
> +		[will_not_call_mercury, thread_safe], "{
> +	Item = Array->GetValue(Index);
> +}").
> +
> +

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

> +
> +:- pragma foreign_code("MC++",
> +		array__copy(Array0::array_ui, Array::array_uo),
> +		[will_not_call_mercury, thread_safe], "
> +		// XXX need to deep copy it
> +	Array = Array0;
> +
> +").
> +
> +:- pragma foreign_code("MC++",
> +		array__copy(Array0::in, Array::array_uo),
> +		[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!


> +    static void
> +    mercury__builtin____Compare____float_0_0(
> +          MR_Word_Ref result, MR_Float x, MR_Float y)
> +    {
> +                              (MR_Runtime::MR_fatal_error(
> +                                 ""incomparable floats in compare/3""),
> +                              MR_COMPARE_EQUAL)); 
> +        MR_newobj(*result, r, 0);
> +    }
> +

Ditto.

> +
> +    static void
> +    mercury__builtin____Compare____string_0_0(MR_Word_Ref result,
> +            MR_String x, MR_String y)
> +    {
> +        int res = String::Compare(x, y);
> +                  MR_COMPARE_LESS);
> +        MR_newobj(*result, r, 0);
> +    }
> +

Ditto.

> +    static void
> +    mercury__builtin____Compare____character_0_0(
> +            MR_Word_Ref result, MR_Char x, MR_Char y)
> +    {
> +                      MR_COMPARE_LESS);
> +            MR_newobj(*result, r, 0);
> +    }
> +

Ditto.


> 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?

> +#ifndef ML_DETERMINISM_GUARD
> +#define ML_DETERMINISM_GUARD
> +  #define zML_DET = 0
> +  #define zML_SEMIDET = 1
> +  #define zML_CC_MULTI = 2
> +  #define zML_CC_NONDET = 3
> +  #define zML_MULTI = 4
> +  #define zML_NONDET = 5
> +  #define zML_ERRONEOUS = 6
> +  #define zML_FAILURE = 7
> +
> +	/*
> +	** The enumeration constants in this enum must be in the same
> +	** order as the functors in the Mercury type `determinism'
> +	** defined above.
> +	*/
> +	typedef enum {
> +		ML_DET,
> +		ML_SEMIDET,
> +		ML_CC_MULTI,
> +		ML_CC_NONDET,
> +		ML_MULTI,
> +		ML_NONDET,
> +		ML_ERRONEOUS,
> +		ML_FAILURE
> +	} ML_Determinism;
> +#endif
> +").
> +


> Index: library/gc.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/gc.m,v
> retrieving revision 1.2
> diff -u -r1.2 gc.m
> --- library/gc.m	1999/12/21 10:33:57	1.2
> +++ library/gc.m	2000/12/01 03:34:04
> @@ -38,7 +38,7 @@
>  
>  :- pragma no_inline(garbage_collect/0).
>  
> -:- pragma c_code(garbage_collect, [will_not_call_mercury], "
> +:- pragma foreign_code("C", garbage_collect, [will_not_call_mercury], "
>  #ifdef CONSERVATIVE_GC
>    #ifndef MR_HIGHLEVEL_CODE
>  	/* clear out the stacks and registers before garbage collecting */
> @@ -49,6 +49,9 @@
>  
>  	GC_gcollect();
>  #endif
> +").
> +:- pragma foreign_code("MC++", garbage_collect, [will_not_call_mercury], "
> +	// Do nothing 
>  ").
>  

Hmm, not sure about this.  I think I would prefer a SORRY.


> 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.

> +
> +:- 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?

> +
> +:- 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?

> +:- 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?

> 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?


> Index: library/std_util.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
> retrieving revision 1.207
> diff -u -r1.207 std_util.m
> --- library/std_util.m	2000/11/24 06:02:10	1.207
> +++ library/std_util.m	2000/12/01 03:37:26
> @@ -91,7 +91,8 @@
>  
>  % The "unit" type - stores no information at all.
>  
> -:- type unit		--->	unit.
> +	% XXX I get a warning for this one too
> +:- type unit		--->	unit ; aaa.
>  

So?

> Index: library/string.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/string.m,v
> retrieving revision 1.140
> diff -u -r1.140 string.m

> @@ -1843,11 +2140,23 @@
>  		SUCCESS_INDICATOR = TRUE;
>  	}
>  }").
> +:- pragma foreign_code("MC++",
> +	string__first_char(Str::in, First::in, Rest::out),
> +		[will_not_call_mercury, thread_safe], "{
> +	MR_Integer len = Str->get_Length();
> +	if (len > 0) {
> +		SUCCESS_INDICATOR = (First == Str->get_Chars(0) &&
> +			String::Compare(Str, 1, Rest, 0, len) == 0);
> +	} else {
> +		SUCCESS_INDICATOR = FALSE;
> +	}
> +}").

This looks wrong, you should be assigning to Rest somewhere.

ie Rest = (Str)->Substring(1);

> @@ -1864,17 +2173,38 @@
>  		SUCCESS_INDICATOR = TRUE;
>  	}
>  }").
> +:- pragma foreign_code("MC++", 
> +	string__first_char(Str::in, First::out, Rest::out),
> +		[will_not_call_mercury, thread_safe], "{
> +	if (Str->get_Length() == 0) {
> +		SUCCESS_INDICATOR = FALSE;
> +	} else {
> +		First = Str->get_Chars(0);
> +                Rest = (Str)->Substring(1);

Indentation.

> +		SUCCESS_INDICATOR = TRUE;
> +        }
> +}").
> +
--------------------------------------------------------------------------
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