[m-rev.] for review: mmc --make, submodules and java
Peter Wang
novalazy at gmail.com
Wed May 6 13:50:43 AEST 2009
2009/5/5 Julien Fischer <juliensf at csse.unimelb.edu.au>:
>
> parse_tree is fine; it's introducing import dependencies back the other way
> that concerns me, i.e. having the frontend packages import the code
> generators.
Here is an updated log message and interdiff.
Branches: main
Make `mmc --make' support submodules when compiling to Java. Java files must
be placed in subdirectories named after the package that each class belongs to.
compiler/java_names.m
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
Add a new module in the parse_tree package to contain code related to
name mangling for Java.
compiler/mlds.m:
compiler/java_util.m:
Move predicates to java_names.m.
compiler/mlds_to_java.m:
Move predicates to java_names.m.
Delete an unused predicate.
compiler/file_names.m:
Rename `erlang_module_name' as it is now also used for Java.
Make `module_name_to_file_name_general' return file names for `.java'
and `.class' files that include package subdirectories.
compiler/make.program_target.m:
Clean `.class' files on make clean.
compiler/mlds_to_il.m:
mdbcomp/prim_data.m:
Move `sym_name_to_list' to mdbcomp.prim_data.
compiler/compile_target_code.m:
compiler/elds_to_erlang.m:
Conform to changes.
library/Mmakefile:
Delete hacks that work around Mercury not writing submodule .java files
in subdirectories.
diff --git a/compiler/file_names.m b/compiler/file_names.m
index 514238a..17c5b16 100644
--- a/compiler/file_names.m
+++ b/compiler/file_names.m
@@ -130,8 +130,7 @@
:- import_module libs.handle_options.
:- import_module libs.options.
:- import_module mdbcomp.prim_data.
-:- import_module ml_backend. % XXX unwanted dependency
-:- import_module ml_backend.mlds_to_java. % XXX unwanted dependency
+:- import_module parse_tree.java_names.
:- import_module parse_tree.prog_util.
:- import_module parse_tree.source_file_map.
@@ -269,7 +268,8 @@ choose_file_name(_ModuleName, BaseParentDirs,
BaseName, Ext, Search, MkDir,
)
)
->
- FileName = BaseName
+ make_file_name(BaseParentDirs, do_not_search, do_create_dirs, BaseName,
+ Ext, FileName, !IO)
;
% The source files, the final executables, library files (including
% .init files) output files intended for use by the user, and phony
@@ -428,7 +428,7 @@ module_name_to_make_var_name(ModuleName, MakeVarName) :-
make_file_name(SubDirNames, Search, MkDir, BaseName, Ext, FileName, !IO) :-
globals.io_get_globals(Globals, !IO),
globals.lookup_bool_option(Globals, use_grade_subdirs, UseGradeSubdirs),
- globals.lookup_string_option(Globals, fullarch, FullArch),
+ globals.lookup_bool_option(Globals, use_subdirs, UseSubdirs),
(
UseGradeSubdirs = yes,
file_is_arch_or_grade_dependent(Globals, Ext),
@@ -448,6 +448,7 @@ make_file_name(SubDirNames, Search, MkDir,
BaseName, Ext, FileName, !IO) :-
)
->
grade_directory_component(Globals, Grade),
+ globals.lookup_string_option(Globals, fullarch, FullArch),
% The extra "Mercury" is needed so we can use `--intermod-directory
% Mercury/<grade>/<fullarch>' and `--c-include
@@ -456,17 +457,27 @@ make_file_name(SubDirNames, Search, MkDir,
BaseName, Ext, FileName, !IO) :-
% libraries.
DirComponents = ["Mercury", Grade, FullArch, "Mercury" | SubDirNames]
;
+ UseSubdirs = yes
+ ->
DirComponents = ["Mercury" | SubDirNames]
+ ;
+ DirComponents = SubDirNames
),
(
- MkDir = do_create_dirs,
- DirName = dir.relative_path_name_from_components(DirComponents),
- make_directory(DirName, _, !IO)
+ DirComponents = [],
+ FileName = BaseName
;
- MkDir = do_not_create_dirs
- ),
- Components = DirComponents ++ [BaseName],
- FileName = dir.relative_path_name_from_components(Components).
+ DirComponents = [_ | _],
+ (
+ MkDir = do_create_dirs,
+ DirName = dir.relative_path_name_from_components(DirComponents),
+ make_directory(DirName, _, !IO)
+ ;
+ MkDir = do_not_create_dirs
+ ),
+ Components = DirComponents ++ [BaseName],
+ FileName = dir.relative_path_name_from_components(Components)
+ ).
:- pred file_is_arch_or_grade_dependent(globals::in, string::in) is semidet.
diff --git a/compiler/java_names.m b/compiler/java_names.m
new file mode 100644
index 0000000..485b87f
--- /dev/null
+++ b/compiler/java_names.m
@@ -0,0 +1,288 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2002-2009 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: java_names.m.
+% Main authors: juliensf, mjwybrow, wangp.
+%
+% This module contains utility routines related to naming things in Java,
+% which are also required in the frontend.
+%
+%-----------------------------------------------------------------------------%
+
+:- module parse_tree.java_names.
+:- interface.
+
+:- import_module mdbcomp.prim_data.
+
+:- import_module bool.
+
+%-----------------------------------------------------------------------------%
+
+ % For the Java back-end, we need to distinguish between module qualifiers
+ % and type qualifiers, because type names get the case of their initial
+ % letter inverted (i.e. lowercase => uppercase).
+ %
+ % This duplicates mlds_qual_kind so as not to introduce unwanted
+ % dependencies in either direction.
+ %
+:- type java_qual_kind
+ ---> module_qual
+ ; type_qual.
+
+ % Java doesn't allow a fully-qualified class to have the same name as a
+ % package. Our workaround is to name package components with trailing
+ % underscores, e.g. `mammal_.primate_.chimp' where `chimp' is a class.
+ % This is enabled with `package_name_mangling'.
+ %
+ % The packages `mercury' and `mercury.runtime' are named without
+ % underscores simply because there is existing handwritten code already
+ % using those names.
+ %
+:- type package_name_mangling
+ ---> package_name_mangling
+ ; no_package_name_mangling.
+
+ % Mangle a name so that it is suitable for Java.
+ %
+:- pred mangle_sym_name_for_java(sym_name::in, java_qual_kind::in,
+ string::in, package_name_mangling::in, string::out) is det.
+
+ % Returns yes iff the given package is one provided by the Mercury
+ % implementation, `mercury' or `mercury.runtime'.
+ %
+:- func is_mercury_provided_java_package(sym_name) = bool.
+
+ % Used in module_name_to_file_name to derive file names for Java files.
+ % Returns a module name which each component mangled.
+ %
+:- func java_module_name(module_name) = module_name.
+
+ % If the given name conficts with a reserved Java word we must add a
+ % prefix to it to avoid compilation errors.
+ %
+:- func valid_java_symbol_name(string) = string.
+
+ % Succeeds iff the given string matches a reserved word in Java.
+ %
+:- pred java_is_keyword(string::in) is semidet.
+
+ % Invert the case of the first letter of the string.
+ %
+:- func flip_initial_case(string) = string.
+
+ % Invert the case of the first letter of the last component of
+ % a (possibly) qualified name.
+ %
+:- func flip_initial_case_of_final_part(sym_name) = sym_name.
+
+ % The package containing the Mercury standard library.
+ %
+:- func mercury_std_library_package_name = sym_name.
+
+ % The package containing the Mercury Java runtime classes.
+ %
+:- func mercury_runtime_package_name = sym_name.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module parse_tree.file_names.
+:- import_module parse_tree.prog_foreign. % for name_mangle
+
+:- import_module char.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+mangle_sym_name_for_java(SymName, QualKind, QualifierOp,
+ PackageNameMangling, JavaSafeName) :-
+ mangle_sym_name_for_java_2(SymName, QualKind, PackageNameMangling,
+ MangledSymName),
+ JavaSafeName = sym_name_to_string_sep(MangledSymName, QualifierOp).
+
+:- pred mangle_sym_name_for_java_2(sym_name::in, java_qual_kind::in,
+ package_name_mangling::in, sym_name::out) is det.
+
+mangle_sym_name_for_java_2(SymName, QualKind, PackageNameMangling,
+ MangledSymName) :-
+ (
+ SymName = unqualified(Name),
+ JavaSafeName = java_safe_name_component(QualKind, Name),
+ MangledSymName = unqualified(JavaSafeName)
+ ;
+ SymName = qualified(ModuleName0, PlainName),
+ mangle_sym_name_for_java_2(ModuleName0, module_qual,
+ PackageNameMangling, MangledModuleName0),
+ (
+ PackageNameMangling = package_name_mangling,
+ MercuryProvided = is_mercury_provided_java_package(ModuleName0),
+ (
+ MercuryProvided = yes,
+ MangledModuleName = MangledModuleName0
+ ;
+ MercuryProvided = no,
+ MangledModuleName = append_underscore_sym_name(
+ MangledModuleName0)
+ )
+ ;
+ PackageNameMangling = no_package_name_mangling,
+ MangledModuleName = MangledModuleName0
+ ),
+ JavaSafePlainName = java_safe_name_component(QualKind, PlainName),
+ MangledSymName = qualified(MangledModuleName, JavaSafePlainName)
+ ).
+
+:- func java_safe_name_component(java_qual_kind, string) = string.
+
+java_safe_name_component(QualKind, Name) = JavaSafeName :-
+ (
+ QualKind = module_qual,
+ FlippedName = Name
+ ;
+ QualKind = type_qual,
+ FlippedName = flip_initial_case(Name)
+ ),
+ MangledName = name_mangle(FlippedName),
+ JavaSafeName = valid_java_symbol_name(MangledName).
+
+is_mercury_provided_java_package(ModuleName) = MercuryProvided :-
+ ( ModuleName = mercury_std_library_package_name ->
+ MercuryProvided = yes
+ ; ModuleName = mercury_runtime_package_name ->
+ MercuryProvided = yes
+ ;
+ MercuryProvided = no
+ ).
+
+:- func append_underscore_sym_name(sym_name) = sym_name.
+
+append_underscore_sym_name(SymName0) = SymName :-
+ (
+ SymName0 = unqualified(Name),
+ SymName = unqualified(Name ++ "_")
+ ;
+ SymName0 = qualified(ModuleSymName, Name),
+ SymName = qualified(ModuleSymName, Name ++ "_")
+ ).
+
+%-----------------------------------------------------------------------------%
+
+java_module_name(ModuleName) = JavaModuleName :-
+ QualModuleName = qualify_mercury_std_library_module_name(ModuleName),
+ mangle_sym_name_for_java_2(QualModuleName, module_qual,
+ package_name_mangling, JavaModuleName).
+
+%-----------------------------------------------------------------------------%
+
+valid_java_symbol_name(SymName) = ValidSymName :-
+ Prefix = "mr_",
+ ( java_is_keyword(SymName) ->
+ % This is a reserved Java word, add the above prefix.
+ ValidSymName = Prefix ++ SymName
+ ; string.append(Prefix, Suffix, SymName) ->
+ % This name already contains the prefix we are adding to
+ % variables to avoid conficts, so add an additional '_'.
+ ValidSymName = Prefix ++ "_" ++ Suffix
+ ;
+ % Normal name; do nothing.
+ ValidSymName = SymName
+ ).
+
+%-----------------------------------------------------------------------------%
+
+java_is_keyword("abstract").
+java_is_keyword("boolean").
+java_is_keyword("break").
+java_is_keyword("byte").
+java_is_keyword("case").
+java_is_keyword("catch").
+java_is_keyword("char").
+java_is_keyword("class").
+java_is_keyword("const").
+java_is_keyword("continue").
+java_is_keyword("default").
+java_is_keyword("do").
+java_is_keyword("double").
+java_is_keyword("else").
+java_is_keyword("enum").
+java_is_keyword("extends").
+java_is_keyword("false").
+java_is_keyword("final").
+java_is_keyword("finally").
+java_is_keyword("float").
+java_is_keyword("for").
+java_is_keyword("goto").
+java_is_keyword("if").
+java_is_keyword("implements").
+java_is_keyword("import").
+java_is_keyword("instanceof").
+java_is_keyword("int").
+java_is_keyword("interface").
+java_is_keyword("long").
+java_is_keyword("native").
+java_is_keyword("new").
+java_is_keyword("null").
+java_is_keyword("package").
+java_is_keyword("private").
+java_is_keyword("protected").
+java_is_keyword("public").
+java_is_keyword("return").
+java_is_keyword("short").
+java_is_keyword("static").
+java_is_keyword("strictfp").
+java_is_keyword("super").
+java_is_keyword("switch").
+java_is_keyword("synchronized").
+java_is_keyword("this").
+java_is_keyword("throw").
+java_is_keyword("throws").
+java_is_keyword("transient").
+java_is_keyword("true").
+java_is_keyword("try").
+java_is_keyword("void").
+java_is_keyword("volatile").
+java_is_keyword("while").
+
+%-----------------------------------------------------------------------------%
+
+flip_initial_case(S0) = S :-
+ ( string.first_char(S0, First0, Rest) ->
+ ( char.is_upper(First0) ->
+ First = char.to_lower(First0)
+ ; char.is_lower(First0) ->
+ First = char.to_upper(First0)
+ ;
+ First = First0
+ ),
+ string.first_char(S, First, Rest)
+ ;
+ S = S0
+ ).
+
+flip_initial_case_of_final_part(unqualified(Name)) =
+ unqualified(flip_initial_case(Name)).
+flip_initial_case_of_final_part(qualified(Qual, Name)) =
+ qualified(Qual, flip_initial_case(Name)).
+
+%-----------------------------------------------------------------------------%
+
+mercury_std_library_package_name = unqualified("mercury").
+
+mercury_runtime_package_name = qualified(unqualified("mercury"), "runtime").
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "java_names.m".
+
+%-----------------------------------------------------------------------------%
+:- end_module java_names.
+%-----------------------------------------------------------------------------%
diff --git a/compiler/java_util.m b/compiler/java_util.m
index 1436f44..b3c5523 100644
--- a/compiler/java_util.m
+++ b/compiler/java_util.m
@@ -19,13 +19,6 @@
:- interface.
:- import_module backend_libs.builtin_ops.
-:- import_module mdbcomp.prim_data.
-
-%-----------------------------------------------------------------------------%
-
- % Succeeds iff the given string matches a reserved word in Java.
- %
-:- pred java_is_keyword(string::in) is semidet.
%-----------------------------------------------------------------------------%
%
@@ -61,16 +54,6 @@
:- pred java_binary_infix_op(binary_op::in, string::out) is semidet.
%-----------------------------------------------------------------------------%
-
- % The package containing the Mercury standard library.
- %
-:- func mercury_std_library_package_name = sym_name.
-
- % The package containing the Mercury Java runtime classes.
- %
-:- func mercury_runtime_package_name = sym_name.
-
-%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
@@ -131,67 +114,6 @@ java_binary_infix_op(int_ge, ">=").
%-----------------------------------------------------------------------------%
-java_is_keyword("abstract").
-java_is_keyword("boolean").
-java_is_keyword("break").
-java_is_keyword("byte").
-java_is_keyword("case").
-java_is_keyword("catch").
-java_is_keyword("char").
-java_is_keyword("class").
-java_is_keyword("const").
-java_is_keyword("continue").
-java_is_keyword("default").
-java_is_keyword("do").
-java_is_keyword("double").
-java_is_keyword("else").
-java_is_keyword("enum").
-java_is_keyword("extends").
-java_is_keyword("false").
-java_is_keyword("final").
-java_is_keyword("finally").
-java_is_keyword("float").
-java_is_keyword("for").
-java_is_keyword("goto").
-java_is_keyword("if").
-java_is_keyword("implements").
-java_is_keyword("import").
-java_is_keyword("instanceof").
-java_is_keyword("int").
-java_is_keyword("interface").
-java_is_keyword("long").
-java_is_keyword("native").
-java_is_keyword("new").
-java_is_keyword("null").
-java_is_keyword("package").
-java_is_keyword("private").
-java_is_keyword("protected").
-java_is_keyword("public").
-java_is_keyword("return").
-java_is_keyword("short").
-java_is_keyword("static").
-java_is_keyword("strictfp").
-java_is_keyword("super").
-java_is_keyword("switch").
-java_is_keyword("synchronized").
-java_is_keyword("this").
-java_is_keyword("throw").
-java_is_keyword("throws").
-java_is_keyword("transient").
-java_is_keyword("true").
-java_is_keyword("try").
-java_is_keyword("void").
-java_is_keyword("volatile").
-java_is_keyword("while").
-
-%-----------------------------------------------------------------------------%
-
-mercury_std_library_package_name = unqualified("mercury").
-
-mercury_runtime_package_name = qualified(unqualified("mercury"), "runtime").
-
-%-----------------------------------------------------------------------------%
-
:- func this_file = string.
this_file = "java_util.m".
diff --git a/compiler/mlds.m b/compiler/mlds.m
index d723892..de58e48 100644
--- a/compiler/mlds.m
+++ b/compiler/mlds.m
@@ -1744,18 +1744,6 @@
%-----------------------------------------------------------------------------%
- % Invert the case of the first letter of the string.
- % This is used for the Java back-end.
- %
-:- func flip_initial_case(string) = string.
-
- % Invert the case of the first letter of the last component of
- % a (possibly) qualified name. This is used for the Java back-end.
- %
-:- func flip_initial_case_of_final_part(sym_name) = sym_name.
-
-%-----------------------------------------------------------------------------%
-
:- type mlds_exported_enums == list(mlds_exported_enum).
:- type mlds_exported_enum
@@ -1784,6 +1772,7 @@
:- import_module parse_tree.file_names.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_util.
+:- import_module parse_tree.java_names.
:- import_module char.
:- import_module int.
@@ -1993,26 +1982,6 @@ mlds_std_tabling_proc_label(ProcLabel0) = ProcLabel :-
),
ProcLabel = mlds_proc_label(PredLabel, ProcId).
-flip_initial_case_of_final_part(unqualified(Name)) =
- unqualified(flip_initial_case(Name)).
-flip_initial_case_of_final_part(qualified(Qual, Name)) =
- qualified(Qual, flip_initial_case(Name)).
-
- % Invert the case of the first letter of the string.
-flip_initial_case(S0) = S :-
- ( string.first_char(S0, First0, Rest) ->
- ( char.is_upper(First0) ->
- First = char.to_lower(First0)
- ; char.is_lower(First0) ->
- First = char.to_upper(First0)
- ;
- First = First0
- ),
- string.first_char(S, First, Rest)
- ;
- S = S0
- ).
-
%-----------------------------------------------------------------------------%
% We represent the set of declaration flags as a bunch of bit-fields packed
diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m
index 338014d..2a4b0e9 100644
--- a/compiler/mlds_to_java.m
+++ b/compiler/mlds_to_java.m
@@ -72,7 +72,6 @@
:- interface.
:- import_module hlds.hlds_module.
-:- import_module mdbcomp.prim_data.
:- import_module ml_backend.mlds.
:- import_module io.
@@ -81,10 +80,6 @@
:- pred output_mlds(module_info::in, mlds::in, io::di, io::uo) is det.
- % Used in module_name_to_file_name to derive file names for Java files.
- %
-:- func java_module_name(module_name) = module_name.
-
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -102,11 +97,13 @@
:- import_module libs.file_util.
:- import_module libs.globals.
:- import_module libs.options.
+:- import_module mdbcomp.prim_data.
:- import_module ml_backend.java_util.
:- import_module ml_backend.ml_code_util. % for ml_gen_local_var_decl_flags.
:- import_module ml_backend.ml_type_gen. % for ml_gen_type_name
:- import_module ml_backend.ml_util.
:- import_module parse_tree.file_names. % for mercury_std_library_name.
+:- import_module parse_tree.java_names.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_foreign.
:- import_module parse_tree.prog_out.
@@ -143,19 +140,6 @@ output_mlds(ModuleInfo, MLDS, !IO) :-
% Utility predicates for various purposes.
%
- % Succeeds iff the given qualified name is part of the standard
- % library (as listed in compiler/modules.m).
- %
-:- pred qualified_name_is_stdlib(mercury_module_name::in) is semidet.
-
-qualified_name_is_stdlib(unqualified(_)) :- fail.
-qualified_name_is_stdlib(qualified(Module, Name)) :-
- (
- mercury_std_library_module_name(qualified(Module, Name))
- ;
- qualified_name_is_stdlib(Module)
- ).
-
% Succeeds iff this definition is a data definition which
% defines RTTI.
%
@@ -290,136 +274,6 @@ reverse_string(String0, String) :-
string.to_char_list(String0, String1),
string.from_rev_char_list(String1, String).
- % Java doesn't allow a fully-qualified class to have the same name as a
- % package. Our workaround is to name package components with trailing
- % underscores, e.g. `mammal_.primate_.chimp' where `chimp' is a class.
- % This is enabled with `package_name_mangling'.
- %
- % The packages `mercury' and `mercury.runtime' are named without
- % underscores simply because there is existing handwritten code already
- % using those names.
- %
-:- type package_name_mangling
- ---> package_name_mangling
- ; no_package_name_mangling.
-
-:- pred mangle_mlds_sym_name_for_java(sym_name::in, mlds_qual_kind::in,
- string::in, package_name_mangling::in, string::out) is det.
-
-mangle_mlds_sym_name_for_java(SymName, QualKind, QualifierOp,
- PackageNameMangling, JavaSafeName) :-
- mangle_mlds_sym_name_for_java_2(SymName, QualKind, PackageNameMangling,
- MangledSymName),
- JavaSafeName = sym_name_to_string_sep(MangledSymName, QualifierOp).
-
-:- pred mangle_mlds_sym_name_for_java_2(sym_name::in, mlds_qual_kind::in,
- package_name_mangling::in, sym_name::out) is det.
-
-mangle_mlds_sym_name_for_java_2(SymName, QualKind, PackageNameMangling,
- MangledSymName) :-
- (
- SymName = unqualified(Name),
- JavaSafeName = java_safe_name_component(QualKind, Name),
- MangledSymName = unqualified(JavaSafeName)
- ;
- SymName = qualified(ModuleName0, PlainName),
- mangle_mlds_sym_name_for_java_2(ModuleName0, module_qual,
- PackageNameMangling, MangledModuleName0),
- (
- PackageNameMangling = package_name_mangling,
- MaybeUnderscore =
should_append_underscore_for_package(ModuleName0),
- (
- MaybeUnderscore = yes,
- MangledModuleName = append_underscore_sym_name(
- MangledModuleName0)
- ;
- MaybeUnderscore = no,
- MangledModuleName = MangledModuleName0
- )
- ;
- PackageNameMangling = no_package_name_mangling,
- MangledModuleName = MangledModuleName0
- ),
- JavaSafePlainName = java_safe_name_component(QualKind, PlainName),
- MangledSymName = qualified(MangledModuleName, JavaSafePlainName)
- ).
-
-:- func java_safe_name_component(mlds_qual_kind, string) = string.
-
-java_safe_name_component(QualKind, Name) = JavaSafeName :-
- (
- QualKind = module_qual,
- FlippedName = Name
- ;
- QualKind = type_qual,
- FlippedName = flip_initial_case(Name)
- ),
- MangledName = name_mangle(FlippedName),
- JavaSafeName = valid_symbol_name(MangledName).
-
-:- func should_append_underscore_for_package(sym_name) = bool.
-
-should_append_underscore_for_package(ModuleName) = Append :-
- ( ModuleName = mercury_std_library_package_name ->
- Append = no
- ; ModuleName = mercury_runtime_package_name ->
- Append = no
- ;
- Append = yes
- ).
-
-:- func append_underscore_sym_name(sym_name) = sym_name.
-
-append_underscore_sym_name(SymName0) = SymName :-
- (
- SymName0 = unqualified(Name),
- SymName = unqualified(Name ++ "_")
- ;
- SymName0 = qualified(ModuleSymName, Name),
- SymName = qualified(ModuleSymName, Name ++ "_")
- ).
-
-java_module_name(ModuleName) = JavaModuleName :-
- QualModuleName = qualify_mercury_std_library_module_name(ModuleName),
- mangle_mlds_sym_name_for_java_2(QualModuleName, module_qual,
- package_name_mangling, JavaModuleName).
-
-%-----------------------------------------------------------------------------%
-%
-% Name mangling code to fix problem of mercury modules having the same name
-% as reserved Java words such as `char' and `int'.
-%
-
- % If the given name conficts with a reserved Java word we must add a
- % prefix to it to avoid compilation errors.
-:- func valid_symbol_name(string) = string.
-
-valid_symbol_name(SymName) = ValidSymName :-
- Prefix = "mr_",
- ( java_is_keyword(SymName) ->
- % This is a reserved Java word, add the above prefix.
- ValidSymName = Prefix ++ SymName
- ; string.append(Prefix, Suffix, SymName) ->
- % This name already contains the prefix we are adding to
- % variables to avoid conficts, so add an additional '_'.
- ValidSymName = Prefix ++ "_" ++ Suffix
- ;
- % Normal name; do nothing.
- ValidSymName = SymName
- ).
-
-:- type java_module_name == sym_name.
-
-:- func valid_module_name(java_module_name) = java_module_name.
-
-valid_module_name(unqualified(String)) = ValidModuleName :-
- ValidString = valid_symbol_name(String),
- ValidModuleName = unqualified(ValidString).
-valid_module_name(qualified(ModuleSpecifier, String)) = ValidModuleName :-
- ValidModuleSpecifier = valid_module_name(ModuleSpecifier),
- ValidString = valid_symbol_name(String),
- ValidModuleName = qualified(ValidModuleSpecifier, ValidString).
-
%-----------------------------------------------------------------------------%
%
% Code to output imports.
@@ -449,11 +303,8 @@ output_import(Import, !IO) :-
unexpected(this_file, "foreign import in Java backend")
),
SymName = mlds_module_name_to_sym_name(ImportName),
- JavaSafeSymName = valid_module_name(SymName),
- File = sym_name_to_string(JavaSafeSymName),
- % XXX Name mangling code should be put here when we start enforcing
- % Java's naming conventions.
- ClassFile = File,
+ mangle_sym_name_for_java(SymName, module_qual, ".", package_name_mangling,
+ ClassFile),
% There are issues related to using import statements and Java's naming
% conventions. To avoid these problems, we output dependencies as comments
% only. This is ok, since we always use fully qualified names anyway.
@@ -925,8 +776,8 @@ create_addr_wrapper_name(CodeAddr,
MangledClassEntityName) :-
% Create a name for this wrapper class based on the fully qualified method
% (predicate) name.
ModuleQualifierSym = mlds_module_name_to_sym_name(ModuleQualifier),
- mangle_mlds_sym_name_for_java(ModuleQualifierSym, QualKind, "__",
- no_package_name_mangling, ModuleNameStr),
+ mangle_sym_name_for_java(ModuleQualifierSym, convert_qual_kind(QualKind),
+ "__", no_package_name_mangling, ModuleNameStr),
ClassEntityName = "addrOf__" ++ ModuleNameStr ++ "__" ++ PredName,
MangledClassEntityName = name_mangle_maybe_shorten(ClassEntityName).
@@ -1039,21 +890,6 @@ generate_call_method_args([Type | Types],
Variable, Counter, Args0, Args) :-
Args1 = Args0 ++ [UnBoxedRval],
generate_call_method_args(Types, Variable, Counter + 1, Args1, Args).
-:- func mlds_module_name_to_string(mlds_module_name) = string.
-
-mlds_module_name_to_string(MldsModuleName) = ModuleNameStr :-
- ModuleName = mlds_module_name_to_sym_name(MldsModuleName),
- ModuleNameStr = symbol_name_to_string(ModuleName, "").
-
-:- func symbol_name_to_string(sym_name, string) = string.
-
-symbol_name_to_string(unqualified(SymName), SymNameStr0) = SymNameStr :-
- SymNameStr = SymNameStr0 ++ SymName.
-symbol_name_to_string(qualified(Qualifier, SymName), SymNameStr0)
- = SymNameStr :-
- SymNameStr1 = symbol_name_to_string(Qualifier, SymNameStr0),
- SymNameStr = SymNameStr1 ++ "__" ++ SymName.
-
:- func make_pred_name_string(mlds_pred_label, proc_id,
maybe(mlds_func_sequence_num)) = string.
@@ -1149,9 +985,7 @@ output_init_2(Indent, InitPred, !IO) :-
output_src_start(Indent, MercuryModuleName, Imports, ForeignDecls, Defns,
!IO) :-
- MLDSModuleName = mercury_module_name_to_mlds(MercuryModuleName),
- ModuleSymName = mlds_module_name_to_sym_name(MLDSModuleName),
- JavaSafeModuleName = valid_module_name(ModuleSymName),
+ JavaSafeModuleName = java_module_name(MercuryModuleName),
output_auto_gen_comment(MercuryModuleName, !IO),
indent_line(Indent, !IO),
io.write_string("/* :- module ", !IO),
@@ -1172,26 +1006,18 @@ output_src_start(Indent, MercuryModuleName,
Imports, ForeignDecls, Defns,
:- pred output_package_info(sym_name::in, io::di, io::uo) is det.
output_package_info(unqualified(_), !IO).
-output_package_info(qualified(Module, _), !IO) :-
+output_package_info(qualified(JavaSafeModule, _), !IO) :-
io.write_string("package ", !IO),
- mangle_mlds_sym_name_for_java(Module, module_qual, ".",
- package_name_mangling, PackageName),
+ PackageName = sym_name_to_string(JavaSafeModule),
io.write_string(PackageName, !IO),
- MaybeUnderscore = should_append_underscore_for_package(Module),
- (
- MaybeUnderscore = yes,
- io.write_string("_;\n", !IO)
- ;
- MaybeUnderscore = no,
- io.write_string(";\n", !IO)
- ).
+ io.write_string(";\n", !IO).
% Check if this module contains a `main' predicate and if it does insert
% a `main' method in the resulting Java class that calls the
% `main' predicate. Save the command line arguments in the class
% variable `args' in the class `mercury.runtime.JavaInternal'.
%
-:- pred maybe_write_main_driver(indent::in, java_module_name::in,
+:- pred maybe_write_main_driver(indent::in, sym_name::in,
list(mlds_defn)::in, io::di, io::uo) is det.
maybe_write_main_driver(Indent, JavaSafeModuleName, Defns, !IO) :-
@@ -1420,7 +1246,7 @@ output_interface(Interface, !IO) :-
Arity, _)
->
SymName = mlds_module_name_to_sym_name(ModuleQualifier),
- mangle_mlds_sym_name_for_java(SymName, QualKind, ".",
+ mangle_sym_name_for_java(SymName, convert_qual_kind(QualKind), ".",
package_name_mangling, ModuleName),
io.format("%s.%s", [s(ModuleName), s(Name)], !IO),
%
@@ -1982,7 +1808,7 @@ output_fully_qualified_thing(qual(ModuleName,
QualKind, Name), OutputFunc,
mlds_module_name_to_sym_name(ModuleName) = WholeModuleName,
% Write the package name components.
- mangle_mlds_sym_name_for_java(PackageName, module_qual, Qualifier,
+ mangle_sym_name_for_java(PackageName, module_qual, Qualifier,
package_name_mangling, MangledPackageName),
io.write_string(MangledPackageName, !IO),
@@ -1992,8 +1818,8 @@ output_fully_qualified_thing(qual(ModuleName,
QualKind, Name), OutputFunc,
true
;
remove_sym_name_prefixes(WholeModuleName, PackageName, NonPackageName),
- mangle_mlds_sym_name_for_java(NonPackageName, QualKind, Qualifier,
- no_package_name_mangling, MangledNonPackageName),
+ mangle_sym_name_for_java(NonPackageName, convert_qual_kind(QualKind),
+ Qualifier, no_package_name_mangling, MangledNonPackageName),
io.write_string(Qualifier, !IO),
io.write_string(MangledNonPackageName, !IO)
),
@@ -2018,6 +1844,11 @@ remove_sym_name_prefixes(SymName0, Prefix, SymName) :-
unexpected(this_file, "remove_sym_name_prefixes: prefix not found")
).
+:- func convert_qual_kind(mlds_qual_kind) = java_qual_kind.
+
+convert_qual_kind(module_qual) = module_qual.
+convert_qual_kind(type_qual) = type_qual.
+
:- pred output_module_name(mercury_module_name::in, io::di, io::uo) is det.
output_module_name(ModuleName, !IO) :-
@@ -3372,7 +3203,7 @@ output_mangled_name(Name, !IO) :-
output_valid_mangled_name(Name, !IO) :-
MangledName = name_mangle(Name),
- JavaSafeName = valid_symbol_name(MangledName),
+ JavaSafeName = valid_java_symbol_name(MangledName),
io.write_string(JavaSafeName, !IO).
:- pred output_call_rval(module_info::in, mlds_rval::in, mlds_module_name::in,
@@ -3734,7 +3565,7 @@
mlds_output_proc_label(mlds_proc_label(PredLabel, ProcId), !IO) :-
mlds_output_data_addr(data_addr(ModuleQualifier, DataName), !IO) :-
SymName = mlds_module_name_to_sym_name(ModuleQualifier),
- mangle_mlds_sym_name_for_java(SymName, module_qual, ".",
+ mangle_sym_name_for_java(SymName, module_qual, ".",
package_name_mangling, ModuleName),
io.write_string(ModuleName, !IO),
io.write_string(".", !IO),
diff --git a/compiler/notes/compiler_design.html
b/compiler/notes/compiler_design.html
index d16a6c1..47d6fd3 100644
--- a/compiler/notes/compiler_design.html
+++ b/compiler/notes/compiler_design.html
@@ -309,6 +309,8 @@ such as pretty-printing.
<p>
file_names.m does conversions between module names and file names.
+ It uses java_names.m, which contains predicates for dealing with names
+ of things in Java.
<p>
module_cmds.m handles the commands for manipulating interface files of
diff --git a/compiler/parse_tree.m b/compiler/parse_tree.m
index 203f901..d0f0960 100644
--- a/compiler/parse_tree.m
+++ b/compiler/parse_tree.m
@@ -68,6 +68,9 @@
:- include_module source_file_map.
:- include_module write_deps_file.
+% Java-related utilities.
+:- include_module java_names.
+
% (Note that intermod and trans_opt also contain routines that
% act on the parse tree, but those modules are considered part
% of the HLDS transformations package.)
diff --git a/library/Mmakefile b/library/Mmakefile
index cd54653..5bcc831 100644
--- a/library/Mmakefile
+++ b/library/Mmakefile
@@ -266,7 +266,7 @@ JAVAS = ` echo $($(STD_LIB_NAME).javas) | sed \
# rather than compiling them separately. This is needed because
# otherwise javac doesn't handle cyclic dependencies between different
# modules.
-classes: javas java_symlinks java_subdir_copies
+classes: javas java_symlinks
$(JAVAC) $(ALL_JAVACFLAGS) $(JAVAS)
# javac expects to find the sources for symbols named mercury.* in
@@ -280,22 +280,6 @@ java_symlinks:
[ -d mercury ] || ln -s . mercury
[ -d runtime ] || ln -s $(MERCURY_DIR)/java/runtime .
-# Mercury doesn't yet put .java files in the directory hierarchies that Java
-# expects. For now we copy a few files manually.
-.PHONY: java_subdir_copies
-java_subdir_copies:
- [ -d bit_buffer_ ] || mkdir bit_buffer_
- [ -d stream_ ] || mkdir stream_
- [ -d string_ ] || mkdir string_
- [ -d thread_ ] || mkdir thread_
- cp bit_buffer.read.java bit_buffer_/read.java
- cp bit_buffer.write.java bit_buffer_/write.java
- cp stream.string_writer.java stream_/string_writer.java
- cp string.builder.java string_/builder.java
- cp thread.channel.java thread_/channel.java
- cp thread.mvar.java thread_/mvar.java
- cp thread.semaphore.java thread_/semaphore.java
-
# Once all of the library classes have been compiled, we put them in a single
# jar file. At this point we also add the runtime classes to a jar file.
# Note that this stage makes use of the symbolic links created earlier to
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list