Files
mercury/compiler/parse_tree_out_cons_id.m
Zoltan Somogyi 386160f937 s/dont/do_not/ in the compiler directory.
compiler/*.m:
    Standardize on the do_not spelling over the dont contraction
    in the compiler directory. (We used to have a lot of both spellings.)
2024-08-12 12:49:23 +02:00

444 lines
16 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1994-2012 The University of Melbourne.
% Copyright (C) 2014-2018, 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.
%---------------------------------------------------------------------------%
%
% File: parse_tree_out_cons_id.m.
% Main author: fjh.
%
% NOTE All the predicates and functions below whose names have
% the "mercury_" prefix were originally in a module, mercury_to_mercury.m,
% whose documentation said that it "converts cons_ids back into
% Mercury source text", though this claim was true only for cons_ids
% that *can* appear in Mercury source text. (For cons_ids that can be
% constructed only by the compiler, the result won't be valid Mercury code.)
%
% The other predicates and functions originally came from prog_out.m,
% which made no such claim.
%
%---------------------------------------------------------------------------%
:- module parse_tree.parse_tree_out_cons_id.
:- 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 string.
:- import_module string.builder.
%---------------------------------------------------------------------------%
:- type needs_brackets
---> needs_brackets
% Needs brackets, if it is an op.
; does_not_need_brackets.
% Doesn't need brackets.
% Output a cons_id, parenthesizing it if necessary.
%
:- func mercury_cons_id_to_string(output_lang, needs_brackets, cons_id)
= string.
:- pred mercury_output_cons_id(output_lang::in, needs_brackets::in,
cons_id::in, io.text_output_stream::in, io::di, io::uo) is det.
:- pred mercury_format_cons_id(output_lang::in, needs_brackets::in,
cons_id::in, S::in, U::di, U::uo) is det <= pt_output(S, U).
%---------------------------------------------------------------------------%
% Convert a cons_id to a string.
%
% The maybe_quoted_cons_id_and_arity_to_string version is for use
% in error messages, while the cons_id_and_arity_to_string version
% is for use when generating target language code. The differences are
% that
%
% - the former puts quotation marks around user-defined cons_ids
% (i.e. those that are represented by cons/3), as opposed to
% builtin cons_ids such as integers, while the latter does not, and
%
% - the latter mangles user-defined cons_ids to ensure that they
% are acceptable in our target languages e.g. in comments,
% while the former does no mangling.
%
% The difference in the names refers to the first distinction above.
%
:- func maybe_quoted_cons_id_and_arity_to_string(cons_id) = string.
:- func cons_id_and_arity_to_string(cons_id) = string.
:- func unqual_cons_id_and_arity_to_string(cons_id) = string.
:- func maybe_quoted_du_ctor_and_arity_to_string(du_ctor)
= string.
:- func du_ctor_and_arity_to_string(du_ctor) = string.
:- func unqual_du_ctor_and_arity_to_string(du_ctor) = string.
:- pred int_const_to_string_and_suffix(some_int_const::in,
string::out, string::out) is det.
%---------------------------------------------------------------------------%
:- 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.sym_name.
:- import_module parse_tree.parse_tree_out_sym_name.
:- import_module list.
:- import_module term_io.
%---------------------------------------------------------------------------%
mercury_cons_id_to_string(Lang, NeedsBrackets, ConsId) = Str :-
State0 = string.builder.init,
mercury_format_cons_id(Lang, NeedsBrackets, ConsId, string.builder.handle,
State0, State),
Str = string.builder.to_string(State).
mercury_output_cons_id(Lang, NeedsBrackets, ConsId, Stream, !IO) :-
mercury_format_cons_id(Lang, NeedsBrackets, ConsId, Stream, !IO).
mercury_format_cons_id(Lang, NeedsBrackets, ConsId, S, !U) :-
(
ConsId = du_data_ctor(du_ctor(Name, _, _)),
(
NeedsBrackets = needs_brackets,
mercury_format_bracketed_sym_name(Name, S, !U)
;
NeedsBrackets = does_not_need_brackets,
mercury_format_sym_name(Name, S, !U)
)
;
ConsId = tuple_cons(_),
(
Lang = output_mercury,
add_string("{}", S, !U)
;
Lang = output_debug,
add_string("tuple{}", S, !U)
)
;
ConsId = some_int_const(IntConst),
(
IntConst = int_const(Int),
add_int(Int, S, !U)
;
IntConst = uint_const(UInt),
add_uint(UInt, S, !U)
;
IntConst = int8_const(Int8),
add_int8(Int8, S, !U)
;
IntConst = uint8_const(UInt8),
add_uint8(UInt8, S, !U)
;
IntConst = int16_const(Int16),
add_int16(Int16, S, !U)
;
IntConst = uint16_const(UInt16),
add_uint16(UInt16, S, !U)
;
IntConst = int32_const(Int32),
add_int32(Int32, S, !U)
;
IntConst = uint32_const(UInt32),
add_uint32(UInt32, S, !U)
;
IntConst = int64_const(Int64),
add_int64(Int64, S, !U)
;
IntConst = uint64_const(UInt64),
add_uint64(UInt64, S, !U)
)
;
ConsId = float_const(Float),
add_float(Float, S, !U)
;
ConsId = char_const(Char),
add_string(term_io.quoted_char_to_string(Char), S, !U)
;
ConsId = string_const(Str),
add_quoted_string(Str, S, !U)
;
ConsId = impl_defined_const(IDCKind),
add_string(impl_defined_const_kind_to_str(IDCKind), S, !U)
;
ConsId = closure_cons(ShroudedPredProcId),
% XXX Should probably print this out in name/arity form.
ShroudedPredProcId = shrouded_pred_proc_id(PredInt, ProcInt),
add_string("<closure_cons(", S, !U),
add_int(PredInt, S, !U),
add_string(", ", S, !U),
add_int(ProcInt, S, !U),
% add_string(", ", S, !U),
% add_lambda_eval_method(EvalMethod, S, !U),
add_string(")>", S, !U)
;
ConsId = type_ctor_info_const(ModuleName, TypeName, Arity),
ModuleStr = sym_name_to_string(ModuleName),
string.int_to_string(Arity, ArityStr),
add_strings(["<type_ctor_info for ", ModuleStr, ".", TypeName,
"/", ArityStr, ">"], S, !U)
;
ConsId = base_typeclass_info_const(ModuleSymName, ClassId,
InstanceNum, InstanceStr),
ModuleNameStr = sym_name_to_string(ModuleSymName),
ClassId = class_id(ClassName, ClassArity),
string.format("class_id(%s, %d)",
[s(mercury_sym_name_to_string(ClassName)), i(ClassArity)],
ClassStr),
string.format("from module %s, instance number %d (%s)",
[s(ModuleNameStr), i(InstanceNum), s(InstanceStr)],
ModuleInstanceStr),
string.format("<base_typeclass_info for %s, %s>",
[s(ClassStr), s(ModuleInstanceStr)], ConsIdStr),
add_string(ConsIdStr, S, !U)
;
ConsId = type_info_cell_constructor(_),
add_string("<type_info_cell_constructor>", S, !U)
;
ConsId = typeclass_info_cell_constructor,
add_string("<typeclass_info_cell_constructor>", S, !U)
;
ConsId = type_info_const(TIConstNum),
add_string("<type_info_cell_constructor " ++
int_to_string(TIConstNum) ++ ">", S, !U)
;
ConsId = typeclass_info_const(TCIConstNum),
add_string("<typeclass_info_cell_constructor " ++
int_to_string(TCIConstNum) ++ ">", S, !U)
;
ConsId = ground_term_const(ConstNum, SubConsId),
add_string("<ground_term_cell_constructor " ++
int_to_string(ConstNum) ++ ", ", S, !U),
mercury_format_cons_id(Lang, does_not_need_brackets, SubConsId, S, !U),
add_string(">", S, !U)
;
ConsId = tabling_info_const(_),
add_string("<tabling info>", S, !U)
;
ConsId = table_io_entry_desc(_),
add_string("<table_io_entry_desc>", S, !U)
;
ConsId = deep_profiling_proc_layout(_),
add_string("<deep_profiling_proc_layout>", S, !U)
).
%---------------------------------------------------------------------------%
maybe_quoted_cons_id_and_arity_to_string(ConsId) =
cons_id_and_arity_to_string_maybe_quoted(do_not_mangle_cons,
quote_cons, do_not_strip_qual, ConsId).
cons_id_and_arity_to_string(ConsId) =
cons_id_and_arity_to_string_maybe_quoted(mangle_cons,
do_not_quote_cons, do_not_strip_qual, ConsId).
unqual_cons_id_and_arity_to_string(ConsId) =
cons_id_and_arity_to_string_maybe_quoted(mangle_cons,
do_not_quote_cons, strip_qual, ConsId).
%---------------------%
maybe_quoted_du_ctor_and_arity_to_string(DuCtor) =
du_ctor_and_arity_to_string_maybe_quoted(do_not_mangle_cons,
quote_cons, do_not_strip_qual, DuCtor).
du_ctor_and_arity_to_string(DuCtor) =
du_ctor_and_arity_to_string_maybe_quoted(mangle_cons,
do_not_quote_cons, do_not_strip_qual, DuCtor).
unqual_du_ctor_and_arity_to_string(DuCtor) =
du_ctor_and_arity_to_string_maybe_quoted(mangle_cons,
do_not_quote_cons, strip_qual, DuCtor).
%---------------------%
:- type maybe_quote_cons
---> do_not_quote_cons
; quote_cons.
:- type maybe_mangle_cons
---> do_not_mangle_cons
; mangle_cons.
:- type maybe_strip_qual
---> do_not_strip_qual
; strip_qual.
:- func cons_id_and_arity_to_string_maybe_quoted(maybe_mangle_cons,
maybe_quote_cons, maybe_strip_qual, cons_id) = string.
cons_id_and_arity_to_string_maybe_quoted(MangleCons, QuoteCons, StripQual,
ConsId) = String :-
(
ConsId = du_data_ctor(DuCtor),
String = du_ctor_and_arity_to_string_maybe_quoted(MangleCons,
QuoteCons, StripQual, DuCtor)
;
ConsId = tuple_cons(Arity),
String = "{}/" ++ string.int_to_string(Arity)
;
ConsId = some_int_const(IntConst),
int_const_to_string_and_suffix(IntConst, String, _Suffix)
;
ConsId = float_const(Float),
String = float_to_string(Float)
;
ConsId = char_const(CharConst),
String = term_io.quoted_char_to_string(CharConst)
;
ConsId = string_const(StringConst),
String = term_io.quoted_string(StringConst)
;
ConsId = impl_defined_const(IDCKind),
(
QuoteCons = do_not_quote_cons,
String = impl_defined_const_kind_to_str(IDCKind)
;
QuoteCons = quote_cons,
String = "`" ++ impl_defined_const_kind_to_str(IDCKind) ++ "'"
)
;
ConsId = closure_cons(PredProcId),
PredProcId = shrouded_pred_proc_id(PredId, ProcId),
String =
"closure_cons<pred " ++ int_to_string(PredId) ++
" proc " ++ int_to_string(ProcId) ++ ">"
;
ConsId = type_ctor_info_const(Module, Ctor, Arity),
String =
"<type_ctor_info " ++ sym_name_to_string(Module) ++ "." ++
Ctor ++ "/" ++ int_to_string(Arity) ++ ">"
;
ConsId = base_typeclass_info_const(_, _, _, _),
String = "<base_typeclass_info>"
;
ConsId = type_info_cell_constructor(_),
String = "<type_info_cell_constructor>"
;
ConsId = typeclass_info_cell_constructor,
String = "<typeclass_info_cell_constructor>"
;
ConsId = type_info_const(_),
String = "<type_info_const>"
;
ConsId = typeclass_info_const(_),
String = "<typeclass_info_const>"
;
ConsId = ground_term_const(_, _),
String = "<ground_term_const>"
;
ConsId = tabling_info_const(PredProcId),
PredProcId = shrouded_pred_proc_id(PredId, ProcId),
String =
"<tabling_info " ++ int_to_string(PredId) ++
", " ++ int_to_string(ProcId) ++ ">"
;
ConsId = table_io_entry_desc(PredProcId),
PredProcId = shrouded_pred_proc_id(PredId, ProcId),
String =
"<table_io_entry_desc " ++ int_to_string(PredId) ++ ", " ++
int_to_string(ProcId) ++ ">"
;
ConsId = deep_profiling_proc_layout(PredProcId),
PredProcId = shrouded_pred_proc_id(PredId, ProcId),
String =
"<deep_profiling_proc_layout " ++ int_to_string(PredId) ++ ", " ++
int_to_string(ProcId) ++ ">"
).
:- func du_ctor_and_arity_to_string_maybe_quoted(maybe_mangle_cons,
maybe_quote_cons, maybe_strip_qual, du_ctor) = string.
du_ctor_and_arity_to_string_maybe_quoted(MangleCons, QuoteCons,
StripQual, DuCtor) = String :-
DuCtor = du_ctor(SymName, Arity, _TypeCtor),
(
StripQual = do_not_strip_qual,
SymNameString0 = sym_name_to_string(SymName)
;
StripQual = strip_qual,
SymNameString0 = unqualify_name(SymName)
),
(
MangleCons = do_not_mangle_cons,
SymNameString = SymNameString0
;
MangleCons = mangle_cons,
( if string.contains_char(SymNameString0, '*') then
% We need to protect against the * appearing next to a /.
Stuff =
( pred(Char::in, Str0::in, Str::out) is det :-
( if Char = ('*') then
string.append(Str0, "star", Str)
else
string.char_to_string(Char, CharStr),
string.append(Str0, CharStr, Str)
)
),
string.foldl(Stuff, SymNameString0, "", SymNameString1)
else
SymNameString1 = SymNameString0
),
SymNameString = term_io.escaped_string(SymNameString1)
),
string.int_to_string(Arity, ArityString),
(
QuoteCons = do_not_quote_cons,
String = SymNameString ++ "/" ++ ArityString
;
QuoteCons = quote_cons,
String = "`" ++ SymNameString ++ "'/" ++ ArityString
).
int_const_to_string_and_suffix(IntConst, Str, Suffix) :-
(
IntConst = int_const(Int),
Str = string.int_to_string(Int), Suffix = ""
;
IntConst = int8_const(Int8),
Str = string.int8_to_string(Int8), Suffix = "i8"
;
IntConst = int16_const(Int16),
Str = string.int16_to_string(Int16), Suffix = "i16"
;
IntConst = int32_const(Int32),
Str = string.int32_to_string(Int32), Suffix = "i32"
;
IntConst = int64_const(Int64),
Str = string.int64_to_string(Int64), Suffix = "i64"
;
IntConst = uint_const(UInt),
Str = string.uint_to_string(UInt), Suffix = "u"
;
IntConst = uint8_const(UInt8),
Str = string.uint8_to_string(UInt8), Suffix = "u8"
;
IntConst = uint16_const(UInt16),
Str = string.uint16_to_string(UInt16), Suffix = "u16"
;
IntConst = uint32_const(UInt32),
Str = string.uint32_to_string(UInt32), Suffix = "u32"
;
IntConst = uint64_const(UInt64),
Str = string.uint64_to_string(UInt64), Suffix = "u64"
).
%---------------------------------------------------------------------------%
:- end_module parse_tree.parse_tree_out_cons_id.
%---------------------------------------------------------------------------%