Files
mercury/browser/name_mangle.m
Fergus Henderson f1d1041d08 Add support for invoking interactive queries to mdb.
Estimated hours taken: 17

Add support for invoking interactive queries to mdb.

browser/interactive_query.m:
	New module, to implement interactive queries.

browser/dl.m:
browser/name_mangle.m:
	Copy these files from extras/dynamic_linking, since
	they are needed by browser/interactive_query.m.

configure.in:
runtime/mercury_conf.h.in:
	Autodetect the presence of support for dlopen() etc.

browser/dl.m:
	Add #ifdefs so that the code will compile (but report
	an error at runtime) if dlopen() etc. are not supported.

browser/browser_library.m:
	Add interface_query, dl, and name_mangle to the list of
	modules in this library.

trace/mercury_trace_browse.h:
trace/mercury_trace_browse.c:
	Add a new function MR_trace_query() to interface to the ML_query()
	function defined by browser/interfactive_query.m.

trace/mercury_trace_internal.c:
	Add code to implement new commands `query', `cc_query', `io_query',
	and `mmc_options', using the MR_trace_query() function defined by
	trace/mercury_trace_browse.h.

runtime/mercury_grade.h:
	Add code to define MR_GRADE_OPT, so that browser/interactive_query.m
	can use this to invoke mmc with the same grade that the executable
	being debugged was built with.

doc/mdb_categories:
doc/user_guide.texi:
	Document the new commands `query', `cc_query', `io_query',
	and `mmc_options'.
1999-03-05 12:52:34 +00:00

225 lines
6.9 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1998 The University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%-----------------------------------------------------------------------------%
% File: name_mangle.m.
% Purpose: name mangling support.
% Main author: fjh.
% Stability: low.
% This module provides the proc_name_mangle/1 function, which takes a value of
% type `mercury_proc' and returns a string which is the symbol name for
% specified procedure, and which is suitable for use in a call to dl__sym.
%
% The details of name mangling are implementation-dependent, so unfortunately
% the values stored in the `mercury_proc' type might be subject to change
% in different Mercury implementations. Any code which creates or
% examines values of that type should be carefully isolated so that
% it can be easily changed if the representation of `mercury_proc' changes.
%-----------------------------------------------------------------------------%
:- module name_mangle.
:- interface.
% Given a mercury_proc specifying the module name,
% predicate or function indicator, predicate name, arity,
% and mode number of a Mercury procedure,
% return the label name of that procedure.
% The label name returned is suitable for passing to dl__sym.
%
:- func proc_name_mangle(mercury_proc) = string.
:- type mercury_proc --->
mercury_proc(is_pred_or_func, module_name, pred_name, arity, mode_num).
:- type is_pred_or_func
---> predicate
; function.
:- type module_name == sym_name.
:- type sym_name
---> qualified(sym_name, string)
; unqualified(string).
:- type pred_name == string.
:- type arity == int.
:- type mode_num == int. % mode numbers start from zero
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module string, char, int, list.
% XXX most of the code below is very similar to the code in
% compiler/llds_out.m. Any changes there may require changes here
% and vice versa.
%-----------------------------------------------------------------------------%
proc_name_mangle(MercuryProc) = LabelName :-
MercuryProc = mercury_proc(PredOrFunc, Module, Name0, Arity, ModeNum),
sym_name_mangle(Module, ModuleName),
(
(
Module = unqualified("builtin")
;
Name0 = "main",
Arity = 2
)
% The conditions above define which labels are printed without
% module qualification.
->
LabelName0 = Name0
;
qualify_name(ModuleName, Name0, LabelName0)
),
name_mangle(LabelName0, LabelName1),
( PredOrFunc = function ->
OrigArity is Arity - 1
;
OrigArity = Arity
),
string__int_to_string(OrigArity, ArityString),
string__int_to_string(ModeNum, ModeNumString),
string__append_list([LabelName1, "_", ArityString, "_", ModeNumString],
LabelName2),
(
PredOrFunc = function,
string__append("fn__", LabelName2, LabelName3)
;
PredOrFunc = predicate,
LabelName3 = LabelName2
),
string__append("mercury__", LabelName3, LabelName4),
( use_asm_labels ->
string__append("_entry_", LabelName4, LabelName)
;
LabelName = LabelName4
).
:- pred sym_name_mangle(sym_name, string).
:- mode sym_name_mangle(in, out) is det.
sym_name_mangle(unqualified(Name), MangledName) :-
name_mangle(Name, MangledName).
sym_name_mangle(qualified(ModuleName, PlainName), MangledName) :-
sym_name_mangle(ModuleName, MangledModuleName),
name_mangle(PlainName, MangledPlainName),
qualify_name(MangledModuleName, MangledPlainName,
MangledName).
% 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.
:- pred name_mangle(string, string).
:- mode name_mangle(in, out) is det.
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
)
;
convert_to_valid_c_identifier(Name, MangledName)
).
:- pred convert_to_valid_c_identifier(string, string).
:- mode convert_to_valid_c_identifier(in, out) is det.
convert_to_valid_c_identifier(String, Name) :-
(
name_conversion_table(String, Name0)
->
Name = Name0
;
convert_to_valid_c_identifier_2(String, Name0),
string__append("f", Name0, Name)
).
:- pred qualify_name(string, string, string).
:- mode qualify_name(in, in, out) is det.
qualify_name(Module0, Name0, Name) :-
string__append_list([Module0, "__", 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").
% 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 underlines.
% 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".
:- pred convert_to_valid_c_identifier_2(string, string).
:- mode convert_to_valid_c_identifier_2(in, out) is det.
convert_to_valid_c_identifier_2(String, Name) :-
(
string__first_char(String, Char, Rest)
->
char__to_int(Char, Code),
string__int_to_string(Code, CodeString),
string__append("_", CodeString, ThisCharString),
convert_to_valid_c_identifier_2(Rest, Name0),
string__append(ThisCharString, Name0, Name)
;
% String is the empty string
Name = String
).
:- pred use_asm_labels is semidet.
:- pragma c_code(use_asm_labels, [will_not_call_mercury, thread_safe], "
#ifdef USE_ASM_LABELS
SUCCESS_INDICATOR = TRUE;
#else
SUCCESS_INDICATOR = FALSE;
#endif
").
%-----------------------------------------------------------------------------%