[m-rev.] diff: removing more bad dependencies
Zoltan Somogyi
zs at cs.mu.OZ.AU
Sun Mar 16 20:27:43 AEDT 2003
On 16-Mar-2003, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> > % XXX should avoid dependency on trace.m here
> > - { trace__path_to_string(Path, PathStr) },
> > + { goal_path_to_string(Path, PathStr) },
>
> The XXX comment there can be deleted now.
Done.
> I think it is better if all of the dependencies between subsystems are listed
> explicitly in the source for the top-level module for each subsystem.
> For example, I think it should be clear from compiler/ml_backend.m
> that this backend depends on the ll_backend.
>
> So if the import of ll_backend is removed from compiler/ml_backend.m,
> I think it would be best to at least keep an XXX comment in that file
> explaining that ll_backend is needed by ml_closure_gen.m.
Done.
> Also, could you please post the source for the newly added module
> backend_libs__name_mangle?
Sorry. Here it is.
Zoltan.
%-----------------------------------------------------------------------------%
% Copyright (C) 2003 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: name_mangle.m
% This module defines routines for generating and/or outputing identifiers
% for modules, predicates/functions, and procedures in forms that are
% syntactically acceptable in all our target languages, meaning C, Java
% and MSIL.
% Warning: any changes to the name mangling algorithms implemented in this
% module will also require changes to extras/dynamic_linking/name_mangle.m,
% profiler/demangle.m and util/mdemangle.c.
%-----------------------------------------------------------------------------%
:- module backend_libs__name_mangle.
:- interface.
:- import_module backend_libs__proc_label.
:- import_module hlds__hlds_data.
:- import_module parse_tree__prog_data.
:- import_module io, bool, string.
% Output a proc label (used for building static call graph for prof).
:- pred output_proc_label(proc_label::in, io__state::di, io__state::uo) is det.
% Get a proc label string (used by procs which are exported to C).
% The boolean controls whether label_prefix is added to the string.
:- func proc_label_to_c_string(proc_label, bool) = string.
% Mangle an arbitrary name into a C etc identifier
:- func name_mangle(string) = string.
% Mangle a possibly module-qualified Mercury symbol name
% into a C identifier.
:- func sym_name_mangle(sym_name) = string.
% Produces a string of the form Module__Name.
:- func qualify_name(string, string) = string.
% Create a name for base_typeclass_info.
:- func make_base_typeclass_info_name(class_id, string) = string.
% Output the name for base_typeclass_info,
% with the appropriate mercury_data_prefix.
:- pred output_base_typeclass_info_name(class_id::in, string::in,
io__state::di, io__state::uo) is det.
% Prints the name of the initialization function
% for a given module.
:- pred output_init_name(module_name::in, io__state::di, io__state::uo) is det.
% Returns the name of the initialization function
% for a given module.
:- func make_init_name(module_name) = string.
% Returns the name of the Aditi-RL code constant
% for a given module.
:- func make_rl_data_name(module_name) = string.
% Print out the name of the tabling variable for the specified
% procedure.
:- pred output_tabling_pointer_var_name(proc_label::in,
io__state::di, io__state::uo) is det.
% To ensure that Mercury labels don't clash with C symbols, we
% prefix them with `mercury__'.
:- func mercury_label_prefix = string.
% All the C data structures we generate which are either fully static
% or static after initialization should have this prefix, to ensure
% that Mercury global variables don't clash with C symbols.
:- func mercury_data_prefix = string.
:- implementation.
:- import_module hlds__hlds_pred.
:- import_module parse_tree__prog_util.
:- import_module char, int, list, std_util.
%-----------------------------------------------------------------------------%
output_proc_label(ProcLabel, !IO) :-
ProcLabelString = proc_label_to_c_string(ProcLabel, yes),
io__write_string(ProcLabelString, !IO).
proc_label_to_c_string(proc(DefiningModule, PredOrFunc, PredModule,
PredName, Arity, ModeNum0), AddPrefix) = ProcLabelString :-
LabelName = make_pred_or_func_name(DefiningModule, PredOrFunc,
PredModule, PredName, Arity, AddPrefix),
( PredOrFunc = function ->
OrigArity = Arity - 1
;
OrigArity = Arity
),
string__int_to_string(OrigArity, ArityString),
proc_id_to_int(ModeNum0, ModeInt),
string__int_to_string(ModeInt, ModeNumString),
string__append_list([LabelName, "_", ArityString, "_", ModeNumString],
ProcLabelString).
% For a special proc, output a label of the form:
% mercury____<PredName>___<TypeModule>__<TypeName>_<TypeArity>_<Mode>
proc_label_to_c_string(special_proc(Module, PredName, TypeModule,
TypeName, TypeArity, ModeNum0), AddPrefix) = ProcLabelString :-
% figure out the LabelName
DummyArity = -1, % not used by make_pred_or_func_name.
LabelName = make_pred_or_func_name(unqualified(""), predicate,
unqualified(""), PredName, DummyArity, AddPrefix),
% figure out the ModeNumString
string__int_to_string(TypeArity, TypeArityString),
proc_id_to_int(ModeNum0, ModeInt),
string__int_to_string(ModeInt, ModeNumString),
% mangle all the relevent names
MangledModule = sym_name_mangle(Module),
MangledTypeModule = sym_name_mangle(TypeModule),
MangledTypeName = name_mangle(TypeName),
% Module-qualify the type name.
% To handle locally produced unification preds for imported types,
% we need to qualify it with both the module name of the
% type, and also (if it is different) the module name of the
% current module.
QualifiedMangledTypeName = qualify_name(MangledTypeModule,
MangledTypeName),
FullyQualifiedMangledTypeName = maybe_qualify_name(MangledModule,
QualifiedMangledTypeName),
% join it all together
string__append_list( [LabelName, "_", FullyQualifiedMangledTypeName,
"_", TypeArityString, "_", ModeNumString],
ProcLabelString).
% Make a name identifying a predicate or a function, given the
% defining module, predicate or function indicator, declaring module,
% predicate name, arity, and whether or not to add the
% mercury_label_prefix.
:- func make_pred_or_func_name(module_name, pred_or_func, module_name, string,
arity, bool) = string.
%
% Warning: any changes to the name mangling algorithm here will also
% require changes to extras/dynamic_linking/name_mangle.m,
% profiler/demangle.m and util/mdemangle.c.
%
make_pred_or_func_name(DefiningModule, PredOrFunc, DeclaringModule,
Name0, Arity, AddPrefix) = LabelName :-
DeclaringModuleName = sym_name_mangle(DeclaringModule),
DefiningModuleName = sym_name_mangle(DefiningModule),
(
(
mercury_private_builtin_module(DeclaringModule)
;
mercury_public_builtin_module(DeclaringModule)
;
Name0 = "main",
Arity = 2
;
string__prefix(Name0, "__")
)
% The conditions above define which labels are printed without
% module qualification. XXX Changes to runtime/* are necessary
% to allow `builtin' or `private_builtin' labels to be
% qualified.
->
LabelName0 = Name0
;
LabelName0 = qualify_name(DeclaringModuleName, Name0)
),
(
% if this is a specialized version of a predicate
% defined in some other module, then it needs both
% module prefixes
DefiningModule \= DeclaringModule
->
string__append_list([DefiningModuleName, "__", LabelName0],
LabelName1)
;
LabelName1 = LabelName0
),
LabelName2 = name_mangle(LabelName1),
(
PredOrFunc = function,
string__append("fn__", LabelName2, LabelName3)
;
PredOrFunc = predicate,
LabelName3 = LabelName2
),
(
AddPrefix = yes
->
string__append(mercury_label_prefix, LabelName3, LabelName)
;
LabelName = LabelName3
).
%
% Warning: any changes to the name mangling algorithm here will also
% require changes to extras/dynamic_linking/name_mangle.m,
% profiler/demangle.m and util/mdemangle.c.
%
sym_name_mangle(unqualified(Name)) =
name_mangle(Name).
sym_name_mangle(qualified(ModuleName, PlainName)) = MangledName :-
MangledModuleName = sym_name_mangle(ModuleName),
MangledPlainName = name_mangle(PlainName),
MangledName = qualify_name(MangledModuleName, MangledPlainName).
% Convert a Mercury predicate name into something that can form
% part of a C identifier. This predicate is necessary because
% quoted names such as 'name with embedded spaces' are valid
% predicate names in Mercury.
name_mangle(Name) = MangledName :-
( string__is_alnum_or_underscore(Name) ->
% any names that start with `f_' are changed so that
% they start with `f__', so that we can use names starting
% with `f_' (followed by anything except an underscore)
% without fear of name collisions
( string__append("f_", Suffix, Name) ->
string__append("f__", Suffix, MangledName)
;
MangledName = Name
)
;
MangledName = convert_to_valid_c_identifier(Name)
).
:- func convert_to_valid_c_identifier(string) = string.
convert_to_valid_c_identifier(String) = Name :-
( name_conversion_table(String, Name0) ->
Name = Name0
;
Name0 = convert_to_valid_c_identifier_2(String),
string__append("f", Name0, Name)
).
qualify_name(Module0, Name0) = Name :-
string__append_list([Module0, "__", Name0], Name).
% Produces a string of the form Module__Name, unless Module__
% is already a prefix of Name.
:- func maybe_qualify_name(string, string) = string.
maybe_qualify_name(Module0, Name0) = Name :-
string__append(Module0, "__", UnderscoresModule),
( string__append(UnderscoresModule, _, Name0) ->
Name = Name0
;
string__append(UnderscoresModule, Name0, Name)
).
% A table used to convert Mercury functors into
% C identifiers. Feel free to add any new translations you want.
% The C identifiers should start with "f_",
% to avoid introducing name clashes.
% If the functor name is not found in the table, then
% we use a fall-back method which produces ugly names.
:- pred name_conversion_table(string, string).
:- mode name_conversion_table(in, out) is semidet.
name_conversion_table("\\=", "f_not_equal").
name_conversion_table(">=", "f_greater_or_equal").
name_conversion_table("=<", "f_less_or_equal").
name_conversion_table("=", "f_equal").
name_conversion_table("<", "f_less_than").
name_conversion_table(">", "f_greater_than").
name_conversion_table("-", "f_minus").
name_conversion_table("+", "f_plus").
name_conversion_table("*", "f_times").
name_conversion_table("/", "f_slash").
name_conversion_table(",", "f_comma").
name_conversion_table(";", "f_semicolon").
name_conversion_table("!", "f_cut").
name_conversion_table("{}", "f_tuple").
name_conversion_table("[|]", "f_cons").
name_conversion_table("[]", "f_nil").
% This is the fall-back method.
% Given a string, produce a C identifier
% for that string by concatenating the decimal
% expansions of the character codes in the string,
% separated by undellines.
% The C identifier will start with "f_"; this predicate
% constructs everything except the initial "f".
%
% For example, given the input "\n\t" we return "_10_8".
:- func convert_to_valid_c_identifier_2(string) = string.
convert_to_valid_c_identifier_2(String) = Name :-
( string__first_char(String, Char, Rest) ->
% XXX This will cause ABI incompatibilities between
% compilers which are built in grades that have
% different character representations.
char__to_int(Char, Code),
string__int_to_string(Code, CodeString),
string__append("_", CodeString, ThisCharString),
Name0 = convert_to_valid_c_identifier_2(Rest),
string__append(ThisCharString, Name0, Name)
;
% String is the empty string
Name = String
).
%-----------------------------------------------------------------------------%
output_base_typeclass_info_name(ClassId, TypeNames, !IO) :-
Str = make_base_typeclass_info_name(ClassId, TypeNames),
io__write_string(mercury_data_prefix, !IO),
io__write_string("__", !IO),
io__write_string(Str, !IO).
make_base_typeclass_info_name(class_id(ClassSym, ClassArity), TypeNames)
= Str :-
MangledClassString = sym_name_mangle(ClassSym),
string__int_to_string(ClassArity, ArityString),
MangledTypeNames = name_mangle(TypeNames),
string__append_list(["base_typeclass_info_", MangledClassString,
"__arity", ArityString, "__", MangledTypeNames], Str).
%-----------------------------------------------------------------------------%
output_init_name(ModuleName, !IO) :-
InitName = make_init_name(ModuleName),
io__write_string(InitName, !IO).
make_init_name(ModuleName) = InitName :-
MangledModuleName = sym_name_mangle(ModuleName),
string__append_list(["mercury__", MangledModuleName, "__"], InitName).
make_rl_data_name(ModuleName) = RLDataConstName :-
MangledModuleName = sym_name_mangle(ModuleName),
string__append("mercury__aditi_rl_data__", MangledModuleName,
RLDataConstName).
output_tabling_pointer_var_name(ProcLabel, !IO) :-
io__write_string("mercury_var__table_root__", !IO),
output_proc_label(ProcLabel, !IO).
%-----------------------------------------------------------------------------%
mercury_label_prefix = "mercury__".
mercury_data_prefix = "mercury_data_".
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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