mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 12:26:29 +00:00
Its syntax is
disable_warnings [warning_category1, ...] Goal
Its semantics is identical to Goal's semantics, with the only difference
being that the compiler will not generate warnings belonging to the listed
categories for code inside Goal.
At the moment, we support the disabling of two warning categories:
singleton variable warnings, and warnings about recursive calls that are not
*tail* recursive. However, the documentation of the latter is commented out
until we use the same code for generating such warnings regardless of what
backend generates code.
doc/reference_manual.texi:
Document the new language extension.
NEWS:
Mention the new language extension.
library/ops.m:
Make "disable_warnings" (and its "disable_warning" variant) binary prefix
operators, as required for the syntax of the new scope.
compiler/prog_item.m:
Add disable_warnings_expr as a new kind of goal in the parse tree.
compiler/hlds_goal.m:
Add disable_warnings as a new kind of scope goal in the HLDS.
compiler/prog_data.m:
Add a type that represents the set of warnings that may be disabled.
This type cannot be in prog_item.m, because it is needed by the HLDS,
and we don't want the HLDS to depend on prog_item.m.
compiler/parse_goal.m:
Parse the new kind of goal, transforming it from source code to parse tree.
compiler/goal_expr_to_goal.m:
Transform the new kind of goal from parse tree to HLDS.
compiler/prog_out.m:
compiler/parse_tree_out_clause.m:
compiler/hlds_out_goal.m:
Output the new kinds of parse tree and HLDS goals.
compiler/make_hlds_warn.m:
Disable singleton variable warnings when the new scope asks for that.
compiler/mark_tail_calls.m:
Disable warnings about non-tail-recursive recursive calls
when the new scope asks for that.
Improve a warning message.
compiler/ml_tailcall.m:
Document why this sort-of-duplicate implementation of the
warnings about non-tail-recursive recursive calls cannot respect
the new scope. (I believe this sort-of-duplicate code should be deleted.)
Improve the same warning message as in mark_tail_calls.m.
compiler/constraint.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/erl_code_gen.m:
compiler/get_dependencies.m:
compiler/goal_util.m:
compiler/hlds_desc.m:
compiler/interval.m:
compiler/lambda.m:
compiler/modecheck_goal.m:
compiler/module_qual.collect_mq_info.m:
compiler/polymorphism.m:
compiler/prog_item_stats.m:
compiler/prog_util.m:
compiler/purity.m:
compiler/quantification.m:
compiler/saved_vars.m:
compiler/simplify_goal_scope.m:
compiler/simplify_proc.m:
compiler/stm_expand.m:
compiler/switch_detection.m:
compiler/try_expand.m:
compiler/typecheck.m:
compiler/unique_modes.m:
Handle the new kind of scope.
In a couple of places, fix comments.
tests/invalid/require_tailrec_1.{m,err_exp}:
Wrap a disable_warnings scope around one of the non-tail-recursive
recursive calls we used to get a warning about, and expect that
we don't get this warning anymore. (We still do get this warning in grades
that use ml_tailcall.m instead of mark_tail_calls.m to generate such
warnings, as mentioned above.)
Specify Mercury syntax highlighting for the source file.
Expect the improved wording of a warning.
tests/invalid/require_tailrec_2.{m,err_exp}:
Specify Mercury syntax highlighting for the source file.
Expect the improved wording of a warning.
tests/warnings/singleton_test.m:
Add a test of a singleton variable whose warning is disabled.
893 lines
32 KiB
Mathematica
893 lines
32 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2015 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This module converts the parse tree structure representations of clauses
|
|
% back into Mercury source text.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module parse_tree.parse_tree_out_clause.
|
|
:- interface.
|
|
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.parse_tree_out_info.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.prog_item.
|
|
|
|
:- import_module io.
|
|
:- import_module list.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_item_clause(merc_out_info::in, item_clause_info::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred output_instance_method_clause(sym_name::in, item_clause_info::in,
|
|
io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_goal(prog_varset::in, int::in, goal::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred write_goal_warnings(goal_warning::in, list(goal_warning)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred mercury_output_trace_expr(pred(T, io, io)::in(pred(in, di, uo) is det),
|
|
trace_expr(T)::in, io::di, io::uo) is det.
|
|
|
|
:- pred mercury_output_trace_compiletime(trace_compiletime::in,
|
|
io::di, io::uo) is det.
|
|
|
|
:- pred mercury_output_trace_runtime(trace_runtime::in,
|
|
io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module parse_tree.maybe_error.
|
|
:- import_module parse_tree.mercury_to_mercury.
|
|
:- import_module parse_tree.parse_tree_out_term.
|
|
:- import_module parse_tree.prog_out.
|
|
:- import_module parse_tree.prog_util.
|
|
|
|
:- import_module bool.
|
|
:- import_module int.
|
|
:- import_module maybe.
|
|
:- import_module term.
|
|
:- import_module term_io.
|
|
:- import_module varset.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_output_item_clause(Info, ItemClause, !IO) :-
|
|
ItemClause = item_clause_info(PredName0, PredOrFunc, ArgTerms, _MaybeAttrs,
|
|
VarSet, MaybeBodyGoal, Context, _SeqNum),
|
|
get_clause_body_goal(MaybeBodyGoal, BodyGoal),
|
|
maybe_unqualify_sym_name(Info, PredName0, PredName),
|
|
maybe_output_line_number(Info, Context, !IO),
|
|
(
|
|
PredOrFunc = pf_predicate,
|
|
mercury_output_pred_clause(VarSet, PredName, ArgTerms, BodyGoal, !IO)
|
|
;
|
|
PredOrFunc = pf_function,
|
|
pred_args_to_func_args(ArgTerms, FuncArgTerms, ResultTerm),
|
|
mercury_output_func_clause(VarSet, PredName, FuncArgTerms, ResultTerm,
|
|
BodyGoal, !IO)
|
|
),
|
|
io.write_string(".\n", !IO).
|
|
|
|
output_instance_method_clause(MethodName, ItemClause, !IO) :-
|
|
ItemClause = item_clause_info(_PredName, PredOrFunc, ArgTerms, _MaybeAttrs,
|
|
VarSet, MaybeBodyGoal, _Context, _SeqNum),
|
|
get_clause_body_goal(MaybeBodyGoal, BodyGoal),
|
|
(
|
|
PredOrFunc = pf_predicate,
|
|
mercury_output_pred_clause(VarSet, MethodName, ArgTerms, BodyGoal, !IO)
|
|
;
|
|
PredOrFunc = pf_function,
|
|
pred_args_to_func_args(ArgTerms, FuncArgTerms, ResultTerm),
|
|
mercury_output_func_clause(VarSet, MethodName,
|
|
FuncArgTerms, ResultTerm, BodyGoal, !IO)
|
|
).
|
|
|
|
:- pred get_clause_body_goal(maybe1(goal)::in, goal::out) is det.
|
|
|
|
get_clause_body_goal(MaybeBodyGoal, BodyGoal) :-
|
|
(
|
|
MaybeBodyGoal = ok1(BodyGoal)
|
|
;
|
|
MaybeBodyGoal = error1(_),
|
|
PredName = unqualified("there_was_a_syntax_error"),
|
|
BodyGoal = call_expr(term.context_init, PredName, [], purity_pure)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_pred_clause(prog_varset::in, sym_name::in,
|
|
list(prog_term)::in, goal::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_pred_clause(VarSet, PredName, Args, Body, !IO) :-
|
|
mercury_output_sym_name(PredName, !IO),
|
|
(
|
|
Args = [HeadArg | TailArgs],
|
|
io.write_string("(", !IO),
|
|
mercury_format_comma_separated_terms(VarSet, print_name_only,
|
|
HeadArg, TailArgs, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Args = []
|
|
),
|
|
( if Body = true_expr(_) then
|
|
true
|
|
else
|
|
io.write_string(" :-\n\t", !IO),
|
|
mercury_output_goal(VarSet, 1, Body, !IO)
|
|
).
|
|
|
|
:- pred mercury_output_func_clause(prog_varset::in, sym_name::in,
|
|
list(prog_term)::in, prog_term::in, goal::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_func_clause(VarSet, PredName, Args, Result, Body, !IO) :-
|
|
mercury_output_sym_name(PredName, !IO),
|
|
(
|
|
Args = [HeadArg | TailArgs],
|
|
io.write_string("(", !IO),
|
|
mercury_format_comma_separated_terms(VarSet, print_name_only,
|
|
HeadArg, TailArgs, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Args = []
|
|
),
|
|
io.write_string(" = ", !IO),
|
|
( if Body = true_expr(_) then
|
|
mercury_format_term_nq(VarSet, print_name_only, next_to_graphic_token,
|
|
Result, !IO)
|
|
else
|
|
mercury_format_term(VarSet, print_name_only, Result, !IO),
|
|
io.write_string(" :-\n\t", !IO),
|
|
mercury_output_goal(VarSet, 1, Body, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_output_goal(VarSet, Indent, Goal, !IO) :-
|
|
(
|
|
Goal = fail_expr(_),
|
|
io.write_string("fail", !IO)
|
|
;
|
|
Goal = true_expr(_),
|
|
io.write_string("true", !IO)
|
|
;
|
|
Goal = implies_expr(_, SubGoalA, SubGoalB),
|
|
Indent1 = Indent + 1,
|
|
io.write_string("(", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_connected_goal(VarSet, Indent1, SubGoalA, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string("=>", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_connected_goal(VarSet, Indent1, SubGoalB, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = equivalent_expr(_, SubGoalA, SubGoalB),
|
|
Indent1 = Indent + 1,
|
|
io.write_string("(", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_connected_goal(VarSet, Indent1, SubGoalA, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string("<=>", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_connected_goal(VarSet, Indent1, SubGoalB, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = quant_expr(QuantType, QuantVarsKind, _, Vars, SubGoal),
|
|
(
|
|
Vars = [],
|
|
mercury_output_goal(VarSet, Indent, SubGoal, !IO)
|
|
;
|
|
Vars = [_ | _],
|
|
(
|
|
QuantType = quant_some,
|
|
io.write_string("some", !IO)
|
|
;
|
|
QuantType = quant_all,
|
|
io.write_string("all", !IO)
|
|
),
|
|
io.write_string("[", !IO),
|
|
(
|
|
QuantVarsKind = quant_ordinary_vars,
|
|
mercury_output_vars(VarSet, print_name_only, Vars, !IO)
|
|
;
|
|
QuantVarsKind = quant_state_vars,
|
|
mercury_output_state_vars(VarSet, print_name_only, Vars, !IO)
|
|
),
|
|
io.write_string("] (", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
)
|
|
;
|
|
Goal = promise_equivalent_solutions_expr(_, Vars, StateVars,
|
|
DotSVars, ColonSVars, SubGoal),
|
|
mercury_output_promise_eqv_solutions_goal(VarSet, Indent,
|
|
Vars, StateVars, DotSVars, ColonSVars, SubGoal,
|
|
"promise_equivalent_solutions", !IO)
|
|
;
|
|
Goal = promise_equivalent_solution_sets_expr(_, Vars, StateVars,
|
|
DotSVars, ColonSVars, SubGoal),
|
|
mercury_output_promise_eqv_solutions_goal(VarSet, Indent,
|
|
Vars, StateVars, DotSVars, ColonSVars, SubGoal,
|
|
"promise_equivalent_solution_sets", !IO)
|
|
;
|
|
Goal = promise_equivalent_solution_arbitrary_expr(_, Vars, StateVars,
|
|
DotSVars, ColonSVars, SubGoal),
|
|
mercury_output_promise_eqv_solutions_goal(VarSet, Indent,
|
|
Vars, StateVars, DotSVars, ColonSVars, SubGoal, "arbitrary", !IO)
|
|
;
|
|
Goal = promise_purity_expr(_, Purity, SubGoal),
|
|
(
|
|
Purity = purity_pure,
|
|
io.write_string("promise_pure (", !IO)
|
|
;
|
|
Purity = purity_semipure,
|
|
io.write_string("promise_semipure (", !IO)
|
|
;
|
|
Purity = purity_impure,
|
|
io.write_string("promise_impure (", !IO)
|
|
),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = require_detism_expr(_, Detism, SubGoal),
|
|
(
|
|
Detism = detism_det,
|
|
io.write_string("require_det", !IO)
|
|
;
|
|
Detism = detism_semi,
|
|
io.write_string("require_semidet", !IO)
|
|
;
|
|
Detism = detism_multi,
|
|
io.write_string("require_multi", !IO)
|
|
;
|
|
Detism = detism_non,
|
|
io.write_string("require_nondet", !IO)
|
|
;
|
|
Detism = detism_cc_multi,
|
|
io.write_string("require_cc_multi", !IO)
|
|
;
|
|
Detism = detism_cc_non,
|
|
io.write_string("require_cc_nondet", !IO)
|
|
;
|
|
Detism = detism_erroneous,
|
|
io.write_string("require_erroneous", !IO)
|
|
;
|
|
Detism = detism_failure,
|
|
io.write_string("require_failure", !IO)
|
|
),
|
|
io.write_string(" (", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = require_complete_switch_expr(_, Var, SubGoal),
|
|
io.write_string("require_complete_switch [", !IO),
|
|
mercury_output_plain_or_dot_var(VarSet, print_name_only, Var, !IO),
|
|
io.write_string("] (", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = require_switch_arms_detism_expr(_, Var, Detism, SubGoal),
|
|
(
|
|
Detism = detism_det,
|
|
io.write_string("require_switch_arms_det", !IO)
|
|
;
|
|
Detism = detism_semi,
|
|
io.write_string("require_switch_arms_semidet", !IO)
|
|
;
|
|
Detism = detism_multi,
|
|
io.write_string("require_switch_arms_multi", !IO)
|
|
;
|
|
Detism = detism_non,
|
|
io.write_string("require_switch_arms_nondet", !IO)
|
|
;
|
|
Detism = detism_cc_multi,
|
|
io.write_string("require_switch_arms_cc_multi", !IO)
|
|
;
|
|
Detism = detism_cc_non,
|
|
io.write_string("require_switch_arms_cc_nondet", !IO)
|
|
;
|
|
Detism = detism_erroneous,
|
|
io.write_string("require_switch_arms_erroneous", !IO)
|
|
;
|
|
Detism = detism_failure,
|
|
io.write_string("require_switch_arms_failure", !IO)
|
|
),
|
|
io.write_string(" [", !IO),
|
|
mercury_output_plain_or_dot_var(VarSet, print_name_only, Var, !IO),
|
|
io.write_string("] (", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = disable_warnings_expr(_, HeadWarning, TailWarnings, SubGoal),
|
|
io.write_string("disable_warnings [", !IO),
|
|
write_goal_warnings(HeadWarning, TailWarnings, !IO),
|
|
io.write_string("] (", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = atomic_expr(_, Outer, Inner, _, MainGoal, OrElseGoals),
|
|
io.write_string("atomic [outer(", !IO),
|
|
(
|
|
Outer = atomic_state_var(OVar),
|
|
io.write_string("!", !IO),
|
|
mercury_output_var(VarSet, print_name_only, OVar, !IO)
|
|
;
|
|
Outer = atomic_var_pair(OuterDI, OuterUO),
|
|
mercury_output_var(VarSet, print_name_only, OuterDI, !IO),
|
|
io.write_string(", ", !IO),
|
|
mercury_output_var(VarSet, print_name_only, OuterUO, !IO)
|
|
),
|
|
io.write_string("), inner(", !IO),
|
|
(
|
|
Inner = atomic_state_var(IVar),
|
|
io.write_string("!", !IO),
|
|
mercury_output_var(VarSet, print_name_only, IVar, !IO)
|
|
;
|
|
Inner = atomic_var_pair(InnerDI, InnerUO),
|
|
mercury_output_var(VarSet, print_name_only, InnerDI, !IO),
|
|
io.write_string(", ", !IO),
|
|
mercury_output_var(VarSet, print_name_only, InnerUO, !IO)
|
|
),
|
|
io.write_string(")] (", !IO),
|
|
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_orelse_goals(VarSet, Indent1, [MainGoal | OrElseGoals],
|
|
!IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = trace_expr(_, MaybeCompileTime, MaybeRunTime, MaybeIO,
|
|
MutableVars, SubGoal),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string("trace [", !IO),
|
|
some [!NeedComma] (
|
|
!:NeedComma = no,
|
|
(
|
|
MaybeCompileTime = yes(CompileTime),
|
|
mercury_output_trace_expr(mercury_output_trace_compiletime,
|
|
CompileTime, !IO),
|
|
!:NeedComma = yes
|
|
;
|
|
MaybeCompileTime = no
|
|
),
|
|
(
|
|
MaybeRunTime = yes(RunTime),
|
|
mercury_output_comma_if_needed(!.NeedComma, !IO),
|
|
mercury_output_trace_expr(mercury_output_trace_runtime,
|
|
RunTime, !IO),
|
|
!:NeedComma = yes
|
|
;
|
|
MaybeRunTime = no
|
|
),
|
|
(
|
|
MaybeIO = yes(IOStateVar),
|
|
mercury_output_comma_if_needed(!.NeedComma, !IO),
|
|
io.write_string("io(!", !IO),
|
|
mercury_output_var(VarSet, print_name_only, IOStateVar, !IO),
|
|
io.write_string(")", !IO),
|
|
!:NeedComma = yes
|
|
;
|
|
MaybeIO = no
|
|
),
|
|
list.foldl2(
|
|
mercury_output_trace_mutable_var_and_comma(VarSet,
|
|
print_name_only),
|
|
MutableVars, !.NeedComma, _, !IO)
|
|
),
|
|
io.write_string("]", !IO),
|
|
mercury_output_newline(Indent + 1, !IO),
|
|
mercury_output_goal(VarSet, Indent + 1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = try_expr(_, MaybeIO, SubGoal, Then, MaybeElse, Catches,
|
|
MaybeCatchAny),
|
|
io.write_string("(try [", !IO),
|
|
(
|
|
MaybeIO = yes(IOStateVar),
|
|
io.write_string("io(!", !IO),
|
|
mercury_output_var(VarSet, print_name_only, IOStateVar, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
MaybeIO = no
|
|
),
|
|
io.write_string("] (", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string("then", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, Then, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
(
|
|
MaybeElse = yes(Else),
|
|
io.write_string("else", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, Else, !IO)
|
|
;
|
|
MaybeElse = no
|
|
),
|
|
list.foldl(mercury_output_catch(VarSet, Indent), Catches, !IO),
|
|
(
|
|
MaybeCatchAny = yes(catch_any_expr(CatchAnyVar, CatchAnyGoal)),
|
|
io.write_string("catch_any ", !IO),
|
|
mercury_output_var(VarSet, print_name_only, CatchAnyVar, !IO),
|
|
io.write_string(" ->", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, CatchAnyGoal, !IO)
|
|
;
|
|
MaybeCatchAny = no
|
|
),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = if_then_else_expr(_, Vars, StateVars, Cond, Then, Else),
|
|
io.write_string("(if", !IO),
|
|
mercury_output_some(VarSet, Vars, StateVars, !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, Cond, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string("then", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, Then, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string("else", !IO),
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, Else, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = not_expr(_, SubGoal),
|
|
io.write_string("\\+ (", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = conj_expr(_, SubGoalA, SubGoalB),
|
|
mercury_output_goal(VarSet, Indent, SubGoalA, !IO),
|
|
io.write_string(",", !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
mercury_output_goal(VarSet, Indent, SubGoalB, !IO)
|
|
;
|
|
Goal = par_conj_expr(_, SubGoalA, SubGoalB),
|
|
io.write_string("(", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoalA, !IO),
|
|
mercury_output_par_conj(VarSet, Indent, SubGoalB, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = disj_expr(_, SubGoalA, SubGoalB),
|
|
io.write_string("(", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, SubGoalA, !IO),
|
|
mercury_output_disj(VarSet, Indent, SubGoalB, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
Goal = event_expr(_, Name, Terms),
|
|
io.write_string("event ", !IO),
|
|
mercury_output_call(VarSet, unqualified(Name), Terms, !IO)
|
|
;
|
|
Goal = call_expr(_, Name, Terms, Purity),
|
|
write_purity_prefix(Purity, !IO),
|
|
mercury_output_call(VarSet, Name, Terms, !IO)
|
|
;
|
|
Goal = unify_expr(_, TermA, TermB, Purity),
|
|
write_purity_prefix(Purity, !IO),
|
|
mercury_output_term(VarSet, print_name_only, TermA, !IO),
|
|
io.write_string(" = ", !IO),
|
|
mercury_output_term_nq(VarSet, print_name_only, next_to_graphic_token,
|
|
TermB, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_connected_goal(prog_varset::in, int::in, goal::in,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_connected_goal(VarSet, Indent, Goal, !IO) :-
|
|
(
|
|
( Goal = fail_expr(_)
|
|
; Goal = true_expr(_)
|
|
; Goal = implies_expr(_, _, _)
|
|
; Goal = equivalent_expr(_, _, _)
|
|
; Goal = try_expr(_, _, _, _, _, _, _)
|
|
; Goal = if_then_else_expr(_, _, _, _, _, _)
|
|
; Goal = not_expr(_, _)
|
|
; Goal = par_conj_expr(_, _, _)
|
|
; Goal = disj_expr(_, _, _)
|
|
; Goal = event_expr(_, _, _)
|
|
; Goal = call_expr(_, _, _, _)
|
|
; Goal = unify_expr(_, _, _, _)
|
|
),
|
|
mercury_output_goal(VarSet, Indent, Goal, !IO)
|
|
;
|
|
( Goal = quant_expr(_, _, _, _, _)
|
|
; Goal = promise_equivalent_solutions_expr(_, _, _, _, _, _)
|
|
; Goal = promise_equivalent_solution_sets_expr(_, _, _, _, _, _)
|
|
; Goal = promise_equivalent_solution_arbitrary_expr(_, _, _, _, _, _)
|
|
; Goal = promise_purity_expr(_, _, _)
|
|
; Goal = require_detism_expr(_, _, _)
|
|
; Goal = require_complete_switch_expr(_, _, _)
|
|
; Goal = require_switch_arms_detism_expr(_, _, _, _)
|
|
; Goal = disable_warnings_expr(_, _, _, _)
|
|
; Goal = conj_expr(_, _, _)
|
|
; Goal = atomic_expr(_, _, _, _, _, _)
|
|
; Goal = trace_expr(_, _, _, _, _, _)
|
|
),
|
|
io.write_string("(", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, Goal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_plain_or_dot_var(prog_varset::in, var_name_print::in,
|
|
plain_or_dot_var::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_plain_or_dot_var(VarSet, VarNamePrint, PODVar, !IO) :-
|
|
(
|
|
PODVar = podv_plain(Var),
|
|
mercury_output_var(VarSet, VarNamePrint, Var, !IO)
|
|
;
|
|
PODVar = podv_dot(Var),
|
|
io.write_string("!.", !IO),
|
|
mercury_output_var(VarSet, VarNamePrint, Var, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_call(prog_varset::in, sym_name::in, list(prog_term)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_call(VarSet, SymName, Term, !IO) :-
|
|
(
|
|
SymName = qualified(ModuleName, PredName),
|
|
mercury_output_bracketed_sym_name_ngt(next_to_graphic_token,
|
|
ModuleName, !IO),
|
|
io.write_string(".", !IO),
|
|
term.context_init(Context0),
|
|
SubTerm = term.functor(term.atom(PredName), Term, Context0),
|
|
mercury_output_term_nq(VarSet, print_name_only, next_to_graphic_token,
|
|
SubTerm, !IO)
|
|
;
|
|
SymName = unqualified(PredName),
|
|
term.context_init(Context0),
|
|
SubTerm = term.functor(term.atom(PredName), Term, Context0),
|
|
mercury_output_term_nq(VarSet, print_name_only, next_to_graphic_token,
|
|
SubTerm, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_disj(prog_varset::in, int::in, goal::in,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_disj(VarSet, Indent, Goal, !IO) :-
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(";", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
( if Goal = disj_expr(_, SubGoalA, SubGoalB) then
|
|
mercury_output_goal(VarSet, Indent1, SubGoalA, !IO),
|
|
mercury_output_disj(VarSet, Indent, SubGoalB, !IO)
|
|
else
|
|
mercury_output_goal(VarSet, Indent1, Goal, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_par_conj(prog_varset::in, int::in, goal::in,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_par_conj(VarSet, Indent, Goal, !IO) :-
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string("&", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
( if Goal = par_conj_expr(_, SubGoalA, SubGoalB) then
|
|
mercury_output_goal(VarSet, Indent1, SubGoalA, !IO),
|
|
mercury_output_par_conj(VarSet, Indent, SubGoalB, !IO)
|
|
else
|
|
mercury_output_goal(VarSet, Indent1, Goal, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_orelse_goals(prog_varset::in, int::in, list(goal)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_orelse_goals(VarSet, Indent, Goals, !IO) :-
|
|
(
|
|
Goals = []
|
|
;
|
|
Goals = [HeadGoal | TailGoals],
|
|
(
|
|
TailGoals = [],
|
|
mercury_output_goal(VarSet, Indent + 1, HeadGoal, !IO)
|
|
;
|
|
TailGoals = [_|_],
|
|
mercury_output_goal(VarSet, Indent + 1, HeadGoal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string("orelse", !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
mercury_output_orelse_goals(VarSet, Indent, TailGoals, !IO)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_some(varset(T)::in, list(var(T))::in, list(var(T))::in,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_some(VarSet, Vars, StateVars, !IO) :-
|
|
( if
|
|
( Vars = [_ | _]
|
|
; StateVars = [_ | _]
|
|
)
|
|
then
|
|
io.write_string(" some [", !IO),
|
|
mercury_output_vars(VarSet, print_name_only, Vars, !IO),
|
|
( if
|
|
Vars = [_ | _],
|
|
StateVars = [_ | _]
|
|
then
|
|
io.write_string(", ", !IO),
|
|
% XXX BUG: we should print StateVars even if Vars = [].
|
|
mercury_output_state_vars(VarSet, print_name_only, StateVars, !IO)
|
|
else
|
|
true
|
|
),
|
|
io.write_string("]", !IO)
|
|
else
|
|
true
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_promise_eqv_solutions_goal(prog_varset::in, int::in,
|
|
list(prog_var)::in, list(prog_var)::in, list(prog_var)::in,
|
|
list(prog_var)::in, goal::in, string::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_promise_eqv_solutions_goal(VarSet, Indent,
|
|
Vars, StateVars, DotSVars, ColonSVars, Goal, Keyword, !IO) :-
|
|
( if
|
|
Vars = [],
|
|
StateVars = [],
|
|
DotSVars = [],
|
|
ColonSVars = []
|
|
then
|
|
% This should have been caught be parse_goal when reading in
|
|
% the term, but there is no point in aborting here.
|
|
mercury_output_goal(VarSet, Indent, Goal, !IO)
|
|
else
|
|
io.write_string(Keyword, !IO),
|
|
io.write_string(" [", !IO),
|
|
mercury_output_vars(VarSet, print_name_only, Vars, !IO),
|
|
( if
|
|
Vars = [_ | _],
|
|
StateVars = [_ | _]
|
|
then
|
|
io.write_string(", ", !IO)
|
|
else
|
|
true
|
|
),
|
|
mercury_output_state_vars_using_prefix(VarSet, print_name_only,
|
|
"!", StateVars, !IO),
|
|
( if
|
|
( Vars = [_ | _]
|
|
; StateVars = [_ | _]
|
|
),
|
|
DotSVars = [_ | _]
|
|
then
|
|
io.write_string(", ", !IO)
|
|
else
|
|
true
|
|
),
|
|
mercury_output_state_vars_using_prefix(VarSet, print_name_only,
|
|
"!.", DotSVars, !IO),
|
|
( if
|
|
( Vars = [_ | _]
|
|
; StateVars = [_ | _]
|
|
; DotSVars = [_ | _]
|
|
),
|
|
ColonSVars = [_ | _]
|
|
then
|
|
io.write_string(", ", !IO)
|
|
else
|
|
true
|
|
),
|
|
mercury_output_state_vars_using_prefix(VarSet, print_name_only,
|
|
"!:", ColonSVars, !IO),
|
|
io.write_string("] (", !IO),
|
|
Indent1 = Indent + 1,
|
|
mercury_output_newline(Indent1, !IO),
|
|
mercury_output_goal(VarSet, Indent1, Goal, !IO),
|
|
mercury_output_newline(Indent, !IO),
|
|
io.write_string(")", !IO)
|
|
).
|
|
|
|
:- pred mercury_output_state_vars_using_prefix(prog_varset::in,
|
|
var_name_print::in, string::in, list(prog_var)::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_state_vars_using_prefix(_VarSet, _VarNamePrint, _BangPrefix,
|
|
[], !IO).
|
|
mercury_output_state_vars_using_prefix(VarSet, VarNamePrint, BangPrefix,
|
|
[SVar | SVars], !IO) :-
|
|
io.write_string(BangPrefix, !IO),
|
|
mercury_format_var(VarSet, VarNamePrint, SVar, !IO),
|
|
(
|
|
SVars = [_ | _],
|
|
io.write_string(", ", !IO),
|
|
mercury_output_state_vars_using_prefix(VarSet, VarNamePrint,
|
|
BangPrefix, SVars, !IO)
|
|
;
|
|
SVars = []
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
write_goal_warnings(HeadWarning, TailWarnings, !IO) :-
|
|
io.write_string(goal_warning_to_string(HeadWarning), !IO),
|
|
(
|
|
TailWarnings = []
|
|
;
|
|
TailWarnings = [HeadTailWarning | TailTailWarnings],
|
|
io.write_string(", ", !IO),
|
|
write_goal_warnings(HeadTailWarning, TailTailWarnings, !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
mercury_output_trace_expr(PrintBase, TraceExpr, !IO) :-
|
|
(
|
|
TraceExpr = trace_base(Base),
|
|
PrintBase(Base, !IO)
|
|
;
|
|
TraceExpr = trace_not(TraceExprA),
|
|
io.write_string("not(", !IO),
|
|
mercury_output_trace_expr(PrintBase, TraceExprA, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
TraceExpr = trace_op(trace_or, TraceExprA, TraceExprB),
|
|
io.write_string("(", !IO),
|
|
mercury_output_trace_expr(PrintBase, TraceExprA, !IO),
|
|
io.write_string(") or (", !IO),
|
|
mercury_output_trace_expr(PrintBase, TraceExprB, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
TraceExpr = trace_op(trace_and, TraceExprA, TraceExprB),
|
|
mercury_output_trace_expr(PrintBase, TraceExprA, !IO),
|
|
io.write_string(" and ", !IO),
|
|
mercury_output_trace_expr(PrintBase, TraceExprB, !IO)
|
|
).
|
|
|
|
mercury_output_trace_compiletime(CompileTime, !IO) :-
|
|
(
|
|
CompileTime = trace_flag(FlagName),
|
|
io.write_string("flag(", !IO),
|
|
term_io.quote_string(FlagName, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
CompileTime = trace_grade(Grade),
|
|
parse_trace_grade_name(GradeName, Grade),
|
|
io.write_string("grade(", !IO),
|
|
io.write_string(GradeName, !IO),
|
|
io.write_string(")", !IO)
|
|
;
|
|
CompileTime = trace_trace_level(Level),
|
|
io.write_string("tracelevel(", !IO),
|
|
(
|
|
Level = trace_level_shallow,
|
|
io.write_string("shallow", !IO)
|
|
;
|
|
Level = trace_level_deep,
|
|
io.write_string("deep", !IO)
|
|
),
|
|
io.write_string(")", !IO)
|
|
).
|
|
|
|
mercury_output_trace_runtime(trace_envvar(EnvVarName), !IO) :-
|
|
io.write_string("env(", !IO),
|
|
term_io.quote_string(EnvVarName, !IO),
|
|
io.write_string(")", !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_trace_mutable_var(prog_varset::in, var_name_print::in,
|
|
trace_mutable_var::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_trace_mutable_var(VarSet, VarNamePrint, MutableVar, !IO) :-
|
|
MutableVar = trace_mutable_var(MutableName, StateVar),
|
|
io.write_string("state(", !IO),
|
|
io.write_string(MutableName, !IO),
|
|
io.write_string(", !", !IO),
|
|
mercury_output_var(VarSet, VarNamePrint, StateVar, !IO),
|
|
io.write_string(")", !IO).
|
|
|
|
:- pred mercury_output_trace_mutable_var_and_comma(prog_varset::in,
|
|
var_name_print::in, trace_mutable_var::in, bool::in, bool::out,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_trace_mutable_var_and_comma(VarSet, VarNamePrint,
|
|
MutableVar, !NeedComma, !IO) :-
|
|
mercury_output_comma_if_needed(!.NeedComma, !IO),
|
|
!:NeedComma = yes,
|
|
mercury_output_trace_mutable_var(VarSet, VarNamePrint, MutableVar, !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_catch(prog_varset::in, int::in, catch_expr::in,
|
|
io::di, io::uo) is det.
|
|
|
|
mercury_output_catch(VarSet, Indent, catch_expr(Pattern, Goal), !IO) :-
|
|
io.write_string("catch ", !IO),
|
|
mercury_output_term(VarSet, print_name_only, Pattern, !IO),
|
|
io.write_string(" ->", !IO),
|
|
mercury_output_newline(Indent + 1, !IO),
|
|
mercury_output_goal(VarSet, Indent + 1, Goal, !IO),
|
|
mercury_output_newline(Indent, !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred mercury_output_comma_if_needed(bool::in, io::di, io::uo) is det.
|
|
|
|
mercury_output_comma_if_needed(no, !IO).
|
|
mercury_output_comma_if_needed(yes, !IO) :-
|
|
io.write_string(", ", !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module parse_tree.parse_tree_out_clause.
|
|
%---------------------------------------------------------------------------%
|