mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
221 lines
9.1 KiB
Mathematica
221 lines
9.1 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2001-2007, 2011 The University of Melbourne.
|
|
% Copyright (C) 2024 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% This module defines the types that the smart recompilation system uses
|
|
% that must be parts of the parse trees of .intN files.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module recompilation.item_types.
|
|
:- interface.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.timestamp.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module map.
|
|
:- import_module term.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% XXX ITEM_LIST Choose a base name for these types that DOESN'T clash
|
|
% with the item type in the parse tree. While the types here are closely
|
|
% related to prog_item.item, they are NOT the same. Using the same name
|
|
% here encourages thinking that they are, which may lead to bugs.
|
|
%
|
|
% XXX ITEM_LIST Document what prog_item.item, or what sequence of
|
|
% prog_item.items, each item_type may correspond to.
|
|
|
|
:- type recomp_item_id
|
|
---> recomp_item_id(recomp_item_type, recomp_item_name).
|
|
|
|
% XXX RECOMP Consider splitting this type into two or more types,
|
|
% one for each separate purpose. We use this, amongst other things,
|
|
% for selecting one field from several data structures (module_versions,
|
|
% used_items, resolved_used_items, module_imported_items, and
|
|
% gathered_items) which have similar but NOT IDENTICAL sets of fields,
|
|
% so some of these item_types *have* no corresponding field in some
|
|
% of those structures.
|
|
%
|
|
:- type recomp_item_type
|
|
---> recomp_type_name
|
|
% Just the name of the type, not its body. It is common
|
|
% for a value of a type to be passed through a predicate without
|
|
% inspecting the value -- such predicates do not need to be
|
|
% recompiled if the body of the type changes (except for
|
|
% equivalence types).
|
|
; recomp_type_defn
|
|
; recomp_inst
|
|
; recomp_mode
|
|
; recomp_typeclass
|
|
; recomp_functor % The RHS of a var-functor unification.
|
|
; recomp_predicate
|
|
; recomp_function
|
|
% XXX ARITY The arity we record next to function_items *seems*
|
|
% to be the user_arity (though its type is just "arity"),
|
|
% but in the presence of with_type annotations, even that is
|
|
% in question.
|
|
; recomp_mutable
|
|
; recomp_foreign_proc.
|
|
% XXX ARITY This does not say whether the foreign_proc is for
|
|
% a predicate or a function, which affects the interpretation
|
|
% of the associated arity.
|
|
|
|
:- inst recomp_simple for recomp_item_type/0
|
|
---> recomp_type_name
|
|
; recomp_type_defn
|
|
; recomp_inst
|
|
; recomp_mode
|
|
; recomp_typeclass.
|
|
|
|
:- inst recomp_pred_or_func for recomp_item_type/0
|
|
---> recomp_predicate
|
|
; recomp_function.
|
|
|
|
:- type recomp_item_name
|
|
---> recomp_item_name(sym_name, arity).
|
|
% For predicates and functions, the arity is the pred_form_arity,
|
|
% I think (zs).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- func pred_or_func_to_recomp_item_type(pred_or_func::in)
|
|
= (recomp_item_type::out(recomp_pred_or_func)) is det.
|
|
|
|
:- pred string_to_recomp_item_type(string, recomp_item_type).
|
|
:- mode string_to_recomp_item_type(in, out) is semidet.
|
|
:- mode string_to_recomp_item_type(out, in) is det.
|
|
|
|
:- func type_ctor_to_recomp_item_name(type_ctor) = recomp_item_name.
|
|
:- func inst_ctor_to_recomp_item_name(inst_ctor) = recomp_item_name.
|
|
:- func mode_ctor_to_recomp_item_name(mode_ctor) = recomp_item_name.
|
|
|
|
:- func recomp_item_name_to_type_ctor(recomp_item_name) = type_ctor.
|
|
:- func recomp_item_name_to_inst_ctor(recomp_item_name) = inst_ctor.
|
|
:- func recomp_item_name_to_mode_ctor(recomp_item_name) = mode_ctor.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Map modules' names to their version number info.
|
|
:- type module_item_version_numbers_map ==
|
|
map(module_name, module_item_version_numbers).
|
|
|
|
% Values of this type specify the version number of each visible item
|
|
% in a module.
|
|
%
|
|
% XXX The comment on the type of the predecessor of the vn_instances field
|
|
% said: "For each interface file, we keep a version number for each class",
|
|
% which is quite confusing.
|
|
%
|
|
:- type module_item_version_numbers
|
|
---> module_item_version_numbers(
|
|
mivn_type_names :: name_arity_version_map,
|
|
mivn_type_defns :: name_arity_version_map,
|
|
mivn_insts :: name_arity_version_map,
|
|
mivn_modes :: name_arity_version_map,
|
|
mivn_typeclasses :: name_arity_version_map,
|
|
mivn_instances :: recomp_item_name_version_map,
|
|
mivn_predicates :: name_arity_version_map,
|
|
mivn_functions :: name_arity_version_map
|
|
).
|
|
|
|
:- type name_arity_version_map == map(name_arity, version_number).
|
|
|
|
% Identify a particular version of a program item.
|
|
% This could be done using a timestamp or a hash value.
|
|
%
|
|
% XXX RECOMP We had a thread on m-rev on .used files starting on 2021-04-19
|
|
% on replacing this with two separate representations of time: a binary one
|
|
% containing seconds since the epoch, plus any sub-second-precision
|
|
% information the OS may offer, and a text one for the readability
|
|
% of .used files.
|
|
%
|
|
:- type version_number == timestamp.
|
|
|
|
:- type recomp_item_name_version_map == map(recomp_item_name, version_number).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- func init_module_item_version_numbers = module_item_version_numbers.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred parse_version_number_term(term(T)::in, version_number::out) is semidet.
|
|
|
|
:- pred parse_timestamp_term(term(T)::in, timestamp::out) is semidet.
|
|
|
|
:- func version_number_to_string(version_number) = string.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
pred_or_func_to_recomp_item_type(pf_predicate) = recomp_predicate.
|
|
pred_or_func_to_recomp_item_type(pf_function) = recomp_function.
|
|
|
|
% The mismatch between the string and the recomp_item_type for type and
|
|
% type_body is for historical reasons.
|
|
string_to_recomp_item_type("type", recomp_type_name).
|
|
string_to_recomp_item_type("type_body", recomp_type_defn).
|
|
string_to_recomp_item_type("inst", recomp_inst).
|
|
string_to_recomp_item_type("mode", recomp_mode).
|
|
string_to_recomp_item_type("typeclass", recomp_typeclass).
|
|
string_to_recomp_item_type("functor", recomp_functor).
|
|
string_to_recomp_item_type("predicate", recomp_predicate).
|
|
string_to_recomp_item_type("function", recomp_function).
|
|
string_to_recomp_item_type("mutable", recomp_mutable).
|
|
string_to_recomp_item_type("foreign_proc", recomp_foreign_proc).
|
|
|
|
type_ctor_to_recomp_item_name(type_ctor(SymName, Arity))
|
|
= recomp_item_name(SymName, Arity).
|
|
inst_ctor_to_recomp_item_name(inst_ctor(SymName, Arity))
|
|
= recomp_item_name(SymName, Arity).
|
|
mode_ctor_to_recomp_item_name(mode_ctor(SymName, Arity))
|
|
= recomp_item_name(SymName, Arity).
|
|
|
|
recomp_item_name_to_type_ctor(recomp_item_name(SymName, Arity))
|
|
= type_ctor(SymName, Arity).
|
|
recomp_item_name_to_inst_ctor(recomp_item_name(SymName, Arity))
|
|
= inst_ctor(SymName, Arity).
|
|
recomp_item_name_to_mode_ctor(recomp_item_name(SymName, Arity))
|
|
= mode_ctor(SymName, Arity).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
init_module_item_version_numbers =
|
|
module_item_version_numbers(map.init, map.init, map.init, map.init,
|
|
map.init, map.init, map.init, map.init).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
parse_version_number_term(Term, Timestamp) :-
|
|
parse_timestamp_term(Term, Timestamp).
|
|
|
|
parse_timestamp_term(Term, Timestamp) :-
|
|
Term = term.functor(term.string(Str), [], _),
|
|
parse_timestamp_string(Str, Timestamp).
|
|
|
|
version_number_to_string(VersionNumber) = VersionNumberStr :-
|
|
string.format("""%s""", [s(timestamp_to_string(VersionNumber))],
|
|
VersionNumberStr).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
:- end_module recompilation.item_types.
|
|
%-----------------------------------------------------------------------------%
|