[m-rev.] diff: C# interface for .NET backend.
Tyson Dowd
trd at cs.mu.OZ.AU
Wed May 2 09:01:44 AEST 2001
> > :- pred ml_gen_nondet_pragma_c_code(code_model, pragma_foreign_proc_attributes,
>
> Maybe you should change this to ml_gen_nondet_pragma_foreign_code to be
> consistent.
Done, I changed it to ml_gen_nondet_pragma_foreign_proc to be even more
accurate.
> > + % For ordinary (not model_non) pragma foreign_code in C#,
> > + % we generate a call to an out-of-line procedure that contains
> > + % the user's code.
> > +
> What happens if you declare nondet pragma foreign_code in C#?
We now test for this and call sorry/2.
> > --- compiler/mlds.m 2001/02/28 15:59:18 1.49
> > +++ compiler/mlds.m 2001/04/30 13:50:33
> > @@ -1011,7 +1011,6 @@
> > ; mark_hp(mlds__lval)
> > % Tell the heap sub-system to store a marker
> > % (for later use in restore_hp/1 instructions)
> > - % in the specified lval
> > %
> Why delete this line?
Oops, that I certainly didn't mean.
> > + ; 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
>
> What is the difference between the user's foreign language and the foreign
> language of this code?
foreign_language is one of the enumeration of the foreign_language type.
The user's foreign language code is the actual code fragment that the
programmer put inside the pragma.
I've explained this a bit better now.
> > +:- import_module ilds, ilasm, il_peephole.
> > +:- import_module ml_util, ml_code_util.
> > +:- import_module mlds_to_c. /* to output C code for .cpp files */
> > +:- use_module llds. /* for user_c_code */
> > +
> > +:- import_module bool, int, map, string, list, assoc_list, term, std_util.
> > +:- import_module library, require, counter.
> > +
> > +:- import_module mlds_to_il.
> > +
>
> I would imagine that the mlds_to_c import isn't needed.
Yes, and llds_out too.
> > + % This section could very nearly be turned into a
> > + % mlds_to_csharp module, which turns MLDS into managed C++.
> > + % Note that it relies on quite a few predicates in mlds_to_il.
> > + % XXX we should clean up the dependencies.
> > + % XXX we don't output contexts for any of this.
>
> Really that this section could almost be turned into a mlds_to_csharp
> module?
Ah, I can remove this comment now that I've done it.
And I now think the dependencies are OK, it's important to share the same
type conversions (turning MLDS types into IL types).
> > + io__nl,
> > + io__write_strings([
> > + "// #using ""mercury_mcpp.dll""\n",
> > + "// #using ""mercury_il.dll""\n",
> > + "// #using """, ModuleNameStr, ".dll""\n",
> > +
> > + % XXX We have to use the mercury namespace, as
> > + % llds_out still generates some of the code used in the
> > + % C sharp interface, and so it doesn't have "mercury::"
> > + % namespace qualifiers.
>
> . not :: qualifier.
True, but I think this might not be necessary for much longer anyway.
I've fixed the comment and removed the 3 lines above it that aren't
doing anything useful.
> > - method_c_code :: bool, % method contains c_code
> > + method_c_code :: maybe(foreign_language),
> > + % method contains foreign code
> > % method-wide attributes (static)
> > arguments :: arguments_map, % The arguments
> > method_name :: member_name, % current method name
> > @@ -182,7 +185,7 @@
> >
> Not sure that the *_c_code names are still appropiate, maybe switch to
> foreign.
Good point, I forgot to come back and do this.
> Otherwise the diff looks fine.
Here is the incremental diff:
diff -u compiler/ml_code_gen.m compiler/ml_code_gen.m
--- compiler/ml_code_gen.m
+++ compiler/ml_code_gen.m
@@ -773,7 +773,7 @@
:- import_module arg_info, llds, llds_out. % XXX needed for pragma foreign code
:- import_module export, foreign. % XXX needed for pragma foreign code
:- import_module hlds_pred, hlds_data.
-:- import_module goal_util, type_util, mode_util, builtin_ops.
+:- import_module goal_util, type_util, mode_util, builtin_ops, error_util.
:- import_module passes_aux, modules.
:- import_module globals, options.
@@ -2024,7 +2024,7 @@
CodeModel, OuterContext, MLDS_Decls, MLDS_Statements) -->
(
{ PragmaImpl = ordinary(C_Code, _MaybeContext) },
- ml_gen_ordinary_pragma_foreign_code(CodeModel, Attributes,
+ ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
C_Code, OuterContext, MLDS_Decls, MLDS_Statements)
;
@@ -2032,7 +2032,7 @@
LocalVarsDecls, LocalVarsContext,
FirstCode, FirstContext, LaterCode, LaterContext,
_Treatment, SharedCode, SharedContext) },
- ml_gen_nondet_pragma_c_code(CodeModel, Attributes,
+ ml_gen_nondet_pragma_foreign_proc(CodeModel, Attributes,
PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
OuterContext, LocalVarsDecls, LocalVarsContext,
FirstCode, FirstContext, LaterCode, LaterContext,
@@ -2041,7 +2041,7 @@
{ PragmaImpl = import(Name, HandleReturn, Vars, _Context) },
{ C_Code = string__append_list([HandleReturn, " ",
Name, "(", Vars, ");"]) },
- ml_gen_ordinary_pragma_foreign_code(CodeModel, Attributes,
+ ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
C_Code, OuterContext, MLDS_Decls, MLDS_Statements)
).
@@ -2056,13 +2056,14 @@
%
%
-:- pred ml_gen_nondet_pragma_c_code(code_model, pragma_foreign_proc_attributes,
+:- pred ml_gen_nondet_pragma_foreign_proc(code_model,
+ pragma_foreign_proc_attributes,
pred_id, proc_id, list(prog_var),
list(maybe(pair(string, mode))), list(prog_type), prog_context,
string, maybe(prog_context), string, maybe(prog_context),
string, maybe(prog_context), string, maybe(prog_context),
mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_nondet_pragma_c_code(in, in, in, in, in, in, in, in,
+:- mode ml_gen_nondet_pragma_foreign_proc(in, in, in, in, in, in, in, in,
in, in, in, in, in, in, in, in, out, out, in, out) is det.
% For model_non pragma c_code,
@@ -2116,11 +2117,18 @@
% gets inlined and optimized away. Of course we also need to
% #undef it afterwards.
%
-ml_gen_nondet_pragma_c_code(CodeModel, Attributes,
+ml_gen_nondet_pragma_foreign_proc(CodeModel, Attributes,
PredId, _ProcId, ArgVars, ArgDatas, OrigArgTypes, Context,
LocalVarsDecls, LocalVarsContext, FirstCode, FirstContext,
LaterCode, LaterContext, SharedCode, SharedContext,
MLDS_Decls, MLDS_Statements) -->
+
+ { foreign_language(Attributes, Lang) },
+ ( { Lang = csharp } ->
+ { sorry(this_file, "nondet pragma foreign_proc for C#") }
+ ;
+ []
+ ),
%
% Combine all the information about the each arg
%
@@ -2252,47 +2260,47 @@
]) },
{ MLDS_Decls = ConvDecls }.
-:- pred ml_gen_ordinary_pragma_foreign_code(code_model,
+:- pred ml_gen_ordinary_pragma_foreign_proc(code_model,
pragma_foreign_proc_attributes,
pred_id, proc_id, list(prog_var),
list(maybe(pair(string, mode))), list(prog_type),
string, prog_context,
mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_ordinary_pragma_foreign_code(in, in, in, in, in, in,
+:- mode ml_gen_ordinary_pragma_foreign_proc(in, in, in, in, in, in,
in, in, in, out, out, in, out) is det.
-ml_gen_ordinary_pragma_foreign_code(CodeModel, Attributes,
+ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes,
PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
Foreign_Code, Context, MLDS_Decls, MLDS_Statements) -->
{ foreign_language(Attributes, Lang) },
( { Lang = c },
- ml_gen_ordinary_pragma_c_code(CodeModel, Attributes,
+ ml_gen_ordinary_pragma_c_proc(CodeModel, Attributes,
PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
Foreign_Code, Context, MLDS_Decls, MLDS_Statements)
; { Lang = managed_cplusplus },
- ml_gen_ordinary_pragma_c_code(CodeModel, Attributes,
+ ml_gen_ordinary_pragma_c_proc(CodeModel, Attributes,
PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
Foreign_Code, Context, MLDS_Decls, MLDS_Statements)
; { Lang = csharp },
- ml_gen_ordinary_pragma_csharp_code(CodeModel, Attributes,
+ ml_gen_ordinary_pragma_csharp_proc(CodeModel, Attributes,
PredId, ProcId, ArgVars, ArgDatas, OrigArgTypes,
Foreign_Code, Context, MLDS_Decls, MLDS_Statements)
).
-:- pred ml_gen_ordinary_pragma_csharp_code(code_model,
+:- pred ml_gen_ordinary_pragma_csharp_proc(code_model,
pragma_foreign_proc_attributes,
pred_id, proc_id, list(prog_var),
list(maybe(pair(string, mode))), list(prog_type),
string, prog_context,
mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_ordinary_pragma_csharp_code(in, in, in, in, in, in,
+:- mode ml_gen_ordinary_pragma_csharp_proc(in, in, in, in, in, in,
in, in, in, out, out, in, out) is det.
% For ordinary (not model_non) pragma foreign_code in C#,
% we generate a call to an out-of-line procedure that contains
% the user's code.
-ml_gen_ordinary_pragma_csharp_code(_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) },
@@ -2309,19 +2317,19 @@
{ MLDS_Decls = [] }.
-:- pred ml_gen_ordinary_pragma_c_code(code_model,
+:- pred ml_gen_ordinary_pragma_c_proc(code_model,
pragma_foreign_proc_attributes,
pred_id, proc_id, list(prog_var),
list(maybe(pair(string, mode))), list(prog_type),
string, prog_context,
mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_ordinary_pragma_c_code(in, in, in, in, in, in,
+:- mode ml_gen_ordinary_pragma_c_proc(in, in, in, in, in, in,
in, in, in, out, out, in, out) is det.
- % For ordinary (not model_non) pragma c_code,
+ % For ordinary (not model_non) pragma c_proc,
% we generate code of the following form:
%
- % model_det pragma_c_code:
+ % model_det pragma_c_proc:
%
% #define MR_PROC_LABEL <procedure name>
% <declaration of locals needed for boxing/unboxing>
@@ -2337,7 +2345,7 @@
% }
% #undef MR_PROC_LABEL
%
- % model_semi pragma_c_code:
+ % model_semi pragma_c_proc:
%
% #define MR_PROC_LABEL <procedure name>
% <declaration of locals needed for boxing/unboxing>
@@ -2376,7 +2384,7 @@
% different for targets other than C, e.g. when compiling to
% Java.
%
-ml_gen_ordinary_pragma_c_code(CodeModel, Attributes,
+ml_gen_ordinary_pragma_c_proc(CodeModel, Attributes,
PredId, _ProcId, ArgVars, ArgDatas, OrigArgTypes,
C_Code, Context, MLDS_Decls, MLDS_Statements) -->
%
@@ -3085,6 +3093,9 @@
{ error("model_non disj in model_det disjunction") }
)
).
+
+:- func this_file = string.
+this_file = "mlds_to_c.m".
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
diff -u compiler/ml_util.m compiler/ml_util.m
--- compiler/ml_util.m
+++ compiler/ml_util.m
@@ -294,9 +294,7 @@
Body = function(_, _, yes(FunctionBody)),
statement_contains_statement(FunctionBody, Statement),
Statement = mlds__statement(Stmt, _),
- (
- Stmt = atomic(outline_target_code(ForeignLang, _, _))
- ).
+ Stmt = atomic(outline_target_code(ForeignLang, _, _)).
defn_is_type(Defn) :-
Defn = mlds__defn(Name, _Context, _Flags, _Body),
diff -u compiler/mlds.m compiler/mlds.m
--- compiler/mlds.m
+++ compiler/mlds.m
@@ -1011,6 +1011,7 @@
; mark_hp(mlds__lval)
% Tell the heap sub-system to store a marker
% (for later use in restore_hp/1 instructions)
+ % in the specified lval.
%
% It's OK for the target to treat this as a no-op,
% and probably that is what most targets will do.
@@ -1044,11 +1045,13 @@
% statements.
; outline_target_code(
foreign_language,
- % the foreign language of this code
+ % the foreign language this code is
+ % written in.
list(mlds__lval),
% where to store return value(s)
string
% the user's foreign language code
+ % fragment
)
% Do whatever is specified by the string, which
% can be any piece of code in the specified
diff -u mlds_to_csharp.m mlds_to_csharp.m
--- mlds_to_csharp.m
+++ mlds_to_csharp.m
@@ -28,12 +28,11 @@
:- import_module globals, options, passes_aux.
:- import_module builtin_ops, c_util, modules, tree.
:- import_module hlds_pred. % for `pred_proc_id'.
-:- import_module prog_data, prog_out, llds_out.
+:- import_module prog_data, prog_out.
:- import_module rtti, type_util, error_util.
:- import_module ilds, ilasm, il_peephole.
:- import_module ml_util, ml_code_util.
-:- import_module mlds_to_c. /* to output C code for .cpp files */
:- use_module llds. /* for user_c_code */
:- import_module bool, int, map, string, list, assoc_list, term, std_util.
@@ -85,30 +84,20 @@
%-----------------------------------------------------------------------------%
- % This section could very nearly be turned into a
- % mlds_to_csharp module, which turns MLDS into managed C++.
- % Note that it relies on quite a few predicates in mlds_to_il.
- % XXX we should clean up the dependencies.
% XXX we don't output contexts for any of this.
:- pred generate_c_code(mlds, io__state, io__state).
:- mode generate_c_code(in, di, uo) is det.
generate_c_code(MLDS) -->
{ MLDS = mlds(ModuleName, ForeignCode, _Imports, Defns) },
- { prog_out__sym_name_to_string(ModuleName, ModuleNameStr) },
{ ClassName = mlds_module_name_to_class_name(
mercury_module_name_to_mlds(ModuleName)) },
io__nl,
io__write_strings([
- "// #using ""mercury_mcpp.dll""\n",
- "// #using ""mercury_il.dll""\n",
- "// #using """, ModuleNameStr, ".dll""\n",
-
- % XXX We have to use the mercury namespace, as
- % llds_out still generates some of the code used in the
- % C sharp interface, and so it doesn't have "mercury::"
- % namespace qualifiers.
+ % XXX We may be able to drop the mercury namespace soon,
+ % as there doesn't appear to be any llds generated code in
+ % the C# code anymore.
"using mercury;\n",
"\n"]),
diff -u compiler/mlds_to_il.m compiler/mlds_to_il.m
--- compiler/mlds_to_il.m
+++ compiler/mlds_to_il.m
@@ -140,9 +140,8 @@
:- import_module ilasm, il_peephole.
:- import_module ml_util, ml_code_util, error_util.
-:- import_module mlds_to_c. /* to output C code for .cpp files */
:- import_module ml_type_gen.
-:- use_module llds. /* for user_c_code */
+:- use_module llds. /* for user_foreign_code */
:- import_module bool, int, map, string, set, list, assoc_list, term.
:- import_module library, require, counter.
@@ -157,20 +156,20 @@
module_name :: mlds_module_name, % the module name
assembly_name :: assembly_name, % the assembly name
imports :: mlds__imports, % the imports
- file_c_code :: set(foreign_language), % file foreign code
+ file_foreign_langs :: set(foreign_language), % file foreign code
il_data_rep :: il_data_rep, % data representation.
% class-wide attributes (all accumulate)
alloc_instrs :: instr_tree, % .cctor allocation instructions
init_instrs :: instr_tree, % .cctor init instructions
classdecls :: list(classdecl), % class methods and fields
has_main :: bool, % class contains main
- class_c_code :: set(foreign_language),% class foreign code
+ class_foreign_langs :: set(foreign_language),% class foreign code
% method-wide attributes (accumulating)
locals :: locals_map, % The current locals
instr_tree :: instr_tree, % The instruction tree (unused)
label_counter :: counter, % the label counter
block_counter :: counter, % the block counter
- method_c_code :: maybe(foreign_language),
+ method_foreign_lang :: maybe(foreign_language),
% method contains foreign code
% method-wide attributes (static)
arguments :: arguments_map, % The arguments
@@ -196,9 +195,9 @@
% Generate code for all the methods in this module.
list__foldl(generate_method_defn, Defns, Info0, Info1),
- ( Info1 ^ method_c_code = yes(SomeLang) ->
- Info2 = Info1 ^ file_c_code :=
- set__insert(Info1 ^ file_c_code, SomeLang)
+ ( Info1 ^ method_foreign_lang = yes(SomeLang) ->
+ Info2 = Info1 ^ file_foreign_langs :=
+ set__insert(Info1 ^ file_foreign_langs, SomeLang)
;
Info2 = Info1
),
@@ -220,7 +219,7 @@
% assembly in a separate step during the build (using
% AL.EXE).
- Info3 ^ file_c_code = ForeignLangs,
+ Info3 ^ file_foreign_langs = ForeignLangs,
(
SymName = qualified(unqualified("mercury"), _)
->
@@ -229,7 +228,7 @@
;
ThisAssembly = [assembly(AssemblyName)],
% If not in the library, but we have C code,
- % declare the __c_code module as an assembly we
+ % declare the foreign module as an assembly we
% reference
list__map(mangle_foreign_code_module(ModuleName),
set__to_sorted_list(ForeignLangs),
@@ -965,8 +964,8 @@
atomic_statement_to_il(outline_target_code(Lang, ReturnLvals, _Code),
Instrs) -->
il_info_get_module_name(ModuleName),
- ( no =^ method_c_code ->
- ^ method_c_code := yes(Lang),
+ ( no =^ method_foreign_lang ->
+ ^ method_foreign_lang := yes(Lang),
{ mangle_foreign_code_module(ModuleName, Lang,
OutlineLangModuleName) },
{ ClassName = mlds_module_name_to_class_name(
@@ -1013,9 +1012,9 @@
atomic_statement_to_il(inline_target_code(_Lang, _Code), node(Instrs)) -->
il_info_get_module_name(ModuleName),
- ( no =^ method_c_code ->
+ ( no =^ method_foreign_lang ->
% XXX we hardcode managed C++ here
- ^ method_c_code := yes(managed_cplusplus),
+ ^ method_foreign_lang := yes(managed_cplusplus),
{ mangle_dataname_module(no, ModuleName, NewModuleName) },
{ ClassName = mlds_module_name_to_class_name(NewModuleName) },
signature(_, RetType, Params) =^ signature,
@@ -2758,11 +2757,11 @@
il_info_new_method(ILArgs, ILSignature, MethodName) -->
=(Info),
- ( yes(SomeLang) =^ method_c_code ->
- ^ file_c_code :=
- set__insert(Info ^ file_c_code, SomeLang),
- ^ class_c_code :=
- set__insert(Info ^ class_c_code, SomeLang)
+ ( yes(SomeLang) =^ method_foreign_lang ->
+ ^ file_foreign_langs :=
+ set__insert(Info ^ file_foreign_langs, SomeLang),
+ ^ class_foreign_langs :=
+ set__insert(Info ^ class_foreign_langs, SomeLang)
;
[]
),
@@ -2770,7 +2769,7 @@
^ instr_tree := empty,
^ label_counter := counter__init(1),
^ block_counter := counter__init(1),
- ^ method_c_code := no,
+ ^ method_foreign_lang := no,
^ arguments := ILArgs,
^ method_name := MethodName,
^ signature := ILSignature.
diff -u mlds_to_mcpp.m mlds_to_mcpp.m
--- mlds_to_mcpp.m
+++ mlds_to_mcpp.m
@@ -81,11 +81,8 @@
%-----------------------------------------------------------------------------%
- % This section could very nearly be turned into a
- % mlds_to_managed_cpp module, which turns MLDS into managed C++.
- % Note that it relies on quite a few predicates in mlds_to_il.
- % XXX we should clean up the dependencies.
- % XXX we don't output contexts for any of this.
+ % XXX we don't output contexts correctly -- we need to write out the
+ % original context at the end of the user's MC++ code.
:- pred generate_mcplusplus_code(mlds, io__state, io__state).
:- mode generate_mcplusplus_code(in, di, uo) is det.
generate_mcplusplus_code(MLDS) -->
--
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