mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 23:05:21 +00:00
Estimated hours taken: 220
Aditi update syntax, type and mode checking.
Change the hlds_goal for constructions in preparation for
structure reuse to avoid making multiple conflicting changes.
compiler/hlds_goal.m:
Merge `higher_order_call' and `class_method_call' into a single
`generic_call' goal type. This also has alternatives for the
various Aditi builtins for which type declarations can't
be written.
Remove the argument types field from higher-order/class method calls.
It wasn't used often, and wasn't updated by optimizations
such as inlining. The types can be obtained from the vartypes
field of the proc_info.
Add a `lambda_eval_method' field to lambda_goals.
Add a field to constructions to identify which RL code fragment should
be used for an top-down Aditi closure.
Add fields to constructions to hold structure reuse information.
This is currently ignored -- the changes to implement structure
reuse will be committed to the alias branch.
This is included here to avoid lots of CVS conflicts caused by
changing the definition of `hlds_goal' twice.
Add a field to `some' goals to specify whether the quantification
can be removed. This is used to make it easier to ensure that
indexes are used for updates.
Add a field to lambda_goals to describe whether the modes were
guessed by the compiler and may need fixing up after typechecking
works out the argument types.
Add predicate `hlds_goal__generic_call_id' to work out a call_id
for a generic call for use in error messages.
compiler/purity.m:
compiler/post_typecheck.m:
Fill in the modes of Aditi builtin calls and closure constructions.
This needs to know which are the `aditi__state' arguments, so
it must be done after typechecking.
compiler/prog_data.m:
Added `:- type sym_name_and_arity ---> sym_name/arity'.
Add a type `lambda_eval_method', which describes how a closure
is to be executed. The alternatives are normal Mercury execution,
bottom-up execution by Aditi and top-down execution by Aditi.
compiler/prog_out.m:
Add predicate `prog_out__write_sym_name_and_arity', which
replaces duplicated inline code in a few places.
compiler/hlds_data.m:
Add a `lambda_eval_method' field to `pred_const' cons_ids and
`pred_closure_tag' cons_tags.
compiler/hlds_pred.m:
Remove type `pred_call_id', replace it with type `simple_call_id',
which combines a `pred_or_func' and a `sym_name_and_arity'.
Add a type `call_id' which describes all the different types of call,
including normal calls, higher-order and class-method calls
and Aditi builtins.
Add `aditi_top_down' to the type `marker'.
Remove `aditi_interface' from type `marker'. Interfacing to
Aditi predicates is now handled by `generic_call' hlds_goals.
Add a type `rl_exprn_id' which identifies a predicate to
be executed top-down by Aditi.
Add a `maybe(rl_exprn_id)' field to type `proc_info'.
Add predicate `adjust_func_arity' to convert between the arity
of a function to its arity as a predicate.
Add predicates `get_state_args' and `get_state_args_det' to
extract the DCG state arguments from an argument list.
Add predicate `pred_info_get_call_id' to get a `simple_call_id'
for a predicate for use in error messages.
compiler/hlds_out.m:
Write the new representation for call_ids.
Add a predicate `hlds_out__write_call_arg_id' which
replaces similar code in mode_errors.m and typecheck.m.
compiler/prog_io_goal.m:
Add support for `aditi_bottom_up' and `aditi_top_down' annotations
on pred expressions.
compiler/prog_io_util.m:
compiler/prog_io_pragma.m:
Add predicates
- `prog_io_util:parse_name_and_arity' to parse `SymName/Arity'
(moved from prog_io_pragma.m).
- `prog_io_util:parse_pred_or_func_name_and_arity to parse
`pred SymName/Arity' or `func SymName/Arity'.
- `prog_io_util:parse_pred_or_func_and_args' to parse terms resembling
a clause head (moved from prog_io_pragma.m).
compiler/type_util.m:
Add support for `aditi_bottom_up' and `aditi_top_down' annotations
on higher-order types.
Add predicates `construct_higher_order_type',
`construct_higher_order_pred_type' and
`construct_higher_order_func_type' to avoid some code duplication.
compiler/mode_util.m:
Add predicate `unused_mode/1', which returns `builtin:unused'.
Add functions `aditi_di_mode/0', `aditi_ui_mode/0' and
`aditi_uo_mode/0' which return `in', `in', and `out', but will
be changed to return `di', `ui' and `uo' when alias tracking
is implemented.
compiler/goal_util.m:
Add predicate `goal_util__generic_call_vars' which returns
any arguments to a generic_call which are not in the argument list,
for example the closure passed to a higher-order call or
the typeclass_info for a class method call.
compiler/llds.m:
compiler/exprn_aux.m:
compiler/dupelim.m:
compiler/llds_out.m:
compiler/opt_debug.m:
Add builtin labels for the Aditi update operations.
compiler/hlds_module.m:
Add predicate predicate_table_search_pf_sym, used for finding
possible matches for a call with the wrong number of arguments.
compiler/intermod.m:
Don't write predicates which build `aditi_top_down' goals,
because there is currently no way to tell importing modules
which RL code fragment to use.
compiler/simplify.m:
Obey the `cannot_remove' field of explicit quantification goals.
compiler/make_hlds.m:
Parse Aditi updates.
Don't typecheck clauses for which syntax errors in Aditi updates
are found - this avoids spurious "undefined predicate `aditi_insert/3'"
errors.
Factor out some common code to handle terms of the form `Head :- Body'.
Factor out common code in the handling of pred and func expressions.
compiler/typecheck.m:
Typecheck Aditi builtins.
Allow the argument types of matching predicates to be adjusted
when typechecking the higher-order arguments of Aditi builtins.
Change `typecheck__resolve_pred_overloading' to take a list of
argument types rather than a `map(var, type)' and a list of
arguments to allow a transformation to be performed on the
argument types before passing them.
compiler/error_util.m:
Move the part of `report_error_num_args' which writes
"wrong number of arguments (<x>; expected <y>)" from
typecheck.m for use by make_hlds.m when reporting errors
for Aditi builtins.
compiler/modes.m:
compiler/unique_modes.m:
compiler/modecheck_call.m:
Modecheck Aditi builtins.
compiler/lambda.m:
Handle the markers for predicates introduced for
`aditi_top_down' and `aditi_bottom_up' lambda expressions.
compiler/polymorphism.m:
Add extra type_infos to `aditi_insert' calls
describing the tuple to insert.
compiler/call_gen.m:
Generate code for Aditi builtins.
compiler/unify_gen.m:
compiler/bytecode_gen.m:
Abort on `aditi_top_down' and `aditi_bottom_up' lambda
expressions - code generation for them is not yet implemented.
compiler/magic.m:
Use the `aditi_call' generic_call rather than create
a new procedure for each Aditi predicate called from C.
compiler/rl_out.pp:
compiler/rl_gen.m:
compiler/rl.m:
Move some utility code used by magic.m and call_gen.m into rl.m.
Remove an XXX comment about reference counting being not yet
implemented - Evan has fixed that.
library/ops.m:
compiler/mercury_to_mercury.m:
doc/transition_guide.texi:
Add unary prefix operators `aditi_bottom_up' and `aditi_top_down',
used as qualifiers on lambda expressions.
Add infix operator `==>' to separate the tuples in an
`aditi_modify' call.
compiler/follow_vars.m:
Thread a `map(prog_var, type)' through, needed because
type information is no longer held in higher-order call goals.
compiler/table_gen.m:
Use the `make_*_construction' predicates in hlds_goal.m
to construct constants.
compiler/*.m:
Trivial changes to add extra fields to hlds_goal structures.
doc/reference_manual.texi:
Document Aditi updates.
Use @samp{pragma base_relation} instead of
@samp{:- pragma base_relation} throughout the Aditi documentation
to be consistent with other parts of the reference manual.
tests/valid/Mmakefile:
tests/valid/aditi_update.m:
tests/valid/aditi.m:
Test case.
tests/valid/Mmakefile:
Remove some hard-coded --intermodule-optimization rules which are
no longer needed because `mmake depend' is now run in this directory.
tests/invalid/*.err_exp:
Fix expected output for changes in reporting of call_ids
in typecheck.m.
tests/invalid/Mmakefile
tests/invalid/aditi_update_errors.{m,err_exp}:
tests/invalid/aditi_update_mode_errors.{m,err_exp}:
Test error messages for Aditi updates.
tests/valid/aditi.m:
tests/invalid/aditi.m:
Cut down version of extras/aditi/aditi.m to provide basic declarations
for Aditi compilation such as `aditi__state' and the modes
`aditi_di', `aditi_uo' and `aditi_ui'. Installing extras/aditi/aditi.m
somewhere would remove the need for these.
507 lines
15 KiB
Mathematica
507 lines
15 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1993-1999 The University of Melbourne.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module prog_out.
|
|
|
|
% Main author: fjh.
|
|
|
|
% This module defines some predicates which output various parts
|
|
% of the parse tree created by prog_io.
|
|
|
|
% WARNING - this module is mostly junk at the moment!
|
|
% Only the first hundred lines or so are meaningful.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- interface.
|
|
:- import_module prog_data.
|
|
:- import_module list, io.
|
|
|
|
:- pred prog_out__write_messages(message_list, io__state, io__state).
|
|
:- mode prog_out__write_messages(in, di, uo) is det.
|
|
|
|
:- pred prog_out__write_context(prog_context, io__state, io__state).
|
|
:- mode prog_out__write_context(in, di, uo) is det.
|
|
|
|
:- pred prog_out__context_to_string(prog_context, string).
|
|
:- mode prog_out__context_to_string(in, out) is det.
|
|
|
|
% XXX This pred should be deleted, and all uses replaced with
|
|
% XXX error_util:write_error_pieces, once zs has committed that
|
|
% XXX error_util.m.
|
|
:- pred prog_out__write_strings_with_context(prog_context, list(string),
|
|
io__state, io__state).
|
|
:- mode prog_out__write_strings_with_context(in, in, di, uo) is det.
|
|
|
|
% Write out a symbol name, with special characters escaped,
|
|
% but without any quotes. This is suitable for use in
|
|
% error messages, where the caller should print out an
|
|
% enclosing forward/backward-quote pair (`...').
|
|
:- pred prog_out__write_sym_name(sym_name, io__state, io__state).
|
|
:- mode prog_out__write_sym_name(in, di, uo) is det.
|
|
|
|
:- pred prog_out__write_sym_name_and_arity(sym_name_and_arity,
|
|
io__state, io__state).
|
|
:- mode prog_out__write_sym_name_and_arity(in, di, uo) is det.
|
|
|
|
% Write out a symbol name, enclosed in single forward quotes ('...')
|
|
% if necessary, and with any special characters escaped.
|
|
% The output should be a syntactically valid Mercury term.
|
|
:- pred prog_out__write_quoted_sym_name(sym_name, io__state, io__state).
|
|
:- mode prog_out__write_quoted_sym_name(in, di, uo) is det.
|
|
|
|
% sym_name_to_string(SymName, String):
|
|
% convert a symbol name to a string,
|
|
% with module qualifiers separated by
|
|
% the standard Mercury module qualifier operator
|
|
% (currently ":", but may eventually change to ".")
|
|
:- pred prog_out__sym_name_to_string(sym_name, string).
|
|
:- mode prog_out__sym_name_to_string(in, out) is det.
|
|
|
|
% sym_name_to_string(SymName, Separator, String):
|
|
% convert a symbol name to a string,
|
|
% with module qualifiers separated by Separator.
|
|
:- pred prog_out__sym_name_to_string(sym_name, string, string).
|
|
:- mode prog_out__sym_name_to_string(in, in, out) is det.
|
|
|
|
:- pred prog_out__write_module_spec(module_specifier, io__state, io__state).
|
|
:- mode prog_out__write_module_spec(in, di, uo) is det.
|
|
|
|
:- pred prog_out__write_module_list(list(module_name), io__state, io__state).
|
|
:- mode prog_out__write_module_list(in, di, uo) is det.
|
|
|
|
:- pred prog_out__write_list(list(T), pred(T, io__state, io__state),
|
|
io__state, io__state).
|
|
:- mode prog_out__write_list(in, pred(in, di, uo) is det, di, uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
:- import_module term, varset, term_io.
|
|
:- import_module require, string, std_util, term, term_io, varset, int.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% write out the list of error/warning messages which is
|
|
% returned when a module is parsed.
|
|
|
|
prog_out__write_messages([]) --> [].
|
|
prog_out__write_messages([Message | Messages]) -->
|
|
prog_out__write_message(Message),
|
|
prog_out__write_messages(Messages).
|
|
|
|
:- pred prog_out__write_message(pair(string, term), io__state, io__state).
|
|
:- mode prog_out__write_message(in, di, uo) is det.
|
|
|
|
prog_out__write_message(Msg - Term) -->
|
|
(
|
|
{ Term = term__functor(_Functor, _Args, Context0) }
|
|
->
|
|
{ Context0 = term__context(File, Line) },
|
|
{ Context = term__context(File, Line) },
|
|
prog_out__write_context(Context)
|
|
;
|
|
[]
|
|
),
|
|
io__write_string(Msg),
|
|
(
|
|
{ Term = term__functor(term__atom(""), [], _Context2) }
|
|
->
|
|
io__write_string(".\n")
|
|
;
|
|
io__write_string(": "),
|
|
{ varset__init(VarSet) },
|
|
% XXX variable names in error messages
|
|
term_io__write_term_nl(VarSet, Term)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Write out the information in term context (at the moment, just
|
|
% the line number) in a form suitable for the beginning of an
|
|
% error message.
|
|
|
|
prog_out__write_context(Context) -->
|
|
{ prog_out__context_to_string(Context, ContextMessage) },
|
|
io__write_string(ContextMessage).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Write to a string the information in term context (at the moment,
|
|
% just the line number) in a form suitable for the beginning of an
|
|
% error message.
|
|
|
|
prog_out__context_to_string(Context, ContextMessage) :-
|
|
term__context_file(Context, FileName),
|
|
term__context_line(Context, LineNumber),
|
|
( FileName = "" ->
|
|
ContextMessage = ""
|
|
;
|
|
string__format("%s:%03d: ", [s(FileName), i(LineNumber)],
|
|
ContextMessage)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
prog_out__write_strings_with_context(Context, Strings) -->
|
|
{ prog_out__context_to_string(Context, ContextMessage) },
|
|
{ string__length(ContextMessage, ContextLength) },
|
|
prog_out__write_strings_with_context_2(ContextMessage,
|
|
ContextLength, Strings, 0).
|
|
|
|
:- pred prog_out__write_strings_with_context_2(string, int, list(string), int,
|
|
io__state, io__state).
|
|
:- mode prog_out__write_strings_with_context_2(in, in, in, in, di, uo) is det.
|
|
|
|
prog_out__write_strings_with_context_2(_ContextMessage, _ContextLength,
|
|
[], _) --> [].
|
|
prog_out__write_strings_with_context_2(ContextMessage, ContextLength,
|
|
[S|Ss], N0) -->
|
|
{ string__length(S, MessageLength) },
|
|
(
|
|
{ N0 = 0 }
|
|
->
|
|
io__write_string(ContextMessage),
|
|
io__write_string(" "),
|
|
io__write_string(S),
|
|
{ N is ContextLength + MessageLength },
|
|
{ Rest = Ss }
|
|
;
|
|
{ N1 is MessageLength + N0 },
|
|
{ num_columns(NumColumns) },
|
|
{ N1 < NumColumns }
|
|
->
|
|
io__write_string(S),
|
|
{ N = N1 },
|
|
{ Rest = Ss }
|
|
;
|
|
io__write_char('\n'),
|
|
{ N = 0 },
|
|
{ Rest = [S|Ss] }
|
|
),
|
|
prog_out__write_strings_with_context_2(ContextMessage,
|
|
ContextLength, Rest, N).
|
|
|
|
|
|
:- pred num_columns(int::out) is det.
|
|
|
|
num_columns(80).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% write out a (possibly qualified) symbol name
|
|
|
|
prog_out__write_sym_name(qualified(ModuleSpec,Name)) -->
|
|
prog_out__write_module_spec(ModuleSpec),
|
|
io__write_string(":"),
|
|
term_io__write_escaped_string(Name).
|
|
prog_out__write_sym_name(unqualified(Name)) -->
|
|
term_io__write_escaped_string(Name).
|
|
|
|
prog_out__write_sym_name_and_arity(Name / Arity) -->
|
|
prog_out__write_sym_name(Name),
|
|
io__write_string("/"),
|
|
io__write_int(Arity).
|
|
|
|
prog_out__write_quoted_sym_name(SymName) -->
|
|
io__write_string("'"),
|
|
prog_out__write_sym_name(SymName),
|
|
io__write_string("'").
|
|
|
|
prog_out__sym_name_to_string(SymName, String) :-
|
|
prog_out__sym_name_to_string(SymName, ":", String).
|
|
|
|
prog_out__sym_name_to_string(SymName, Separator, String) :-
|
|
prog_out__sym_name_to_string_2(SymName, Separator, Parts, []),
|
|
string__append_list(Parts, String).
|
|
|
|
:- pred prog_out__sym_name_to_string_2(sym_name, string,
|
|
list(string), list(string)).
|
|
:- mode prog_out__sym_name_to_string_2(in, in, out, in) is det.
|
|
|
|
prog_out__sym_name_to_string_2(qualified(ModuleSpec,Name), Separator) -->
|
|
prog_out__sym_name_to_string_2(ModuleSpec, Separator),
|
|
[Separator, Name].
|
|
prog_out__sym_name_to_string_2(unqualified(Name), _) -->
|
|
[Name].
|
|
|
|
% write out a module specifier
|
|
|
|
prog_out__write_module_spec(ModuleSpec) -->
|
|
prog_out__write_sym_name(ModuleSpec).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
prog_out__write_module_list(Modules) -->
|
|
prog_out__write_list(Modules, write_module).
|
|
|
|
:- pred write_module(module_name::in, io__state::di, io__state::uo) is det.
|
|
|
|
write_module(Module) -->
|
|
io__write_string("`"),
|
|
prog_out__write_sym_name(Module),
|
|
io__write_string("'").
|
|
|
|
prog_out__write_list([Import1, Import2, Import3 | Imports], Writer) -->
|
|
call(Writer, Import1),
|
|
io__write_string(", "),
|
|
prog_out__write_list([Import2, Import3 | Imports], Writer).
|
|
prog_out__write_list([Import1, Import2], Writer) -->
|
|
call(Writer, Import1),
|
|
io__write_string(" and "),
|
|
call(Writer, Import2).
|
|
prog_out__write_list([Import], Writer) -->
|
|
call(Writer, Import).
|
|
prog_out__write_list([], _) -->
|
|
{ error("prog_out__write_module_list") }.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% THE REMAINDER OF THIS FILE IS JUNK THAT IS NOT USED.
|
|
% It has been made obsolete by mercury_to_mercury.m.
|
|
% However, the code below handles operator precedence better
|
|
% than mercury_to_mercury.m.
|
|
|
|
/**************************
|
|
|
|
% Please note that this code is the property of
|
|
% the University of Melbourne and is Copyright 1985, 1986, 1987, 1988 by it.
|
|
%
|
|
% All rights are reserved.
|
|
%
|
|
% Author: Philip Dart, 1988
|
|
% Based on a theme by Lawrence Byrd and Lee Naish.
|
|
% Fixed again by Lee Naish 9/88
|
|
|
|
% May bear some vague resemblance to some code written by Lawrence Byrd
|
|
% at Edinburgh a long time ago.
|
|
|
|
prog_out__writeDCGClause(Head, Body, VarSet) -->
|
|
% prog_out__get_op_prec("-->", 1, Prec),
|
|
{ Prec = 1199 },
|
|
prog_out__qwrite(Prec, VarSet, Head),
|
|
io__write_string(" -->"),
|
|
prog_out__write_goal(Body, 1, ',', VarSet).
|
|
|
|
:- type context ---> '(' ; (';') ; (then) ; (else) ; ','.
|
|
|
|
:- pred prog_out__write_goal(goal, int, context, varset, io__state, io__state).
|
|
:- mode prog_out__write_goal(in, in, in, in, di, uo) is det.
|
|
|
|
prog_out__write_goal(fail, I0, T, _VarSet) -->
|
|
prog_out__beforelit(T, I0),
|
|
io__write_string("fail").
|
|
|
|
prog_out__write_goal(true, I0, T, _VarSet) -->
|
|
prog_out__beforelit(T, I0),
|
|
io__write_string("true").
|
|
|
|
prog_out__write_goal(some(Vars,Goal), I0, T, VarSet) -->
|
|
prog_out__beforelit(T, I0),
|
|
io__write_string("some ["),
|
|
prog_out__write_var_list(Vars, VarSet),
|
|
io__write_string("] ("),
|
|
{ I1 is I0 + 1 },
|
|
prog_out__write_goal(Goal, I1, '(', VarSet),
|
|
io__write_string("\n"),
|
|
prog_out__indent(I0),
|
|
io__write_string(")").
|
|
|
|
prog_out__write_goal(all(Vars,Goal), I0, T, VarSet) -->
|
|
prog_out__beforelit(T, I0),
|
|
io__write_string("all ["),
|
|
prog_out__write_var_list(Vars, VarSet),
|
|
io__write_string("] ("),
|
|
{ I1 is I0 + 1 },
|
|
prog_out__write_goal(Goal, I1, '(', VarSet),
|
|
io__write_string("\n"),
|
|
prog_out__indent(I0),
|
|
io__write_string(")").
|
|
|
|
prog_out__write_goal((P, Q), I0, T, VarSet) -->
|
|
prog_out__write_goal(P, I0, T, VarSet),
|
|
io__write_string(","),
|
|
{if T = (',') then I = I0 else I is I0 + 1},
|
|
prog_out__write_goal(Q, I, (','), VarSet).
|
|
|
|
prog_out__write_goal(if_then_else(Vars,C,A,B), I, T, VarSet) -->
|
|
{if T = (then) then I1 is I + 1 else I1 = I},
|
|
(if {T = (else)} then
|
|
[]
|
|
else
|
|
io__write_string("\n"),
|
|
prog_out__indent(I1)
|
|
),
|
|
io__write_string(" if "),
|
|
prog_out__write_some_vars(VarSet, Vars),
|
|
prog_out__write_goal(C, I, '(', VarSet),
|
|
io__write_string(" then"),
|
|
prog_out__write_goal(A, I1, (then), VarSet),
|
|
io__write_string("\n"),
|
|
prog_out__indent(I1),
|
|
io__write_string("else"),
|
|
prog_out__write_goal(B, I1, (else), VarSet),
|
|
(if {T = (else)} then
|
|
[]
|
|
else
|
|
io__write_string("\n"),
|
|
prog_out__indent(I1),
|
|
io__write_string(")")
|
|
).
|
|
|
|
prog_out__write_goal(if_then(Vars,C,A), I, T, VarSet) -->
|
|
{if T = (then) then I1 is I + 1 else I1 = I},
|
|
(if {T = (else)} then
|
|
[]
|
|
else
|
|
io__write_string("\n"),
|
|
prog_out__indent(I1)
|
|
),
|
|
io__write_string(" if "),
|
|
prog_out__write_some_vars(VarSet, Vars),
|
|
prog_out__write_goal(C, I, '(', VarSet),
|
|
io__write_string(" then"),
|
|
prog_out__write_goal(A, I1, (then), VarSet),
|
|
(if {T = (else)} then
|
|
[]
|
|
else
|
|
io__write_string("\n"),
|
|
prog_out__indent(I1),
|
|
io__write_string(")")
|
|
).
|
|
|
|
prog_out__write_goal((P ; Q), I, T, VarSet) -->
|
|
(if {T = (;)} then
|
|
io__write_string("\t\n"),
|
|
prog_out__write_goal(P, I, (;), VarSet)
|
|
else
|
|
io__write_string("\n"),
|
|
prog_out__indent(I),
|
|
io__write_string("("),
|
|
prog_out__write_goal(P, I, '(', VarSet)
|
|
),
|
|
io__write_string("\n"),
|
|
prog_out__indent(I),
|
|
io__write_string(";"),
|
|
prog_out__write_goal(Q, I, (;), VarSet),
|
|
(if {T = (;)} then
|
|
[]
|
|
else
|
|
io__write_string("\n"),
|
|
prog_out__indent(I),
|
|
io__write_string(")")
|
|
).
|
|
|
|
prog_out__write_goal(not(A), I, _, VarSet) -->
|
|
io__write_string("not("),
|
|
prog_out__write_goal(A, I, '(', VarSet),
|
|
io__write_string(")").
|
|
|
|
prog_out__write_goal(call(X), I, T, VarSet) -->
|
|
prog_out__beforelit(T, I),
|
|
% Pos 1 of (,) has lowest prec of constructs
|
|
% prog_out__get_op_prec(",", 1, Prec),
|
|
{ Prec = 999 },
|
|
prog_out__qwrite(Prec, VarSet, X).
|
|
|
|
prog_out__write_var_list(_VarSet, Vars) -->
|
|
io__write_anything(Vars).
|
|
|
|
prog_out__write_some_vars(_VarSet, Vars) -->
|
|
io__write_string("some "),
|
|
io__write_anything(Vars). % XXX
|
|
|
|
:- pred prog_out__beforelit(context, int, io__state, io__state).
|
|
:- mode prog_out__beforelit(in, in, di, uo) is det.
|
|
|
|
prog_out__beforelit('(', _) -->
|
|
io__write_string("\t").
|
|
prog_out__beforelit((;), I) -->
|
|
io__write_string("\n"),
|
|
{ I1 is I + 1 },
|
|
prog_out__indent(I1),
|
|
io__write_string("\t").
|
|
prog_out__beforelit((then), I) -->
|
|
io__write_string("\n"),
|
|
{ I1 is I + 1 },
|
|
prog_out__indent(I1).
|
|
prog_out__beforelit((else), I) -->
|
|
io__write_string("\n"),
|
|
{ I1 is I + 1 },
|
|
prog_out__indent(I1).
|
|
prog_out__beforelit(',', I) -->
|
|
io__write_string("\n"),
|
|
prog_out__indent(I).
|
|
|
|
:- pred prog_out__indent(int, io__state, io__state).
|
|
:- mode prog_out__indent(int, di, uo) is det.
|
|
prog_out__indent(N) -->
|
|
(if {N > 0} then
|
|
io__write_string("\t"),
|
|
{ N1 is N - 1 },
|
|
prog_out__indent(N1)
|
|
else
|
|
[]
|
|
).
|
|
|
|
:- pred prog_out__qwrite(int, varset, term, io__state, io__state).
|
|
:- mode prog_out__qwrite(in, in, in, di, uo) is det.
|
|
|
|
% XXX problems with precedence
|
|
|
|
prog_out__qwrite(_Prec, VarSet, X) -->
|
|
term_io__write_term(VarSet, X).
|
|
|
|
:- pred prog_out__get_op_prec(string, int, int, io__state, io__state).
|
|
:- mode prog_out__get_op_prec(in, in, out, di, uo) is det.
|
|
|
|
prog_out__get_op_prec(Op, Pos, Prec) -->
|
|
term_io__current_ops(Ops),
|
|
{ get_prec_and_type(Op, Ops, Prec1, Type),
|
|
prog_out__op_adj(Pos, Type, Adj),
|
|
Prec is Prec1 - Adj
|
|
}.
|
|
|
|
get_prec_and_type(ThisOp, [Op|Ops], Prec, Type) :-
|
|
(if some [Prec1, Type1]
|
|
Op = op(Prec1, Type1, ThisOp)
|
|
then
|
|
Prec = Prec1,
|
|
Type = Type1
|
|
else
|
|
get_prec_and_type(ThisOp, Ops, Prec, Type)
|
|
).
|
|
|
|
:- pred prog_out__op_adj(int, op_type, int).
|
|
:- mode prog_out__op_adj(in, in, out) is det.
|
|
|
|
prog_out__op_adj(1, xfx, 1).
|
|
prog_out__op_adj(1, xfy, 1).
|
|
prog_out__op_adj(1, fxy, 1).
|
|
prog_out__op_adj(1, fxx, 1).
|
|
prog_out__op_adj(1, yfx, 0).
|
|
% prog_out__op_adj(1, yfy, 0).
|
|
prog_out__op_adj(1, fyx, 0).
|
|
prog_out__op_adj(1, fyy, 0).
|
|
prog_out__op_adj(2, xfx, 1).
|
|
prog_out__op_adj(2, xfy, 0).
|
|
prog_out__op_adj(2, fxy, 0).
|
|
prog_out__op_adj(2, fxx, 1).
|
|
prog_out__op_adj(2, yfx, 1).
|
|
% prog_out__op_adj(2, yfy, 0).
|
|
prog_out__op_adj(2, fyx, 1).
|
|
prog_out__op_adj(2, fyy, 0).
|
|
prog_out__op_adj(1, xf, 1).
|
|
prog_out__op_adj(1, fx, 1).
|
|
prog_out__op_adj(1, yf, 0).
|
|
prog_out__op_adj(1, fy, 0).
|
|
|
|
******************************/
|