mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 09:53:36 +00:00
1690 lines
62 KiB
Mathematica
1690 lines
62 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2015 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This module converts the parse tree structure representations of pragmas
|
|
% back into Mercury source text.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module parse_tree.parse_tree_out_pragma.
|
|
:- interface.
|
|
|
|
:- import_module parse_tree.parse_tree_out_info.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.prog_data_pragma.
|
|
:- import_module parse_tree.prog_item.
|
|
|
|
:- import_module bool.
|
|
:- import_module io.
|
|
:- import_module maybe.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_item_decl_pragma(merc_out_info::in,
|
|
io.text_output_stream::in, item_decl_pragma_info::in,
|
|
io::di, io::uo) is det.
|
|
:- pred mercury_output_item_impl_pragma(merc_out_info::in,
|
|
io.text_output_stream::in, item_impl_pragma_info::in,
|
|
io::di, io::uo) is det.
|
|
:- pred mercury_output_item_generated_pragma(merc_out_info::in,
|
|
io.text_output_stream::in, item_generated_pragma_info::in,
|
|
io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_item_pred_marker(io.text_output_stream::in,
|
|
pragma_info_pred_marker::in, io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_pragma_decl_pred_pf_name_arity(
|
|
io.text_output_stream::in, string::in, pred_pf_name_arity::in, string::in,
|
|
io::di, io::uo) is det.
|
|
:- func mercury_pragma_decl_pred_pf_name_arity_to_string(string,
|
|
pred_pf_name_arity, string) = string.
|
|
|
|
:- pred mercury_output_pragma_foreign_decl(io.text_output_stream::in,
|
|
pragma_info_foreign_decl::in, io::di, io::uo) is det.
|
|
:- func mercury_pragma_foreign_decl_to_string(pragma_info_foreign_decl)
|
|
= string.
|
|
|
|
:- pred mercury_output_pragma_foreign_proc(io.text_output_stream::in,
|
|
output_lang::in, pragma_info_foreign_proc::in, io::di, io::uo) is det.
|
|
:- func mercury_pragma_foreign_proc_to_string(output_lang,
|
|
pragma_info_foreign_proc) = string.
|
|
|
|
:- pred mercury_output_pragma_type_spec(io.text_output_stream::in,
|
|
output_lang::in, pragma_info_type_spec::in, io::di, io::uo) is det.
|
|
|
|
:- pred mercury_output_pragma_unused_args(io.text_output_stream::in,
|
|
pragma_info_unused_args::in, io::di, io::uo) is det.
|
|
|
|
:- pred mercury_output_pragma_exceptions(io.text_output_stream::in,
|
|
pragma_info_exceptions::in, io::di, io::uo) is det.
|
|
|
|
:- pred mercury_output_pragma_trailing_info(io.text_output_stream::in,
|
|
pragma_info_trailing_info::in, io::di, io::uo) is det.
|
|
|
|
:- pred mercury_output_pragma_mm_tabling_info(io.text_output_stream::in,
|
|
pragma_info_mm_tabling_info::in, io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% This predicate outputs termination_info pragmas;
|
|
% such annotations can be part of .opt and .trans_opt files.
|
|
%
|
|
:- pred write_pragma_termination_info(io.text_output_stream::in,
|
|
output_lang::in, pragma_info_termination_info::in, io::di, io::uo) is det.
|
|
|
|
% Return a string representation of the given arg size info.
|
|
% Include the representation of any error infos if the first arg is yes.
|
|
%
|
|
:- func maybe_arg_size_info_to_string(bool, maybe(generic_arg_size_info(T)))
|
|
= string.
|
|
|
|
% Return a string representation of the given termination info.
|
|
% Include the representation of any error_infos if the first arg is yes.
|
|
%
|
|
:- func maybe_termination_info_to_string(bool,
|
|
maybe(generic_termination_info(S, T))) = string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred write_pragma_termination2_info(io.text_output_stream::in,
|
|
output_lang::in, pragma_info_termination2_info::in, io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred write_pragma_structure_sharing_info(io.text_output_stream::in,
|
|
output_lang::in, pragma_info_structure_sharing::in, io::di, io::uo) is det.
|
|
|
|
:- pred write_pragma_structure_reuse_info(io.text_output_stream::in,
|
|
output_lang::in, pragma_info_structure_reuse::in, io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.compiler_util.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.rat.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.mercury_to_mercury.
|
|
:- import_module parse_tree.parse_tree_out_inst.
|
|
:- import_module parse_tree.parse_tree_out_pred_decl.
|
|
:- import_module parse_tree.parse_tree_out_term.
|
|
:- import_module parse_tree.prog_ctgc.
|
|
:- import_module parse_tree.prog_data_foreign.
|
|
:- import_module parse_tree.prog_out.
|
|
:- import_module parse_tree.prog_util.
|
|
:- import_module parse_tree.var_db.
|
|
|
|
:- import_module char.
|
|
:- import_module list.
|
|
:- import_module one_or_more.
|
|
:- import_module pair.
|
|
:- import_module require.
|
|
:- import_module set.
|
|
:- import_module string.
|
|
:- import_module term.
|
|
:- import_module term_io.
|
|
:- import_module unit.
|
|
:- import_module varset.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_output_item_decl_pragma(Info, Stream, ItemDeclPragma, !IO) :-
|
|
ItemDeclPragma = item_pragma_info(Pragma, Context, _SeqNum),
|
|
maybe_output_line_number(Info, Context, Stream, !IO),
|
|
Lang = get_output_lang(Info),
|
|
(
|
|
Pragma = decl_pragma_obsolete_pred(ObsPredInfo),
|
|
mercury_output_pragma_obsolete_pred(Stream, ObsPredInfo, !IO)
|
|
;
|
|
Pragma = decl_pragma_obsolete_proc(ObsProcInfo),
|
|
mercury_output_pragma_obsolete_proc(Stream, Lang, ObsProcInfo, !IO)
|
|
;
|
|
Pragma = decl_pragma_format_call(FormatCallInfo),
|
|
mercury_output_pragma_format_call(Stream, FormatCallInfo, !IO)
|
|
;
|
|
Pragma = decl_pragma_type_spec(TypeSpecInfo),
|
|
mercury_output_pragma_type_spec(Stream, Lang, TypeSpecInfo, !IO)
|
|
;
|
|
Pragma = decl_pragma_oisu(OISUInfo),
|
|
mercury_output_pragma_oisu(Stream, OISUInfo, !IO)
|
|
;
|
|
Pragma = decl_pragma_terminates(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"terminates", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = decl_pragma_does_not_terminate(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"does_not_terminate", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = decl_pragma_check_termination(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"check_termination", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = decl_pragma_termination_info(TermInfo),
|
|
write_pragma_termination_info(Stream, Lang, TermInfo, !IO)
|
|
;
|
|
Pragma = decl_pragma_termination2_info(Term2Info),
|
|
write_pragma_termination2_info(Stream, Lang, Term2Info, !IO)
|
|
;
|
|
Pragma = decl_pragma_structure_sharing(SharingInfo),
|
|
write_pragma_structure_sharing_info(Stream, Lang, SharingInfo, !IO)
|
|
;
|
|
Pragma = decl_pragma_structure_reuse(ReuseInfo),
|
|
write_pragma_structure_reuse_info(Stream, Lang, ReuseInfo, !IO)
|
|
).
|
|
|
|
mercury_output_item_impl_pragma(Info, Stream, ItemImplPragma, !IO) :-
|
|
ItemImplPragma = item_pragma_info(Pragma, Context, _SeqNum),
|
|
maybe_output_line_number(Info, Context, Stream, !IO),
|
|
Lang = get_output_lang(Info),
|
|
(
|
|
Pragma = impl_pragma_foreign_decl(FDInfo),
|
|
mercury_output_pragma_foreign_decl(Stream, FDInfo, !IO)
|
|
;
|
|
Pragma = impl_pragma_foreign_code(FCInfo),
|
|
mercury_output_pragma_foreign_code(Stream, FCInfo, !IO)
|
|
;
|
|
Pragma = impl_pragma_foreign_proc(FPInfo),
|
|
mercury_output_pragma_foreign_proc(Stream, Lang, FPInfo, !IO)
|
|
;
|
|
Pragma = impl_pragma_foreign_proc_export(FPEInfo),
|
|
mercury_format_pragma_foreign_proc_export(Lang, FPEInfo, Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_external_proc(ExternalInfo),
|
|
mercury_format_pragma_external_proc(ExternalInfo, Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_fact_table(FactTableInfo),
|
|
mercury_format_pragma_fact_table(FactTableInfo, Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_inline(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"inline", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_no_inline(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"no_inline", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_tabled(TabledInfo),
|
|
mercury_output_pragma_tabled(Stream, TabledInfo, !IO)
|
|
;
|
|
Pragma = impl_pragma_consider_used(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"consider_used", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_no_detism_warning(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"no_determinism_warning", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_mode_check_clauses(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"mode_check_clauses", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_require_tail_rec(RequireTailrecPragma),
|
|
mercury_output_pragma_require_tail_rec(Stream, Lang,
|
|
RequireTailrecPragma, !IO)
|
|
;
|
|
Pragma = impl_pragma_promise_pure(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"promise_pure", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_promise_semipure(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"promise_semipure", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_promise_eqv_clauses(PredSpec),
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(
|
|
"promise_equivalent_clauses", PredSpec, "", Stream, !IO)
|
|
;
|
|
Pragma = impl_pragma_require_feature_set(RFSInfo),
|
|
mercury_format_pragma_require_feature_set(RFSInfo, Stream, !IO)
|
|
).
|
|
|
|
mercury_output_item_generated_pragma(Info, Stream, ItemGenPragma, !IO) :-
|
|
ItemGenPragma = item_pragma_info(Pragma, Context, _SeqNum),
|
|
maybe_output_line_number(Info, Context, Stream, !IO),
|
|
(
|
|
Pragma = gen_pragma_unused_args(UnusedArgsInfo),
|
|
mercury_output_pragma_unused_args(Stream, UnusedArgsInfo, !IO)
|
|
;
|
|
Pragma = gen_pragma_exceptions(ExceptionsInfo),
|
|
mercury_output_pragma_exceptions(Stream, ExceptionsInfo, !IO)
|
|
;
|
|
Pragma = gen_pragma_trailing_info(TrailingInfo),
|
|
mercury_output_pragma_trailing_info(Stream, TrailingInfo, !IO)
|
|
;
|
|
Pragma = gen_pragma_mm_tabling_info(TablingInfo),
|
|
mercury_output_pragma_mm_tabling_info(Stream, TablingInfo, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_output_item_pred_marker(Stream, PredMarker, !IO) :-
|
|
PredMarker = pragma_info_pred_marker(PredSpec, PredMarkerKind),
|
|
(
|
|
PredMarkerKind = pmpk_inline,
|
|
PragmaName = "inline"
|
|
;
|
|
PredMarkerKind = pmpk_noinline,
|
|
PragmaName = "no_inline"
|
|
;
|
|
PredMarkerKind = pmpk_promise_eqv_clauses,
|
|
PragmaName = "promise_equivalent_clauses"
|
|
;
|
|
PredMarkerKind = pmpk_promise_pure,
|
|
PragmaName = "promise_pure"
|
|
;
|
|
PredMarkerKind = pmpk_promise_semipure,
|
|
PragmaName = "promise_semipure"
|
|
;
|
|
PredMarkerKind = pmpk_terminates,
|
|
PragmaName = "terminates"
|
|
;
|
|
PredMarkerKind = pmpk_does_not_terminate,
|
|
PragmaName = "does_not_terminate"
|
|
;
|
|
PredMarkerKind = pmpk_mode_check_clauses,
|
|
PragmaName = "mode_check_clauses"
|
|
),
|
|
mercury_format_pragma_decl_pred_pf_name_arity(PragmaName, PredSpec, "",
|
|
Stream, !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a generic pragma declaration. Used to implement
|
|
% several kinds of pragmas.
|
|
%
|
|
|
|
:- pred mercury_format_pragma_decl_pred_or_proc_pfumm_name(string::in,
|
|
pred_or_proc_pfumm_name::in, string::in, S::in, U::di, U::uo)
|
|
is det <= output(S, U).
|
|
|
|
mercury_format_pragma_decl_pred_or_proc_pfumm_name(PragmaName,
|
|
PredOrProcSpec, AfterStr, S, !U) :-
|
|
PredOrProcSpecStr =
|
|
pred_or_proc_pfumm_name_to_string(output_mercury, PredOrProcSpec),
|
|
add_string(":- pragma ", S, !U),
|
|
add_string(PragmaName, S, !U),
|
|
add_string("(", S, !U),
|
|
add_string(PredOrProcSpecStr, S, !U),
|
|
add_string(AfterStr, S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_pragma_decl_pred_pf_name_arity(Stream, PragmaName, PredSpec,
|
|
MaybeAfter, !IO) :-
|
|
mercury_format_pragma_decl_pred_pf_name_arity(PragmaName, PredSpec,
|
|
MaybeAfter, Stream, !IO).
|
|
|
|
mercury_pragma_decl_pred_pf_name_arity_to_string(PragmaName, PredSpec,
|
|
MaybeAfter) = String :-
|
|
mercury_format_pragma_decl_pred_pf_name_arity(PragmaName, PredSpec,
|
|
MaybeAfter, unit, "", String).
|
|
|
|
:- pred mercury_format_pragma_decl_pred_pf_name_arity(string::in,
|
|
pred_pf_name_arity::in, string::in, S::in, U::di, U::uo) is det
|
|
<= output(S, U).
|
|
|
|
mercury_format_pragma_decl_pred_pf_name_arity(PragmaName, PredSpec0,
|
|
AfterStr, S, !U) :-
|
|
add_string(":- pragma ", S, !U),
|
|
add_string(PragmaName, S, !U),
|
|
add_string("(", S, !U),
|
|
PredSpec0 = pred_pf_name_arity(PredOrFunc, PredName, Arity),
|
|
mercury_format_pred_pf_name_arity(PredOrFunc, PredName, Arity, S, !U),
|
|
add_string(AfterStr, S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
%---------------------%
|
|
|
|
:- pred mercury_format_pragma_decl_pred_pfu_name_arity(string::in,
|
|
pred_pfu_name_arity::in, string::in, S::in, U::di, U::uo)
|
|
is det <= output(S, U).
|
|
|
|
mercury_format_pragma_decl_pred_pfu_name_arity(PragmaName, PredSpec0,
|
|
AfterStr, S, !U) :-
|
|
add_string(":- pragma ", S, !U),
|
|
add_string(PragmaName, S, !U),
|
|
add_string("(", S, !U),
|
|
PredSpec0 = pred_pfu_name_arity(PFU, PredName, Arity),
|
|
mercury_format_pred_pfu_name_arity(PFU, PredName, Arity, S, !U),
|
|
add_string(AfterStr, S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a foreign_decl pragma.
|
|
%
|
|
|
|
mercury_output_pragma_foreign_decl(Stream, FDInfo, !IO) :-
|
|
mercury_format_pragma_foreign_decl(FDInfo, Stream, !IO).
|
|
|
|
mercury_pragma_foreign_decl_to_string(FDInfo) = String :-
|
|
mercury_format_pragma_foreign_decl(FDInfo, unit, "", String).
|
|
|
|
:- pred mercury_format_pragma_foreign_decl(pragma_info_foreign_decl::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_foreign_decl(FDInfo, S, !U) :-
|
|
FDInfo = pragma_info_foreign_decl(Lang, IsLocal, LiteralOrInclude),
|
|
add_string(":- pragma foreign_decl(", S, !U),
|
|
mercury_format_foreign_language_string(Lang, S, !U),
|
|
add_string(", ", S, !U),
|
|
(
|
|
IsLocal = foreign_decl_is_local,
|
|
add_string("local", S, !U)
|
|
;
|
|
IsLocal = foreign_decl_is_exported,
|
|
add_string("exported", S, !U)
|
|
),
|
|
add_string(", ", S, !U),
|
|
mercury_format_foreign_literal_or_include(LiteralOrInclude, S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a foreign_code pragma.
|
|
%
|
|
|
|
:- pred mercury_output_pragma_foreign_code(io.text_output_stream::in,
|
|
pragma_info_foreign_code::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_pragma_foreign_code(Stream, FCInfo, !IO) :-
|
|
FCInfo = pragma_info_foreign_code(Lang, LiteralOrInclude),
|
|
LangStr = mercury_foreign_language_to_string(Lang),
|
|
LorIStr = foreign_literal_or_include_to_string(LiteralOrInclude),
|
|
io.format(Stream, ":- pragma foreign_code(%s, %s).\n",
|
|
[s(LangStr), s(LorIStr)], !IO).
|
|
|
|
:- func foreign_literal_or_include_to_string(foreign_literal_or_include)
|
|
= string.
|
|
|
|
foreign_literal_or_include_to_string(LiteralOrInclude) = Str :-
|
|
mercury_format_foreign_literal_or_include(LiteralOrInclude, unit, "", Str).
|
|
|
|
:- pred mercury_format_foreign_literal_or_include(
|
|
foreign_literal_or_include::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_foreign_literal_or_include(LiteralOrInclude, S, !U) :-
|
|
(
|
|
LiteralOrInclude = floi_literal(Code),
|
|
mercury_format_foreign_code_string(Code, S, !U)
|
|
;
|
|
LiteralOrInclude = floi_include_file(FileName),
|
|
add_string("include_file(", S, !U),
|
|
add_quoted_string(FileName, S, !U),
|
|
add_string(")", S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
% The code here is similar to the code for term_io.quote_string,
|
|
% but \n and \t are output directly, rather than escaped.
|
|
% Any changes here may require corresponding changes to term_io and vice versa.
|
|
|
|
:- pred mercury_format_foreign_code_string(string::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_foreign_code_string(Str, S, !U) :-
|
|
add_string("""", S, !U),
|
|
mercury_format_escaped_string(Str, S, !U),
|
|
add_string("""", S, !U).
|
|
|
|
:- pred mercury_format_escaped_string(string::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_escaped_string(String, S, !U) :-
|
|
string.foldl(mercury_format_escaped_char(S), String, !U).
|
|
|
|
:- pred mercury_format_escaped_char(S::in, char::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_escaped_char(S, Char, !U) :-
|
|
( if escape_special_char(Char, QuoteChar) then
|
|
add_char('\\', S, !U),
|
|
add_char(QuoteChar, S, !U)
|
|
else if mercury_is_source_char(Char) then
|
|
add_char(Char, S, !U)
|
|
else
|
|
add_string(mercury_escape_char(Char), S, !U)
|
|
).
|
|
|
|
% escape_special_char(Char, EscapeChar):
|
|
%
|
|
% True iff Char is character for which there is a special backslash-escape
|
|
% character EscapeChar that can be used after a backslash in Mercury
|
|
% foreign_code string literals to represent Char.
|
|
%
|
|
:- pred escape_special_char(char::in, char::out) is semidet.
|
|
|
|
escape_special_char('''', '''').
|
|
escape_special_char('"', '"').
|
|
escape_special_char('\\', '\\').
|
|
escape_special_char('\b', 'b').
|
|
|
|
% Succeed if Char is a character which is allowed in
|
|
% Mercury string and character literals.
|
|
%
|
|
:- pred mercury_is_source_char(char::in) is semidet.
|
|
|
|
mercury_is_source_char(Char) :-
|
|
( char.is_alnum(Char)
|
|
; is_mercury_punctuation_char(Char)
|
|
; Char = '\n'
|
|
; Char = '\t'
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a foreign_proc pragma.
|
|
%
|
|
|
|
mercury_output_pragma_foreign_proc(Stream, Lang, FPInfo, !IO) :-
|
|
mercury_format_pragma_foreign_proc(Lang, FPInfo, Stream, !IO).
|
|
|
|
mercury_pragma_foreign_proc_to_string(Lang, FPInfo) = String :-
|
|
mercury_format_pragma_foreign_proc(Lang, FPInfo, unit, "", String).
|
|
|
|
:- pred mercury_format_pragma_foreign_proc(output_lang::in,
|
|
pragma_info_foreign_proc::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_foreign_proc(Lang, FPInfo, S, !U) :-
|
|
FPInfo = pragma_info_foreign_proc(Attributes, PredName, PredOrFunc, Vars0,
|
|
ProgVarSet, InstVarSet, PragmaCode),
|
|
add_string(":- pragma foreign_proc(", S, !U),
|
|
ForeignLang = get_foreign_language(Attributes),
|
|
mercury_format_foreign_language_string(ForeignLang, S, !U),
|
|
add_string(", ", S, !U),
|
|
mercury_format_sym_name(PredName, S, !U),
|
|
(
|
|
PredOrFunc = pf_predicate,
|
|
Vars = Vars0,
|
|
ResultVars = []
|
|
;
|
|
PredOrFunc = pf_function,
|
|
pred_args_to_func_args(Vars0, Vars, ResultVar),
|
|
ResultVars = [ResultVar]
|
|
),
|
|
(
|
|
Vars = []
|
|
;
|
|
Vars = [_ | _],
|
|
add_string("(", S, !U),
|
|
mercury_format_pragma_foreign_proc_vars(Lang, ProgVarSet, InstVarSet,
|
|
Vars, S, !U),
|
|
add_string(")", S, !U)
|
|
),
|
|
(
|
|
PredOrFunc = pf_predicate
|
|
;
|
|
PredOrFunc = pf_function,
|
|
add_string(" = (", S, !U),
|
|
mercury_format_pragma_foreign_proc_vars(Lang, ProgVarSet, InstVarSet,
|
|
ResultVars, S, !U),
|
|
add_string(")", S, !U)
|
|
),
|
|
add_string(", ", S, !U),
|
|
mercury_format_pragma_foreign_attributes(ProgVarSet, Attributes, S, !U),
|
|
add_string(", ", S, !U),
|
|
PragmaCode = fp_impl_ordinary(C_Code, _),
|
|
mercury_format_foreign_code_string(C_Code, S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
%---------------------%
|
|
|
|
:- pred mercury_format_pragma_foreign_proc_vars(output_lang::in,
|
|
prog_varset::in, inst_varset::in, list(pragma_var)::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_foreign_proc_vars(_, _, _, [], _S, !U).
|
|
mercury_format_pragma_foreign_proc_vars(Lang, ProgVarSet, InstVarSet,
|
|
[Var | Vars], S, !U) :-
|
|
Var = pragma_var(_Var, VarName, Mode, _BoxPolicy),
|
|
add_string(VarName, S, !U),
|
|
add_string(" :: ", S, !U),
|
|
mercury_format_mode(Lang, InstVarSet, Mode, S, !U),
|
|
(
|
|
Vars = []
|
|
;
|
|
Vars = [_ | _],
|
|
add_string(", ", S, !U)
|
|
),
|
|
mercury_format_pragma_foreign_proc_vars(Lang, ProgVarSet, InstVarSet,
|
|
Vars, S, !U).
|
|
|
|
%---------------------%
|
|
|
|
:- pred mercury_format_pragma_foreign_attributes(prog_varset::in,
|
|
pragma_foreign_proc_attributes::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_foreign_attributes(VarSet, Attributes, S, !U) :-
|
|
add_string("[", S, !U),
|
|
add_list(add_string, ", ",
|
|
foreign_proc_attributes_to_strings(Attributes, VarSet), S, !U),
|
|
add_string("]", S, !U).
|
|
|
|
% Convert the foreign code attributes to their source code representations
|
|
% suitable for placing in the attributes list of the pragma (not all
|
|
% attributes have one). In particular, the foreign language attribute needs
|
|
% to be handled separately as it belongs at the start of the pragma.
|
|
%
|
|
:- func foreign_proc_attributes_to_strings(pragma_foreign_proc_attributes,
|
|
prog_varset) = list(string).
|
|
|
|
foreign_proc_attributes_to_strings(Attrs, VarSet) = StringList :-
|
|
MayCallMercury = get_may_call_mercury(Attrs),
|
|
ThreadSafe = get_thread_safe(Attrs),
|
|
TabledForIO = get_tabled_for_io(Attrs),
|
|
Purity = get_purity(Attrs),
|
|
Terminates = get_terminates(Attrs),
|
|
UserSharing = get_user_annotated_sharing(Attrs),
|
|
Exceptions = get_may_throw_exception(Attrs),
|
|
OrdinaryDespiteDetism = get_ordinary_despite_detism(Attrs),
|
|
MayModifyTrail = get_may_modify_trail(Attrs),
|
|
MayCallMM_Tabled = get_may_call_mm_tabled(Attrs),
|
|
BoxPolicy = get_box_policy(Attrs),
|
|
AffectsLiveness = get_affects_liveness(Attrs),
|
|
AllocatesMemory = get_allocates_memory(Attrs),
|
|
RegistersRoots = get_registers_roots(Attrs),
|
|
MaybeMayDuplicate = get_may_duplicate(Attrs),
|
|
MaybeMayExportBody = get_may_export_body(Attrs),
|
|
ExtraAttributes = get_extra_attributes(Attrs),
|
|
(
|
|
MayCallMercury = proc_may_call_mercury,
|
|
MayCallMercuryStr = "may_call_mercury"
|
|
;
|
|
MayCallMercury = proc_will_not_call_mercury,
|
|
MayCallMercuryStr = "will_not_call_mercury"
|
|
),
|
|
(
|
|
ThreadSafe = proc_not_thread_safe,
|
|
ThreadSafeStr = "not_thread_safe"
|
|
;
|
|
ThreadSafe = proc_thread_safe,
|
|
ThreadSafeStr = "thread_safe"
|
|
;
|
|
ThreadSafe = proc_maybe_thread_safe,
|
|
ThreadSafeStr = "maybe_thread_safe"
|
|
),
|
|
(
|
|
TabledForIO = proc_tabled_for_io,
|
|
TabledForIOStr = "tabled_for_io"
|
|
;
|
|
TabledForIO = proc_tabled_for_io_unitize,
|
|
TabledForIOStr = "tabled_for_io_unitize"
|
|
;
|
|
TabledForIO = proc_tabled_for_descendant_io,
|
|
TabledForIOStr = "tabled_for_descendant_io"
|
|
;
|
|
TabledForIO = proc_not_tabled_for_io,
|
|
TabledForIOStr = "not_tabled_for_io"
|
|
),
|
|
(
|
|
Purity = purity_pure,
|
|
PurityStrList = ["promise_pure"]
|
|
;
|
|
Purity = purity_semipure,
|
|
PurityStrList = ["promise_semipure"]
|
|
;
|
|
Purity = purity_impure,
|
|
PurityStrList = []
|
|
),
|
|
(
|
|
Terminates = proc_terminates,
|
|
TerminatesStrList = ["terminates"]
|
|
;
|
|
Terminates = proc_does_not_terminate,
|
|
TerminatesStrList = ["does_not_terminate"]
|
|
;
|
|
Terminates = depends_on_mercury_calls,
|
|
TerminatesStrList = []
|
|
),
|
|
(
|
|
UserSharing = user_sharing(Sharing, MaybeTypes),
|
|
String = user_annotated_sharing_to_string(VarSet, Sharing, MaybeTypes),
|
|
UserSharingStrList = [String]
|
|
;
|
|
UserSharing = no_user_annotated_sharing,
|
|
UserSharingStrList = []
|
|
),
|
|
(
|
|
Exceptions = proc_will_not_throw_exception,
|
|
ExceptionsStrList = ["will_not_throw_exception"]
|
|
;
|
|
Exceptions = default_exception_behaviour,
|
|
ExceptionsStrList = []
|
|
),
|
|
(
|
|
OrdinaryDespiteDetism = yes,
|
|
OrdinaryDespiteDetismStrList = ["ordinary_despite_detism"]
|
|
;
|
|
OrdinaryDespiteDetism = no,
|
|
OrdinaryDespiteDetismStrList = []
|
|
),
|
|
(
|
|
MayModifyTrail = proc_may_modify_trail,
|
|
MayModifyTrailStrList = ["may_modify_trail"]
|
|
;
|
|
MayModifyTrail = proc_will_not_modify_trail,
|
|
MayModifyTrailStrList = ["will_not_modify_trail"]
|
|
),
|
|
(
|
|
MayCallMM_Tabled = proc_may_call_mm_tabled,
|
|
MayCallMM_TabledStrList = ["may_call_mm_tabled"]
|
|
;
|
|
MayCallMM_Tabled = proc_will_not_call_mm_tabled,
|
|
MayCallMM_TabledStrList =["will_not_call_mm_tabled"]
|
|
;
|
|
MayCallMM_Tabled = proc_default_calls_mm_tabled,
|
|
MayCallMM_TabledStrList = []
|
|
),
|
|
(
|
|
BoxPolicy = bp_native_if_possible,
|
|
BoxPolicyStrList = []
|
|
;
|
|
BoxPolicy = bp_always_boxed,
|
|
BoxPolicyStrList = ["always_boxed"]
|
|
),
|
|
(
|
|
AffectsLiveness = proc_affects_liveness,
|
|
AffectsLivenessStrList = ["affects_liveness"]
|
|
;
|
|
AffectsLiveness = proc_does_not_affect_liveness,
|
|
AffectsLivenessStrList = ["doesnt_affect_liveness"]
|
|
;
|
|
AffectsLiveness = proc_default_affects_liveness,
|
|
AffectsLivenessStrList = []
|
|
),
|
|
(
|
|
AllocatesMemory = proc_does_not_allocate_memory,
|
|
AllocatesMemoryStrList =["doesnt_allocate_memory"]
|
|
;
|
|
AllocatesMemory = proc_allocates_bounded_memory,
|
|
AllocatesMemoryStrList = ["allocates_bounded_memory"]
|
|
;
|
|
AllocatesMemory = proc_allocates_unbounded_memory,
|
|
AllocatesMemoryStrList = ["allocates_unbounded_memory"]
|
|
;
|
|
AllocatesMemory = proc_default_allocates_memory,
|
|
AllocatesMemoryStrList = []
|
|
),
|
|
(
|
|
RegistersRoots = proc_registers_roots,
|
|
RegistersRootsStrList = ["registers_roots"]
|
|
;
|
|
RegistersRoots = proc_does_not_register_roots,
|
|
RegistersRootsStrList =["doesnt_register_roots"]
|
|
;
|
|
RegistersRoots = proc_does_not_have_roots,
|
|
RegistersRootsStrList = ["doesnt_have_roots"]
|
|
;
|
|
RegistersRoots = proc_default_registers_roots,
|
|
RegistersRootsStrList = []
|
|
),
|
|
(
|
|
MaybeMayDuplicate = yes(MayDuplicate),
|
|
(
|
|
MayDuplicate = proc_may_duplicate,
|
|
MayDuplicateStrList = ["may_duplicate"]
|
|
;
|
|
MayDuplicate = proc_may_not_duplicate,
|
|
MayDuplicateStrList = ["may_not_duplicate"]
|
|
)
|
|
;
|
|
MaybeMayDuplicate = no,
|
|
MayDuplicateStrList = []
|
|
),
|
|
(
|
|
MaybeMayExportBody = yes(MayExportBody),
|
|
(
|
|
MayExportBody = proc_may_export_body,
|
|
MayExportBodyStrList = ["may_export_body"]
|
|
;
|
|
MayExportBody = proc_may_not_export_body,
|
|
MayExportBodyStrList = ["may_not_export_body"]
|
|
)
|
|
;
|
|
MaybeMayExportBody = no,
|
|
MayExportBodyStrList = []
|
|
),
|
|
StringList = [MayCallMercuryStr, ThreadSafeStr, TabledForIOStr |
|
|
PurityStrList] ++ TerminatesStrList ++ UserSharingStrList ++
|
|
ExceptionsStrList ++
|
|
OrdinaryDespiteDetismStrList ++ MayModifyTrailStrList ++
|
|
MayCallMM_TabledStrList ++ BoxPolicyStrList ++
|
|
AffectsLivenessStrList ++ AllocatesMemoryStrList ++
|
|
RegistersRootsStrList ++ MayDuplicateStrList ++ MayExportBodyStrList ++
|
|
list.map(extra_attribute_to_string, ExtraAttributes).
|
|
|
|
:- func user_annotated_sharing_to_string(prog_varset, structure_sharing_domain,
|
|
maybe(user_sharing_type_information)) = string.
|
|
|
|
user_annotated_sharing_to_string(VarSet, Sharing, MaybeTypes) = String :-
|
|
(
|
|
Sharing = structure_sharing_bottom,
|
|
String = "no_sharing"
|
|
;
|
|
Sharing = structure_sharing_top(_),
|
|
String = "unknown_sharing"
|
|
;
|
|
Sharing = structure_sharing_real(SharingPairs),
|
|
(
|
|
MaybeTypes = yes(user_type_info(Types, TypeVarSet)),
|
|
TypeStrs = list.map(
|
|
mercury_type_to_string(TypeVarSet, print_name_only),
|
|
Types),
|
|
TypeListStr = string.join_list(", ", TypeStrs),
|
|
MaybeTypesStr = "yes(" ++ TypeListStr ++ ")"
|
|
;
|
|
MaybeTypes = no,
|
|
MaybeTypesStr = "no",
|
|
TypeVarSet = varset.init
|
|
),
|
|
SharingPairStrs = list.map(sharing_pair_to_string(VarSet, TypeVarSet),
|
|
SharingPairs),
|
|
SharingPairListStr = string.join_list(", ", SharingPairStrs),
|
|
String = string.append_list(
|
|
["sharing(", MaybeTypesStr, ", [", SharingPairListStr, "])"])
|
|
).
|
|
|
|
:- func sharing_pair_to_string(prog_varset, tvarset, structure_sharing_pair)
|
|
= string.
|
|
|
|
sharing_pair_to_string(VarSet, TypeVarSet, DataA - DataB) = Str :-
|
|
DataA = selected_cel(VarA, SelectorA),
|
|
DataB = selected_cel(VarB, SelectorB),
|
|
VarStrA = mercury_var_to_string_vs(VarSet, print_name_only, VarA),
|
|
VarStrB = mercury_var_to_string_vs(VarSet, print_name_only, VarB),
|
|
SelectorStrA = selector_to_string(TypeVarSet, SelectorA),
|
|
SelectorStrB = selector_to_string(TypeVarSet, SelectorB),
|
|
StrA = "cel(" ++ VarStrA ++ ", [" ++ SelectorStrA ++ "])",
|
|
StrB = "cel(" ++ VarStrB ++ ", [" ++ SelectorStrB ++ "])",
|
|
Str = StrA ++ " - " ++ StrB.
|
|
|
|
:- func selector_to_string(tvarset, selector) = string.
|
|
|
|
selector_to_string(TypeVarSet, Selector) = String :-
|
|
UnitStrs = list.map(unit_selector_to_string(TypeVarSet), Selector),
|
|
String = string.join_list(", ", UnitStrs).
|
|
|
|
:- func unit_selector_to_string(tvarset, unit_selector) = string.
|
|
|
|
unit_selector_to_string(TypeVarSet, UnitSelector) = String :-
|
|
(
|
|
UnitSelector = typesel(Type),
|
|
String = mercury_type_to_string(TypeVarSet, print_name_only, Type)
|
|
;
|
|
UnitSelector = termsel(_, _),
|
|
unexpected($pred, "termsel in user-annotated sharing")
|
|
).
|
|
|
|
:- func extra_attribute_to_string(pragma_foreign_proc_extra_attribute)
|
|
= string.
|
|
|
|
extra_attribute_to_string(refers_to_llds_stack) = "refers_to_llds_stack".
|
|
extra_attribute_to_string(backend(low_level_backend)) = "low_level_backend".
|
|
extra_attribute_to_string(backend(high_level_backend)) = "high_level_backend".
|
|
extra_attribute_to_string(needs_call_standard_output_registers) =
|
|
"needs_call_standard_output_registers".
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a foreign_proc_export pragma.
|
|
%
|
|
|
|
:- pred mercury_format_pragma_foreign_proc_export(output_lang::in,
|
|
pragma_info_foreign_proc_export::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_foreign_proc_export(Lang, FPEInfo, S, !U) :-
|
|
FPEInfo = pragma_info_foreign_proc_export(_Origin, ForeignLang,
|
|
PredNameModesPF, ExportName, VarSet),
|
|
PredNameModesPF = proc_pf_name_modes(PredOrFunc, SymName, Modes),
|
|
add_string(":- pragma foreign_export(", S, !U),
|
|
mercury_format_foreign_language_string(ForeignLang, S, !U),
|
|
add_string(", ", S, !U),
|
|
mercury_format_sym_name(SymName, S, !U),
|
|
varset.coerce(VarSet, InstVarSet),
|
|
(
|
|
PredOrFunc = pf_function,
|
|
pred_args_to_func_args(Modes, ArgModes, RetMode),
|
|
add_string("(", S, !U),
|
|
mercury_format_mode_list(Lang, InstVarSet, ArgModes, S, !U),
|
|
add_string(") = ", S, !U),
|
|
mercury_format_mode(Lang, InstVarSet, RetMode, S, !U)
|
|
;
|
|
PredOrFunc = pf_predicate,
|
|
add_string("(", S, !U),
|
|
mercury_format_mode_list(Lang, InstVarSet, Modes, S, !U),
|
|
add_string(")", S, !U)
|
|
),
|
|
add_string(", ", S, !U),
|
|
add_string(ExportName, S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output an external_proc pragma.
|
|
%
|
|
|
|
:- pred mercury_format_pragma_external_proc(pragma_info_external_proc::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_external_proc(ExternalInfo, S, !U) :-
|
|
ExternalInfo = pragma_info_external_proc(PFNameArity, MaybeBackend),
|
|
PFNameArity = pred_pf_name_arity(PorF, PredName, user_arity(Arity)),
|
|
PorFStr = pred_or_func_to_str(PorF),
|
|
add_string(":- pragma external_", S, !U),
|
|
add_string(PorFStr, S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_sym_name(PredName, S, !U),
|
|
add_string("/", S, !U),
|
|
add_int(Arity, S, !U),
|
|
(
|
|
MaybeBackend = no
|
|
;
|
|
MaybeBackend = yes(Backend),
|
|
add_string(", [", S, !U),
|
|
add_string(backend_to_string(Backend), S, !U),
|
|
add_string("]", S, !U)
|
|
),
|
|
add_string(").\n", S, !U).
|
|
|
|
:- func backend_to_string(backend) = string.
|
|
|
|
backend_to_string(Backend) = Str :-
|
|
(
|
|
Backend = low_level_backend,
|
|
Str = "low_level_backend"
|
|
;
|
|
Backend = high_level_backend,
|
|
Str = "high_level_backend"
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a type_spec pragma.
|
|
%
|
|
|
|
mercury_output_pragma_type_spec(Stream, Lang, TypeSpecInfo, !IO) :-
|
|
TypeSpecInfo = pragma_info_type_spec(PFUMM, PredName, _SpecModuleName,
|
|
TypeSubst, VarSet, _),
|
|
io.write_string(Stream, ":- pragma type_spec(", !IO),
|
|
(
|
|
(
|
|
PFUMM = pfumm_predicate(ModesOrArity),
|
|
PredOrFunc = pf_predicate
|
|
;
|
|
PFUMM = pfumm_function(ModesOrArity),
|
|
PredOrFunc = pf_function
|
|
),
|
|
(
|
|
ModesOrArity = moa_modes(Modes),
|
|
PredNameModesPF = proc_pf_name_modes(PredOrFunc, PredName, Modes),
|
|
PredStr = proc_pf_name_modes_to_string(Lang, PredNameModesPF),
|
|
io.write_string(Stream, PredStr, !IO)
|
|
;
|
|
ModesOrArity = moa_arity(Arity),
|
|
mercury_format_pred_pf_name_arity(PredOrFunc, PredName, Arity,
|
|
Stream, !IO)
|
|
)
|
|
;
|
|
PFUMM = pfumm_unknown(PredArity),
|
|
mercury_format_pred_name_arity(PredName, PredArity, Stream, !IO)
|
|
),
|
|
io.write_string(Stream, ", ", !IO),
|
|
% The code that parses type_spec pragmas ensures that all types variables
|
|
% in the substitution are named. Therefore there is no reason to print
|
|
% variable numbers. In fact, printing variable numbers would be a bug,
|
|
% since any code reading the pragma we are now writing out would mistake
|
|
% the variable number as part of the variable *name*. See the long comment
|
|
% on the tspec_tvarset field of the pragma in prog_item.m.
|
|
TypeSubst = one_or_more(HeadTypeSubst, TailTypeSubsts),
|
|
(
|
|
TailTypeSubsts = [],
|
|
% In the common case of there being only type substitution,
|
|
% do not put unnecessary parentheses around it.
|
|
mercury_output_type_subst(VarSet, print_name_only,
|
|
HeadTypeSubst, Stream, !IO)
|
|
;
|
|
TailTypeSubsts = [_ | _],
|
|
io.write_string(Stream, "(", !IO),
|
|
write_out_list(mercury_output_type_subst(VarSet, print_name_only),
|
|
", ", [HeadTypeSubst | TailTypeSubsts], Stream, !IO),
|
|
io.write_string(Stream, ")", !IO)
|
|
),
|
|
io.write_string(Stream, ").\n", !IO).
|
|
|
|
:- pred mercury_output_type_subst(tvarset::in, var_name_print::in,
|
|
pair(tvar, mer_type)::in, io.text_output_stream::in,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_type_subst(VarSet, VarNamePrint, Var - Type, Stream, !IO) :-
|
|
mercury_output_var_vs(VarSet, VarNamePrint, Var, Stream, !IO),
|
|
io.write_string(Stream, " = ", !IO),
|
|
mercury_output_type(VarSet, VarNamePrint, Type, Stream, !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output an unused_args pragma.
|
|
%
|
|
|
|
mercury_output_pragma_unused_args(Stream, UnusedArgsInfo, !IO) :-
|
|
UnusedArgsInfo = pragma_info_unused_args(PredNameArityPFMn, UnusedArgs),
|
|
PredNameArityPFMn = proc_pf_name_arity_mn(PredOrFunc, SymName,
|
|
user_arity(Arity), ModeNum),
|
|
PorFStr = pred_or_func_to_full_str(PredOrFunc),
|
|
SymNameStr = mercury_bracketed_sym_name_to_string(SymName),
|
|
UnusedArgsStr = int_list_to_string(UnusedArgs),
|
|
io.format(Stream, ":- pragma unused_args(%s, %s, %d, %d, [%s]",
|
|
[s(PorFStr), s(SymNameStr), i(Arity), i(ModeNum), s(UnusedArgsStr)],
|
|
!IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output an exceptions pragma.
|
|
%
|
|
|
|
mercury_output_pragma_exceptions(Stream, ExceptionsInfo, !IO) :-
|
|
ExceptionsInfo = pragma_info_exceptions(PredNameArityPFMn, ThrowStatus),
|
|
PredNameArityPFMn = proc_pf_name_arity_mn(PredOrFunc, SymName,
|
|
user_arity(Arity), ModeNum),
|
|
PorFStr = pred_or_func_to_full_str(PredOrFunc),
|
|
SymNameStr = mercury_bracketed_sym_name_to_string(SymName),
|
|
(
|
|
ThrowStatus = will_not_throw,
|
|
ThrowStr = "will_not_throw"
|
|
;
|
|
ThrowStatus = may_throw(ExceptionType),
|
|
(
|
|
ExceptionType = user_exception,
|
|
ThrowStr = "may_throw(user_exception)"
|
|
;
|
|
ExceptionType = type_exception,
|
|
ThrowStr = "may_throw(type_exception)"
|
|
)
|
|
;
|
|
ThrowStatus = throw_conditional,
|
|
ThrowStr = "conditional"
|
|
),
|
|
io.format(Stream, ":- pragma exceptions(%s, %s, %d, %d, %s).\n",
|
|
[s(PorFStr), s(SymNameStr), i(Arity), i(ModeNum), s(ThrowStr)], !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a trailing_info pragma.
|
|
%
|
|
|
|
mercury_output_pragma_trailing_info(Stream, TrailingInfo, !IO) :-
|
|
TrailingInfo =
|
|
pragma_info_trailing_info(PredNameArityPFMn, TrailingStatus),
|
|
PredNameArityPFMn = proc_pf_name_arity_mn(PredOrFunc, SymName,
|
|
user_arity(Arity), ModeNum),
|
|
PorFStr = pred_or_func_to_full_str(PredOrFunc),
|
|
SymNameStr = mercury_bracketed_sym_name_to_string(SymName),
|
|
(
|
|
TrailingStatus = trail_may_modify,
|
|
TrailStr = "may_modify_trail"
|
|
;
|
|
TrailingStatus = trail_will_not_modify,
|
|
TrailStr = "will_not_modify_trail"
|
|
;
|
|
TrailingStatus = trail_conditional,
|
|
TrailStr = "conditional"
|
|
),
|
|
io.format(Stream, ":- pragma trailing_info(%s, %s, %d, %d, %s).\n",
|
|
[s(PorFStr), s(SymNameStr), i(Arity), i(ModeNum), s(TrailStr)], !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a mm_tabling_info pragma.
|
|
%
|
|
|
|
mercury_output_pragma_mm_tabling_info(Stream, TablingInfo, !IO) :-
|
|
TablingInfo = pragma_info_mm_tabling_info(PredNameArityPFMn,
|
|
MM_TablingStatus),
|
|
PredNameArityPFMn = proc_pf_name_arity_mn(PredOrFunc, SymName,
|
|
user_arity(Arity), ModeNum),
|
|
PorFStr = pred_or_func_to_full_str(PredOrFunc),
|
|
SymNameStr = mercury_bracketed_sym_name_to_string(SymName),
|
|
(
|
|
MM_TablingStatus = mm_tabled_may_call,
|
|
MMStr = "mm_tabled_may_call"
|
|
;
|
|
MM_TablingStatus = mm_tabled_will_not_call,
|
|
MMStr = "mm_tabled_will_not_call"
|
|
;
|
|
MM_TablingStatus = mm_tabled_conditional,
|
|
MMStr = "mm_tabled_conditional"
|
|
),
|
|
io.format(Stream, ":- pragma mm_tabling_info(%s, %s, %d, %d, %s).\n",
|
|
[s(PorFStr), s(SymNameStr), i(Arity), i(ModeNum), s(MMStr)], !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output an obsolete_pred or obsolete_proc pragma.
|
|
%
|
|
|
|
:- pred mercury_output_pragma_obsolete_pred(io.text_output_stream::in,
|
|
pragma_info_obsolete_pred::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_pragma_obsolete_pred(Stream, ObsoletePredInfo, !IO) :-
|
|
ObsoletePredInfo = pragma_info_obsolete_pred(PredSpec, ObsoleteInFavourOf),
|
|
PredSpec = pred_pfu_name_arity(PFU, PredName, Arity),
|
|
PredStr = mercury_pred_pfu_name_arity_to_string(PFU, PredName, Arity),
|
|
ObsoleteStrs = list.map(wrapped_sym_name_arity_to_string,
|
|
ObsoleteInFavourOf),
|
|
ObsoleteStr = string.join_list(", ", ObsoleteStrs),
|
|
io.format(Stream, ":- pragma obsolete(%s, [%s]).\n",
|
|
[s(PredStr), s(ObsoleteStr)], !IO).
|
|
|
|
:- pred mercury_output_pragma_obsolete_proc(io.text_output_stream::in,
|
|
output_lang::in, pragma_info_obsolete_proc::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_pragma_obsolete_proc(Stream, Lang, ObsoleteProcInfo, !IO) :-
|
|
ObsoleteProcInfo =
|
|
pragma_info_obsolete_proc(PredNameModesPF, ObsoleteInFavourOf),
|
|
PredStr = proc_pf_name_modes_to_string(Lang, PredNameModesPF),
|
|
ObsoleteStrs = list.map(wrapped_sym_name_arity_to_string,
|
|
ObsoleteInFavourOf),
|
|
ObsoleteStr = string.join_list(", ", ObsoleteStrs),
|
|
io.format(Stream, ":- pragma obsolete_proc(%s, [%s]).\n",
|
|
[s(PredStr), s(ObsoleteStr)], !IO).
|
|
|
|
:- func wrapped_sym_name_arity_to_string(sym_name_arity) = string.
|
|
|
|
wrapped_sym_name_arity_to_string(SNA) = Str :-
|
|
SNA = sym_name_arity(SymName, Arity),
|
|
Str = mercury_bracketed_sym_name_to_string(SymName) ++
|
|
"/" ++ string.int_to_string(Arity).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a format_call pragma.
|
|
%
|
|
|
|
:- pred mercury_output_pragma_format_call(io.text_output_stream::in,
|
|
pragma_info_format_call::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_pragma_format_call(Stream, FormatCallInfo, !IO) :-
|
|
FormatCallInfo = pragma_info_format_call(PredSpec, OoMFormatArgsSpecs),
|
|
PredSpec = pred_pf_name_arity(PF, PredName, Arity),
|
|
PredStr = mercury_pred_pf_name_arity_to_string(PF, PredName, Arity),
|
|
OoMFormatArgsSpecs = one_or_more(HeadFormatArgsSpec, TailFormatArgsSpecs),
|
|
(
|
|
TailFormatArgsSpecs = [],
|
|
SecondArgStr = format_string_values_to_string(HeadFormatArgsSpec)
|
|
;
|
|
TailFormatArgsSpecs = [_ | _],
|
|
ArgsSpecsStrs = list.map(format_string_values_to_string,
|
|
[HeadFormatArgsSpec | TailFormatArgsSpecs]),
|
|
ArgsSpecsStr = string.join_list(", ", ArgsSpecsStrs),
|
|
string.format("[%s]", [s(ArgsSpecsStr)], SecondArgStr)
|
|
),
|
|
io.format(Stream, ":- pragma format_call(%s, [%s]).\n",
|
|
[s(PredStr), s(SecondArgStr)], !IO).
|
|
|
|
:- func format_string_values_to_string(format_string_values) = string.
|
|
|
|
format_string_values_to_string(FormatStringValues) = Str :-
|
|
FormatStringValues = format_string_values(OrigFS, OrigVL, _CurFS, _CurVL),
|
|
string.format("format_string_values(%d, %d)", [i(OrigFS), i(OrigVL)], Str).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a require tail recursion pragma.
|
|
%
|
|
|
|
:- pred mercury_output_pragma_require_tail_rec(io.text_output_stream::in,
|
|
output_lang::in, pragma_info_require_tail_rec::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_pragma_require_tail_rec(Stream, Lang, RequireTR, !IO) :-
|
|
RequireTR = pragma_info_require_tail_rec(PredOrProcSpec, Info),
|
|
ProcSpecStr = pred_or_proc_pfumm_name_to_string(Lang, PredOrProcSpec),
|
|
(
|
|
Info = suppress_tailrec_warnings(_),
|
|
io.format(Stream, ":- pragma warn_tail_recursion(%s, [none]).\n",
|
|
[s(ProcSpecStr)], !IO)
|
|
;
|
|
Info = enable_tailrec_warnings(WarnOrError, Type, _),
|
|
warning_or_error_string(WarnOrError, WarnOrErrorStr),
|
|
require_tailrec_type_string(Type, TypeStr),
|
|
io.format(Stream, ":- pragma warn_tail_recursion(%s, [%s, %s]).\n",
|
|
[s(ProcSpecStr), s(WarnOrErrorStr), s(TypeStr)], !IO)
|
|
).
|
|
|
|
:- func pred_or_proc_pfumm_name_to_string(output_lang,
|
|
pred_or_proc_pfumm_name) = string.
|
|
|
|
pred_or_proc_pfumm_name_to_string(Lang, PredOrProcSpec)
|
|
= PredOrProcSpecStr :-
|
|
PredOrProcSpec = pred_or_proc_pfumm_name(PFUMM, PredName),
|
|
(
|
|
PFUMM = pfumm_unknown(PredArity),
|
|
PredOrProcSpecStr =
|
|
mercury_pred_name_arity_to_string(PredName, PredArity)
|
|
;
|
|
(
|
|
PFUMM = pfumm_predicate(ModesOrArity),
|
|
PredOrFunc = pf_predicate
|
|
;
|
|
PFUMM = pfumm_function(ModesOrArity),
|
|
PredOrFunc = pf_function
|
|
),
|
|
(
|
|
ModesOrArity = moa_arity(Arity),
|
|
PredOrProcSpecStr = mercury_pred_pf_name_arity_to_string(
|
|
PredOrFunc, PredName, Arity)
|
|
;
|
|
ModesOrArity = moa_modes(Modes),
|
|
MaybeDet = maybe.no,
|
|
% XXX ARITY Compare to the corresponding code in
|
|
% mercury_format_pragma_foreign_proc_export.
|
|
varset.init(InstVarSet), % The varset isn't really used.
|
|
(
|
|
PredOrFunc = pf_predicate,
|
|
PredOrProcSpecStr = mercury_pred_mode_subdecl_to_string(Lang,
|
|
InstVarSet, PredName, Modes, MaybeDet)
|
|
;
|
|
PredOrFunc = pf_function,
|
|
pred_args_to_func_args(Modes, ArgModes, RetMode),
|
|
PredOrProcSpecStr = mercury_func_mode_subdecl_to_string(Lang,
|
|
InstVarSet, PredName, ArgModes, RetMode, MaybeDet)
|
|
)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a tabled pragma.
|
|
%
|
|
|
|
:- pred mercury_output_pragma_tabled(io.text_output_stream::in,
|
|
pragma_info_tabled::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_pragma_tabled(Stream, TabledInfo, !IO) :-
|
|
TabledInfo =
|
|
pragma_info_tabled(TabledMethod, PredOrProcSpec, MaybeAttributes),
|
|
PragmaName = tabled_eval_method_to_pragma_name(TabledMethod),
|
|
(
|
|
MaybeAttributes = yes(Attributes),
|
|
Attributes = table_attributes(Strictness, MaybeSizeLimit, Stats,
|
|
AllowReset, WarnForIgnore),
|
|
some [!Strs] (
|
|
!:Strs = [],
|
|
(
|
|
Strictness = cts_all_strict
|
|
;
|
|
Strictness = cts_all_fast_loose,
|
|
!:Strs = ["fast_loose" | !.Strs]
|
|
;
|
|
Strictness = cts_specified(Args, HiddenArgMethod),
|
|
ArgStrs = list.map(maybe_arg_tabling_method_to_string, Args),
|
|
ArgsStr = string.join_list(", ", ArgStrs),
|
|
(
|
|
HiddenArgMethod = table_hidden_arg_value,
|
|
HiddenArgStr = "hidden_arg_value"
|
|
;
|
|
HiddenArgMethod = table_hidden_arg_addr,
|
|
HiddenArgStr = "hidden_arg_addr"
|
|
),
|
|
SpecifiedStr = "specified([" ++ ArgsStr ++ "], " ++
|
|
HiddenArgStr ++ ")",
|
|
!:Strs = [SpecifiedStr | !.Strs]
|
|
),
|
|
(
|
|
MaybeSizeLimit = yes(SizeLimit),
|
|
LimitStr = "limit(" ++ int_to_string(SizeLimit) ++ ")",
|
|
!:Strs = [LimitStr | !.Strs]
|
|
;
|
|
MaybeSizeLimit = no
|
|
),
|
|
(
|
|
Stats = table_gather_statistics,
|
|
!:Strs = ["statistics" | !.Strs]
|
|
;
|
|
Stats = table_dont_gather_statistics
|
|
),
|
|
(
|
|
AllowReset = table_allow_reset,
|
|
!:Strs = ["allow_reset" | !.Strs]
|
|
;
|
|
AllowReset = table_dont_allow_reset
|
|
),
|
|
(
|
|
WarnForIgnore = table_attr_ignore_with_warning
|
|
;
|
|
WarnForIgnore = table_attr_ignore_without_warning,
|
|
!:Strs = ["disable_warning_if_ignored" | !.Strs]
|
|
),
|
|
(
|
|
!.Strs = [],
|
|
AfterStr = ""
|
|
;
|
|
!.Strs = [_ | _],
|
|
AfterStr = ", [" ++ string.join_list(", ", !.Strs) ++ "]"
|
|
)
|
|
)
|
|
;
|
|
MaybeAttributes = no,
|
|
AfterStr = ""
|
|
),
|
|
mercury_format_pragma_decl_pred_or_proc_pfumm_name(PragmaName,
|
|
PredOrProcSpec, AfterStr, Stream, !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a fact_table pragma.
|
|
%
|
|
|
|
:- pred mercury_format_pragma_fact_table(pragma_info_fact_table::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_fact_table(FactTableInfo, S, !U) :-
|
|
FactTableInfo = pragma_info_fact_table(PredSpec, FileName),
|
|
add_string(":- pragma fact_table(", S, !U),
|
|
PredSpec = pred_pfu_name_arity(PFU, PredName, UserArity),
|
|
mercury_format_pred_pfu_name_arity(PFU, PredName, UserArity, S, !U),
|
|
add_string(", ", S, !U),
|
|
add_quoted_string(FileName, S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output an oisu (order independent state update) pragma.
|
|
%
|
|
|
|
:- pred mercury_output_pragma_oisu(io.text_output_stream::in,
|
|
pragma_info_oisu::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_pragma_oisu(Stream, OISUInfo, !IO) :-
|
|
mercury_format_pragma_oisu(OISUInfo, Stream, !IO).
|
|
|
|
:- pred mercury_format_pragma_oisu(pragma_info_oisu::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_oisu(OISUInfo, S, !U) :-
|
|
OISUInfo = pragma_info_oisu(TypeCtor, CreatorPreds, MutatorPreds,
|
|
DestructorPreds),
|
|
add_string(":- pragma oisu(", S, !U),
|
|
TypeCtor = type_ctor(TypeName, TypeArity),
|
|
mercury_format_bracketed_sym_name_ngt(next_to_graphic_token, TypeName,
|
|
S, !U),
|
|
add_string("/", S, !U),
|
|
add_int(TypeArity, S, !U),
|
|
add_string(",\n", S, !U),
|
|
add_string("\tcreators([\n", S, !U),
|
|
mercury_format_pred_pf_name_arity_list(CreatorPreds, S, !U),
|
|
add_string("\t]),\n", S, !U),
|
|
add_string("\tmutators([\n", S, !U),
|
|
mercury_format_pred_pf_name_arity_list(MutatorPreds, S, !U),
|
|
add_string("\t]),\n", S, !U),
|
|
add_string("\tdestructors([\n", S, !U),
|
|
mercury_format_pred_pf_name_arity_list(DestructorPreds, S, !U),
|
|
add_string("\t])\n", S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
:- pred mercury_format_pred_pf_name_arity_list(list(pred_pf_name_arity)::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pred_pf_name_arity_list([], _S, !U).
|
|
mercury_format_pred_pf_name_arity_list([PredSpec | PredSpecs], S, !U) :-
|
|
mercury_format_pred_pf_name_arity_list_lag(PredSpec, PredSpecs, S, !U).
|
|
|
|
:- pred mercury_format_pred_pf_name_arity_list_lag(pred_pf_name_arity::in,
|
|
list(pred_pf_name_arity)::in, S::in, U::di, U::uo) is det
|
|
<= output(S, U).
|
|
|
|
mercury_format_pred_pf_name_arity_list_lag(PredSpec, PredSpecs, S, !U) :-
|
|
add_string("\t\t", S, !U),
|
|
PredSpec = pred_pf_name_arity(PredOrFunc, PredName, UserArity),
|
|
mercury_format_pred_pf_name_arity(PredOrFunc, PredName, UserArity, S, !U),
|
|
(
|
|
PredSpecs = [],
|
|
add_string("\n", S, !U)
|
|
;
|
|
PredSpecs = [HeadPredSpec | TailPredSpecs],
|
|
add_string(",\n", S, !U),
|
|
mercury_format_pred_pf_name_arity_list_lag(HeadPredSpec, TailPredSpecs,
|
|
S, !U)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a termination_info pragma.
|
|
%
|
|
|
|
write_pragma_termination_info(Stream, Lang, TermInfo, !IO) :-
|
|
TermInfo = pragma_info_termination_info(PredNameModesPF,
|
|
MaybeArgSize, MaybeTermination),
|
|
PredStr = proc_pf_name_modes_to_string(Lang, PredNameModesPF),
|
|
ArgSizeStr = maybe_arg_size_info_to_string(no, MaybeArgSize),
|
|
TermStr = maybe_termination_info_to_string(no, MaybeTermination),
|
|
io.format(Stream, ":- pragma termination_info(%s, %s, %s).\n",
|
|
[s(PredStr), s(ArgSizeStr), s(TermStr)], !IO).
|
|
|
|
maybe_arg_size_info_to_string(Verbose, MaybeArgSizeInfo) = Str :-
|
|
(
|
|
MaybeArgSizeInfo = no,
|
|
Str = "not_set"
|
|
;
|
|
MaybeArgSizeInfo = yes(finite(Const, UsedArgs)),
|
|
string.format("finite(%d, %s)",
|
|
[i(Const), s(used_args_to_string(UsedArgs))], Str)
|
|
;
|
|
MaybeArgSizeInfo = yes(infinite(ErrorInfo)),
|
|
(
|
|
Verbose = no,
|
|
Str = "infinite"
|
|
;
|
|
Verbose = yes,
|
|
string.format("infinite(%s)", [s(string.string(ErrorInfo))], Str)
|
|
)
|
|
).
|
|
|
|
:- func used_args_to_string(list(bool)) = string.
|
|
|
|
used_args_to_string(UsedArgs) = Str :-
|
|
BoolStrs = list.map(bool_to_string, UsedArgs),
|
|
string.format("[%s]", [s(string.join_list(", ", BoolStrs))], Str).
|
|
|
|
:- func bool_to_string(bool) = string.
|
|
|
|
bool_to_string(no) = "no".
|
|
bool_to_string(yes) = "yes".
|
|
|
|
maybe_termination_info_to_string(Verbose, MaybeTerminationInfo) = Str :-
|
|
(
|
|
MaybeTerminationInfo = no,
|
|
Str = "not_set"
|
|
;
|
|
MaybeTerminationInfo = yes(cannot_loop(_)),
|
|
Str = "cannot_loop"
|
|
;
|
|
MaybeTerminationInfo = yes(can_loop(ErrorInfo)),
|
|
(
|
|
Verbose = no,
|
|
Str = "can_loop"
|
|
;
|
|
Verbose = yes,
|
|
string.format("can_loop(%s)", [s(string.string(ErrorInfo))], Str)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a termination2_info pragma.
|
|
%
|
|
|
|
write_pragma_termination2_info(Stream, Lang, Term2Info, !IO) :-
|
|
Term2Info = pragma_info_termination2_info(PredNameModesPF,
|
|
MaybeSuccess, MaybeFailure, MaybeTermination),
|
|
PredStr = proc_pf_name_modes_to_string(Lang, PredNameModesPF),
|
|
SuccessStr = maybe_pragma_constr_arg_size_info_to_string(MaybeSuccess),
|
|
FailureStr = maybe_pragma_constr_arg_size_info_to_string(MaybeFailure),
|
|
TermStr = maybe_pragma_termination_info_to_string(MaybeTermination),
|
|
io.format(Stream, ":- pragma termination2_info(%s, %s, %s, %s).\n",
|
|
[s(PredStr), s(SuccessStr), s(FailureStr), s(TermStr)], !IO).
|
|
|
|
:- func maybe_pragma_constr_arg_size_info_to_string(
|
|
maybe(pragma_constr_arg_size_info)) = string.
|
|
|
|
maybe_pragma_constr_arg_size_info_to_string(no) = "not_set".
|
|
maybe_pragma_constr_arg_size_info_to_string(yes(ArgSizeConstraints)) = Str :-
|
|
ConstraintStrs = list.map(arg_size_constr_to_string, ArgSizeConstraints),
|
|
ConstraintsStr = string.join_list(", ", ConstraintStrs),
|
|
Str = string.format("constraints([%s])", [s(ConstraintsStr)]).
|
|
|
|
:- func arg_size_constr_to_string(arg_size_constr) = string.
|
|
|
|
arg_size_constr_to_string(Constraint) = Str :-
|
|
(
|
|
Constraint = le(Terms, Constant),
|
|
OpStr = "le"
|
|
;
|
|
Constraint = eq(Terms, Constant),
|
|
OpStr = "eq"
|
|
),
|
|
TermStrs = list.map(arg_size_term_to_string, Terms),
|
|
TermsStr = string.join_list(", ", TermStrs),
|
|
Str = string.format("%s([%s], %s)",
|
|
[s(OpStr), s(TermsStr), s(rat.to_rat_string(Constant))]).
|
|
|
|
:- func arg_size_term_to_string(arg_size_term) = string.
|
|
|
|
arg_size_term_to_string(arg_size_term(VarId, Coeff)) =
|
|
string.format("term(%d, %s)", [i(VarId), s(rat.to_rat_string(Coeff))]).
|
|
|
|
:- func maybe_pragma_termination_info_to_string(maybe(pragma_termination_info))
|
|
= string.
|
|
|
|
maybe_pragma_termination_info_to_string(MaybeTermination) = Str :-
|
|
(
|
|
MaybeTermination = no,
|
|
Str = "not_set"
|
|
;
|
|
MaybeTermination = yes(Termination),
|
|
(
|
|
Termination = can_loop(_),
|
|
Str = "can_loop"
|
|
;
|
|
Termination = cannot_loop(_),
|
|
Str = "cannot_loop"
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a structure_sharing pragma.
|
|
%
|
|
|
|
write_pragma_structure_sharing_info(Stream, Lang, SharingInfo, !IO) :-
|
|
SharingInfo = pragma_info_structure_sharing(PredNameModesPF,
|
|
HeadVars, HeadVarTypes, VarSet, TVarSet, MaybeSharingAs),
|
|
PredStr = proc_pf_name_modes_to_string(Lang, PredNameModesPF),
|
|
io.format(Stream, ":- pragma structure_sharing(%s, ", [s(PredStr)], !IO),
|
|
% write headvars and types:
|
|
write_vars_and_types(Stream, VarSet, TVarSet, HeadVars, HeadVarTypes, !IO),
|
|
% write structure sharing information.
|
|
io.write_string(Stream, ", ", !IO),
|
|
prog_ctgc.print_interface_structure_sharing_domain(Stream,
|
|
vns_varset(VarSet), TVarSet, MaybeSharingAs, !IO),
|
|
io.write_string(Stream, ").\n", !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a structure_reuse pragma.
|
|
%
|
|
|
|
write_pragma_structure_reuse_info(Stream, Lang, ReuseInfo, !IO) :-
|
|
ReuseInfo = pragma_info_structure_reuse(PredNameModesPF,
|
|
HeadVars, HeadVarTypes, VarSet, TVarSet, MaybeStructureReuseDomain),
|
|
PredStr = proc_pf_name_modes_to_string(Lang, PredNameModesPF),
|
|
io.format(Stream, ":- pragma structure_reuse(%s, ", [s(PredStr)], !IO),
|
|
% write headvars and types:
|
|
write_vars_and_types(Stream, VarSet, TVarSet, HeadVars, HeadVarTypes, !IO),
|
|
% write structure reuse information.
|
|
io.write_string(Stream, ", ", !IO),
|
|
prog_ctgc.print_interface_maybe_structure_reuse_domain(Stream,
|
|
vns_varset(VarSet), TVarSet, MaybeStructureReuseDomain, !IO),
|
|
io.write_string(Stream, ").\n", !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Predicates used to help print both structure_sharing and structure_reuse
|
|
% pragmas.
|
|
%
|
|
|
|
:- pred write_vars_and_types(io.text_output_stream::in,
|
|
prog_varset::in, tvarset::in, prog_vars::in, list(mer_type)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
write_vars_and_types(Stream, VarSet, TypeVarSet, HeadVars, HeadVarTypes,
|
|
!IO) :-
|
|
(
|
|
HeadVars = [],
|
|
io.write_string(Stream, "vars, types", !IO)
|
|
;
|
|
HeadVars = [_ | _],
|
|
io.write_string(Stream, "vars(", !IO),
|
|
mercury_output_vars_vs(VarSet, print_name_only, HeadVars, Stream, !IO),
|
|
io.write_string(Stream, "), ", !IO),
|
|
|
|
io.write_string(Stream, "types(", !IO),
|
|
write_out_list(mercury_output_type(TypeVarSet, print_name_only),
|
|
", ", HeadVarTypes, Stream, !IO),
|
|
io.write_string(Stream, ")", !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Output a require_feature_set pragma.
|
|
%
|
|
|
|
:- pred mercury_format_pragma_require_feature_set(
|
|
pragma_info_require_feature_set::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pragma_require_feature_set(RFSInfo, S, !U) :-
|
|
RFSInfo = pragma_info_require_feature_set(Features0),
|
|
Features = set.to_sorted_list(Features0),
|
|
add_string(":- pragma require_feature_set(", S, !U),
|
|
add_list(mercury_format_required_feature, ", ", Features, S, !U),
|
|
add_string(").\n", S, !U).
|
|
|
|
:- pred mercury_format_required_feature(required_feature::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_required_feature(Feature, S, !U) :-
|
|
( Feature = reqf_concurrency, Str = "concurrency"
|
|
; Feature = reqf_single_prec_float, Str = "single_prec_float"
|
|
; Feature = reqf_double_prec_float, Str = "double_prec_float"
|
|
; Feature = reqf_memo, Str = "memo"
|
|
; Feature = reqf_parallel_conj, Str = "parallel_conj"
|
|
; Feature = reqf_trailing, Str = "trailing"
|
|
; Feature = reqf_strict_sequential, Str = "strict_sequential"
|
|
; Feature = reqf_conservative_gc, Str = "conservative_gc"
|
|
),
|
|
add_string(Str, S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Utility predicates.
|
|
%
|
|
|
|
:- func mercury_pred_name_arity_to_string(sym_name, user_arity) = string.
|
|
|
|
mercury_pred_name_arity_to_string(PredName, UserArity) = String :-
|
|
mercury_format_pred_name_arity(PredName, UserArity, unit, "", String).
|
|
|
|
:- pred mercury_format_pred_name_arity(sym_name::in, user_arity::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pred_name_arity(PredName, user_arity(Arity), S, !U) :-
|
|
NGT = next_to_graphic_token,
|
|
mercury_format_bracketed_sym_name_ngt(NGT, PredName, S, !U),
|
|
add_string("/", S, !U),
|
|
add_int(Arity, S, !U).
|
|
|
|
:- func mercury_pred_pf_name_arity_to_string(pred_or_func, sym_name,
|
|
user_arity) = string.
|
|
|
|
mercury_pred_pf_name_arity_to_string(PredOrFunc, PredName, Arity) = String :-
|
|
mercury_format_pred_pf_name_arity(PredOrFunc, PredName, Arity,
|
|
unit, "", String).
|
|
|
|
:- pred mercury_format_pred_pf_name_arity(pred_or_func::in,
|
|
sym_name::in, user_arity::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pred_pf_name_arity(PredOrFunc, PredName, UserArity, S, !U) :-
|
|
add_string(pred_or_func_to_str(PredOrFunc), S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_pred_name_arity(PredName, UserArity, S, !U),
|
|
add_string(")", S, !U).
|
|
|
|
:- func mercury_pred_pfu_name_arity_to_string(pred_func_or_unknown,
|
|
sym_name, user_arity) = string.
|
|
|
|
mercury_pred_pfu_name_arity_to_string(PFU, PredName, UserArity) = String :-
|
|
mercury_format_pred_pfu_name_arity(PFU, PredName, UserArity,
|
|
unit, "", String).
|
|
|
|
:- pred mercury_format_pred_pfu_name_arity(pred_func_or_unknown::in,
|
|
sym_name::in, user_arity::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_pred_pfu_name_arity(PFU, PredName, UserArity, S, !U) :-
|
|
(
|
|
( PFU = pfu_predicate, PredOrFunc = pf_predicate
|
|
; PFU = pfu_function, PredOrFunc = pf_function
|
|
),
|
|
mercury_format_pred_pf_name_arity(PredOrFunc, PredName, UserArity,
|
|
S, !U)
|
|
;
|
|
PFU = pfu_unknown,
|
|
mercury_format_pred_name_arity(PredName, UserArity, S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
:- func proc_pf_name_modes_to_string(output_lang, proc_pf_name_modes) = string.
|
|
|
|
proc_pf_name_modes_to_string(Lang, PredNameModesPF) = Str :-
|
|
PredNameModesPF = proc_pf_name_modes(PredOrFunc, SymName, Modes),
|
|
varset.init(InstVarSet),
|
|
MaybeDet = no,
|
|
(
|
|
PredOrFunc = pf_predicate,
|
|
Str = mercury_pred_mode_subdecl_to_string(Lang, InstVarSet, SymName,
|
|
Modes, MaybeDet)
|
|
;
|
|
PredOrFunc = pf_function,
|
|
pred_args_to_func_args(Modes, FuncArgModes, ReturnArgMode),
|
|
Str = mercury_func_mode_subdecl_to_string(Lang, InstVarSet, SymName,
|
|
FuncArgModes, ReturnArgMode, MaybeDet)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func int_list_to_string(list(int)) = string.
|
|
|
|
int_list_to_string(Ints) = Str :-
|
|
mercury_format_int_list(Ints, unit, "", Str).
|
|
|
|
:- pred mercury_format_int_list(list(int)::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_int_list([], _S, !U).
|
|
mercury_format_int_list([Head | Tail], S, !U) :-
|
|
add_int(Head, S, !U),
|
|
mercury_format_int_list_2(Tail, S, !U).
|
|
|
|
:- pred mercury_format_int_list_2(list(int)::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_int_list_2([], _S, !U).
|
|
mercury_format_int_list_2([Head | Tail], S, !U) :-
|
|
add_string(", ", S, !U),
|
|
add_int(Head, S, !U),
|
|
mercury_format_int_list_2(Tail, S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module parse_tree.parse_tree_out_pragma.
|
|
%---------------------------------------------------------------------------%
|