[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