Files
mercury/compiler/parse_tree_out_pred_decl.m
Julien Fischer ba31ed494b Update and fix copyright notices.
compiler/*.m:
    As above.
2024-12-30 22:16:59 +11:00

568 lines
24 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2015-2016, 2019-2021, 2023-2024 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
% predicate and function declarations back into Mercury source text.
%
% Many of the predicates in this module are have two slightly different
% versions. Either one is for functions and the other is for predicates,
% or one is for known functions and the other for predicates *and* for
% functions that are not known to be functions due to the use of a
% `with_type` annotation, which hides the return type.
%
%---------------------------------------------------------------------------%
:- module parse_tree.parse_tree_out_pred_decl.
:- interface.
:- import_module mdbcomp.
:- import_module mdbcomp.prim_data.
:- import_module mdbcomp.sym_name.
:- import_module parse_tree.parse_tree_out_info.
:- import_module parse_tree.parse_tree_output.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_item.
:- import_module io.
:- import_module list.
:- import_module maybe.
:- import_module string.
:- import_module string.builder.
%---------------------------------------------------------------------------%
% XXX Document me.
%
:- pred mercury_format_pred_or_func_decl(output_lang::in, var_name_print::in,
tvarset::in, inst_varset::in, pred_or_func::in, existq_tvars::in,
sym_name::in, types_and_maybe_modes::in,
maybe(mer_type)::in, maybe(mer_inst)::in, maybe(determinism)::in,
purity::in, univ_exist_constraints::in, string::in, string::in, string::in,
S::in, U::di, U::uo) is det <= pt_output(S, U).
% XXX Document me.
%
:- pred mercury_format_func_decl(output_lang::in, var_name_print::in,
tvarset::in, inst_varset::in, existq_tvars::in, sym_name::in,
types_and_maybe_modes::in, maybe(determinism)::in, purity::in,
univ_exist_constraints::in, string::in, string::in, string::in,
S::in, U::di, U::uo) is det <= pt_output(S, U).
%---------------------------------------------------------------------------%
% Output a `:- pred' declaration.
%
:- func mercury_pred_type_to_string(tvarset, var_name_print,
existq_tvars, sym_name, list(mer_type), maybe(determinism),
purity, univ_exist_constraints) = string.
:- pred mercury_output_pred_type(io.text_output_stream::in, tvarset::in,
var_name_print::in, existq_tvars::in, sym_name::in, list(mer_type)::in,
maybe(determinism)::in, purity::in, univ_exist_constraints::in,
io::di, io::uo) is det.
:- pred mercury_format_pred_type(tvarset::in, var_name_print::in,
existq_tvars::in, sym_name::in, list(mer_type)::in,
maybe(determinism)::in, purity::in, univ_exist_constraints::in,
S::in, U::di, U::uo) is det <= pt_output(S, U).
% Output a `:- func' declaration.
%
:- func mercury_func_type_to_string(tvarset, var_name_print,
existq_tvars, sym_name, list(mer_type), mer_type, maybe(determinism),
purity, univ_exist_constraints) = string.
:- pred mercury_output_func_type(io.text_output_stream::in,
tvarset::in, var_name_print::in, existq_tvars::in, sym_name::in,
list(mer_type)::in, mer_type::in, maybe(determinism)::in, purity::in,
univ_exist_constraints::in, io::di, io::uo) is det.
:- pred mercury_format_func_type(tvarset::in, var_name_print::in,
existq_tvars::in, sym_name::in, list(mer_type)::in, mer_type::in,
maybe(determinism)::in, purity::in, univ_exist_constraints::in,
S::in, U::di, U::uo) is det <= pt_output(S, U).
%---------------------------------------------------------------------------%
% XXX Document me.
%
:- func mercury_pred_mode_decl_to_string(output_lang, inst_varset, sym_name,
list(mer_mode), maybe(mer_inst), maybe(determinism)) = string.
:- pred mercury_output_pred_mode_decl(io.text_output_stream::in,
output_lang::in, inst_varset::in, sym_name::in,
list(mer_mode)::in, maybe(mer_inst)::in, maybe(determinism)::in,
io::di, io::uo) is det.
:- pred mercury_format_pred_mode_decl(output_lang::in,
inst_varset::in, sym_name::in, list(mer_mode)::in, maybe(mer_inst)::in,
maybe(determinism)::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
:- pred mercury_format_pred_or_func_mode_decl_gen(output_lang::in,
inst_varset::in, sym_name::in, list(mer_mode)::in, maybe(mer_inst)::in,
maybe(determinism)::in, string::in, string::in,
S::in, U::di, U::uo) is det <= pt_output(S, U).
% XXX Document me.
%
:- func mercury_func_mode_decl_to_string(output_lang, inst_varset, sym_name,
list(mer_mode), mer_mode, maybe(determinism)) = string.
:- pred mercury_output_func_mode_decl(io.text_output_stream::in,
output_lang::in, inst_varset::in, sym_name::in,
list(mer_mode)::in, mer_mode::in, maybe(determinism)::in,
io::di, io::uo) is det.
:- pred mercury_format_func_mode_decl(output_lang::in, inst_varset::in,
sym_name::in, list(mer_mode)::in, mer_mode::in, maybe(determinism)::in,
S::in, U::di, U::uo) is det <= pt_output(S, U).
:- pred mercury_format_func_mode_decl_gen(output_lang::in, inst_varset::in,
sym_name::in, list(mer_mode)::in, mer_mode::in, maybe(determinism)::in,
string::in, string::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
% XXX Document me.
%
:- func mercury_mode_subdecl_to_string(output_lang, pred_or_func, inst_varset,
sym_name, list(mer_mode), maybe(determinism)) = string.
:- pred mercury_output_mode_subdecl(io.text_output_stream::in,
output_lang::in, pred_or_func::in, inst_varset::in, sym_name::in,
list(mer_mode)::in, maybe(determinism)::in, io::di, io::uo) is det.
:- pred mercury_format_mode_subdecl(output_lang::in, pred_or_func::in,
inst_varset::in, sym_name::in, list(mer_mode)::in, maybe(determinism)::in,
S::in, U::di, U::uo) is det <= pt_output(S, U).
% XXX Document me.
%
:- func mercury_pred_mode_subdecl_to_string(output_lang, inst_varset, sym_name,
list(mer_mode), maybe(determinism)) = string.
:- pred mercury_output_pred_mode_subdecl(io.text_output_stream::in,
output_lang::in, inst_varset::in, sym_name::in,
list(mer_mode)::in, maybe(determinism)::in, io::di, io::uo) is det.
:- pred mercury_format_pred_or_func_mode_subdecl(output_lang::in,
inst_varset::in, sym_name::in, list(mer_mode)::in, maybe(mer_inst)::in,
maybe(determinism)::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
% XXX Document me.
%
:- func mercury_func_mode_subdecl_to_string(output_lang, inst_varset, sym_name,
list(mer_mode), mer_mode, maybe(determinism)) = string.
:- pred mercury_output_func_mode_subdecl(io.text_output_stream::in,
output_lang::in, inst_varset::in, sym_name::in,
list(mer_mode)::in, mer_mode::in, maybe(determinism)::in,
io::di, io::uo) is det.
:- pred mercury_format_func_mode_subdecl(output_lang::in, inst_varset::in,
sym_name::in, list(mer_mode)::in, mer_mode::in, maybe(determinism)::in,
S::in, U::di, U::uo) is det <= pt_output(S, U).
%---------------------------------------------------------------------------%
:- pragma type_spec_constrained_preds([pt_output(Stream, State)],
apply_to_superclasses,
[subst([Stream => io.text_output_stream, State = io.state]),
subst([Stream => string.builder.handle, State = string.builder.state])]).
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module parse_tree.parse_tree_out_inst.
:- import_module parse_tree.parse_tree_out_misc.
:- import_module parse_tree.parse_tree_out_sym_name.
:- import_module parse_tree.parse_tree_out_term.
:- import_module parse_tree.parse_tree_out_type.
:- import_module parse_tree.prog_util.
:- import_module require.
:- import_module varset.
%---------------------------------------------------------------------------%
mercury_format_pred_or_func_decl(Lang, VarNamePrint, TypeVarSet, InstVarSet,
PredOrFunc, ExistQVars, PredName, TypesAndMaybeModes,
MaybeWithType, MaybeWithInst, MaybeDet0, Purity, ClassContext,
StartString, Separator, Terminator, S, !U) :-
get_declared_types_and_maybe_modes(TypesAndMaybeModes, MaybeWithInst,
MaybeDet0, Types, MaybeModes),
(
MaybeModes = yes(Modes),
MaybeDet1 = maybe.no,
mercury_format_pred_or_func_type_decl_2(TypeVarSet, VarNamePrint,
PredOrFunc, ExistQVars, PredName, Types, MaybeWithType, MaybeDet1,
Purity, ClassContext, StartString, Separator, S, !U),
mercury_format_pred_or_func_mode_decl_gen(Lang, InstVarSet, PredName,
Modes, MaybeWithInst, MaybeDet0, StartString, Terminator, S, !U)
;
MaybeModes = no,
mercury_format_pred_or_func_type_decl_2(TypeVarSet, VarNamePrint,
PredOrFunc, ExistQVars, PredName, Types, MaybeWithType, MaybeDet0,
Purity, ClassContext, StartString, Terminator, S, !U)
).
%---------------------%
mercury_format_func_decl(Lang, VarNamePrint, TypeVarSet, InstVarSet,
ExistQVars, FuncName, TypesAndMaybeModes,
MaybeDet, Purity, ClassContext, StartString, Separator, Terminator,
S, !U) :-
(
TypesAndMaybeModes = no_types_arity_zero,
% There should be at least a type for the return value.
unexpected($pred, "no_types_arity_zero")
;
TypesAndMaybeModes = types_only(Types),
pred_args_to_func_args(Types, ArgTypes, RetType),
mercury_format_func_type_2(TypeVarSet, VarNamePrint,
ExistQVars, FuncName, ArgTypes, RetType, MaybeDet, Purity,
ClassContext, StartString, Terminator, S, !U)
;
TypesAndMaybeModes = types_and_modes(TypesAndModes),
split_types_and_modes(TypesAndModes, Types, Modes),
pred_args_to_func_args(Types, ArgTypes, RetType),
pred_args_to_func_args(Modes, ArgModes, RetMode),
mercury_format_func_type_2(TypeVarSet, VarNamePrint,
ExistQVars, FuncName, ArgTypes, RetType, no, Purity,
ClassContext, StartString, Separator, S, !U),
mercury_format_func_mode_decl_gen(Lang, InstVarSet, FuncName,
ArgModes, RetMode, MaybeDet, StartString, Terminator, S, !U)
).
%---------------------------------------------------------------------------%
mercury_pred_type_to_string(TypeVarSet, VarNamePrint, ExistQVars, PredName,
Types, MaybeDet, Purity, ClassContext) = Str :-
State0 = string.builder.init,
mercury_format_pred_type(TypeVarSet, VarNamePrint, ExistQVars,
PredName, Types, MaybeDet, Purity, ClassContext,
string.builder.handle, State0, State),
Str = string.builder.to_string(State).
mercury_output_pred_type(Stream, TypeVarSet, VarNamePrint, ExistQVars,
PredName, Types, MaybeDet, Purity, ClassContext, !IO) :-
mercury_format_pred_type(TypeVarSet, VarNamePrint, ExistQVars, PredName,
Types, MaybeDet, Purity, ClassContext, Stream, !IO).
mercury_format_pred_type(TypeVarSet, VarNamePrint, ExistQVars, PredName,
Types, MaybeDet, Purity, ClassContext, S, !U) :-
MaybeWithType = maybe.no,
mercury_format_pred_or_func_type_decl_2(TypeVarSet, VarNamePrint,
pf_predicate, ExistQVars, PredName, Types, MaybeWithType, MaybeDet,
Purity, ClassContext, ":- ", ".\n", S, !U).
%---------------------%
mercury_func_type_to_string(TypeVarSet, VarNamePrint, ExistQVars, FuncName,
ArgTypes, RetType, MaybeDet, Purity, ClassContext) = Str :-
State0 = string.builder.init,
mercury_format_func_type(TypeVarSet, VarNamePrint, ExistQVars,
FuncName, ArgTypes, RetType, MaybeDet, Purity, ClassContext,
string.builder.handle, State0, State),
Str = string.builder.to_string(State).
mercury_output_func_type(Stream, VarSet, ExistQVars, FuncName,
ArgTypes, RetType, MaybeDet, Purity, ClassContext, VarNamePrint,
!IO) :-
mercury_format_func_type(VarSet, ExistQVars, FuncName, ArgTypes, RetType,
MaybeDet, Purity, ClassContext, VarNamePrint, Stream, !IO).
mercury_format_func_type(TypeVarSet, VarNamePrint, ExistQVars, FuncName,
ArgTypes, RetType, MaybeDet, Purity, ClassContext, S, !U) :-
mercury_format_func_type_2(TypeVarSet, VarNamePrint, ExistQVars, FuncName,
ArgTypes, RetType, MaybeDet, Purity, ClassContext, ":- ", ".\n",
S, !U).
%---------------------------------------------------------------------------%
%
% Predicates used in the implementation of both
% mercury_format_pred_or_func_decl/mercury_format_func_decl
% and
% mercury_format_pred_type/mercury_format_func_type.
%
:- pred mercury_format_pred_or_func_type_decl_2( tvarset::in,
var_name_print::in, pred_or_func::in, existq_tvars::in,
sym_name::in, list(mer_type)::in, maybe(mer_type)::in,
maybe(determinism)::in, purity::in, univ_exist_constraints::in,
string::in, string::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
mercury_format_pred_or_func_type_decl_2(TypeVarSet, VarNamePrint, PredOrFunc,
ExistQVars, PredName, Types, MaybeWithType, MaybeDet, Purity,
Constraints, StartString, Separator, S, !U) :-
add_string(StartString, S, !U),
mercury_format_quantifier(TypeVarSet, VarNamePrint, ExistQVars, S, !U),
Constraints = univ_exist_constraints(UnivConstraints, ExistConstraints),
( if
ExistQVars = [],
ExistConstraints = []
then
MaybeExistConstraints = no_exist_constraints
else
MaybeExistConstraints =
have_exist_constraints_print_paren(ExistConstraints),
add_string("(", S, !U)
),
add_purity_prefix(Purity, S, !U),
PredOrFuncStr = pred_or_func_to_str(PredOrFunc),
add_string(PredOrFuncStr, S, !U),
add_string(" ", S, !U),
(
Types = [_ | _],
% The following left parenthesis is a graphic token.
mercury_format_sym_name_ngt(next_to_graphic_token, PredName, S, !U),
add_string("(", S, !U),
add_list(mercury_format_type(TypeVarSet, VarNamePrint), ", ", Types,
S, !U),
add_string(")", S, !U)
;
Types = [],
% In a zero arity predicate declaration containing no determinism
% information, the next token could be the period that signifies
% the end of the declaration.
mercury_format_bracketed_sym_name_ngt(next_to_graphic_token, PredName,
S, !U)
),
(
MaybeWithType = yes(WithType),
add_string(" `with_type` (", S, !U),
mercury_format_type(TypeVarSet, VarNamePrint, WithType, S, !U),
add_string(")", S, !U)
;
MaybeWithType = no
),
% We need to handle is/2 specially, because it is used for determinism
% annotations (`... is det'), and so the compiler will misinterpret
% a bare `:- pred is(int, int_expr)' as % `:- pred int is int_expr'
% and then report some very confusing error message. Thus you _have_
% to give a determinism annotation in the pred declaration for is/2,
% e.g. `:- pred is(int, int_expr) is det.' (Yes, this made me puke too.)
%
% The alternative is a term traversal in parse_determinism_suffix in
% parse_item.m. That alternative is nicer, but it is less efficient.
( if
PredOrFunc = pf_predicate,
MaybeDet = no,
unqualify_name(PredName) = "is",
list.length(Types, 2)
then
% This determinism will be ignored.
mercury_format_det_annotation(yes(detism_det), S, !U)
else
mercury_format_det_annotation(MaybeDet, S, !U)
),
mercury_format_class_context(TypeVarSet, VarNamePrint,
UnivConstraints, MaybeExistConstraints, S, !U),
add_string(Separator, S, !U).
%---------------------%
:- pred mercury_format_func_type_2(tvarset::in, var_name_print::in,
existq_tvars::in, sym_name::in, list(mer_type)::in, mer_type::in,
maybe(determinism)::in, purity::in, univ_exist_constraints::in,
string::in, string::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
mercury_format_func_type_2(VarSet, VarNamePrint, ExistQVars, FuncName, Types,
RetType, MaybeDet, Purity, Constraints, StartString, Separator,
S, !U) :-
add_string(StartString, S, !U),
mercury_format_quantifier(VarSet, VarNamePrint, ExistQVars, S, !U),
Constraints = univ_exist_constraints(UnivConstraints, ExistConstraints),
( if
ExistQVars = [],
ExistConstraints = []
then
MaybeExistConstraints = no_exist_constraints
else
MaybeExistConstraints =
have_exist_constraints_print_paren(ExistConstraints),
add_string("(", S, !U)
),
add_purity_prefix(Purity, S, !U),
add_string("func ", S, !U),
(
Types = [_ | _],
% The following left parenthesis is a graphic token.
mercury_format_sym_name_ngt(next_to_graphic_token, FuncName, S, !U),
add_string("(", S, !U),
add_list(mercury_format_type(VarSet, VarNamePrint), ", ", Types,
S, !U),
add_string(")", S, !U)
;
Types = [],
% In a zero arity predicate declaration containing no determinism
% information, the next token could be the period that signifies
% the end of the declaration. For functions, that cannot happen,
% but treating this call as being next to a graphic token is
% consistent with the corresponding code for predicates above.
mercury_format_bracketed_sym_name_ngt(next_to_graphic_token, FuncName,
S, !U)
),
add_string(" = ", S, !U),
mercury_format_type(VarSet, VarNamePrint, RetType, S, !U),
mercury_format_det_annotation(MaybeDet, S, !U),
mercury_format_class_context(VarSet, VarNamePrint,
UnivConstraints, MaybeExistConstraints, S, !U),
add_string(Separator, S, !U).
%---------------------------------------------------------------------------%
mercury_pred_mode_decl_to_string(Lang, VarSet, PredName, Modes,
MaybeWithInst, MaybeDet) = Str :-
State0 = string.builder.init,
mercury_format_pred_mode_decl(Lang, VarSet, PredName, Modes,
MaybeWithInst, MaybeDet, string.builder.handle, State0, State),
Str = string.builder.to_string(State).
mercury_output_pred_mode_decl(Stream, Lang, VarSet, PredName, Modes,
MaybeWithInst, MaybeDet, !IO) :-
mercury_format_pred_mode_decl(Lang, VarSet, PredName, Modes,
MaybeWithInst, MaybeDet, Stream, !IO).
mercury_format_pred_mode_decl(Lang, VarSet, PredName, Modes,
MaybeWithInst, MaybeDet, S, !U) :-
mercury_format_pred_or_func_mode_decl_gen(Lang, VarSet, PredName, Modes,
MaybeWithInst, MaybeDet, ":- ", ".\n", S, !U).
mercury_format_pred_or_func_mode_decl_gen(Lang, VarSet, PredName, Modes,
MaybeWithInst, MaybeDet, StartString, Separator, S, !U) :-
add_string(StartString, S, !U),
add_string("mode ", S, !U),
mercury_format_pred_or_func_mode_subdecl(Lang, VarSet, PredName, Modes,
MaybeWithInst, MaybeDet, S, !U),
add_string(Separator, S, !U).
%---------------------%
mercury_func_mode_decl_to_string(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet) = Str :-
State0 = string.builder.init,
mercury_format_func_mode_decl(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, string.builder.handle, State0, State),
Str = string.builder.to_string(State).
mercury_output_func_mode_decl(Stream, Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, !IO) :-
mercury_format_func_mode_decl(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, Stream, !IO).
mercury_format_func_mode_decl(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, S, !U) :-
mercury_format_func_mode_decl_gen(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, ":- ", ".\n", S, !U).
mercury_format_func_mode_decl_gen(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, StartString, Separator, S, !U) :-
add_string(StartString, S, !U),
add_string("mode ", S, !U),
mercury_format_func_mode_subdecl(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, S, !U),
add_string(Separator, S, !U).
%---------------------------------------------------------------------------%
mercury_mode_subdecl_to_string(Lang, PredOrFunc, InstVarSet, Name, Modes,
MaybeDet) = Str :-
State0 = string.builder.init,
mercury_format_mode_subdecl(Lang, PredOrFunc, InstVarSet, Name, Modes,
MaybeDet, string.builder.handle, State0, State),
Str = string.builder.to_string(State).
mercury_output_mode_subdecl(Stream, Lang, PredOrFunc, InstVarSet, Name, Modes,
MaybeDet, !IO) :-
mercury_format_mode_subdecl(Lang, PredOrFunc, InstVarSet, Name, Modes,
MaybeDet, Stream, !IO).
mercury_format_mode_subdecl(Lang, PredOrFunc, InstVarSet, Name, Modes,
MaybeDet, S, !U) :-
(
PredOrFunc = pf_predicate,
mercury_format_pred_or_func_mode_subdecl(Lang, InstVarSet, Name,
Modes, no, MaybeDet, S, !U)
;
PredOrFunc = pf_function,
pred_args_to_func_args(Modes, ArgModes, RetMode),
mercury_format_func_mode_subdecl(Lang, InstVarSet, Name, ArgModes,
RetMode, MaybeDet, S, !U)
).
%---------------------%
mercury_pred_mode_subdecl_to_string(Lang, VarSet, PredName, Modes, MaybeDet)
= Str :-
State0 = string.builder.init,
mercury_format_pred_or_func_mode_subdecl(Lang, VarSet, PredName, Modes, no,
MaybeDet, string.builder.handle, State0, State),
Str = string.builder.to_string(State).
mercury_output_pred_mode_subdecl(Stream, Lang, VarSet, PredName, Modes,
MaybeDet, !IO) :-
mercury_format_pred_or_func_mode_subdecl(Lang, VarSet, PredName,
Modes, no, MaybeDet, Stream, !IO).
mercury_format_pred_or_func_mode_subdecl(Lang, InstVarSet, PredName, Modes,
MaybeWithInst, MaybeDet, S, !U) :-
(
Modes = [_ | _],
mercury_format_sym_name_ngt(next_to_graphic_token, PredName, S, !U),
add_string("(", S, !U),
mercury_format_mode_list(Lang, InstVarSet, Modes, S, !U),
add_string(")", S, !U)
;
Modes = [],
mercury_format_bracketed_sym_name_ngt(next_to_graphic_token, PredName,
S, !U)
),
(
MaybeWithInst = yes(WithInst),
add_string(" `with_inst` (", S, !U),
mercury_format_inst(Lang, InstVarSet, WithInst, S, !U),
add_string(")", S, !U)
;
MaybeWithInst = no
),
mercury_format_det_annotation(MaybeDet, S, !U).
%---------------------%
mercury_func_mode_subdecl_to_string(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet) = Str :-
State0 = string.builder.init,
mercury_format_func_mode_subdecl(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, string.builder.handle, State0, State),
Str = string.builder.to_string(State).
mercury_output_func_mode_subdecl(Stream, Lang, VarSet, FuncName,
Modes, RetMode, MaybeDet, !IO) :-
mercury_format_func_mode_subdecl(Lang, VarSet, FuncName, Modes, RetMode,
MaybeDet, Stream, !IO).
mercury_format_func_mode_subdecl(Lang, InstVarSet, FuncName, Modes, RetMode,
MaybeDet, S, !U) :-
(
Modes = [_ | _],
mercury_format_sym_name_ngt(next_to_graphic_token, FuncName, S, !U),
add_string("(", S, !U),
mercury_format_mode_list(Lang, InstVarSet, Modes, S, !U),
add_string(")", S, !U)
;
Modes = [],
mercury_format_bracketed_sym_name_ngt(next_to_graphic_token, FuncName,
S, !U)
),
add_string(" = ", S, !U),
mercury_format_mode(Lang, InstVarSet, RetMode, S, !U),
mercury_format_det_annotation(MaybeDet, S, !U).
%---------------------------------------------------------------------------%
:- pred mercury_format_det_annotation(maybe(determinism)::in, S::in,
U::di, U::uo) is det <= pt_output(S, U).
mercury_format_det_annotation(MaybeDet, S, !U) :-
(
MaybeDet = no
;
MaybeDet = yes(Det),
add_string(" is ", S, !U),
add_string(mercury_det_to_string(Det), S, !U)
).
%---------------------------------------------------------------------------%
:- end_module parse_tree.parse_tree_out_pred_decl.
%---------------------------------------------------------------------------%