[m-dev.] for review: Java backend
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Feb 15 21:46:35 AEDT 2001
On 14-Feb-2001, Julien Fischer <juliensf at students.cs.mu.oz.au> wrote:
>
> +:- pred mlds_sym_name_mangle_java(sym_name, string).
> +:- mode mlds_sym_name_mangle_java(in, out) is det.
> +
> +mlds_sym_name_mangle_java(unqualified(Name), MangledName) :-
> + llds_out__name_mangle(Name, MangledName).
> +mlds_sym_name_mangle_java(qualified(ModuleName, PlainName), MangledName) :-
> + mlds_sym_name_mangle_java(ModuleName, MangledModuleName),
> + llds_out__name_mangle(PlainName, MangledPlainName),
> + mlds_qualify_mangled_name(MangledModuleName, MangledPlainName,
> + MangledName).
> +
> +:- pred mlds_qualify_mangled_name(string, string, string).
> +:- mode mlds_qualify_mangled_name(in, in, out) is det.
> +
> +mlds_qualify_mangled_name(Module0, Name0, Name) :-
> + string__append_list([Module0,".",Name0], Name).
The `mlds_' doesn't really make sense there, since these are just
strings; there's nothing MLDS-specific about that routine, rather
it is Java-specific. So I suggest
s/mlds_qualify_mangled_name/java_qualify_mangled_name/
or perhaps just s/mlds_qualify_mangled_name/qualify_mangled_name/.
Also mlds_sym_name_mangle_java isn't great; I think
`java_mangle_mlds_sym_name' or `mangle_mlds_sym_name_for_java' would
be better.
> +mlds_output_src_file(Indent, MLDS) -->
...
> + % XXX Need to handle non-Java foriegn code at this point.
s/foriegn/foreign/
> +%------------------------------------------------------------------------------%
> +%
> +% MLDS->MLDS Transformations
> +%
> +
> + % For each Unify and Compare predicate create a class that
> + % implements either the Unify or Compare interface respectively.
s/predicate/predicate,/
> + % The call function that is implemented in the class then
> + % calls Unify and Compare.
s/call/`call'/
> + %
> +:- pred transform_special_predicates(mercury_module_name, mlds__defns,
> + mlds__defns).
> +:- mode transform_special_predicates(in, in, out) is det.
> +
> +transform_special_predicates(ModuleName, Defns0, Defns) :-
> + list__filter(defn_is_special_pred, Defns0, SpecialPredDefns),
> + wrap_predicates(ModuleName, SpecialPredDefns, WrappedDefns),
> + list__append(WrappedDefns, Defns0, Defns).
> +
> +:- pred wrap_predicates(mercury_module_name, mlds__defns, mlds__defns).
> +:- mode wrap_predicates(in, in, out) is det.
> +
> +wrap_predicates(_, [], []).
> +wrap_predicates(ModuleName, [Defn0 | Defns0], Defns) :-
> + wrap_predicate(ModuleName, Defn0, Defn),
> + wrap_predicates(ModuleName, Defns0, Defns1),
> + list__append([Defn], Defns1, Defns).
The last line should be just `Defns = [Defn | Defns1]',
or even better write it as a head unification
wrap_predicates(_, [], []).
wrap_predicates(ModuleName, [Defn0 | Defns0], [Defn | Defns]) :-
wrap_predicate(ModuleName, Defn0, Defn),
wrap_predicates(ModuleName, Defns0, Defns).
(Or alternatively, just use list__map.)
> +:- pred wrap_predicate(mercury_module_name, mlds__defn, mlds__defn).
> +:- mode wrap_predicate(in, in, out) is det.
> +
> +wrap_predicate(ModuleName, Defn, ClassDefn) :-
> + Defn = mlds__defn(Name, _, _, _),
> + (
> + Name = function(Label, _, _, _),
> + Label = special_pred(PredName, _, _, _)
> +
> + ->
> +
> + ( PredName = "__Unify__"
> +
> + ->
> + InterfaceName = "Unify"
> +
> + ; PredName = "__Compare__"
> +
> + ->
> + InterfaceName = "Compare"
> + ;
> + InterfaceName = ""
> +
> + ),
There's lots of blank lines here in wierd places. Plese delete them.
In general, fix the layout of that code.
The line `InterfaceName = ""' looks wrong.
Perhaps that should call error/1.
If not, it would be better to use a maybe(string) rather
than using "" as a special value.
You may need to handle the "Index" special predicates here.
> +generate_wrapper_class(ModuleName, Interface, MethodDefn, ClassDefn) :-
> + MethodDefn = mlds__defn(Name, Context, _DeclFlags, _DefnBody),
> + (
> + Name = function(Label, _ProcID, _MaybeSeqNum, _PredID),
> + Label = special_pred(PredName0, _, Type, Arity)
> + ->
> +
> + %
> + % Create class components.
> + %
> + ClassImports = [],
> + ClassExtends = [],
> + InterfaceDefn = mlds__class_type(Interface, 0, mlds__interface),
> + ClassImplements = [InterfaceDefn],
> + %
> + % Create a method that calls the orignal predicate.
> + %
s/orignal/original/
> + %
> + % Transform a list of function arguments into a list of local
> + % variable declarations of the same name and type. Create
> + % initializers that initalize each new local variable to the
> + % correct element in the `args' array.
> + %
> +:- pred generate_wrapper_decls(mercury_module_name, mlds__context,
> + mlds__arguments, int, mlds__defns).
> +:- mode generate_wrapper_decls(in, in, in, in, out) is det.
> +
> +generate_wrapper_decls(_, _, [], _, []).
> +generate_wrapper_decls(ModuleName, Context, [Arg | Args], Count, Defns) :-
> + Arg = Name - Type,
> + Flags = ml_gen_local_var_decl_flags,
> + string__int_to_string(Count, Index),
> + string__append("args[", Index, UnqualName0),
> + string__append(UnqualName0, "]", UnqualName),
> + NewVarName = qual(mercury_module_name_to_mlds(ModuleName), UnqualName),
Hmm, here you're using "args[0]" as a _variable name_?
I think it would be much nicer to use the `array_index' unary_op.
> + %
> + % Package everything together.
> + %
> + NewArgLval = var(NewVarName, mlds__generic_type),
> + Initializer = lval(NewArgLval),
> + Body = mlds__data(Type, init_obj(Initializer)),
> + Defn = mlds__defn(Name, Context, Flags, Body),
> + %
> + % Recrusively call ourself to process the next argument.
> + %
> + generate_wrapper_decls(ModuleName, Context, Args, Count + 1, Defns0),
> + list__append([Defn], Defns0, Defns).
s/Recrus/Recurs/
See comments above regarding use of list__append here.
> +%------------------------------------------------------------------------------
> +%
> +% Code to output the start and end of a source file.
> +%
> +
> +:- pred mlds_output_src_start(indent, mercury_module_name, mlds__imports,
> + mlds__defns, io__state, io__state).
> +
> +:- mode mlds_output_src_start(in, in, in, in, di, uo) is det.
> +
> +mlds_output_src_start(Indent, ModuleName, Imports, Defns) -->
> + mlds_output_auto_gen_comment(ModuleName),
> + mlds_indent(Indent),
> + io__write_string("/* :- module "),
> + prog_out__write_sym_name(ModuleName),
> + io__write_string(". */\n\n"),
> + mlds_output_package_info(ModuleName),
> + mlds_output_imports(Imports),
> + io__write_string("public class "),
> + prog_out__write_sym_name(ModuleName),
> + io__write_string(" {\n"),
> + mlds_maybe_write_main_driver(Indent + 1, ModuleName, Defns).
All of these `mlds_' prefixes are inappropriate here;
they should be replaced with `java_', or perhaps just deleted.
> + % Check if this module contains a main predicate and if it does insert
> + % a dummy main function in the resulting Java class that calls
> + % the main predicate.
The use of the word `dummy' here isn't quite right.
So I suggest s/dummy main/main/
(or perhaps s/dummy main/Java main/)
Also s/main/`main'/g would make it clearer.
> +mlds_maybe_write_main_driver(Indent, ModuleName, Defns) -->
> + (
> + { list__member(Defn, Defns) },
> + { Defn = mlds__defn(Name, _, _, _) },
> + { Name = function(FuncName, _, _, _) },
> + { FuncName = pred(predicate, _, "main", 2) }
That code duplicates some code in mercury_compile.m;
it would be a good idea to abstract that code out into
a routine in ml_util.m.
> +mlds_output_class(Indent, Name, _Context, ClassDefn) -->
> + { Name = qual(ModuleName, UnqualName) },
> + ({ UnqualName = type(_, _) } ->
s/({/( {/
> + []
> + ;
> + {error("mlds_to_java.m: mlds_output_class")}
s/{/{ /
s/}/} /
Use unexpected/2 from error_util.m, and this_file/0.
> + % Output superclass that this class extends. Java does
> + % not support multiple inheritance, so more than one superclass
> + % is an error.
> + %
> +:- pred mlds_output_extends_list(list(mlds__class_id), io__state, io__state).
> +:- mode mlds_output_extends_list(in, di, uo) is det.
> +
> +mlds_output_extends_list([]) --> [].
> +mlds_output_extends_list([SuperClass]) -->
> + io__write_string(" extends "),
> + mlds_output_type(SuperClass).
> +mlds_output_extends_list([_, _ | _]) -->
> + { error("mlds_to_java.m: multiple inheritance not supported in Java") }.
Use unexpected/2 from error_util.m, and this_file/0.
> +:- pred mlds_output_class_body(indent, mlds__class_kind,
> + mlds__qualified_entity_name, mlds__defns, mlds_module_name, io__state,
> + io__state).
Please indent wrapped type declarations by two tabs.
> +mlds_output_class_body(_Indent, mlds__struct, _, _AllMembers, _) -->
> + { error("mlds_to_java.m: structs not supported in Java.") }.
Use unexpected/2 and this_file/0.
> +mlds_output_enum_constant(Indent, EnumModuleName, Defn) -->
...
> + ;
> + { error("mlds_to_java.m: mlds_output_enum_constant: definition body was not data.") }
> + ).
Likewise here.
> +%-----------------------------------------------------------------------------%
> +%
> +% Code to output data declarations/definitions
> +%
> +
> +:- pred mlds_output_data_decl(mlds__qualified_entity_name, mlds__type,
> + initializer_array_size, io__state, io__state).
> +:- mode mlds_output_data_decl(in, in, in, di, uo) is det.
> +
> +mlds_output_data_decl(Name, Type, InitializerSize) -->
> + mlds_output_data_decl_ho(mlds_output_type,
> + (pred(Tp::in, di, uo) is det -->
> + mlds_output_type_suffix(Tp, InitializerSize)),
> + Name, Type).
>
> +:- pred mlds_output_data_decl_ho(output_type, output_type,
> + mlds__qualified_entity_name, mlds__type, io__state, io__state).
> +:- mode mlds_output_data_decl_ho(in(output_type), in(output_type),
> + in, in, di, uo) is det.
> +
> +mlds_output_data_decl_ho(OutputPrefix, OutputSuffix, Name, Type) -->
> + OutputPrefix(Type),
> + io__write_char(' '),
> + mlds_output_fully_qualified_name(Name),
> + OutputSuffix(Type).
Java doesn't require suffixes for its type declarations, so *all*
of that stuff do with output_type_suffix should go.
> + % We need to provide initializers for local variables
> + % to avoid problems with definite assignment.
I suggest s/definite assignment/Java's rules for definite assignment/
> +:- pred mlds_output_initializer(mlds__type, mlds__initializer,
> + io__state, io__state).
> +:- mode mlds_output_initializer(in, in, di, uo) is det.
> +
> +mlds_output_initializer(Type, Initializer) -->
> + io__write_string(" = "),
> + ( { mlds_needs_initialization(Initializer) = yes } ->
> + ( { Initializer = init_obj(Rval) }
> +
> + ->
> + ( { type_is_object(Type),
> + rval_is_int_const(Rval) }
> + ->
> + %
> + % If it is a enumeration object
> + % create new object.
> + %
> + io__write_string("new "),
> + mlds_output_type(Type),
> + io__write_char('('),
> + mlds_output_initializer_body(
> + Initializer),
> + io__write_char(')')
> + ;
> + % If it is an non-enumeration
> + % object, insert appropriate
> + % cast.
> + % XXX The logic of this is a bit
> + % wrong. Fixing it would eliminate
> + % some of the unecessary casting
> + % that happens
> + %
> + io__write_string("("),
> + mlds_output_type(Type),
> + io__write_string(") "),
> + mlds_output_initializer_body(
> + Initializer)
> + )
> + ;
> + mlds_output_initializer_body(Initializer)
> + )
> + ;
Fix the indentation and layout.
[to be continued]
--
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-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