[m-rev.] diff: C# interface for .NET backend.
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu May 3 02:12:05 AEST 2001
On 01-May-2001, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
mlds.m:
> + ; outline_target_code(
> + foreign_language,
> + % the foreign language of this code
> + list(mlds__lval),
> + % where to store return value(s)
> + string
> + % the user's foreign language code
> + )
> + % Do whatever is specified by the string, which
> + % can be any piece of code in the specified
> + % foreign language (C#, managed C++, or
> + % whatever).
> + % This is implemented by calling an externally
> + % defined function, which the backend must
> + % generate the definition for (in some other
> + % file perhaps) and calling it.
Why does this have a list of where to store the return values?
And why doesn't it have a list of the input argument rvals (or their names)?
> Index: compiler/mlds_to_csharp.m
...
> + %
> + % Generate the `__csharp_code.cs' file which contains the c sharp
> + % code.
> + %
> +output_csharp_code(MLDS) -->
> + { MLDS = mlds(ModuleName, _ForeignCode, _Imports, _Defns) },
> + output_src_start(ModuleName),
> + io__nl,
> +
> + generate_c_code(MLDS),
...
> +:- pred generate_c_code(mlds, io__state, io__state).
> +:- mode generate_c_code(in, di, uo) is det.
> +generate_c_code(MLDS) -->
s/generate_c_code/generate_csharp_code/g ?
> + generate_foreign_header_code(mercury_module_name_to_mlds(ModuleName),
> + ForeignCode),
> +
> + { Namespace0 = get_class_namespace(ClassName) },
> + { list__reverse(Namespace0) = [Head | Tail] ->
> + Namespace = list__reverse([Head ++ "__csharp_code" | Tail])
> + ;
> + Namespace = Namespace0
> + },
> +
> + io__write_list(Namespace, "\n",
> + (pred(N::in, di, uo) is det -->
> + io__format("namespace %s {", [s(N)])
> + )),
The namespace name here should be (1) escaped (by prefixing it with "@") and/or
(2) mangled, in case it (1) is a C# keyword or (2) contains special characters
((2) is not very important, but (1) is not unlikely and should be handled
correctly).
> +:- pred generate_method_c_code(mlds_module_name, mlds__defn,
> + io__state, io__state).
> +:- mode generate_method_c_code(in, in, di, uo) is det.
> +
> + % XXX we don't handle export
> +generate_method_c_code(_, defn(export(_), _, _, _)) --> [].
> +generate_method_c_code(_, defn(data(_), _, _, _)) --> [].
> +generate_method_c_code(_, defn(type(_, _), _, _, _)) --> [].
> +generate_method_c_code(_ModuleName,
s/c_code/csharp_code/g ?
...
> + ;
> + % IL doesn't support multiple return values
> + sorry(this_file, "multiple return values")
s/IL/C#/ ?
> +:- pred write_csharp_statement(mlds__statement, io__state, io__state).
> +:- mode write_csharp_statement(in, di, uo) is det.
> +write_csharp_statement(statement(Statement, _Context)) -->
> + (
> + { Statement = atomic(outline_target_code(csharp,
> + _Lvals, Code)) }
> + ->
> + io__write_string(Code),
> + io__nl
> + ;
> + { Statement = block(Defns, Statements) }
> + ->
> + io__write_list(Defns, "", write_csharp_defn_decl),
> + io__write_string("{\n"),
> + io__write_list(Statements, "", write_csharp_statement),
> + io__write_string("\n}\n")
> + ;
> + { Statement = return(Rvals) }
> + ->
> + ( { Rvals = [Rval] } ->
> + io__write_string("return "),
> + write_csharp_rval(Rval),
> + io__write_string(";\n")
> + ;
> + { sorry(this_file, "multiple return values") }
> + )
> + ;
> + { functor(Statement, SFunctor, Arity) },
> + io__write_string("// unimplemented: "),
> + io__write_string(SFunctor),
> + io__write_string("/"),
> + io__write(Arity),
> + io__nl
> + ).
You should at least output something which will cause the C Sharp compiler to
report an error, rather than silently ignoring it. Or just call error/1.
> +%-------------------------------------------------------------------
> +% code below here is not used.
> +%-------------------------------------------------------------------
That comment is not true.
For example, there's a call to write_csharp_rval immediately above,
and write_csharp_rval is defined below that comment:
> +:- pred write_csharp_rval(mlds__rval, io__state, io__state).
> +:- mode write_csharp_rval(in, di, uo) is det.
> +write_csharp_rval(lval(Lval)) -->
> + write_csharp_lval(Lval).
> +write_csharp_rval(mkword(_Tag, _Rval)) -->
> + io__write_string(" /* mkword rval -- unimplemented */ ").
> +write_csharp_rval(const(RvalConst)) -->
> + write_csharp_rval_const(RvalConst).
> +write_csharp_rval(unop(Unop, Rval)) -->
> + (
> + { Unop = std_unop(StdUnop) },
> + { c_util__unary_prefix_op(StdUnop, UnopStr) }
> + ->
> + io__write_string(UnopStr),
> + io__write_string("("),
> + write_csharp_rval(Rval),
> + io__write_string(")")
> + ;
> + { Unop = cast(Type) }
> + ->
> + io__write_string("("),
> + write_csharp_parameter_type(Type),
> + io__write_string(") "),
> + write_csharp_rval(Rval)
> + ;
> + io__write_string(" /* XXX box or unbox unop -- unimplemented */ "),
> + write_csharp_rval(Rval)
> + ).
That XXX is another place where something which is unimplemented
will get silently ignored and may result in wrong code being generated.
Better to call error/1.
> +write_csharp_rval(binop(Binop, Rval1, Rval2)) -->
> + (
> + { c_util__binary_infix_op(Binop, BinopStr) }
> + ->
> + io__write_string("("),
> + write_csharp_rval(Rval1),
> + io__write_string(") "),
> + io__write_string(BinopStr),
> + io__write_string(" ("),
> + write_csharp_rval(Rval2),
> + io__write_string(")")
> + ;
> + io__write_string(" /* binop rval -- unimplemented */ ")
> + ).
Likewise here.
> +write_csharp_rval(mem_addr(_)) -->
> + io__write_string(" /* mem_addr rval -- unimplemented */ ").
And here.
> +:- pred write_csharp_rval_const(mlds__rval_const, io__state, io__state).
> +:- mode write_csharp_rval_const(in, di, uo) is det.
> +write_csharp_rval_const(true) --> io__write_string("1").
> +write_csharp_rval_const(false) --> io__write_string("0").
> +write_csharp_rval_const(int_const(I)) --> io__write_int(I).
> +write_csharp_rval_const(float_const(F)) --> io__write_float(F).
> + % XXX We don't quote this correctly.
> +write_csharp_rval_const(string_const(S)) -->
> + io__write_string(""""),
> + io__write_string(S),
> + io__write_string("""").
That XXX should be fixed.
You can use c_util__output_quoted_string.
> +write_csharp_rval_const(multi_string_const(_L, _S)) -->
> + io__write_string(" /* multi_string_const rval -- unimplemented */ ").
Likewise here, you can use c_util__output_multi_quoted_string.
> +write_csharp_rval_const(data_addr_const(_)) -->
> + io__write_string(" /* data_addr_const rval -- unimplemented */ ").
That XXX is another place where something which is unimplemented
will get silently ignored and may result in wrong code being generated.
Better to call error/1.
> +write_csharp_rval_const(null(_)) -->
> + io__write_string("0").
C# has a "null" keyword; you should use it.
> +:- pred write_csharp_defn_decl(mlds__defn, io__state, io__state).
> +:- mode write_csharp_defn_decl(in, di, uo) is det.
> +write_csharp_defn_decl(Defn) -->
> + { Defn = mlds__defn(Name, _Context, _Flags, DefnBody) },
> + ( { DefnBody = data(Type, _Initializer) },
> + { Name = data(var(VarName)) }
> + ->
Fix the non-standard indentation.
> + write_csharp_parameter_type(Type),
> + io__write_string(" "),
> + write_mlds_var_name_for_parameter(VarName),
> + io__write_string(";\n")
> + ;
> + io__write_string("// unimplemented defn decl\n")
> + ).
That is another place where something which is unimplemented
will get silently ignored and may result in wrong code being generated.
Better to call error/1. Also it should have an XXX.
> + % XXX need to revisit this and choose types appropriately
> +:- pred write_il_simple_type_as_csharp_type(simple_type::in,
> + io__state::di, io__state::uo) is det.
> +write_il_simple_type_as_csharp_type(int8) -->
> + io__write_string("int").
> +write_il_simple_type_as_csharp_type(int16) -->
> + io__write_string("int").
> +write_il_simple_type_as_csharp_type(int32) -->
> + io__write_string("int").
> +write_il_simple_type_as_csharp_type(int64) -->
> + io__write_string("int").
That code looks pretty wrong to me; wouldn't it be better to just call error/1
here?
The types you want here are sbyte, short, int, and long repectively.
> +write_il_simple_type_as_csharp_type(uint8) -->
> + io__write_string("unsigned int").
> +write_il_simple_type_as_csharp_type(uint16) -->
> + io__write_string("unsigned int").
> +write_il_simple_type_as_csharp_type(uint32) -->
> + io__write_string("unsigned int").
> +write_il_simple_type_as_csharp_type(uint64) -->
> + io__write_string("unsigned int").
Here it should be byte, ushort, uint, ulong.
> +write_il_simple_type_as_csharp_type(native_int) -->
> + io__write_string("int").
> +write_il_simple_type_as_csharp_type(native_uint) -->
> + io__write_string("unsigned int").
That's a bug: s/unsigned int/uint/
> +write_il_simple_type_as_csharp_type(float32) -->
> + io__write_string("float").
> +write_il_simple_type_as_csharp_type(float64) -->
> + io__write_string("float").
float64 is "double", not "float".
> +write_il_simple_type_as_csharp_type(bool) -->
> + io__write_string("int").
s/int/bool/
> + % XXX this is not the right syntax
> +write_il_simple_type_as_csharp_type(value_class(ClassName)) -->
> + write_csharp_class_name(ClassName).
Better to call error/1, I think.
> + % XXX this is not the right syntax
> +write_il_simple_type_as_csharp_type(interface(ClassName)) -->
> + write_csharp_class_name(ClassName).
Better to call error/1, I think.
> + % XXX this needs more work
> +write_il_simple_type_as_csharp_type('[]'(_Type, _Bounds)) -->
> + io__write_string("object[]").
Better to call error/1, I think.
(Or at very very least s/object/System.Object/,
but I think it's really quite wrong to ignore the _Type,
so error/1 is probably better.)
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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