for review: changes to termination analysis and stack tracing [1/3]
Fergus Henderson
fjh at cs.mu.oz.au
Tue Dec 9 21:15:53 AEDT 1997
On 02-Dec-1997, Zoltan Somogyi <zs at cs.mu.oz.au> wrote:
>
> % term_errors.m
> :- type termination_error
...
> ; no_eqns
Please document the meaning of `no_eqns'.
> % An error is considered a simple error if it is likely that the error is
> % caused by the analysis failing, instead of being due to a programming
> % error. XXX this is not how it is used
> :- pred simple_error(term_errors__termination_error).
> :- mode simple_error(in) is semidet.
...
> simple_error(horder_call).
> simple_error(pragma_c_code).
> simple_error(imported_pred).
> simple_error(can_loop_proc_called(_, _)).
> simple_error(horder_args(_, _)).
> simple_error(does_not_term_pragma(_)).
Hmm, why should `does_not_term_pragma' and `can_loop_proc_called'
be considered simple errors?
> term_errors__output_same_SCC(PredId, Module, Context, ForHLDSDump) -->
> io__write_string("it is in the same SCC as the\n"),
> maybe_write_string(ForHLDSDump, "% "),
> prog_out__write_context(Context),
> io__write_string(" "),
> hlds_out__write_pred_id(Module, PredId).
If that message is supposed to be something that users will see,
I think you should spell out "SCC".
> term_errors__report_term_errors(SCC, Errors, Module) -->
> { get_context_from_scc(SCC, Module, Context) },
> ( { SCC = [PPId] } ->
> { Pieces0 = ["Termination", "of"] },
> { term_errors__describe_one_proc_name(PPId, Module, PredName) },
> { list__append(Pieces0, [PredName], Pieces1) },
It would be simpler to just write
{ term_errors__describe_one_proc_name(PPId, Module, PredName) },
{ Pieces1 = ["Termination", "of", PredName] },
instead of calling list__append.
> { Pieces2 = ["set", "to", "infinity", "the",
> "following", "reason:"] },
...
> { Pieces2 = ["set", "to", "infinity", "the",
> "following", "reasons:"] },
Is there a "for" missing?
("Set to infinity _for_ the following reason"?)
> term_errors__description(pragma_c_code, _, _, Pieces, no) :-
> Pieces = ["It", "contains", "a", "pragma", "c_code()", "declaration."].
Please change that to
Pieces = ["It", "contains", "a", "`pragma c_code'", "declaration."].
> term_errors__description(imported_pred, _, _, Pieces, no) :-
> Pieces = ["it", "contains", "imported", "code."].
Is "It contains imported code" correct? Would it be better
to say "It contains a call to an imported procedure"?
Also, I suggest "code imported from another module" instead of
"imported code".
> term_errors__description(horder_args(CallerPPId, CalleePPId), Single, Module,
> Pieces, no) :-
> (
> Single = yes(PPId),
> require(unify(PPId, CallerPPId), "caller outside this SCC"),
> Piece1 = "It"
> ;
> Single = no,
> term_errors__describe_one_proc_name(CallerPPId, Module, Piece1)
> ),
> Piece2 = "calls",
> term_errors__describe_one_proc_name(CalleePPId, Module, CalleePiece),
> Pieces3 = ["with", "some", "higher", "order", "arguments."],
> Pieces = [Piece1, Piece2, CalleePiece | Pieces3].
How about `"one", "or", "more"' instead of `"some"'?
> term_errors__description(cycle(_StartPPId, CallSites), _, Module, Pieces, no) :-
> ( CallSites = [DirectCall] ->
> term_errors__describe_one_call_site(DirectCall, Module, Site),
> Pieces = ["At", "the", "recursive", "call", "at", Site,
> "the", "arguments", "are", "not", "guaranteed",
> "to", "decrease", "in", "size."]
> ;
> Pieces1 = ["in", "the", "recursive", "cycle",
> "through", "the", "calls", "at"],
s/"in"/"In"/
> term_errors__description(no_eqns, _, _, Pieces, no) :-
> Pieces = ["The", "analysis", "was", "unable", "to", "form", "any",
> "constraints", "between", "the", "arguments", "of", "the",
> "procedures", "in", "this", "SCC."].
I think you should spell out SCC.
> :- pred term_errors__describe_one_pred_name(pred_id::in, module_info::in,
> string::out) is det.
>
> term_errors__describe_one_pred_name(PredId, Module, Piece) :-
> module_info_pred_info(Module, PredId, PredInfo),
> pred_info_module(PredInfo, ModuleName),
> pred_info_name(PredInfo, PredName),
> pred_info_arity(PredInfo, Arity),
> pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
> (
> PredOrFunc = predicate,
> PredOrFuncPart = "predicate ",
> OrigArity = Arity
> ;
> PredOrFunc = function,
> PredOrFuncPart = "function ",
> OrigArity is Arity - 1
> ),
> string__int_to_string(OrigArity, ArityPart),
> string__append_list([
> PredOrFuncPart,
> ModuleName,
> ":",
> PredName,
> "/",
> ArityPart
> ], Piece).
>
> :- pred term_errors__describe_one_proc_name(pred_proc_id::in, module_info::in,
> string::out) is det.
>
> term_errors__describe_one_proc_name(proc(PredId, ProcId), Module, Piece) :-
> module_info_pred_info(Module, PredId, PredInfo),
> pred_info_module(PredInfo, ModuleName),
> pred_info_name(PredInfo, PredName),
> pred_info_arity(PredInfo, Arity),
> pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
> (
> PredOrFunc = predicate,
> PredOrFuncPart = "predicate ",
> OrigArity = Arity
> ;
> PredOrFunc = function,
> PredOrFuncPart = "function ",
> OrigArity is Arity - 1
> ),
> string__int_to_string(OrigArity, ArityPart),
> proc_id_to_int(ProcId, ProcIdInt),
> string__int_to_string(ProcIdInt, ProcIdPart),
> string__append_list([
> PredOrFuncPart,
> ModuleName,
> ":",
> PredName,
> "/",
> ArityPart,
> " mode ",
> ProcIdPart
> ], Piece).
I detect some code duplication here.
`describe_one_proc_name' could be implemented by calling
`describe_one_pred_name'.
As well as the duplication between the above two predicates,
they also duplicate code in hlds_out__write_pre_id. If you can't
figure out how to avoid the duplication, then you should at least
include a comment in both places saying that if you change one
part then you will need to change the other.
Peter Schachte has in fact recently committed a change to
hlds_out__write_pred_id which is not reflected in your code
above, but which should be. He changed it to print out
reasonable names for special predicates (unification, compare/3,
index), e.g. for errors in user-defined equality predicates.
> :- pred term_errors__describe_one_call_site(pair(pred_proc_id,
> term__context)::in, module_info::in, string::out) is det.
>
> term_errors__describe_one_call_site(PPId - Context, Module, Piece) :-
> term_errors__describe_one_proc_name(PPId, Module, ProcName),
> Context = term__context(FileName, LineNumber),
> string__int_to_string(LineNumber, LineNumberPart),
> string__append_list([
> ProcName,
> " at ",
> FileName,
> ":",
> LineNumberPart
> ], Piece).
Term contexts should always be printed in the left-hand margin,
so that tools like `emacs' and `error' can parse them.
... to be continued.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list