mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-24 13:53:54 +00:00
doc/reference_manual.texi:
NEWS:
Document and announce the new pragma.
compiler/prog_data_pragma.m:
compiler/prog_item.m:
Provide a representation for the new pragma. The part that ends up
being referred to from the HLDS goes into prog_data_pragma.m,
the part that is not needed once the HLDS has been constructed
goes into prog_item.m.
compiler/hlds_pred.m:
Add a slot to pred_infos for info from the new pragma.
Fix a bug in the comment on marker_has_format_call.
compiler/add_pragma.m:
Add the information in these pragmas to the HLDS.
compiler/check_pragma_format_call.m:
A new module to check the validity of format_call pragmas.
These checks test whether the arguments named in such pragmas
have the expected types and modes, which means that
the check must be done after both type and mode checking.
compiler/check_hlds.m:
compiler/notes/compiler_design.html:
Add and document the new module.
compiler/hlds_module.m:
Add a field to the module_info that records the set of pred_ids
that have format_call pragmas.
compiler/mercury_compile_front_end.m:
Invoke the check_pragma_format_call pass *provided* that
the new field in the module_info says it has any pragmas to check.
compiler/parse_pragma.m:
Add code to parse the new pragma.
compiler/format_call.m:
Check calls to predicates and functions with the new pragma
the same way as we check calls to string.format, io.format,
and stream.string_writer.format.
This required separating the code that checked calls to such predicates
from the code that optimized calls to such predicates, since
- a predicate or function with a format_call pragma that specifies
more than one argument pair has to have its correctness checked
for each pair, and
- a predicate or function with a format_call pragma does not actually
do any formatting, so that formatting cannot be optimized.
Fix an old bug, where we included the function result in the function's
reported arity, which meant that an error message could mention a call
to a nonexistent function. As part of that fix, the error message
now specifies whether it is complaining about a call to a predicate
or a function.
Change the exported interface of this module a bit
in order to allow the factoring out of repeated code.
compiler/parse_string_format.m:
Separate the parsing of format strings from their optimization,
again because calls to predicates and functions with format_call
pragmas need to be checked but cannot be optimized.
compiler/polymorphism.m:
Record the effect on argument numbers of any type_info and/or
typeclass_info arguments added by this pass.
compiler/convert_parse_tree.m:
compiler/det_analysis.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/hlds_out_pred.m:
compiler/item_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/prog_item_stats.m:
compiler/recompilation.version.m:
compiler/simplify_proc.m:
Conform to the changes above.
tests/invalid/bad_format_call.{m,err_exp}:
A new test case to see whether check_pragma_format_call.m detects
and reports invalid format_call pragmas as expected.
tests/warnings/format_call_warning.{m,exp}:
tests/warnings/format_call_warning_helper.m:
A new test case to see whether we generate the expected set of error
messages for incorrect calls to a predicate with a format_call pragma.
tests/invalid/Mmakefile:
tests/warnings/Mercury.options:
tests/warnings/Mmakefile:
Enable the new test cases.
tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
tests/warnings/disabled_warning.exp:
Expect the predicate vs function distinction to the printed in
error messages about bad calls to formatting predicates and functions.
101 lines
3.5 KiB
Mathematica
101 lines
3.5 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module format_call_warning.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module format_call_warning_helper.
|
|
|
|
:- import_module int.
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
main(!IO) :-
|
|
CurLevel = 6,
|
|
Msg = "The record temperature is",
|
|
TempA = 42.3,
|
|
TempB = 43.2,
|
|
|
|
% This call should get warnings for all four fs/vl pairs.
|
|
maybe_log_msg(CurLevel, 1,
|
|
"%%s: 5.2f", [f(TempA)], [f(TempB)],
|
|
"%5.2f", [s(Msg), f(TempA)], [s(Msg), f(TempB)], !IO),
|
|
|
|
% This call should get a warning for only the second fs/vl pair.
|
|
maybe_log_msg(CurLevel, 1,
|
|
"%5.2f", [f(TempA)], [f(TempB), s(Msg)],
|
|
"%s: %5.2f", [s(Msg), f(TempA)], [s(Msg), f(TempB)], !IO),
|
|
|
|
% This call should not get any warnings.
|
|
maybe_log_msg(CurLevel, 1,
|
|
"%5.2f", [f(TempA)], [f(TempB)],
|
|
"%s: %5.2f", [s(Msg), f(TempA)], [s(Msg), f(TempB)], !IO),
|
|
|
|
% This call should get a warning.
|
|
maybe_log_simple_msg(CurLevel, 1, "%s: %5.2f", [s(Msg), s(Msg)], !IO),
|
|
|
|
% This call should get a warning.
|
|
maybe_log_imported_msg(CurLevel, 1, "%s: %5.2f",
|
|
[f(TempA), f(TempB)], !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred maybe_log_msg(int::in, int::in,
|
|
string::in, list(poly_type)::in, list(poly_type)::in,
|
|
string::in, list(poly_type)::in, list(poly_type)::in,
|
|
io::di, io::uo) is det.
|
|
:- pragma format_call(pred(maybe_log_msg/10),
|
|
[format_string_values(3, 4), format_string_values(3, 5),
|
|
format_string_values(6, 7), format_string_values(6, 8)]).
|
|
|
|
maybe_log_msg(CurLogLevel, MsgLevel,
|
|
FormatStrA, ValuesListA1, ValuesListA2,
|
|
FormatStrB, ValuesListB1, ValuesListB2, !IO) :-
|
|
Diff = MsgLevel - CurLogLevel,
|
|
% The first four calls to io.format below use <format string/values list>
|
|
% pairs that are listed in the format_call pragma. This means that
|
|
% callers of maybe_log_msg should have checked their compatibility,
|
|
% which means that we *don't* want to warn about being unable to check
|
|
% their compatibility *here*.
|
|
( if Diff >= 15 then
|
|
io.format(FormatStrA, ValuesListA1, !IO)
|
|
else if Diff >= 10 then
|
|
io.format(FormatStrA, ValuesListA2, !IO)
|
|
else if Diff >= 5 then
|
|
io.format(FormatStrB, ValuesListB1, !IO)
|
|
else if Diff >= 0 then
|
|
io.format(FormatStrB, ValuesListB2, !IO)
|
|
else
|
|
% While ValuesListB2 is listed in the format_call pragma, the
|
|
% format string does not come from there. Therefore the compiler
|
|
% *should* generate a warning about being unable to check this call
|
|
% due to having no idea about the value of ValuesListB2.
|
|
io.format("%d", ValuesListB2, !IO)
|
|
).
|
|
|
|
:- pred maybe_log_simple_msg(int::in, int::in,
|
|
string::in, list(poly_type)::in, io::di, io::uo) is det.
|
|
:- pragma format_call(pred(maybe_log_simple_msg/6),
|
|
format_string_values(3, 4)).
|
|
|
|
maybe_log_simple_msg(CurLogLevel, MsgLevel,
|
|
FormatStr, ValuesList, !IO) :-
|
|
Diff = MsgLevel - CurLogLevel,
|
|
( if Diff >= 0 then
|
|
io.format(FormatStr, ValuesList, !IO)
|
|
else
|
|
true
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|