mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 09:23:44 +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.
85 lines
2.8 KiB
Mathematica
85 lines
2.8 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
% Test the generation of error messages for invalid format_call pragmas.
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module bad_format_call.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
main(!IO) :-
|
|
arg_num_test_1("%s", [s("a")], !IO),
|
|
|
|
ArgNumTest2 = arg_num_test_2("%s", [s("a")]),
|
|
io.format("%s\n", [s(ArgNumTest2)], !IO),
|
|
|
|
type_test_1("%s", [s("a")], !IO),
|
|
|
|
TypeTest2 = type_test_2("%s", [s("a")]),
|
|
io.format("%s\n", [s(TypeTest2)], !IO),
|
|
|
|
mode_test_1("%s", _, [s("a")], !IO),
|
|
|
|
ModeTest2 = mode_test_2("%s", [s("a")], _),
|
|
io.format("%s\n", [s(ModeTest2)], !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred arg_num_test_1(string::in, list(poly_type)::in, io::di, io::uo) is det.
|
|
:- pragma format_call(pred(arg_num_test_1/4), format_string_values(-2, 5)).
|
|
|
|
arg_num_test_1(FormatStr, Values, !IO) :-
|
|
io.format(FormatStr, Values, !IO).
|
|
|
|
:- func arg_num_test_2(string, list(poly_type)) = string.
|
|
:- pragma format_call(func(arg_num_test_2/2), format_string_values(3, -4)).
|
|
|
|
arg_num_test_2(FormatStr, Values) = Str :-
|
|
string.format(FormatStr, Values, Str).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred type_test_1(string::in, list(poly_type)::in, io::di, io::uo) is det.
|
|
:- pragma format_call(pred(type_test_1/4), format_string_values(2, 3)).
|
|
|
|
type_test_1(FormatStr, Values, !IO) :-
|
|
io.format(FormatStr, Values, !IO).
|
|
|
|
:- func type_test_2(string, list(poly_type)) = string.
|
|
:- pragma format_call(func(type_test_2/2), format_string_values(2, 1)).
|
|
|
|
type_test_2(FormatStr, Values) = Str :-
|
|
string.format(FormatStr, Values, Str).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mode_test_1(string::in, string::out, list(poly_type)::in,
|
|
io::di, io::uo) is det.
|
|
:- pragma format_call(pred(mode_test_1/5), format_string_values(2, 3)).
|
|
|
|
mode_test_1(FormatStr0, FormatStr, Values, !IO) :-
|
|
FormatStr = FormatStr0,
|
|
io.format(FormatStr0, Values, !IO).
|
|
|
|
:- func mode_test_2(string::in, list(poly_type)::in, list(poly_type)::out)
|
|
= (string::out) is det.
|
|
:- pragma format_call(func(mode_test_2/3), format_string_values(1, 3)).
|
|
|
|
mode_test_2(FormatStr, Values0, Values) = Str :-
|
|
Values = Values0,
|
|
string.format(FormatStr, Values, Str).
|
|
|
|
%---------------------------------------------------------------------------%
|