mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
699 lines
25 KiB
Mathematica
699 lines
25 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1994-2012 The University of Melbourne.
|
|
% Copyright (C) 2015-2016, 2018-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 insts and modes back into Mercury source text.
|
|
%
|
|
% However, since mer_insts can represent not just insts that can occur
|
|
% in source code, but also insts created by the compiler, it must also
|
|
% be able to output the latter kind of inst as well. For these, we cannot
|
|
% print them as valid Mercury.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module parse_tree.parse_tree_out_inst.
|
|
:- interface.
|
|
|
|
:- import_module parse_tree.parse_tree_out_info.
|
|
:- import_module parse_tree.parse_tree_output.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module io.
|
|
:- import_module list.
|
|
:- import_module set.
|
|
:- import_module string.
|
|
:- import_module string.builder.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func mercury_inst_list_to_string(output_lang, inst_varset, list(mer_inst))
|
|
= string.
|
|
:- pred mercury_output_inst_list(io.text_output_stream::in, output_lang::in,
|
|
inst_varset::in, list(mer_inst)::in, io::di, io::uo) is det.
|
|
:- pred mercury_format_inst_list(output_lang::in, inst_varset::in,
|
|
list(mer_inst)::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func mercury_inst_to_string(output_lang, inst_varset, mer_inst) = string.
|
|
:- pred mercury_output_inst(io.text_output_stream::in, output_lang::in,
|
|
inst_varset::in, mer_inst::in, io::di, io::uo) is det.
|
|
:- pred mercury_format_inst(output_lang::in, inst_varset::in, mer_inst::in,
|
|
S::in, U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_format_inst_name(output_lang::in, inst_varset::in,
|
|
inst_name::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func mercury_constrained_inst_vars_to_string(output_lang, inst_varset,
|
|
set(inst_var), mer_inst) = string.
|
|
:- pred mercury_format_constrained_inst_vars(output_lang::in, inst_varset::in,
|
|
set(inst_var)::in, mer_inst::in, S::in, U::di, U::uo) is det
|
|
<= pt_output(S, U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_format_ground_pred_inst_info(output_lang::in, inst_varset::in,
|
|
uniqueness::in, pred_inst_info::in, S::in, U::di, U::uo) is det
|
|
<= pt_output(S, U).
|
|
|
|
:- pred mercury_format_any_pred_inst_info(output_lang::in, inst_varset::in,
|
|
uniqueness::in, pred_inst_info::in, S::in, U::di, U::uo) is det
|
|
<= pt_output(S, U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_format_is_live_comma(is_live::in, S::in, U::di, U::uo)
|
|
is det <= pt_output(S, U).
|
|
|
|
:- pred mercury_format_real_comma(unify_is_real::in, S::in, U::di, U::uo)
|
|
is det <= pt_output(S, U).
|
|
|
|
:- func mercury_uniqueness_to_string(uniqueness, string) = string.
|
|
:- pred mercury_format_uniqueness(uniqueness::in, string::in,
|
|
S::in, U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
:- func mercury_any_uniqueness_to_string(uniqueness) = string.
|
|
:- pred mercury_format_any_uniqueness(uniqueness::in,
|
|
S::in, U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func mercury_mode_list_to_string(output_lang, inst_varset, list(mer_mode))
|
|
= string.
|
|
:- pred mercury_output_mode_list(io.text_output_stream::in, output_lang::in,
|
|
inst_varset::in, list(mer_mode)::in, io::di, io::uo) is det.
|
|
:- pred mercury_format_mode_list(output_lang::in, inst_varset::in,
|
|
list(mer_mode)::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
:- func mercury_mode_to_string(output_lang, inst_varset, mer_mode) = string.
|
|
:- pred mercury_output_mode(io.text_output_stream::in, output_lang::in,
|
|
inst_varset::in, mer_mode::in, io::di, io::uo) is det.
|
|
:- pred mercury_format_mode(output_lang::in, inst_varset::in, mer_mode::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 mdbcomp.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.parse_tree_out_cons_id.
|
|
:- 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_mode.
|
|
:- import_module parse_tree.prog_util.
|
|
|
|
:- import_module require.
|
|
:- import_module varset.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_inst_list_to_string(Lang, InstVarSet, Insts) = Str :-
|
|
State0 = string.builder.init,
|
|
mercury_format_inst_list(Lang, InstVarSet, Insts, string.builder.handle,
|
|
State0, State),
|
|
Str = string.builder.to_string(State).
|
|
|
|
mercury_output_inst_list(Stream, Lang, InstVarSet, Insts, !IO) :-
|
|
mercury_format_inst_list(Lang, InstVarSet, Insts, Stream, !IO).
|
|
|
|
mercury_format_inst_list(_, _, [], _S, !U).
|
|
mercury_format_inst_list(Lang, InstVarSet, [Inst | Insts], S, !U) :-
|
|
mercury_format_inst(Lang, InstVarSet, Inst, S, !U),
|
|
(
|
|
Insts = []
|
|
;
|
|
Insts = [_ | _],
|
|
add_string(", ", S, !U),
|
|
mercury_format_inst_list(Lang, InstVarSet, Insts, S, !U)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_inst_to_string(Lang, InstVarSet, Inst) = Str :-
|
|
State0 = string.builder.init,
|
|
mercury_format_inst(Lang, InstVarSet, Inst, string.builder.handle,
|
|
State0, State),
|
|
Str = string.builder.to_string(State).
|
|
|
|
mercury_output_inst(Stream, Lang, InstVarSet, Inst, !IO) :-
|
|
mercury_format_inst(Lang, InstVarSet, Inst, Stream, !IO).
|
|
|
|
mercury_format_inst(Lang, InstVarSet, Inst, S, !U) :-
|
|
(
|
|
Inst = any(Uniq, HOInstInfo),
|
|
(
|
|
HOInstInfo = higher_order(PredInstInfo),
|
|
mercury_format_any_pred_inst_info(Lang, InstVarSet,
|
|
Uniq, PredInstInfo, S, !U)
|
|
;
|
|
HOInstInfo = none_or_default_func,
|
|
mercury_format_any_uniqueness(Uniq, S, !U)
|
|
)
|
|
;
|
|
Inst = free,
|
|
add_string("free", S, !U)
|
|
;
|
|
Inst = bound(Uniq, _, BoundFunctors),
|
|
mercury_format_uniqueness(Uniq, "bound", S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_bound_functors(Lang, InstVarSet, BoundFunctors, S, !U),
|
|
add_string(")", S, !U)
|
|
;
|
|
Inst = ground(Uniq, HOInstInfo),
|
|
(
|
|
HOInstInfo = higher_order(PredInstInfo),
|
|
mercury_format_ground_pred_inst_info(Lang, InstVarSet,
|
|
Uniq, PredInstInfo, S, !U)
|
|
;
|
|
HOInstInfo = none_or_default_func,
|
|
mercury_format_uniqueness(Uniq, "ground", S, !U)
|
|
)
|
|
;
|
|
Inst = inst_var(Var),
|
|
mercury_format_var_vs(InstVarSet, print_name_only, Var, S, !U)
|
|
;
|
|
Inst = constrained_inst_vars(Vars, CInst),
|
|
mercury_format_constrained_inst_vars(Lang, InstVarSet, Vars, CInst,
|
|
S, !U)
|
|
;
|
|
Inst = defined_inst(InstName),
|
|
mercury_format_inst_name(Lang, InstVarSet, InstName, S, !U)
|
|
;
|
|
Inst = not_reached,
|
|
add_string("not_reached", S, !U)
|
|
).
|
|
|
|
:- pred mercury_format_bound_functors(output_lang::in, inst_varset::in,
|
|
list(bound_functor)::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
mercury_format_bound_functors(_, _, [], _S, !U).
|
|
mercury_format_bound_functors(Lang, InstVarSet, [BoundFunctor | BoundFunctors],
|
|
S, !U) :-
|
|
BoundFunctor = bound_functor(ConsId, Args),
|
|
(
|
|
Args = [],
|
|
mercury_format_cons_id(Lang, needs_brackets, ConsId, S, !U)
|
|
;
|
|
Args = [_ | _],
|
|
mercury_format_cons_id(Lang, does_not_need_brackets, ConsId, S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_inst_list(Lang, InstVarSet, Args, S, !U),
|
|
add_string(")", S, !U)
|
|
),
|
|
(
|
|
BoundFunctors = []
|
|
;
|
|
BoundFunctors = [_ | _],
|
|
add_string(" ; ", S, !U),
|
|
mercury_format_bound_functors(Lang, InstVarSet, BoundFunctors, S, !U)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_format_inst_name(Lang, InstVarSet, InstName, S, !U) :-
|
|
(
|
|
InstName = user_inst(Name, Args),
|
|
(
|
|
Args = [],
|
|
mercury_format_bracketed_sym_name(Name, S, !U)
|
|
;
|
|
Args = [_ | _],
|
|
mercury_format_sym_name(Name, S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_inst_list(Lang, InstVarSet, Args, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
InstName = unify_inst(IsLive, Real, InstA, InstB),
|
|
(
|
|
Lang = output_mercury,
|
|
unexpected($pred, "unify_inst")
|
|
;
|
|
Lang = output_debug,
|
|
add_string("$unify(", S, !U),
|
|
mercury_format_is_live_comma(IsLive, S, !U),
|
|
mercury_format_comma_real(Real, S, !U),
|
|
mercury_format_inst_list(Lang, InstVarSet, [InstA, InstB], S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
InstName = merge_inst(InstA, InstB),
|
|
(
|
|
Lang = output_mercury,
|
|
unexpected($pred, "merge_inst")
|
|
;
|
|
Lang = output_debug,
|
|
add_string("$merge_inst(", S, !U),
|
|
mercury_format_inst_list(Lang, InstVarSet, [InstA, InstB], S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
InstName = ground_inst(SubInstName, Uniq, IsLive, Real),
|
|
(
|
|
Lang = output_mercury,
|
|
unexpected($pred, "ground_inst")
|
|
;
|
|
Lang = output_debug,
|
|
add_string("$ground(", S, !U),
|
|
mercury_format_inst_name(Lang, InstVarSet, SubInstName, S, !U),
|
|
add_string(", ", S, !U),
|
|
mercury_format_is_live_comma(IsLive, S, !U),
|
|
mercury_format_uniqueness(Uniq, "shared", S, !U),
|
|
mercury_format_comma_real(Real, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
InstName = any_inst(SubInstName, Uniq, IsLive, Real),
|
|
(
|
|
Lang = output_mercury,
|
|
unexpected($pred, "any_inst")
|
|
;
|
|
Lang = output_debug,
|
|
add_string("$any(", S, !U),
|
|
mercury_format_inst_name(Lang, InstVarSet, SubInstName, S, !U),
|
|
add_string(", ", S, !U),
|
|
mercury_format_is_live_comma(IsLive, S, !U),
|
|
mercury_format_uniqueness(Uniq, "shared", S, !U),
|
|
mercury_format_comma_real(Real, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
InstName = shared_inst(SubInstName),
|
|
(
|
|
Lang = output_mercury,
|
|
unexpected($pred, "shared_inst")
|
|
;
|
|
Lang = output_debug,
|
|
add_string("$shared_inst(", S, !U),
|
|
mercury_format_inst_name(Lang, InstVarSet, SubInstName, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
InstName = mostly_uniq_inst(SubInstName),
|
|
(
|
|
Lang = output_mercury,
|
|
unexpected($pred, "mostly_uniq_inst")
|
|
;
|
|
Lang = output_debug,
|
|
add_string("$mostly_uniq_inst(", S, !U),
|
|
mercury_format_inst_name(Lang, InstVarSet, SubInstName, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
InstName = typed_ground(Uniqueness, Type),
|
|
(
|
|
Lang = output_mercury,
|
|
unexpected($pred, "typed_ground")
|
|
;
|
|
Lang = output_debug,
|
|
add_string("$typed_ground(", S, !U),
|
|
mercury_format_uniqueness(Uniqueness, "shared", S, !U),
|
|
add_string(", ", S, !U),
|
|
varset.init(TypeVarSet),
|
|
mercury_format_type(TypeVarSet, print_name_only, Type, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
InstName = typed_inst(Type, SubInstName),
|
|
(
|
|
Lang = output_mercury,
|
|
mercury_format_inst_name(Lang, InstVarSet, SubInstName, S, !U)
|
|
;
|
|
Lang = output_debug,
|
|
add_string("$typed_inst(", S, !U),
|
|
varset.init(TypeVarSet),
|
|
mercury_format_type(TypeVarSet, print_name_only, Type, S, !U),
|
|
add_string(", ", S, !U),
|
|
mercury_format_inst_name(Lang, InstVarSet, SubInstName, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_constrained_inst_vars_to_string(Lang, InstVarSet, Vars, Inst) = Str :-
|
|
State0 = string.builder.init,
|
|
mercury_format_constrained_inst_vars(Lang, InstVarSet, Vars, Inst,
|
|
string.builder.handle, State0, State),
|
|
Str = string.builder.to_string(State).
|
|
|
|
mercury_format_constrained_inst_vars(Lang, InstVarSet, !.Vars, Inst, S, !U) :-
|
|
( if set.remove_least(Var, !Vars) then
|
|
add_string("(", S, !U),
|
|
mercury_format_var_vs(InstVarSet, print_name_only, Var, S, !U),
|
|
add_string(" =< ", S, !U),
|
|
mercury_format_constrained_inst_vars(Lang, InstVarSet, !.Vars, Inst,
|
|
S, !U),
|
|
add_string(")", S, !U)
|
|
else
|
|
mercury_format_inst(Lang, InstVarSet, Inst, S, !U)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_format_ground_pred_inst_info(Lang, InstVarSet, Uniq, PredInstInfo,
|
|
S, !U) :-
|
|
PredInstInfo = pred_inst_info(PredOrFunc, Modes, MaybeArgRegs, Det),
|
|
(
|
|
Uniq = shared
|
|
;
|
|
( Uniq = unique
|
|
; Uniq = mostly_unique
|
|
; Uniq = clobbered
|
|
; Uniq = mostly_clobbered
|
|
),
|
|
add_string("/* ", S, !U),
|
|
mercury_format_uniqueness(Uniq, "ground", S, !U),
|
|
add_string(" */", S, !U)
|
|
),
|
|
(
|
|
PredOrFunc = pf_predicate,
|
|
(
|
|
Modes = [],
|
|
add_string("((pred) is ", S, !U),
|
|
add_string(mercury_det_to_string(Det), S, !U),
|
|
add_string(")", S, !U)
|
|
;
|
|
Modes = [_ | _],
|
|
add_string("(pred(", S, !U),
|
|
mercury_format_mode_list(Lang, InstVarSet, Modes, S, !U),
|
|
add_string(") is ", S, !U),
|
|
add_string(mercury_det_to_string(Det), S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
PredOrFunc = pf_function,
|
|
pred_args_to_func_args(Modes, ArgModes, RetMode),
|
|
(
|
|
ArgModes = [],
|
|
add_string("((func) = ", S, !U)
|
|
;
|
|
ArgModes = [_ | _],
|
|
add_string("(func(", S, !U),
|
|
mercury_format_mode_list(Lang, InstVarSet, ArgModes, S, !U),
|
|
add_string(") = ", S, !U)
|
|
),
|
|
mercury_format_mode(Lang, InstVarSet, RetMode, S, !U),
|
|
add_string(" is ", S, !U),
|
|
add_string(mercury_det_to_string(Det), S, !U),
|
|
add_string(")", S, !U)
|
|
),
|
|
(
|
|
MaybeArgRegs = arg_reg_types(ArgRegs),
|
|
add_string(" /* arg regs: [", S, !U),
|
|
mercury_format_arg_reg_list(ArgRegs, S, !U),
|
|
add_string("] */", S, !U)
|
|
;
|
|
MaybeArgRegs = arg_reg_types_unset
|
|
).
|
|
|
|
mercury_format_any_pred_inst_info(Lang, InstVarSet, Uniq, PredInstInfo,
|
|
S, !U) :-
|
|
PredInstInfo = pred_inst_info(PredOrFunc, Modes, MaybeArgRegs, Det),
|
|
(
|
|
Uniq = shared
|
|
;
|
|
( Uniq = unique
|
|
; Uniq = mostly_unique
|
|
; Uniq = clobbered
|
|
; Uniq = mostly_clobbered
|
|
),
|
|
add_string("/* ", S, !U),
|
|
mercury_format_uniqueness(Uniq, "any", S, !U),
|
|
add_string(" */", S, !U)
|
|
),
|
|
(
|
|
PredOrFunc = pf_predicate,
|
|
(
|
|
Modes = [],
|
|
add_string("(any_pred is ", S, !U),
|
|
add_string(mercury_det_to_string(Det), S, !U),
|
|
add_string(")", S, !U)
|
|
;
|
|
Modes = [_ | _],
|
|
add_string("(any_pred(", S, !U),
|
|
mercury_format_mode_list(Lang, InstVarSet, Modes, S, !U),
|
|
add_string(") is ", S, !U),
|
|
add_string(mercury_det_to_string(Det), S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
;
|
|
PredOrFunc = pf_function,
|
|
pred_args_to_func_args(Modes, ArgModes, RetMode),
|
|
(
|
|
Modes = [],
|
|
add_string("(any_func = ", S, !U)
|
|
;
|
|
Modes = [_ | _],
|
|
add_string("(any_func(", S, !U),
|
|
mercury_format_mode_list(Lang, InstVarSet, ArgModes, S, !U),
|
|
add_string(") = ", S, !U)
|
|
),
|
|
mercury_format_mode(Lang, InstVarSet, RetMode, S, !U),
|
|
add_string(" is ", S, !U),
|
|
add_string(mercury_det_to_string(Det), S, !U),
|
|
add_string(")", S, !U)
|
|
),
|
|
(
|
|
MaybeArgRegs = arg_reg_types(ArgRegs),
|
|
add_string(" /* arg regs: [", S, !U),
|
|
mercury_format_arg_reg_list(ArgRegs, S, !U),
|
|
add_string("] */", S, !U)
|
|
;
|
|
MaybeArgRegs = arg_reg_types_unset
|
|
).
|
|
|
|
:- pred mercury_format_arg_reg_list(list(ho_arg_reg)::in, S::in,
|
|
U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
mercury_format_arg_reg_list([], _S, !U).
|
|
mercury_format_arg_reg_list([Reg | Regs], S, !U) :-
|
|
(
|
|
Reg = ho_arg_reg_r,
|
|
add_string("reg_r", S, !U)
|
|
;
|
|
Reg = ho_arg_reg_f,
|
|
add_string("reg_f", S, !U)
|
|
),
|
|
(
|
|
Regs = []
|
|
;
|
|
Regs = [_ | _],
|
|
add_string(", ", S, !U),
|
|
mercury_format_arg_reg_list(Regs, S, !U)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_format_is_live_comma(IsLive, S, !U) :-
|
|
(
|
|
IsLive = is_live,
|
|
add_string("live, ", S, !U)
|
|
;
|
|
IsLive = is_dead,
|
|
add_string("dead, ", S, !U)
|
|
).
|
|
|
|
mercury_format_real_comma(Real, S, !U) :-
|
|
(
|
|
Real = real_unify,
|
|
add_string("real, ", S, !U)
|
|
;
|
|
Real = fake_unify,
|
|
add_string("fake, ", S, !U)
|
|
).
|
|
|
|
:- pred mercury_format_comma_real(unify_is_real::in, S::in, U::di, U::uo)
|
|
is det <= pt_output(S, U).
|
|
|
|
mercury_format_comma_real(Real, S, !U) :-
|
|
(
|
|
Real = real_unify,
|
|
add_string(", real", S, !U)
|
|
;
|
|
Real = fake_unify,
|
|
add_string(", fake", S, !U)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_uniqueness_to_string(shared, SharedStr) = SharedStr.
|
|
mercury_uniqueness_to_string(unique, _) = "unique".
|
|
mercury_uniqueness_to_string(mostly_unique, _) = "mostly_unique".
|
|
mercury_uniqueness_to_string(clobbered, _) = "clobbered".
|
|
mercury_uniqueness_to_string(mostly_clobbered, _) = "mostly_clobbered".
|
|
|
|
mercury_format_uniqueness(Uniq, SharedStr, S, !U) :-
|
|
add_string(mercury_uniqueness_to_string(Uniq, SharedStr), S, !U).
|
|
|
|
mercury_any_uniqueness_to_string(shared) = "any".
|
|
mercury_any_uniqueness_to_string(unique) = "unique_any".
|
|
mercury_any_uniqueness_to_string(mostly_unique) = "mostly_unique_any".
|
|
mercury_any_uniqueness_to_string(clobbered) = "clobbered_any".
|
|
mercury_any_uniqueness_to_string(mostly_clobbered) = "mostly_clobbered_any".
|
|
|
|
mercury_format_any_uniqueness(Uniq, S, !U) :-
|
|
add_string(mercury_any_uniqueness_to_string(Uniq), S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_mode_list_to_string(Lang, InstVarSet, Modes) = Str :-
|
|
State0 = string.builder.init,
|
|
mercury_format_mode_list(Lang, InstVarSet, Modes, string.builder.handle,
|
|
State0, State),
|
|
Str = string.builder.to_string(State).
|
|
|
|
mercury_output_mode_list(Stream, Lang, InstVarSet, Modes, !IO) :-
|
|
mercury_format_mode_list(Lang, InstVarSet, Modes, Stream, !IO).
|
|
|
|
mercury_format_mode_list(_, _, [], _S, !U).
|
|
mercury_format_mode_list(Lang, InstVarSet, [Mode | Modes], S, !U) :-
|
|
mercury_format_mode(Lang, InstVarSet, Mode, S, !U),
|
|
(
|
|
Modes = []
|
|
;
|
|
Modes = [_ | _],
|
|
add_string(", ", S, !U),
|
|
mercury_format_mode_list(Lang, InstVarSet, Modes, S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_mode_to_string(Lang, InstVarSet, Mode) = Str :-
|
|
State0 = string.builder.init,
|
|
mercury_format_mode(Lang, InstVarSet, Mode, string.builder.handle,
|
|
State0, State),
|
|
Str = string.builder.to_string(State).
|
|
|
|
mercury_output_mode(Stream, Lang, InstVarSet, Mode, !IO) :-
|
|
mercury_format_mode(Lang, InstVarSet, Mode, Stream, !IO).
|
|
|
|
mercury_format_mode(Lang, InstVarSet, Mode0, S, !U) :-
|
|
(
|
|
Mode0 = from_to_mode(FromInst0, ToInst0),
|
|
% When generating output intended for humans, such as error
|
|
% messages and HLDS dumps, we try to make the mode as easy to read
|
|
% as possible. This involves transforming e.g. "free >> ground"
|
|
% to simply "out".
|
|
%
|
|
% However, we cannot replace the expansions of in, out etc
|
|
% with their names when we are generating actual Mercury code,
|
|
% because if we did, we would make the actual *definitions*
|
|
% of these modes in builtin.int circular.
|
|
(
|
|
Lang = output_mercury,
|
|
mercury_format_from_to_mode(Lang, InstVarSet,
|
|
FromInst0, ToInst0, S, !U)
|
|
;
|
|
Lang = output_debug,
|
|
( if
|
|
FromInst0 = ground(_Uniq, HOInstInfo),
|
|
HOInstInfo = higher_order(pred_inst_info(_, _, _, _)),
|
|
ToInst0 = FromInst0
|
|
then
|
|
% This special case would be recognized by insts_to_mode
|
|
% as in(FromInst). However, in the case of higher order insts,
|
|
% the compiler allows programmers to omit the in(...) wrapper.
|
|
% Since we don't have to write the wrapper, we don't.
|
|
mercury_format_inst(Lang, InstVarSet, FromInst0, S, !U)
|
|
else
|
|
insts_to_mode(FromInst0, ToInst0, Mode1),
|
|
(
|
|
Mode1 = from_to_mode(FromInst1, ToInst1),
|
|
strip_module_names_from_inst(strip_builtin_module_name,
|
|
do_not_set_default_func, FromInst1, FromInst),
|
|
strip_module_names_from_inst(strip_builtin_module_name,
|
|
do_not_set_default_func, ToInst1, ToInst),
|
|
mercury_format_from_to_mode(Lang, InstVarSet,
|
|
FromInst, ToInst, S, !U)
|
|
;
|
|
Mode1 = user_defined_mode(SymName, ArgInsts),
|
|
mercury_format_user_defined_mode(Lang, InstVarSet,
|
|
SymName, ArgInsts, S, !U)
|
|
)
|
|
)
|
|
)
|
|
;
|
|
Mode0 = user_defined_mode(SymName, ArgInsts),
|
|
mercury_format_user_defined_mode(Lang, InstVarSet,
|
|
SymName, ArgInsts, S, !U)
|
|
).
|
|
|
|
:- pred mercury_format_from_to_mode(output_lang::in, inst_varset::in,
|
|
mer_inst::in, mer_inst::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
|
|
|
|
mercury_format_from_to_mode(Lang, InstVarSet, FromInst, ToInst, S, !U) :-
|
|
add_string("(", S, !U),
|
|
mercury_format_inst(Lang, InstVarSet, FromInst, S, !U),
|
|
add_string(" >> ", S, !U),
|
|
mercury_format_inst(Lang, InstVarSet, ToInst, S, !U),
|
|
add_string(")", S, !U).
|
|
|
|
:- pred mercury_format_user_defined_mode(output_lang::in, inst_varset::in,
|
|
sym_name::in, list(mer_inst)::in, S::in, U::di, U::uo) is det
|
|
<= pt_output(S, U).
|
|
|
|
mercury_format_user_defined_mode(Lang, InstVarSet, SymName, ArgInsts, S, !U) :-
|
|
% When generating output for a human, we
|
|
%
|
|
% 1 omit brackets from around sym_names, and
|
|
% 2 omit module qualifiers from sym_names.
|
|
%
|
|
% The brackets are needed only to help the parser when trying to read in
|
|
% the output sym_name, when that happens to be an operator. Humans can
|
|
% parse the bracketless output even if the parser can't.
|
|
%
|
|
% It is extremely rare for two modules to define two modes with identical
|
|
% names. Therefore in 99.9%+ of cases, the module qualifiers on mode names
|
|
% are just clutter that humans would prefer not to have to read.
|
|
(
|
|
ArgInsts = [],
|
|
(
|
|
Lang = output_mercury,
|
|
mercury_format_bracketed_sym_name(SymName, S, !U)
|
|
;
|
|
Lang = output_debug,
|
|
Name = unqualify_name(SymName),
|
|
add_string(Name, S, !U)
|
|
)
|
|
;
|
|
ArgInsts = [_ | _],
|
|
(
|
|
Lang = output_mercury,
|
|
mercury_format_sym_name(SymName, S, !U)
|
|
;
|
|
Lang = output_debug,
|
|
Name = unqualify_name(SymName),
|
|
add_string(Name, S, !U)
|
|
),
|
|
add_string("(", S, !U),
|
|
mercury_format_inst_list(Lang, InstVarSet, ArgInsts, S, !U),
|
|
add_string(")", S, !U)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module parse_tree.parse_tree_out_inst.
|
|
%---------------------------------------------------------------------------%
|