mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-14 05:12:33 +00:00
Estimated hours taken: 600 Branches: main Implemented state variable transformation. NEWS: Record new syntax and withdrawl of !/0 as Prolog cut. compiler/hlds_goal.m: compiler/hlds_out.m: Added implicit/1 constructor to unify_main_context for cases where variables are introduced by compiler transformations. compiler/make_hlds.m: Integrated the state variable transformation with the conversion to HLDS. Changed references to foreign_type and du_type constructors to match recent changes to the foreign type interface. compiler/mercury_compile.m: Removed two unnecessary Prolog cuts left over from the Dark Ages. compiler/mercury_to_mercury.m: Added code to output the new goal_expr constructors for state variable quantifiers (some_state_vars and all_state_vars.) Adapted to handle changes to if_then and if_then_else goal_expr constructors which now include lists of state variables that scope over the condition- and then-goals. compiler/module_qual.m: compiler/prog_util.m: Changes to handle some_state_vars, all_state_vars, and changes to if_then and if_then_else goal_expr constructors. compiler/prog_data.m: Added some_state_vars, all_state_vars constructors and changed if_then and if_then_else constructors in type goal_expr. compiler/prog_io_dcg.m: Changes to handle quantified state variables. compiler/prog_io_goal.m: parse_some_vars_goal now also separates out quantified state variables. compiler/prog_io_util.m: Added pred parse_quantifier_vars/3 which also detects state variables. compiler/typecheck.m: Added case to report_error_undef_cons to handle any uncaught uses of !/1. doc/reference_manual.texi: Documented the transformation. library/builtin.m: library/prolog.m: Deleted code for `!' as fake Prolog cut. library/lexer.m: Made `!' a graphic token rather char than a special token. library/ops.m: Added `!', `!.' and `!:' as prefix ops. library/term.m: Added func var_id/1 which returns an int associated with its var argument which is unique in the context of the given var and the varset it belongs to. library/varset.m: Added pred new_uniquely_named_var/4 which creates a named variable with a unique (w.r.t. the varset) number suffix. tests/general/Mmakefile: tests/general/state_vars_tests.exp: tests/general/state_vars_tests.m: tests/general/state_vars_typeclasses.exp: tests/general/state_vars_typeclasses.m: tests/invalid/Mmakefile: tests/invalid/state_vars_test1.err_exp: tests/invalid/state_vars_test1.m: tests/invalid/state_vars_test2.err_exp: tests/invalid/state_vars_test2.m: tests/invalid/state_vars_test3.err_exp: tests/invalid/state_vars_test3.m: tests/invalid/state_vars_test4.err_exp: tests/invalid/state_vars_test4.m: tests/invalid/state_vars_test5.err_exp: tests/invalid/state_vars_test5.m: Added.
503 lines
19 KiB
Mathematica
503 lines
19 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1994-2001 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.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% main author: fjh
|
|
|
|
% various utility predicates acting on the parse tree data
|
|
% structure defined in prog_data.m.
|
|
|
|
:- module parse_tree__prog_util.
|
|
|
|
:- interface.
|
|
|
|
:- import_module parse_tree__prog_data, term.
|
|
:- import_module std_util, list.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Returns the name of the module containing public builtins;
|
|
% originally this was "mercury_builtin", but it later became
|
|
% just "builtin", and it may eventually be renamed "std:builtin".
|
|
% This module is automatically imported, as if via `import_module'.
|
|
|
|
:- pred mercury_public_builtin_module(sym_name).
|
|
:- mode mercury_public_builtin_module(out) is det.
|
|
|
|
% Returns the name of the module containing private builtins;
|
|
% traditionally this was "mercury_builtin", but it later became
|
|
% "private_builtin", and it may eventually be renamed
|
|
% "std:private_builtin".
|
|
% This module is automatically imported, as if via `use_module'.
|
|
|
|
:- pred mercury_private_builtin_module(sym_name).
|
|
:- mode mercury_private_builtin_module(out) is det.
|
|
|
|
% Returns the name of the module containing builtins for tabling;
|
|
% originally these were in "private_builtin", but they
|
|
% may soon be moved into a separate module.
|
|
% This module is automatically imported iff tabling is enabled.
|
|
|
|
:- pred mercury_table_builtin_module(sym_name).
|
|
:- mode mercury_table_builtin_module(out) is det.
|
|
|
|
% Returns the name of the module containing the builtins for
|
|
% deep profiling.
|
|
% This module is automatically imported iff deep profiling is
|
|
% enabled.
|
|
:- pred mercury_profiling_builtin_module(sym_name).
|
|
:- mode mercury_profiling_builtin_module(out) is det.
|
|
|
|
% Succeeds iff the specified module is one of the three
|
|
% builtin modules listed above which are automatically imported.
|
|
|
|
:- pred any_mercury_builtin_module(sym_name).
|
|
:- mode any_mercury_builtin_module(in) is semidet.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Given a symbol name, return its unqualified name.
|
|
|
|
:- pred unqualify_name(sym_name, string).
|
|
:- mode unqualify_name(in, out) is det.
|
|
|
|
% sym_name_get_module_name(SymName, DefaultModName, ModName):
|
|
% Given a symbol name, return the module qualifier(s).
|
|
% If the symbol is unqualified, then return the specified default
|
|
% module name.
|
|
|
|
:- pred sym_name_get_module_name(sym_name, module_name, module_name).
|
|
:- mode sym_name_get_module_name(in, in, out) is det.
|
|
|
|
% string_to_sym_name(String, Separator, SymName):
|
|
% Convert a string, possibly prefixed with
|
|
% module qualifiers (separated by Separator),
|
|
% into a symbol name.
|
|
%
|
|
:- pred string_to_sym_name(string, string, sym_name).
|
|
:- mode string_to_sym_name(in, in, out) is det.
|
|
|
|
% match_sym_name(PartialSymName, CompleteSymName):
|
|
% succeeds iff there is some sequence of module qualifiers
|
|
% which when prefixed to PartialSymName gives CompleteSymName.
|
|
%
|
|
:- pred match_sym_name(sym_name, sym_name).
|
|
:- mode match_sym_name(in, in) is semidet.
|
|
|
|
% remove_sym_name_prefix(SymName0, Prefix, SymName)
|
|
% succeeds iff
|
|
% SymName and SymName0 have the same module qualifier
|
|
% and the unqualified part of SymName0 has the given prefix
|
|
% and the unqualified part of SymName is the unqualified
|
|
% part of SymName0 with the prefix removed
|
|
:- pred remove_sym_name_prefix(sym_name, string, sym_name).
|
|
:- mode remove_sym_name_prefix(in, in, out) is semidet.
|
|
:- mode remove_sym_name_prefix(out, in, in) is det.
|
|
|
|
% remove_sym_name_suffix(SymName0, Suffix, SymName)
|
|
% succeeds iff
|
|
% SymName and SymName0 have the same module qualifier
|
|
% and the unqualified part of SymName0 has the given suffix
|
|
% and the unqualified part of SymName is the unqualified
|
|
% part of SymName0 with the suffix removed
|
|
:- pred remove_sym_name_suffix(sym_name, string, sym_name).
|
|
:- mode remove_sym_name_suffix(in, in, out) is semidet.
|
|
|
|
% add_sym_name_suffix(SymName0, Suffix, SymName)
|
|
% succeeds iff
|
|
% SymName and SymName0 have the same module qualifier
|
|
% and the unqualified part of SymName is the unqualified
|
|
% part of SymName0 with the suffix added
|
|
:- pred add_sym_name_suffix(sym_name, string, sym_name).
|
|
:- mode add_sym_name_suffix(in, in, out) is det.
|
|
|
|
% insert_module_qualifier(ModuleName, SymName0, SymName):
|
|
% prepend the specified ModuleName onto the module
|
|
% qualifiers in SymName0, giving SymName.
|
|
:- pred insert_module_qualifier(string, sym_name, sym_name).
|
|
:- mode insert_module_qualifier(in, in, out) is det.
|
|
|
|
% Given a possible module qualified sym_name and a list of
|
|
% argument types and a context, construct a term. This is
|
|
% used to construct types.
|
|
|
|
:- pred construct_qualified_term(sym_name, list(term(T)), term(T)).
|
|
:- mode construct_qualified_term(in, in, out) is det.
|
|
|
|
:- pred construct_qualified_term(sym_name, list(term(T)), prog_context, term(T)).
|
|
:- mode construct_qualified_term(in, in, in, out) is det.
|
|
|
|
% Given a sym_name return the top level qualifier of that name.
|
|
:- func outermost_qualifier(sym_name) = string.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% adjust_func_arity(PredOrFunc, FuncArity, PredArity).
|
|
%
|
|
% We internally store the arity as the length of the argument
|
|
% list including the return value, which is one more than the
|
|
% arity of the function reported in error messages.
|
|
:- pred adjust_func_arity(pred_or_func, int, int).
|
|
:- mode adjust_func_arity(in, in, out) is det.
|
|
:- mode adjust_func_arity(in, out, in) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% make_pred_name_with_context(ModuleName, Prefix, PredOrFunc, PredName,
|
|
% Line, Counter, SymName).
|
|
%
|
|
% Create a predicate name with context, e.g. for introduced
|
|
% lambda or deforestation predicates.
|
|
:- pred make_pred_name(module_name, string, maybe(pred_or_func),
|
|
string, new_pred_id, sym_name).
|
|
:- mode make_pred_name(in, in, in, in, in, out) is det.
|
|
|
|
% make_pred_name_with_context(ModuleName, Prefix, PredOrFunc, PredName,
|
|
% Line, Counter, SymName).
|
|
%
|
|
% Create a predicate name with context, e.g. for introduced
|
|
% lambda or deforestation predicates.
|
|
:- pred make_pred_name_with_context(module_name, string, pred_or_func,
|
|
string, int, int, sym_name).
|
|
:- mode make_pred_name_with_context(in, in, in, in, in, in, out) is det.
|
|
|
|
:- type new_pred_id
|
|
---> counter(int, int) % Line number, Counter
|
|
; type_subst(tvarset, type_subst)
|
|
.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% A pred declaration may contains just types, as in
|
|
% :- pred list__append(list(T), list(T), list(T)).
|
|
% or it may contain both types and modes, as in
|
|
% :- pred list__append(list(T)::in, list(T)::in,
|
|
% list(T)::output).
|
|
%
|
|
% This predicate takes the argument list of a pred declaration,
|
|
% splits it into two separate lists for the types and (if present)
|
|
% the modes.
|
|
|
|
:- type maybe_modes == maybe(list(mode)).
|
|
|
|
:- pred split_types_and_modes(list(type_and_mode), list(type), maybe_modes).
|
|
:- mode split_types_and_modes(in, out, out) is det.
|
|
|
|
:- pred split_type_and_mode(type_and_mode, type, maybe(mode)).
|
|
:- mode split_type_and_mode(in, out, out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Perform a substitution on a goal.
|
|
|
|
:- pred prog_util__rename_in_goal(goal, prog_var, prog_var, goal).
|
|
:- mode prog_util__rename_in_goal(in, in, in, out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
:- import_module parse_tree__mercury_to_mercury, (parse_tree__inst).
|
|
:- import_module bool, string, int, map, varset.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% We may eventually want to put the standard library into a package "std":
|
|
% mercury_public_builtin_module(M) :-
|
|
% M = qualified(unqualified("std"), "builtin"))).
|
|
% mercury_private_builtin_module(M) :-
|
|
% M = qualified(unqualified("std"), "private_builtin"))).
|
|
mercury_public_builtin_module(unqualified("builtin")).
|
|
mercury_private_builtin_module(unqualified("private_builtin")).
|
|
mercury_table_builtin_module(unqualified("table_builtin")).
|
|
mercury_profiling_builtin_module(unqualified("profiling_builtin")).
|
|
|
|
any_mercury_builtin_module(Module) :-
|
|
( mercury_public_builtin_module(Module)
|
|
; mercury_private_builtin_module(Module)
|
|
; mercury_table_builtin_module(Module)
|
|
; mercury_profiling_builtin_module(Module)
|
|
).
|
|
|
|
unqualify_name(unqualified(PredName), PredName).
|
|
unqualify_name(qualified(_ModuleName, PredName), PredName).
|
|
|
|
sym_name_get_module_name(unqualified(_), ModuleName, ModuleName).
|
|
sym_name_get_module_name(qualified(ModuleName, _PredName), _, ModuleName).
|
|
|
|
construct_qualified_term(qualified(Module, Name), Args, Context, Term) :-
|
|
construct_qualified_term(Module, [], Context, ModuleTerm),
|
|
UnqualifiedTerm = term__functor(term__atom(Name), Args, Context),
|
|
Term = term__functor(term__atom(":"),
|
|
[ModuleTerm, UnqualifiedTerm], Context).
|
|
construct_qualified_term(unqualified(Name), Args, Context, Term) :-
|
|
Term = term__functor(term__atom(Name), Args, Context).
|
|
|
|
|
|
construct_qualified_term(SymName, Args, Term) :-
|
|
term__context_init(Context),
|
|
construct_qualified_term(SymName, Args, Context, Term).
|
|
|
|
outermost_qualifier(unqualified(Name)) = Name.
|
|
outermost_qualifier(qualified(Module, _Name)) = outermost_qualifier(Module).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
adjust_func_arity(predicate, Arity, Arity).
|
|
adjust_func_arity(function, Arity - 1, Arity).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
split_types_and_modes(TypesAndModes, Types, MaybeModes) :-
|
|
split_types_and_modes_2(TypesAndModes, yes, Types, Modes, Result),
|
|
(
|
|
Result = yes
|
|
->
|
|
MaybeModes = yes(Modes)
|
|
;
|
|
MaybeModes = no
|
|
).
|
|
|
|
:- pred split_types_and_modes_2(list(type_and_mode), bool,
|
|
list(type), list(mode), bool).
|
|
:- mode split_types_and_modes_2(in, in, out, out, out) is det.
|
|
|
|
% T = type, M = mode, TM = combined type and mode
|
|
split_types_and_modes_2([], Result, [], [], Result).
|
|
split_types_and_modes_2([TM|TMs], Result0, [T|Ts], [M|Ms], Result) :-
|
|
split_type_and_mode(TM, Result0, T, M, Result1),
|
|
split_types_and_modes_2(TMs, Result1, Ts, Ms, Result).
|
|
|
|
% if a pred declaration specifies modes for some but
|
|
% not all of the arguments, then the modes are ignored
|
|
% - should this be an error instead?
|
|
% trd: this should never happen because prog_io.m will detect
|
|
% these cases
|
|
|
|
:- pred split_type_and_mode(type_and_mode, bool, type, mode, bool).
|
|
:- mode split_type_and_mode(in, in, out, out, out) is det.
|
|
|
|
split_type_and_mode(type_only(T), _, T, (free -> free), no).
|
|
split_type_and_mode(type_and_mode(T,M), R, T, M, R).
|
|
|
|
split_type_and_mode(type_only(T), T, no).
|
|
split_type_and_mode(type_and_mode(T,M), T, yes(M)).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
prog_util__rename_in_goal(Goal0 - Context, OldVar, NewVar, Goal - Context) :-
|
|
prog_util__rename_in_goal_expr(Goal0, OldVar, NewVar, Goal).
|
|
|
|
:- pred prog_util__rename_in_goal_expr(goal_expr, prog_var, prog_var,
|
|
goal_expr).
|
|
:- mode prog_util__rename_in_goal_expr(in, in, in, out) is det.
|
|
|
|
prog_util__rename_in_goal_expr((GoalA0, GoalB0), OldVar, NewVar,
|
|
(GoalA, GoalB)) :-
|
|
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
|
|
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
|
|
prog_util__rename_in_goal_expr((GoalA0 & GoalB0), OldVar, NewVar,
|
|
(GoalA & GoalB)) :-
|
|
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
|
|
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
|
|
prog_util__rename_in_goal_expr(true, _Var, _NewVar, true).
|
|
prog_util__rename_in_goal_expr((GoalA0; GoalB0), OldVar, NewVar,
|
|
(GoalA; GoalB)) :-
|
|
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
|
|
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
|
|
prog_util__rename_in_goal_expr(fail, _Var, _NewVar, fail).
|
|
prog_util__rename_in_goal_expr(not(Goal0), OldVar, NewVar, not(Goal)) :-
|
|
prog_util__rename_in_goal(Goal0, OldVar, NewVar, Goal).
|
|
prog_util__rename_in_goal_expr(some(Vars0, Goal0), OldVar, NewVar,
|
|
some(Vars, Goal)) :-
|
|
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
|
|
prog_util__rename_in_goal(Goal0, OldVar, NewVar, Goal).
|
|
prog_util__rename_in_goal_expr(some_state_vars(Vars0, Goal0), OldVar, NewVar,
|
|
some_state_vars(Vars, Goal)) :-
|
|
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
|
|
prog_util__rename_in_goal(Goal0, OldVar, NewVar, Goal).
|
|
prog_util__rename_in_goal_expr(all(Vars0, Goal0), OldVar, NewVar,
|
|
all(Vars, Goal)) :-
|
|
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
|
|
prog_util__rename_in_goal(Goal0, OldVar, NewVar, Goal).
|
|
prog_util__rename_in_goal_expr(all_state_vars(Vars0, Goal0), OldVar, NewVar,
|
|
all_state_vars(Vars, Goal)) :-
|
|
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
|
|
prog_util__rename_in_goal(Goal0, OldVar, NewVar, Goal).
|
|
prog_util__rename_in_goal_expr(implies(GoalA0, GoalB0), OldVar, NewVar,
|
|
implies(GoalA, GoalB)) :-
|
|
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
|
|
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
|
|
prog_util__rename_in_goal_expr(equivalent(GoalA0, GoalB0), OldVar, NewVar,
|
|
equivalent(GoalA, GoalB)) :-
|
|
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
|
|
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
|
|
prog_util__rename_in_goal_expr(if_then(Vars0, StateVars0, Cond0, Then0),
|
|
OldVar, NewVar,
|
|
if_then(Vars, StateVars, Cond, Then)) :-
|
|
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
|
|
prog_util__rename_in_vars(StateVars0, OldVar, NewVar, StateVars),
|
|
prog_util__rename_in_goal(Cond0, OldVar, NewVar, Cond),
|
|
prog_util__rename_in_goal(Then0, OldVar, NewVar, Then).
|
|
prog_util__rename_in_goal_expr(
|
|
if_then_else(Vars0, StateVars0, Cond0, Then0, Else0),
|
|
OldVar, NewVar,
|
|
if_then_else(Vars, StateVars, Cond, Then, Else)) :-
|
|
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
|
|
prog_util__rename_in_vars(StateVars0, OldVar, NewVar, StateVars),
|
|
prog_util__rename_in_goal(Cond0, OldVar, NewVar, Cond),
|
|
prog_util__rename_in_goal(Then0, OldVar, NewVar, Then),
|
|
prog_util__rename_in_goal(Else0, OldVar, NewVar, Else).
|
|
prog_util__rename_in_goal_expr(call(SymName, Terms0, Purity), OldVar, NewVar,
|
|
call(SymName, Terms, Purity)) :-
|
|
term__substitute_list(Terms0, OldVar, term__variable(NewVar),
|
|
Terms).
|
|
prog_util__rename_in_goal_expr(unify(TermA0, TermB0, Purity), OldVar, NewVar,
|
|
unify(TermA, TermB, Purity)) :-
|
|
term__substitute(TermA0, OldVar, term__variable(NewVar),
|
|
TermA),
|
|
term__substitute(TermB0, OldVar, term__variable(NewVar),
|
|
TermB).
|
|
|
|
:- pred prog_util__rename_in_vars(list(prog_var), prog_var, prog_var,
|
|
list(prog_var)).
|
|
:- mode prog_util__rename_in_vars(in, in, in, out) is det.
|
|
|
|
prog_util__rename_in_vars([], _, _, []).
|
|
prog_util__rename_in_vars([Var0 | Vars0], OldVar, NewVar, [Var | Vars]) :-
|
|
( Var0 = OldVar ->
|
|
Var = NewVar
|
|
;
|
|
Var = Var0
|
|
),
|
|
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% This would be simpler if we had a string__rev_sub_string_search/3 pred.
|
|
% With that, we could search for underscores right-to-left,
|
|
% and construct the resulting symbol directly.
|
|
% Instead, we search for them left-to-right, and then call
|
|
% insert_module_qualifier to fix things up.
|
|
|
|
string_to_sym_name(String, ModuleSeparator, Result) :-
|
|
(
|
|
string__sub_string_search(String, ModuleSeparator, LeftLength),
|
|
LeftLength > 0
|
|
->
|
|
string__left(String, LeftLength, ModuleName),
|
|
string__length(String, StringLength),
|
|
string__length(ModuleSeparator, SeparatorLength),
|
|
RightLength is StringLength - LeftLength - SeparatorLength,
|
|
string__right(String, RightLength, Name),
|
|
string_to_sym_name(Name, ModuleSeparator, NameSym),
|
|
insert_module_qualifier(ModuleName, NameSym, Result)
|
|
;
|
|
Result = unqualified(String)
|
|
).
|
|
|
|
insert_module_qualifier(ModuleName, unqualified(PlainName),
|
|
qualified(unqualified(ModuleName), PlainName)).
|
|
insert_module_qualifier(ModuleName, qualified(ModuleQual0, PlainName),
|
|
qualified(ModuleQual, PlainName)) :-
|
|
insert_module_qualifier(ModuleName, ModuleQual0, ModuleQual).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% match_sym_name(PartialSymName, CompleteSymName):
|
|
% succeeds iff there is some sequence of module qualifiers
|
|
% which when prefixed to PartialSymName gives CompleteSymName.
|
|
|
|
match_sym_name(qualified(Module1, Name), qualified(Module2, Name)) :-
|
|
match_sym_name(Module1, Module2).
|
|
match_sym_name(unqualified(Name), unqualified(Name)).
|
|
match_sym_name(unqualified(Name), qualified(_, Name)).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
remove_sym_name_prefix(qualified(Module, Name0), Prefix,
|
|
qualified(Module, Name)) :-
|
|
string__append(Prefix, Name, Name0).
|
|
remove_sym_name_prefix(unqualified(Name0), Prefix, unqualified(Name)) :-
|
|
string__append(Prefix, Name, Name0).
|
|
|
|
remove_sym_name_suffix(qualified(Module, Name0), Suffix,
|
|
qualified(Module, Name)) :-
|
|
string__remove_suffix(Name0, Suffix, Name).
|
|
remove_sym_name_suffix(unqualified(Name0), Suffix, unqualified(Name)) :-
|
|
string__remove_suffix(Name0, Suffix, Name).
|
|
|
|
add_sym_name_suffix(qualified(Module, Name0), Suffix,
|
|
qualified(Module, Name)) :-
|
|
string__append(Name0, Suffix, Name).
|
|
add_sym_name_suffix(unqualified(Name0), Suffix, unqualified(Name)) :-
|
|
string__append(Name0, Suffix, Name).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
make_pred_name_with_context(ModuleName, Prefix,
|
|
PredOrFunc, PredName, Line, Counter, SymName) :-
|
|
make_pred_name(ModuleName, Prefix, yes(PredOrFunc), PredName,
|
|
counter(Line, Counter), SymName).
|
|
|
|
make_pred_name(ModuleName, Prefix, MaybePredOrFunc, PredName,
|
|
NewPredId, SymName) :-
|
|
(
|
|
MaybePredOrFunc = yes(PredOrFunc),
|
|
(
|
|
PredOrFunc = predicate,
|
|
PFS = "pred"
|
|
;
|
|
PredOrFunc = function,
|
|
PFS = "func"
|
|
)
|
|
;
|
|
MaybePredOrFunc = no,
|
|
PFS = "pred_or_func"
|
|
),
|
|
(
|
|
NewPredId = counter(Line, Counter),
|
|
string__format("%d__%d", [i(Line), i(Counter)], PredIdStr)
|
|
;
|
|
NewPredId = type_subst(VarSet, TypeSubst),
|
|
SubstToString = lambda([SubstElem::in, SubstStr::out] is det, (
|
|
SubstElem = Var - Type,
|
|
varset__lookup_name(VarSet, Var, VarName),
|
|
TypeString = mercury_type_to_string(VarSet, Type),
|
|
string__append_list([VarName, " = ", TypeString],
|
|
SubstStr)
|
|
)),
|
|
list_to_string(SubstToString, TypeSubst, PredIdStr)
|
|
),
|
|
|
|
string__format("%s__%s__%s__%s",
|
|
[s(Prefix), s(PFS), s(PredName), s(PredIdStr)], Name),
|
|
SymName = qualified(ModuleName, Name).
|
|
|
|
:- pred list_to_string(pred(T, string), list(T), string).
|
|
:- mode list_to_string(pred(in, out) is det, in, out) is det.
|
|
|
|
list_to_string(Pred, List, String) :-
|
|
list_to_string_2(Pred, List, Strings, ["]"]),
|
|
string__append_list(["[" | Strings], String).
|
|
|
|
:- pred list_to_string_2(pred(T, string), list(T), list(string), list(string)).
|
|
:- mode list_to_string_2(pred(in, out) is det, in, out, in) is det.
|
|
|
|
list_to_string_2(_, []) --> [].
|
|
list_to_string_2(Pred, [T | Ts]) -->
|
|
{ call(Pred, T, String) },
|
|
[String],
|
|
( { Ts = [] } ->
|
|
[]
|
|
;
|
|
[", "],
|
|
list_to_string_2(Pred, Ts)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|