mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-14 13:23:53 +00:00
Estimated hours taken: 20 Various fixes to get the GCC back-end interface to bootstrap. library/exception.m: Define function versions of mercury__exception__builtin_catch_3_p_*. This is needed (a) in case we take their address, and (b) for the GCC back-end interface, where we can't use C macros, since we're compiling to assembler. browser/dl.m: browser/util.m: browser/interactive_query.m: compiler/stack_layout.m: Add #includes for header files needed by these modules. browser/dl.m: Delete an unnecessary nested extern declaration, to avoid a warning from `gcc -Wshadow'. compiler/mlds_to_gcc.m: When calling mlds_to_c to process foreign_code, make all definitions public, so that the can be used from the assembler code that we generate in mlds_to_gcc. Don't call mlds_to_c to generate `.c' and `.h' files if the module contains only `pragma foreign_decls', not `pragma foreign_code', `pragma foreign_proc', or `pragma export'. This change is needed to avoid calling mlds_to_c when intermodule optimization is enabled and `pragma c_header_code' declarations have been read in from the `.opt' file and have propagated through to the MLDS. Calling mlds_to_c when the module itself doesn't contain C code breaks things, since Mmake won't compile and link in the generated `.c' files, but those files contain the definition of the `*__init_type_tables()' functions that are referenced by `*_init.c'. XXX This is not quite right, since if the module itself contains `pragma foreign_decls', the `.h' file might be needed. But the Mercury standard library needs intermodule optimization enabled for `make install' to work. A better fix would be to ignore foreign_decls that were defined in other modules, but to call mlds_to_c for foreign_decls that were defined in the module that we're compiling. compiler/modules.m: Change the code which decides when to link in extra object files for foreign code to reflect the above change to when mlds_to_gcc.m invokes mlds_to_c.m. compiler/mlds_to_c.m: When target=asm, i.e. we're compiling to asm, but mlds_to_c.m has been invoked to generate C code for a `foreign_code', `foreign_proc', or `pragma export' declaration, don't generate #include directives for the imported modules, since we may not have generated any header file for them. XXX This is a bit of a hack; it might sometimes lead to problems, since the header files might sometimes be needed. But including them unconditionally is definitely wrong, since they may not exist, and so this change is needed to get the compiler to bootstrap. compiler/Mmakefile: Add a dependency of mercury_compile on $(GCC_BACK_END_LIBS), so that we know to relink it if the GCC back-end has changed. (That variable is set to empty if we're not linking in the GCC back-end, so it won't cause problems when not using the GCC back-end.) library/Mmakefile: browser/Mmakefile: compiler/Mmakefile: Add an `ss' target, for use by tools/bootcheck. tools/bootcheck: Add `--target asm' option. If that is set, pass `--target asm' to mmake, and build and compare the stage 3 `.s' files rather than the `.c' files. Also add `--make-opts' option, for passing options to `make'. Put `-k' in `--make-opts', not `--mmake-opts', since `-k' is an option to `make', not to `mmake'. This makes a difference since although `make' options can be passed to `mmake', any options after the first `make' option are assumed to be options to `make', not to `mmake'.
182 lines
4.9 KiB
Mathematica
182 lines
4.9 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1998-2001 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.
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module mdb__util.
|
|
|
|
:- interface.
|
|
|
|
:- import_module list, string, io.
|
|
|
|
% The stuff defined below is similar to types goal_path and trace_port
|
|
% defined in modules compiler/hlds_goal.m and compiler/trace.m.
|
|
% This enumeration must be EXACTLY the same as the MR_trace_port enum in
|
|
% runtime/mercury_trace_base.h, and in the same order, since the code
|
|
% assumes the representation is the same.
|
|
|
|
:- type trace_port_type
|
|
---> call
|
|
; exit
|
|
; redo
|
|
; fail
|
|
; exception
|
|
; ite_cond
|
|
; ite_then
|
|
; ite_else
|
|
; neg_enter
|
|
; neg_success
|
|
; neg_failure
|
|
; disj
|
|
; switch
|
|
; nondet_pragma_first
|
|
; nondet_pragma_later
|
|
.
|
|
|
|
% This enumeration must be EXACTLY the same as the MR_PredFunc enum in
|
|
% runtime/mercury_stack_layout.h, and in the same order, since the code
|
|
% assumes the representation is the same.
|
|
|
|
:- type pred_or_func
|
|
---> predicate
|
|
; function.
|
|
|
|
:- type goal_path_string == string.
|
|
|
|
% Get user input via the same method used by the internal
|
|
% debugger.
|
|
:- pred util__trace_getline(string, io__result(string), io__state,
|
|
io__state).
|
|
:- mode util__trace_getline(in, out, di, uo) is det.
|
|
|
|
:- pred util__trace_getline(string, io__result(string), io__input_stream,
|
|
io__output_stream, io__state, io__state).
|
|
:- mode util__trace_getline(in, out, in, in, di, uo) is det.
|
|
|
|
% trace_get_command is similar to trace_getline except that it
|
|
% breaks lines into semicolon separated commands, and replaces
|
|
% EOF with the command 'quit'.
|
|
:- pred util__trace_get_command(string, string, io__state, io__state).
|
|
:- mode util__trace_get_command(in, out, di, uo) is det.
|
|
|
|
:- pred util__trace_get_command(string, string, io__input_stream,
|
|
io__output_stream, io__state, io__state).
|
|
:- mode util__trace_get_command(in, out, in, in, di, uo) is det.
|
|
|
|
:- pred util__zip_with(pred(T1, T2, T3), list(T1), list(T2), list(T3)).
|
|
:- mode util__zip_with(pred(in, in, out) is det, in, in, out) is det.
|
|
|
|
% Apply predicate to argument repeatedly until the result
|
|
% remains the same.
|
|
:- pred util__limit(pred(list(T), list(T)), list(T), list(T)).
|
|
:- mode util__limit(pred(in,out) is det, in, out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- implementation.
|
|
|
|
:- import_module int, require.
|
|
|
|
util__trace_getline(Prompt, Result) -->
|
|
io__input_stream(MdbIn),
|
|
io__output_stream(MdbOut),
|
|
util__trace_getline(Prompt, Result, MdbIn, MdbOut).
|
|
|
|
:- pragma promise_pure(util__trace_getline/6).
|
|
|
|
util__trace_getline(Prompt, Result, MdbIn, MdbOut) -->
|
|
{
|
|
impure call_trace_getline(MdbIn, MdbOut, Prompt, Line)
|
|
->
|
|
Result = ok(Line)
|
|
;
|
|
Result = eof
|
|
}.
|
|
|
|
:- impure pred call_trace_getline(input_stream, output_stream, string, string).
|
|
:- mode call_trace_getline(in, in, in, out) is semidet.
|
|
|
|
:- pragma c_header_code("
|
|
#include ""mercury_wrapper.h""
|
|
#include ""mercury_string.h""
|
|
#include ""mercury_trace_base.h""
|
|
#include ""mercury_trace_internal.h""
|
|
#include ""mercury_library_types.h""
|
|
").
|
|
|
|
:- pragma c_code(call_trace_getline(MdbIn::in, MdbOut::in, Prompt::in,
|
|
Line::out),
|
|
[will_not_call_mercury],
|
|
"
|
|
char *line;
|
|
MercuryFile *mdb_in = (MercuryFile *) MdbIn;
|
|
MercuryFile *mdb_out = (MercuryFile *) MdbOut;
|
|
|
|
if (MR_address_of_trace_getline != NULL) {
|
|
line = (*MR_address_of_trace_getline)((char *) Prompt,
|
|
MR_file(*mdb_in), MR_file(*mdb_out));
|
|
} else {
|
|
MR_tracing_not_enabled();
|
|
/* not reached */
|
|
}
|
|
|
|
if (line == NULL) {
|
|
SUCCESS_INDICATOR = FALSE;
|
|
} else {
|
|
MR_make_aligned_string_copy(Line, line);
|
|
MR_free(line);
|
|
SUCCESS_INDICATOR = TRUE;
|
|
}
|
|
"
|
|
).
|
|
|
|
util__trace_get_command(Prompt, Result) -->
|
|
io__input_stream(MdbIn),
|
|
io__output_stream(MdbOut),
|
|
util__trace_get_command(Prompt, Result, MdbIn, MdbOut).
|
|
|
|
:- pragma c_code(util__trace_get_command(Prompt::in, Line::out, MdbIn::in,
|
|
MdbOut::in, State0::di, State::uo),
|
|
[will_not_call_mercury],
|
|
"
|
|
char *line;
|
|
MercuryFile *mdb_in = (MercuryFile *) MdbIn;
|
|
MercuryFile *mdb_out = (MercuryFile *) MdbOut;
|
|
|
|
if (MR_address_of_trace_getline != NULL) {
|
|
line = (*MR_address_of_trace_get_command)(
|
|
(char *) Prompt,
|
|
MR_file(*mdb_in), MR_file(*mdb_out));
|
|
} else {
|
|
MR_tracing_not_enabled();
|
|
/* not reached */
|
|
}
|
|
|
|
MR_make_aligned_string_copy(Line, line);
|
|
MR_free(line);
|
|
|
|
State = State0;
|
|
"
|
|
).
|
|
|
|
util__zip_with(Pred, XXs, YYs, Zipped) :-
|
|
( (XXs = [], YYs = []) ->
|
|
Zipped = []
|
|
; (XXs = [X|Xs], YYs = [Y|Ys]) ->
|
|
Pred(X,Y,PXY),
|
|
Zipped = [PXY|Rest],
|
|
util__zip_with(Pred, Xs, Ys, Rest)
|
|
;
|
|
error("zip_with: list arguments are of unequal length")
|
|
).
|
|
|
|
util__limit(Pred, Xs, Ys) :-
|
|
Pred(Xs, Zs),
|
|
( Xs = Zs ->
|
|
Ys = Zs
|
|
;
|
|
util__limit(Pred, Zs, Ys)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|