Files
mercury/compiler/proc_label.m
Zoltan Somogyi 625ec287f1 Carve five new modules out of prog_type.m.
compiler/prog_type_construct.m:
    New module for constructing types.

compiler/prog_type_repn.m:
    New module for testing things related to type representation.

compiler/prog_type_scan.m:
    New module for gather type vars in types.

compiler/prog_type_test.m:
    New module containing simple tests on types.

compiler/prog_type_unify.m:
    New module for testing whether two types unify, or whether
    one type subsumes another.

compiler/prog_type.m:
    Delete the code moved to the new modules.

compiler/parse_tree.m:
    Include the new modules.

compiler/notes/compiler_design.html:
    Document the new modules.

compiler/*.m:
    Conform to the changes above, by adjusting imports as needed,
    and by deleting any explicit module qualifications that
    this diff makes obsolete.
2023-10-06 08:42:43 +11:00

166 lines
6.5 KiB
Mathematica

%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2003-2008, 2010-2012 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.
%-----------------------------------------------------------------------------%
%
% File: proc_label.m.
% Main author: zs.
%
% This file defines backend-independent identifiers for procedures that a
% backend can use as the basis for the names of the labels or functions
% implementing those procedures. It also has functions for creating these
% identifiers.
%-----------------------------------------------------------------------------%
:- module backend_libs.proc_label.
:- interface.
:- import_module hlds.
:- import_module hlds.hlds_module.
:- import_module hlds.hlds_pred.
:- import_module hlds.hlds_rtti.
:- import_module mdbcomp.
:- import_module mdbcomp.prim_data.
:- import_module parse_tree.
:- import_module parse_tree.prog_data.
% Return the id of the procedure specified by the rtti_proc_label.
%
:- func make_proc_label_from_rtti(rtti_proc_label) = proc_label.
% Return the id of the specified procedure.
%
:- func make_proc_label(module_info, pred_id, proc_id) = proc_label.
% Return the id of the specified mode of the unification procedure
% for the given type.
:- func make_uni_label(module_info, type_ctor, proc_id) = proc_label.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module hlds.pred_name.
:- import_module mdbcomp.builtin_modules.
:- import_module mdbcomp.sym_name.
:- import_module parse_tree.prog_type_test.
:- import_module bool.
:- import_module require.
:- import_module string.
make_proc_label_from_rtti(RttiProcLabel) = ProcLabel :-
RttiProcLabel = rtti_proc_label(PredOrFunc, ThisModule,
PredModule, PredName, PredFormArity, _ArgTypes, _PredId, ProcId,
_ProcHeadVarsWithNames, _ArgModes, _CodeModel,
PredIsImported, _PredIsPseudoImported, Origin,
_ProcIsExported, _ProcIsImported),
ProcLabel = do_make_proc_label(PredOrFunc, ThisModule, PredModule,
PredName, PredFormArity, ProcId, PredIsImported, Origin).
make_proc_label(ModuleInfo, PredId, ProcId) = ProcLabel :-
module_info_get_name(ModuleInfo, ThisModule),
module_info_pred_proc_info(ModuleInfo, PredId, ProcId, PredInfo,
_ProcInfo),
PredOrFunc = pred_info_is_pred_or_func(PredInfo),
PredModule = pred_info_module(PredInfo),
PredName = pred_info_name(PredInfo),
PredFormArity = pred_info_pred_form_arity(PredInfo),
PredIsImported = (if pred_info_is_imported(PredInfo) then yes else no),
pred_info_get_origin(PredInfo, Origin),
ProcLabel = do_make_proc_label(PredOrFunc, ThisModule, PredModule,
PredName, PredFormArity, ProcId, PredIsImported, Origin).
:- func do_make_proc_label(pred_or_func, module_name, module_name,
string, pred_form_arity, proc_id, bool, pred_origin) = proc_label.
do_make_proc_label(PredOrFunc, ThisModule, PredModule, PredName, PredFormArity,
ProcId, PredIsImported, Origin) = ProcLabel :-
( if Origin = origin_compiler(made_for_uci(SpecialPred, TypeCtor)) then
( if
% All type_ctors other than tuples here should be module qualified,
% since builtin types are handled separately in polymorphism.m.
TypeCtor = type_ctor(TypeCtorSymName, TypeArity),
(
TypeCtorSymName = unqualified(TypeName),
type_ctor_is_tuple(TypeCtor),
TypeModule = mercury_public_builtin_module
;
TypeCtorSymName = qualified(TypeModule, TypeName)
)
then
( if
ThisModule \= TypeModule,
SpecialPred = spec_pred_unify,
not hlds_pred.in_in_unification_proc_id(ProcId)
then
DefiningModule = ThisModule
else
DefiningModule = TypeModule
),
proc_id_to_int(ProcId, ProcIdInt),
ProcLabel = special_proc_label(DefiningModule, SpecialPred,
TypeModule, TypeName, TypeArity, ProcIdInt)
else
unexpected($pred,
"cannot make label for special pred `" ++ PredName ++ "'")
)
else
ProcLabel = make_user_proc_label(ThisModule, PredIsImported,
PredOrFunc, PredModule, PredName, PredFormArity, ProcId)
).
% make_user_proc_label(ModuleName, PredIsImported,
% PredOrFunc, ModuleName, PredName, Arity, ProcId) = Label:
%
% Make a proc_label for a user-defined procedure.
%
% The PredIsImported argument should be the result of
% calling pred_info_is_imported.
%
:- func make_user_proc_label(module_name, bool, pred_or_func,
module_name, string, pred_form_arity, proc_id) = proc_label.
make_user_proc_label(ThisModule, PredIsImported, PredOrFunc, PredModule,
PredName, PredFormArity, ProcId) = ProcLabel :-
( if
% Work out which module supplies the code for the predicate.
ThisModule \= PredModule,
PredIsImported = no
then
% This predicate is a specialized version of a pred from a `.opt' file.
DefiningModule = ThisModule
else
DefiningModule = PredModule
),
PredFormArity = pred_form_arity(PredFormArityInt),
proc_id_to_int(ProcId, ProcIdInt),
ProcLabel = ordinary_proc_label(DefiningModule, PredOrFunc,
PredModule, PredName, PredFormArityInt, ProcIdInt).
make_uni_label(ModuleInfo, TypeCtor, UniModeNum) = ProcLabel :-
module_info_get_name(ModuleInfo, ModuleName),
( if TypeCtor = type_ctor(qualified(TypeModule, TypeName), Arity) then
( if hlds_pred.in_in_unification_proc_id(UniModeNum) then
Module = TypeModule
else
Module = ModuleName
),
proc_id_to_int(UniModeNum, UniModeNumInt),
ProcLabel = special_proc_label(Module, spec_pred_unify, TypeModule,
TypeName, Arity, UniModeNumInt)
else
unexpected($pred, "unqualified type_ctor")
).
%-----------------------------------------------------------------------------%
:- end_module backend_libs.proc_label.
%-----------------------------------------------------------------------------%