mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-17 10:23:46 +00:00
library/string.m:
For each predicate and function whose name includes "codepoint",
- create a version in which "codepoint" is replaced by "code_point",
- make this version the main implementation, making the "codepoint"
versions forward to the "code_point" versions,
- add obsolete pragmas for the "codepoint" versions, though these are
commented out for now. This is so that an installed compiler containing
this change will already have the recommended alternative available
when the commenting-out is removed (maybe in a week or so).
NEWS.md:
Announce the new predicates and functions.
compiler/c_util.m:
compiler/const_prop.m:
compiler/inst_check.m:
compiler/parse_tree_out_term.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/write_error_spec.m:
library/pprint.m:
library/pretty_printer.m:
library/string.format.m:
Replace all uses of the "codepoint" versions with the "code_point"
versions.
995 lines
38 KiB
Mathematica
995 lines
38 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 terms in the parse tree structure
|
|
% back into Mercury source text.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module parse_tree.parse_tree_out_term.
|
|
:- interface.
|
|
|
|
:- import_module parse_tree.parse_tree_out_info.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.var_db.
|
|
:- import_module parse_tree.var_table.
|
|
|
|
:- import_module io.
|
|
:- import_module list.
|
|
:- import_module term.
|
|
:- import_module varset.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type needs_quotes
|
|
---> next_to_graphic_token
|
|
% Needs quotes, if it is another graphic token.
|
|
; not_next_to_graphic_token.
|
|
% Doesn't need quotes.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Convert a Mercury variable into a Mercury variable name.
|
|
% This is tricky because the compiler may introduce new variables
|
|
% that either don't have names at all, or whose names end in
|
|
% some sequence of primes (eg. Var''').
|
|
%
|
|
:- pred mercury_convert_var_name(string::in, string::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Output a single variable.
|
|
% Variables that don't have names in the given varset
|
|
% are given the name "V_<n>", where <n> is their variable number.
|
|
% Variables whose name originally started with `V_' have their name changed
|
|
% to start with `V_V_' to avoid name clashes.
|
|
%
|
|
:- pred mercury_output_var(var_table::in, var_name_print::in, prog_var::in,
|
|
io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_var_to_string(var_table, var_name_print, prog_var) = string.
|
|
:- pred mercury_format_var(var_table::in, var_name_print::in, prog_var::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_output_var_vs(varset(T)::in, var_name_print::in, var(T)::in,
|
|
io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_var_to_string_vs(varset(T), var_name_print, var(T)) = string.
|
|
:- pred mercury_format_var_vs(varset(T)::in, var_name_print::in, var(T)::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_output_var_src(var_name_source::in, var_name_print::in,
|
|
prog_var::in, io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_var_to_string_src(var_name_source, var_name_print, prog_var)
|
|
= string.
|
|
:- pred mercury_format_var_src(var_name_source::in, var_name_print::in,
|
|
prog_var::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- func mercury_var_raw_to_string(var_name_print, prog_var, string) = string.
|
|
:- pred mercury_format_var_raw(var_name_print::in, var(T)::in, string::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_format_var_num_only(var(T)::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
% Output a comma-separated list of variables.
|
|
%
|
|
:- pred mercury_output_vars(var_table::in, var_name_print::in,
|
|
list(prog_var)::in, io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_vars_to_string(var_table, var_name_print, list(prog_var))
|
|
= string.
|
|
:- pred mercury_format_vars(var_table::in, var_name_print::in,
|
|
list(prog_var)::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_output_vars_vs(varset(T)::in, var_name_print::in,
|
|
list(var(T))::in, io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_vars_to_string_vs(varset(T), var_name_print, list(var(T)))
|
|
= string.
|
|
:- pred mercury_format_vars_vs(varset(T)::in, var_name_print::in,
|
|
list(var(T))::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_output_vars_src(var_name_source::in, var_name_print::in,
|
|
list(prog_var)::in, io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_vars_to_string_src(var_name_source, var_name_print,
|
|
list(prog_var)) = string.
|
|
:- pred mercury_format_vars_src(var_name_source::in, var_name_print::in,
|
|
list(prog_var)::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
% Output a variable or a list of variables with print_name_only.
|
|
%
|
|
:- func mercury_var_to_name_only(var_table, prog_var) = string.
|
|
:- func mercury_vars_to_name_only(var_table, list(prog_var)) = string.
|
|
:- func mercury_var_to_name_only_vs(varset(T), var(T)) = string.
|
|
:- func mercury_vars_to_name_only_vs(varset(T), list(var(T))) = string.
|
|
:- func mercury_var_to_name_only_src(var_name_source, prog_var) = string.
|
|
:- func mercury_vars_to_name_only_src(var_name_source, list(prog_var))
|
|
= string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func describe_error_term(varset(T), term(T)) = string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Output a term.
|
|
%
|
|
:- pred mercury_output_term_vs(varset(T)::in, var_name_print::in, term(T)::in,
|
|
io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_term_to_string_vs(varset(T), var_name_print, term(T)) = string.
|
|
:- pred mercury_format_term_vs(varset(T)::in, var_name_print::in, term(T)::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_output_term(var_table::in, var_name_print::in,
|
|
prog_term::in, io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_term_to_string(var_table, var_name_print, prog_term)
|
|
= string.
|
|
:- pred mercury_format_term(var_table::in, var_name_print::in,
|
|
prog_term::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_output_term_src(var_name_source::in, var_name_print::in,
|
|
prog_term::in, io.text_output_stream::in, io::di, io::uo) is det.
|
|
|
|
:- pred mercury_output_term_nq_vs(varset(T)::in, var_name_print::in,
|
|
needs_quotes::in, term(T)::in, io.text_output_stream::in,
|
|
io::di, io::uo) is det.
|
|
:- func mercury_term_nq_to_string_vs(varset(T), var_name_print, needs_quotes,
|
|
term(T)) = string.
|
|
:- pred mercury_format_term_nq_vs(varset(T)::in, var_name_print::in,
|
|
needs_quotes::in, term(T)::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_output_term_nq(var_table::in, var_name_print::in,
|
|
needs_quotes::in, prog_term::in, io.text_output_stream::in,
|
|
io::di, io::uo) is det.
|
|
:- func mercury_term_nq_to_string(var_table, var_name_print,
|
|
needs_quotes, prog_term) = string.
|
|
:- pred mercury_format_term_nq(var_table::in, var_name_print::in,
|
|
needs_quotes::in, prog_term::in, S::in, U::di, U::uo) is det
|
|
<= output(S, U).
|
|
|
|
:- pred mercury_output_term_nq_src(var_name_source::in, var_name_print::in,
|
|
needs_quotes::in, prog_term::in, io.text_output_stream::in,
|
|
io::di, io::uo) is det.
|
|
:- func mercury_term_nq_to_string_src(var_name_source, var_name_print,
|
|
needs_quotes, prog_term) = string.
|
|
|
|
:- pred mercury_format_comma_separated_terms_vs(varset(T)::in,
|
|
var_name_print::in, term(T)::in, list(term(T))::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
:- pred mercury_format_comma_separated_terms(var_table::in,
|
|
var_name_print::in, prog_term::in, list(prog_term)::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_output_limited_term_vs(varset(T)::in, var_name_print::in,
|
|
int::in, term(T)::in, io.text_output_stream::in, io::di, io::uo) is det.
|
|
:- func mercury_limited_term_to_string_vs(varset(T), var_name_print, int,
|
|
term(T)) = string.
|
|
|
|
:- pred mercury_output_limited_term_nq_vs(varset(T)::in, var_name_print::in,
|
|
needs_quotes::in, int::in, term(T)::in, io.text_output_stream::in,
|
|
io::di, io::uo) is det.
|
|
:- func mercury_limited_term_nq_to_string_vs(varset(T), var_name_print,
|
|
needs_quotes, int, term(T)) = string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func mercury_bracketed_atom_to_string(needs_quotes, string) = string.
|
|
:- pred mercury_format_bracketed_atom(needs_quotes::in, string::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
:- pred mercury_format_quoted_atom(needs_quotes::in, string::in, S::in,
|
|
U::di, U::uo) is det <= output(S, U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type graphic_char_in_string
|
|
---> no_graphic_chars
|
|
; some_graphic_chars
|
|
; all_graphic_chars.
|
|
|
|
:- func string_graphic_chars(string) = graphic_char_in_string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Is this string a Mercury operator?
|
|
%
|
|
:- pred mercury_op(string::in) is semidet.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module char.
|
|
:- import_module int.
|
|
:- import_module mercury_term_lexer.
|
|
:- import_module ops.
|
|
:- import_module string.
|
|
:- import_module unit.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_convert_var_name(Name, ConvertedName) :-
|
|
% We have to be careful that every possible variable is mapped
|
|
% to a distinct name. Variables without names are given names
|
|
% starting with `V_' followed by a sequence of digits corresponding to
|
|
% their variable id. To ensure that names generated this way don't clash
|
|
% with any variables whose names originally started with `V_', we add
|
|
% another `V_' prefix to those names.
|
|
%
|
|
% Compiler's internal name Converted name
|
|
% ------------------------ --------------
|
|
% none V_[0-9]*
|
|
% .*'+ V_.*_[0-9]*
|
|
% V_.* V_V_.*
|
|
% anything else same as original name
|
|
%
|
|
( if string.remove_suffix(Name, "'", _) then
|
|
strip_trailing_primes(Name, StrippedName, NumPrimes),
|
|
ConvertedName = "V_" ++ StrippedName ++ "_" ++
|
|
string.int_to_string(NumPrimes)
|
|
else if string.prefix(Name, "V_") then
|
|
ConvertedName = "V_" ++ Name
|
|
else
|
|
ConvertedName = Name
|
|
).
|
|
|
|
:- pred strip_trailing_primes(string::in, string::out, int::out) is det.
|
|
|
|
strip_trailing_primes(Name0, Name, Num) :-
|
|
% XXX This implementation is O(N^2), but if N is not very small,
|
|
% then something is very wrong.
|
|
( if string.remove_suffix(Name0, "'", Name1) then
|
|
strip_trailing_primes(Name1, Name, Num0),
|
|
Num = Num0 + 1
|
|
else
|
|
Num = 0,
|
|
Name = Name0
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_output_var(VarTable, VarNamePrint, Var, Stream, !IO) :-
|
|
mercury_format_var(VarTable, VarNamePrint, Var, Stream, !IO).
|
|
|
|
mercury_var_to_string(VarTable, VarNamePrint, Var) = String :-
|
|
mercury_format_var(VarTable, VarNamePrint, Var, unit, "", String).
|
|
|
|
mercury_format_var(VarTable, VarNamePrint, Var, S, !U) :-
|
|
( if var_table.search_var_name(VarTable, Var, Name) then
|
|
mercury_format_var_raw(VarNamePrint, Var, Name, S, !U)
|
|
else
|
|
mercury_format_var_num_only(Var, S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_var_vs(VarSet, VarNamePrint, Var, Stream, !IO) :-
|
|
mercury_format_var_vs(VarSet, VarNamePrint, Var, Stream, !IO).
|
|
|
|
mercury_var_to_string_vs(VarSet, VarNamePrint, Var) = String :-
|
|
mercury_format_var_vs(VarSet, VarNamePrint, Var, unit, "", String).
|
|
|
|
mercury_format_var_vs(VarSet, VarNamePrint, Var, S, !U) :-
|
|
( if varset.search_name(VarSet, Var, Name) then
|
|
mercury_format_var_raw(VarNamePrint, Var, Name, S, !U)
|
|
else
|
|
mercury_format_var_num_only(Var, S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_var_src(VarNameSrc, VarNamePrint, Var, Stream, !IO) :-
|
|
mercury_format_var_src(VarNameSrc, VarNamePrint, Var, Stream, !IO).
|
|
|
|
mercury_var_to_string_src(VarNameSrc, VarNamePrint, Var) = String :-
|
|
mercury_format_var_src(VarNameSrc, VarNamePrint, Var, unit, "", String).
|
|
|
|
mercury_format_var_src(VarNameSrc, VarNamePrint, Var, S, !U) :-
|
|
( if var_db.search_var_name_in_source(VarNameSrc, Var, Name) then
|
|
mercury_format_var_raw(VarNamePrint, Var, Name, S, !U)
|
|
else
|
|
mercury_format_var_num_only(Var, S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_var_raw_to_string(VarNamePrint, Var, Name) = String :-
|
|
mercury_format_var_raw(VarNamePrint, Var, Name, unit, "", String).
|
|
|
|
mercury_format_var_raw(VarNamePrint, Var, Name, S, !U) :-
|
|
( if Name = "" then
|
|
% There is nothing else to print.
|
|
mercury_format_var_num_only(Var, S, !U)
|
|
else
|
|
(
|
|
VarNamePrint = print_num_only,
|
|
mercury_format_var_num_only(Var, S, !U)
|
|
;
|
|
( VarNamePrint = print_name_only
|
|
; VarNamePrint = print_name_and_num
|
|
),
|
|
mercury_convert_var_name(Name, ConvertedName),
|
|
add_string(ConvertedName, S, !U),
|
|
(
|
|
VarNamePrint = print_name_only
|
|
;
|
|
VarNamePrint = print_name_and_num,
|
|
term.var_to_int(Var, VarNum),
|
|
add_string("_", S, !U),
|
|
add_int(VarNum, S, !U)
|
|
)
|
|
)
|
|
).
|
|
|
|
mercury_format_var_num_only(Var, S, !U) :-
|
|
term.var_to_int(Var, VarNum),
|
|
add_string("V_", S, !U),
|
|
add_int(VarNum, S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_output_vars(VarTable, VarNamePrint, Vars, Stream, !IO) :-
|
|
mercury_format_vars(VarTable, VarNamePrint, Vars, Stream, !IO).
|
|
|
|
mercury_vars_to_string(VarTable, VarNamePrint, Vars) = String :-
|
|
mercury_format_vars(VarTable, VarNamePrint, Vars, unit, "", String).
|
|
|
|
mercury_format_vars(VarTable, VarNamePrint, Vars, S, !U) :-
|
|
add_list(mercury_format_var(VarTable, VarNamePrint), ", ", Vars, S, !U).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_vars_vs(VarTable, VarNamePrint, Vars, Stream, !IO) :-
|
|
mercury_format_vars_vs(VarTable, VarNamePrint, Vars, Stream, !IO).
|
|
|
|
mercury_vars_to_string_vs(VarSet, VarNamePrint, Vars) = String :-
|
|
mercury_format_vars_vs(VarSet, VarNamePrint, Vars, unit, "", String).
|
|
|
|
mercury_format_vars_vs(VarSet, VarNamePrint, Vars, S, !U) :-
|
|
add_list(mercury_format_var_vs(VarSet, VarNamePrint), ", ", Vars, S, !U).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_vars_src(VarNameSrc, VarNamePrint, Vars, Stream, !IO) :-
|
|
mercury_format_vars_src(VarNameSrc, VarNamePrint, Vars, Stream, !IO).
|
|
|
|
mercury_vars_to_string_src(VarNameSrc, VarNamePrint, Vars) = String :-
|
|
mercury_format_vars_src(VarNameSrc, VarNamePrint, Vars, unit, "", String).
|
|
|
|
mercury_format_vars_src(VarNameSrc, VarNamePrint, Vars, S, !U) :-
|
|
add_list(mercury_format_var_src(VarNameSrc, VarNamePrint), ", ", Vars,
|
|
S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_var_to_name_only(VarSet, Var) =
|
|
mercury_var_to_string(VarSet, print_name_only, Var).
|
|
|
|
mercury_vars_to_name_only(VarSet, Vars) =
|
|
mercury_vars_to_string(VarSet, print_name_only, Vars).
|
|
|
|
%---------------------%
|
|
|
|
mercury_var_to_name_only_vs(VarSet, Var) =
|
|
mercury_var_to_string_vs(VarSet, print_name_only, Var).
|
|
|
|
mercury_vars_to_name_only_vs(VarSet, Vars) =
|
|
mercury_vars_to_string_vs(VarSet, print_name_only, Vars).
|
|
|
|
%---------------------%
|
|
|
|
mercury_var_to_name_only_src(VarNameSrc, Var) =
|
|
mercury_var_to_string_src(VarNameSrc, print_name_only, Var).
|
|
|
|
mercury_vars_to_name_only_src(VarNameSrc, Vars) =
|
|
mercury_vars_to_string_src(VarNameSrc, print_name_only, Vars).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
describe_error_term(VarSet, Term) =
|
|
% We should consider using the algorithms of term_io.write_term instead of
|
|
% the ones now in mercury_limited_term_to_string to print terms; it adds
|
|
% fewer redundant parentheses.
|
|
mercury_limited_term_to_string_vs(VarSet, print_name_only,
|
|
max_term_string_size_in_syntax_error, Term).
|
|
|
|
% The maximum size of the string representation of a term to print
|
|
% at syntax errors.
|
|
%
|
|
:- func max_term_string_size_in_syntax_error = int.
|
|
|
|
max_term_string_size_in_syntax_error = 80.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_output_term_vs(VarSet, VarNamePrint, Term, Stream, !IO) :-
|
|
mercury_output_term_nq_vs(VarSet, VarNamePrint,
|
|
not_next_to_graphic_token, Term, Stream, !IO).
|
|
|
|
mercury_term_to_string_vs(VarSet, VarNamePrint, Term) =
|
|
mercury_term_nq_to_string_vs(VarSet, VarNamePrint,
|
|
not_next_to_graphic_token, Term).
|
|
|
|
mercury_format_term_vs(VarSet, VarNamePrint, Term, S, !U) :-
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint,
|
|
not_next_to_graphic_token, Term, S, !U).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_term(VarTable, VarNamePrint, Term, Stream, !IO) :-
|
|
mercury_output_term_nq(VarTable, VarNamePrint,
|
|
not_next_to_graphic_token, Term, Stream, !IO).
|
|
|
|
mercury_term_to_string(VarTable, VarNamePrint, Term) =
|
|
mercury_term_nq_to_string(VarTable, VarNamePrint,
|
|
not_next_to_graphic_token, Term).
|
|
|
|
mercury_format_term(VarTable, VarNamePrint, Term, S, !U) :-
|
|
mercury_format_term_nq(VarTable, VarNamePrint,
|
|
not_next_to_graphic_token, Term, S, !U).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_term_src(VarNameSrc, VarNamePrint, Term, Stream, !IO) :-
|
|
(
|
|
VarNameSrc = vns_varset(VarSet),
|
|
mercury_output_term_nq_vs(VarSet, VarNamePrint,
|
|
not_next_to_graphic_token, Term, Stream, !IO)
|
|
;
|
|
VarNameSrc = vns_var_table(VarTable),
|
|
mercury_output_term_nq(VarTable, VarNamePrint,
|
|
not_next_to_graphic_token, Term, Stream, !IO)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken, Term,
|
|
Stream, !IO) :-
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken, Term,
|
|
Stream, !IO).
|
|
|
|
mercury_term_nq_to_string_vs(VarSet, VarNamePrint, NextToGraphicToken, Term)
|
|
= String :-
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken, Term,
|
|
unit, "", String).
|
|
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken, Term,
|
|
S, !U) :-
|
|
% Please keep in sync with mercury_format_term_nq.
|
|
(
|
|
Term = term.variable(Var, _),
|
|
mercury_format_var_vs(VarSet, VarNamePrint, Var, S, !U)
|
|
;
|
|
Term = term.functor(Functor, Args, _),
|
|
( if
|
|
Functor = term.atom(""),
|
|
Args = [F, X | Xs]
|
|
then
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken,
|
|
F, S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_comma_separated_terms_vs(VarSet, VarNamePrint,
|
|
X, Xs, S, !U),
|
|
add_string(")", S, !U)
|
|
else if
|
|
Functor = term.atom("[|]"),
|
|
Args = [X, Xs]
|
|
then
|
|
add_string("[", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, X, S, !U),
|
|
mercury_format_list_args_vs(VarSet, VarNamePrint, Xs, S, !U),
|
|
add_string("]", S, !U)
|
|
else if
|
|
Functor = term.atom("{}"),
|
|
Args = [X | Xs]
|
|
then
|
|
(
|
|
Xs = [],
|
|
% A unary tuple is usually a DCG escape,
|
|
% so add some extra space.
|
|
add_string("{ ", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, X, S, !U),
|
|
add_string(" }", S, !U)
|
|
;
|
|
Xs = [_ | _],
|
|
add_string("{", S, !U),
|
|
mercury_format_comma_separated_terms_vs(VarSet, VarNamePrint,
|
|
X, Xs, S, !U),
|
|
add_string("}", S, !U)
|
|
)
|
|
else if
|
|
Functor = term.atom(FunctorName),
|
|
mercury_op_table_search_op_infos(FunctorName, OpInfos)
|
|
then
|
|
(
|
|
( Args = []
|
|
; Args = [_, _, _ | _]
|
|
),
|
|
mercury_format_plain_functor_args_nq_vs(VarSet,
|
|
VarNamePrint, NextToGraphicToken, Functor, Args, S, !U)
|
|
;
|
|
Args = [ArgA],
|
|
( if OpInfos ^ oi_prefix = pre(_, _) then
|
|
add_string("(", S, !U),
|
|
add_string(FunctorName, S, !U),
|
|
add_string(" ", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, ArgA, S, !U),
|
|
add_string(")", S, !U)
|
|
else if OpInfos ^ oi_postfix = post(_, _) then
|
|
add_string("(", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, ArgA, S, !U),
|
|
add_string(" ", S, !U),
|
|
add_string(FunctorName, S, !U),
|
|
add_string(")", S, !U)
|
|
else
|
|
mercury_format_plain_functor_args_nq_vs(VarSet,
|
|
VarNamePrint, NextToGraphicToken, Functor, Args, S, !U)
|
|
)
|
|
;
|
|
Args = [ArgA, ArgB],
|
|
( if OpInfos ^ oi_binary_prefix = bin_pre(_, _, _) then
|
|
add_string("(", S, !U),
|
|
add_string(FunctorName, S, !U),
|
|
add_string(" ", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, ArgA, S, !U),
|
|
add_string(" ", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, ArgB, S, !U),
|
|
add_string(")", S, !U)
|
|
else if OpInfos ^ oi_infix = in(_, _, _) then
|
|
( if FunctorName = "." then
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint,
|
|
next_to_graphic_token, ArgA, S, !U),
|
|
add_string(".", S, !U),
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint,
|
|
next_to_graphic_token, ArgB, S, !U)
|
|
else
|
|
add_string("(", S, !U),
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint,
|
|
not_next_to_graphic_token, ArgA, S, !U),
|
|
add_string(" ", S, !U),
|
|
add_string(FunctorName, S, !U),
|
|
add_string(" ", S, !U),
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint,
|
|
not_next_to_graphic_token, ArgB, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
else
|
|
mercury_format_plain_functor_args_nq_vs(VarSet,
|
|
VarNamePrint, NextToGraphicToken, Functor, Args, S, !U)
|
|
)
|
|
)
|
|
else
|
|
mercury_format_plain_functor_args_nq_vs(VarSet, VarNamePrint,
|
|
NextToGraphicToken, Functor, Args, S, !U)
|
|
)
|
|
).
|
|
|
|
:- pred mercury_format_plain_functor_args_nq_vs(varset(T)::in,
|
|
var_name_print::in, needs_quotes::in, const::in, list(term(T))::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_plain_functor_args_nq_vs(VarSet, VarNamePrint,
|
|
NextToGraphicToken, Functor, Args, S, !U) :-
|
|
(
|
|
Args = [],
|
|
mercury_format_bracketed_constant_ngt(NextToGraphicToken,
|
|
Functor, S, !U)
|
|
;
|
|
Args = [HeadArg | TailArgs],
|
|
mercury_format_constant(NextToGraphicToken, Functor, S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_comma_separated_terms_vs(VarSet, VarNamePrint,
|
|
HeadArg, TailArgs, S, !U),
|
|
add_string(")", S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_term_nq(VarTable, VarNamePrint, NextToGraphicToken,
|
|
Term, Stream, !IO) :-
|
|
mercury_format_term_nq(VarTable, VarNamePrint, NextToGraphicToken,
|
|
Term, Stream, !IO).
|
|
|
|
mercury_term_nq_to_string(VarTable, VarNamePrint, NextToGraphicToken,
|
|
Term) = String :-
|
|
mercury_format_term_nq(VarTable, VarNamePrint, NextToGraphicToken,
|
|
Term, unit, "", String).
|
|
|
|
mercury_format_term_nq(VarTable, VarNamePrint, NextToGraphicToken, Term,
|
|
S, !U) :-
|
|
% Please keep in sync with mercury_format_term_nq_vs.
|
|
(
|
|
Term = term.variable(Var, _),
|
|
mercury_format_var(VarTable, VarNamePrint, Var, S, !U)
|
|
;
|
|
Term = term.functor(Functor, Args, _),
|
|
( if
|
|
Functor = term.atom(""),
|
|
Args = [F, X | Xs]
|
|
then
|
|
mercury_format_term_nq(VarTable, VarNamePrint, NextToGraphicToken,
|
|
F, S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_comma_separated_terms(VarTable, VarNamePrint,
|
|
X, Xs, S, !U),
|
|
add_string(")", S, !U)
|
|
else if
|
|
Functor = term.atom("[|]"),
|
|
Args = [X, Xs]
|
|
then
|
|
add_string("[", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, X, S, !U),
|
|
mercury_format_list_args(VarTable, VarNamePrint, Xs, S, !U),
|
|
add_string("]", S, !U)
|
|
else if
|
|
Functor = term.atom("{}"),
|
|
Args = [X | Xs]
|
|
then
|
|
(
|
|
Xs = [],
|
|
% A unary tuple is usually a DCG escape,
|
|
% so add some extra space.
|
|
add_string("{ ", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, X, S, !U),
|
|
add_string(" }", S, !U)
|
|
;
|
|
Xs = [_ | _],
|
|
add_string("{", S, !U),
|
|
mercury_format_comma_separated_terms(VarTable, VarNamePrint,
|
|
X, Xs, S, !U),
|
|
add_string("}", S, !U)
|
|
)
|
|
else if
|
|
Functor = term.atom(FunctorName),
|
|
mercury_op_table_search_op_infos(FunctorName, OpInfos)
|
|
then
|
|
(
|
|
( Args = []
|
|
; Args = [_, _, _ | _]
|
|
),
|
|
mercury_format_plain_functor_args_nq(VarTable,
|
|
VarNamePrint, NextToGraphicToken, Functor, Args, S, !U)
|
|
;
|
|
Args = [ArgA],
|
|
( if OpInfos ^ oi_prefix = pre(_, _) then
|
|
add_string("(", S, !U),
|
|
add_string(FunctorName, S, !U),
|
|
add_string(" ", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, ArgA, S, !U),
|
|
add_string(")", S, !U)
|
|
else if OpInfos ^ oi_postfix = post(_, _) then
|
|
add_string("(", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, ArgA, S, !U),
|
|
add_string(" ", S, !U),
|
|
add_string(FunctorName, S, !U),
|
|
add_string(")", S, !U)
|
|
else
|
|
mercury_format_plain_functor_args_nq(VarTable,
|
|
VarNamePrint, NextToGraphicToken, Functor, Args, S, !U)
|
|
)
|
|
;
|
|
Args = [ArgA, ArgB],
|
|
( if OpInfos ^ oi_binary_prefix = bin_pre(_, _, _) then
|
|
add_string("(", S, !U),
|
|
add_string(FunctorName, S, !U),
|
|
add_string(" ", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, ArgA, S, !U),
|
|
add_string(" ", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, ArgB, S, !U),
|
|
add_string(")", S, !U)
|
|
else if OpInfos ^ oi_infix = in(_, _, _) then
|
|
( if FunctorName = "." then
|
|
mercury_format_term_nq(VarTable, VarNamePrint,
|
|
next_to_graphic_token, ArgA, S, !U),
|
|
add_string(".", S, !U),
|
|
mercury_format_term_nq(VarTable, VarNamePrint,
|
|
next_to_graphic_token, ArgB, S, !U)
|
|
else
|
|
add_string("(", S, !U),
|
|
mercury_format_term_nq(VarTable, VarNamePrint,
|
|
not_next_to_graphic_token, ArgA, S, !U),
|
|
add_string(" ", S, !U),
|
|
add_string(FunctorName, S, !U),
|
|
add_string(" ", S, !U),
|
|
mercury_format_term_nq(VarTable, VarNamePrint,
|
|
not_next_to_graphic_token, ArgB, S, !U),
|
|
add_string(")", S, !U)
|
|
)
|
|
else
|
|
mercury_format_plain_functor_args_nq(VarTable,
|
|
VarNamePrint, NextToGraphicToken, Functor, Args, S, !U)
|
|
)
|
|
)
|
|
else
|
|
mercury_format_plain_functor_args_nq(VarTable, VarNamePrint,
|
|
NextToGraphicToken, Functor, Args, S, !U)
|
|
)
|
|
).
|
|
|
|
:- pred mercury_format_plain_functor_args_nq(var_table::in,
|
|
var_name_print::in, needs_quotes::in, const::in, list(prog_term)::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_plain_functor_args_nq(VarTable, VarNamePrint,
|
|
NextToGraphicToken, Functor, Args, S, !U) :-
|
|
(
|
|
Args = [],
|
|
mercury_format_bracketed_constant_ngt(NextToGraphicToken,
|
|
Functor, S, !U)
|
|
;
|
|
Args = [HeadArg | TailArgs],
|
|
mercury_format_constant(NextToGraphicToken, Functor, S, !U),
|
|
add_string("(", S, !U),
|
|
mercury_format_comma_separated_terms(VarTable, VarNamePrint,
|
|
HeadArg, TailArgs, S, !U),
|
|
add_string(")", S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
:- pred mercury_format_list_args_vs(varset(T)::in, var_name_print::in,
|
|
term(T)::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_list_args_vs(VarSet, VarNamePrint, Term, S, !U) :-
|
|
% Please keep in sync with mercury_format_list_args_src.
|
|
( if
|
|
Term = term.functor(term.atom("[|]"), Args, _),
|
|
Args = [X, Xs]
|
|
then
|
|
add_string(", ", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, X, S, !U),
|
|
mercury_format_list_args_vs(VarSet, VarNamePrint, Xs, S, !U)
|
|
else if
|
|
Term = term.functor(term.atom("[]"), [], _)
|
|
then
|
|
true
|
|
else
|
|
add_string(" | ", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, Term, S, !U)
|
|
).
|
|
|
|
:- pred mercury_format_list_args(var_table::in, var_name_print::in,
|
|
prog_term::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_list_args(VarTable, VarNamePrint, Term, S, !U) :-
|
|
% Please keep in sync with mercury_format_list_args.
|
|
( if
|
|
Term = term.functor(term.atom("[|]"), Args, _),
|
|
Args = [X, Xs]
|
|
then
|
|
add_string(", ", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, X, S, !U),
|
|
mercury_format_list_args(VarTable, VarNamePrint, Xs, S, !U)
|
|
else if
|
|
Term = term.functor(term.atom("[]"), [], _)
|
|
then
|
|
true
|
|
else
|
|
add_string(" | ", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, Term, S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_term_nq_src(VarNameSrc, VarNamePrint, NextToGraphicToken,
|
|
Term, Stream, !IO) :-
|
|
(
|
|
VarNameSrc = vns_varset(VarSet),
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken,
|
|
Term, Stream, !IO)
|
|
;
|
|
VarNameSrc = vns_var_table(VarTable),
|
|
mercury_format_term_nq(VarTable, VarNamePrint, NextToGraphicToken,
|
|
Term, Stream, !IO)
|
|
).
|
|
|
|
mercury_term_nq_to_string_src(VarNameSrc, VarNamePrint, NextToGraphicToken,
|
|
Term) = String :-
|
|
(
|
|
VarNameSrc = vns_varset(VarSet),
|
|
String = mercury_term_nq_to_string_vs(VarSet, VarNamePrint,
|
|
NextToGraphicToken, Term)
|
|
;
|
|
VarNameSrc = vns_var_table(VarTable),
|
|
String = mercury_term_nq_to_string(VarTable, VarNamePrint,
|
|
NextToGraphicToken, Term)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_format_comma_separated_terms_vs(VarSet, VarNamePrint,
|
|
HeadTerm, TailTerms, S, !U) :-
|
|
mercury_format_term_vs(VarSet, VarNamePrint, HeadTerm, S, !U),
|
|
mercury_format_remaining_terms_vs(VarSet, VarNamePrint, TailTerms, S, !U).
|
|
|
|
mercury_format_comma_separated_terms(VarTable, VarNamePrint,
|
|
HeadTerm, TailTerms, S, !U) :-
|
|
mercury_format_term(VarTable, VarNamePrint, HeadTerm, S, !U),
|
|
mercury_format_remaining_terms(VarTable, VarNamePrint, TailTerms, S, !U).
|
|
|
|
:- pred mercury_format_remaining_terms_vs(varset(T)::in, var_name_print::in,
|
|
list(term(T))::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_remaining_terms_vs(_VarSet, _VarNamePrint, [], _S, !U).
|
|
mercury_format_remaining_terms_vs(VarSet, VarNamePrint, [Term | Terms],
|
|
S, !U) :-
|
|
add_string(", ", S, !U),
|
|
mercury_format_term_vs(VarSet, VarNamePrint, Term, S, !U),
|
|
mercury_format_remaining_terms_vs(VarSet, VarNamePrint, Terms, S, !U).
|
|
|
|
:- pred mercury_format_remaining_terms(var_table::in, var_name_print::in,
|
|
list(prog_term)::in, S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_remaining_terms(_VarTable, _VarNamePrint, [], _S, !U).
|
|
mercury_format_remaining_terms(VarTable, VarNamePrint, [Term | Terms],
|
|
S, !U) :-
|
|
add_string(", ", S, !U),
|
|
mercury_format_term(VarTable, VarNamePrint, Term, S, !U),
|
|
mercury_format_remaining_terms(VarTable, VarNamePrint, Terms, S, !U).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_format_bracketed_constant_ngt(needs_quotes::in, const::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_bracketed_constant_ngt(NextToGraphicToken, Const, S, !U) :-
|
|
( if
|
|
Const = term.atom(Op),
|
|
mercury_op(Op)
|
|
then
|
|
add_string("(", S, !U),
|
|
add_quoted_atom(Op, S, !U),
|
|
add_string(")", S, !U)
|
|
else
|
|
mercury_format_constant(NextToGraphicToken, Const, S, !U)
|
|
).
|
|
|
|
:- pred mercury_format_constant(needs_quotes::in, const::in,
|
|
S::in, U::di, U::uo) is det <= output(S, U).
|
|
|
|
mercury_format_constant(NextToGraphicToken, Const, S, !U) :-
|
|
( if Const = term.atom(Atom) then
|
|
mercury_format_quoted_atom(NextToGraphicToken, Atom, S, !U)
|
|
else
|
|
add_constant(Const, S, !U)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_limited_term_vs(VarSet, VarNamePrint, Limit, Term,
|
|
Stream, !IO) :-
|
|
mercury_output_limited_term_nq_vs(VarSet, VarNamePrint,
|
|
not_next_to_graphic_token, Limit, Term, Stream, !IO).
|
|
|
|
mercury_limited_term_to_string_vs(VarSet, VarNamePrint, Limit, Term) =
|
|
mercury_limited_term_nq_to_string_vs(VarSet, VarNamePrint,
|
|
not_next_to_graphic_token, Limit, Term).
|
|
|
|
%---------------------%
|
|
|
|
mercury_output_limited_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken,
|
|
Limit, Term, Stream, !IO) :-
|
|
Str = mercury_limited_term_nq_to_string_vs(VarSet, VarNamePrint,
|
|
NextToGraphicToken, Limit, Term),
|
|
io.write_string(Stream, Str, !IO).
|
|
|
|
mercury_limited_term_nq_to_string_vs(VarSet, VarNamePrint, NextToGraphicToken,
|
|
Limit, Term) = String :-
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken, Term,
|
|
unit, "", FullString),
|
|
FullLen = string.count_code_points(FullString),
|
|
( if FullLen =< Limit then
|
|
String = FullString
|
|
else
|
|
(
|
|
Term = term.variable(_, _),
|
|
% We cannot reduce the length of the string.
|
|
String = FullString
|
|
;
|
|
Term = term.functor(Functor, Args, Context),
|
|
NoArgTerm = term.functor(Functor, [], Context),
|
|
mercury_format_term_nq_vs(VarSet, VarNamePrint, NextToGraphicToken,
|
|
NoArgTerm, unit, "", FunctorString),
|
|
(
|
|
Functor = term.atom(_),
|
|
ArityStr = int_to_string(list.length(Args)),
|
|
String = FunctorString ++ "/" ++ ArityStr
|
|
;
|
|
( Functor = term.integer(_, _, _, _)
|
|
; Functor = term.float(_)
|
|
; Functor = term.string(_)
|
|
; Functor = term.implementation_defined(_)
|
|
),
|
|
String = FunctorString
|
|
)
|
|
)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
mercury_bracketed_atom_to_string(NextToGraphicToken, Name) = String :-
|
|
mercury_format_bracketed_atom(NextToGraphicToken, Name, unit, "", String).
|
|
|
|
mercury_format_bracketed_atom(NextToGraphicToken, Name, S, !U) :-
|
|
( if mercury_op(Name) then
|
|
add_string("(", S, !U),
|
|
add_quoted_atom(Name, S, !U),
|
|
add_string(")", S, !U)
|
|
else
|
|
mercury_format_quoted_atom(NextToGraphicToken, Name, S, !U)
|
|
).
|
|
|
|
mercury_format_quoted_atom(NextToGraphicToken, Name, S, !U) :-
|
|
% If the symname is composed of only graphic token chars, then
|
|
% term_io.quote_atom will not quote it; but if it is next another
|
|
% graphic token, it needs to be quoted, otherwise the two would be
|
|
% considered part of one symbol name (e.g. In "int:<", the ":<" parses
|
|
% as one token, so when writing out the "<" after the ":" we need
|
|
% to quote it.
|
|
( if
|
|
NextToGraphicToken = next_to_graphic_token,
|
|
string.to_char_list(Name, Chars),
|
|
( list.member(Char, Chars) =>
|
|
mercury_term_lexer.graphic_token_char(Char)
|
|
)
|
|
then
|
|
add_string("'", S, !U),
|
|
add_escaped_string(Name, S, !U),
|
|
add_string("'", S, !U)
|
|
else
|
|
add_quoted_atom(Name, S, !U)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type graphic_char
|
|
---> not_seen_graphic_char
|
|
; seen_graphic_char.
|
|
|
|
:- type non_graphic_char
|
|
---> not_seen_non_graphic_char
|
|
; seen_non_graphic_char.
|
|
|
|
string_graphic_chars(Str) = Result :-
|
|
string.foldl2(string_graphic_chars_acc, Str,
|
|
not_seen_graphic_char, Graphic, not_seen_non_graphic_char, NonGraphic),
|
|
(
|
|
Graphic = not_seen_graphic_char,
|
|
Result = no_graphic_chars
|
|
;
|
|
Graphic = seen_graphic_char,
|
|
(
|
|
NonGraphic = not_seen_non_graphic_char,
|
|
Result = all_graphic_chars
|
|
;
|
|
NonGraphic = seen_non_graphic_char,
|
|
Result = some_graphic_chars
|
|
)
|
|
).
|
|
|
|
:- pred string_graphic_chars_acc(char::in,
|
|
graphic_char::in, graphic_char::out,
|
|
non_graphic_char::in, non_graphic_char::out) is det.
|
|
|
|
string_graphic_chars_acc(Char, !Graphic, !NonGraphic) :-
|
|
( if mercury_term_lexer.graphic_token_char(Char) then
|
|
!:Graphic = seen_graphic_char
|
|
else
|
|
!:NonGraphic = seen_non_graphic_char
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Predicates to test whether a functor is a Mercury operator.
|
|
%
|
|
|
|
mercury_op(Op) :-
|
|
ops.mercury_op_table_is_op(Op).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module parse_tree.parse_tree_out_term.
|
|
%---------------------------------------------------------------------------%
|