mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-21 12:23:44 +00:00
compiler/elds.m:
compiler/elds_to_erlang.m:
compiler/erl_backend.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/erl_rtti.m:
compiler/erl_unify_gen.m:
compiler/erlang_rtti.m:
compiler/mercury_compile_erl_back_end.m:
Delete these modules, which together constitute the Erlang backend.
compiler/notes/compiler_design.html:
Delete references to the deleted modules.
compiler/parse_tree_out_type_repn.m:
Update the format we use to represent the sets of foreign_type and
foreign_enum declarations for a type as part of its item_type_repn_info,
now that Erlang is no longer a target language.
compiler/parse_type_repn.m:
Accept both the updated version of the item_type_repn_info and the
immediately previous version, since the installed compiler will
initially generate that previous version. However, stop accepting
an even older version that we stopped generating several months ago.
compiler/parse_pragma_foreign.m:
When the compiler finds a reference to Erlang as a foreign language,
add a message about support for Erlang being discontinued to the error
message.
Make the code parsing foreign_decls handle the term containing
the foreign language the same way as the codes parsing foreign
codes, procs, types and enums.
Add a mechanism to help parse_mutable.m to do the same.
compiler/parse_mutable.m:
When the compiler finds a reference to Erlang as a foreign language,
print an error message about support for Erlang being discontinued.
compiler/compute_grade.m:
When the compiler finds a reference to Erlang as a grade component,
print an informational message about support for Erlang being discontinued.
compiler/pickle.m:
compiler/make.build.m:
Delete Erlang foreign procs and types.
compiler/add_foreign_enum.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_type.m:
compiler/check_libgrades.m:
compiler/check_parse_tree_type_defns.m:
compiler/code_gen.m:
compiler/compile_target_code.m:
compiler/compute_grade.m:
compiler/const_struct.m:
compiler/convert_parse_tree.m:
compiler/dead_proc_elim.m:
compiler/decide_type_repn.m:
compiler/deps_map.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/foreign.m:
compiler/globals.m:
compiler/granularity.m:
compiler/handle_options.m:
compiler/hlds_code_util.m:
compiler/hlds_data.m:
compiler/hlds_module.m:
compiler/inlining.m:
compiler/int_emu.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/lco.m:
compiler/llds_out_file.m:
compiler/make.dependencies.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_warn.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_target_util.m:
compiler/ml_top_gen.m:
compiler/mlds.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_export.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_export.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_type.m:
compiler/module_imports.m:
compiler/parse_pragma_foreign.m:
compiler/parse_tree_out.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/prog_data.m:
compiler/prog_data_foreign.m:
compiler/prog_foreign.m:
compiler/prog_item.m:
compiler/simplify_goal_scope.m:
compiler/special_pred.m:
compiler/string_encoding.m:
compiler/top_level.m:
compiler/uint_emu.m:
compiler/write_deps_file.m:
Remove references to Erlang as a backend or as a target language.
tests/invalid/bad_foreign_code.{m,err_exp}:
tests/invalid/bad_foreign_decl.{m,err_exp}:
tests/invalid/bad_foreign_enum.{m,err_exp}:
tests/invalid/bad_foreign_export.{m,err_exp}:
tests/invalid/bad_foreign_export_enum.{m,err_exp}:
tests/invalid/bad_foreign_import_module.{m,err_exp}:
tests/invalid/bad_foreign_proc.{m,err_exp}:
tests/invalid/bad_foreign_type.{m,err_exp}:
Add a test for Erlang as an invalid foreign language. Expect both the
new error message for this new error, and the updated list of now-valid
foreign languages on all errors.
266 lines
11 KiB
Mathematica
266 lines
11 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1996-2011 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: deps_map.m.
|
|
%
|
|
% This module contains a data structure for recording module dependencies
|
|
% and its access predicates. The module_deps_graph module contains another
|
|
% data structure, used for similar purposes, that is built on top of this one.
|
|
% XXX Document the exact relationship between the two.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module parse_tree.deps_map.
|
|
:- interface.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.globals.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.file_names.
|
|
:- import_module parse_tree.module_imports.
|
|
|
|
:- import_module map.
|
|
:- import_module io.
|
|
|
|
% This is the data structure we use to record the dependencies.
|
|
% We keep a map from module name to information about the module.
|
|
|
|
:- type have_processed
|
|
---> not_yet_processed
|
|
; already_processed.
|
|
|
|
:- type deps_map == map(module_name, deps).
|
|
:- type deps
|
|
---> deps(
|
|
have_processed,
|
|
module_and_imports
|
|
).
|
|
|
|
:- type submodule_kind
|
|
---> toplevel
|
|
; nested_submodule
|
|
; separate_submodule.
|
|
|
|
% Check if a module is a top-level module, a nested submodule,
|
|
% or a separate submodule.
|
|
%
|
|
:- func get_submodule_kind(module_name, deps_map) = submodule_kind.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred generate_deps_map(globals::in, module_name::in, maybe_search::in,
|
|
deps_map::in, deps_map::out, io::di, io::uo) is det.
|
|
|
|
% Insert a new entry into the deps_map. If the module already occurred
|
|
% in the deps_map, then we just replace the old entry (presumed to be
|
|
% a dummy entry) with the new one.
|
|
%
|
|
% This can only occur for submodules which have been imported before
|
|
% their parent module was imported: before reading a module and
|
|
% inserting it into the deps map, we check if it was already there,
|
|
% but when we read in the module, we try to insert not just that module
|
|
% but also all the nested submodules inside that module. If a submodule
|
|
% was previously imported, then it may already have an entry in the
|
|
% deps_map. However, unless the submodule is defined both as a separate
|
|
% submodule and also as a nested submodule, the previous entry will be
|
|
% a dummy entry that we inserted after trying to read the source file
|
|
% and failing.
|
|
%
|
|
% Note that the case where a module is defined as both a separate
|
|
% submodule and also as a nested submodule is caught in
|
|
% split_into_submodules.
|
|
%
|
|
% XXX This shouldn't need to be exported.
|
|
%
|
|
:- pred insert_into_deps_map(module_and_imports::in,
|
|
deps_map::in, deps_map::out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module libs.timestamp.
|
|
:- import_module parse_tree.error_util.
|
|
:- import_module parse_tree.parse_error.
|
|
:- import_module parse_tree.prog_data_foreign.
|
|
:- import_module parse_tree.prog_item.
|
|
:- import_module parse_tree.read_modules.
|
|
|
|
:- import_module list.
|
|
:- import_module one_or_more.
|
|
:- import_module one_or_more_map.
|
|
:- import_module pair.
|
|
:- import_module set.
|
|
:- import_module term.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
get_submodule_kind(ModuleName, DepsMap) = Kind :-
|
|
Ancestors = get_ancestors(ModuleName),
|
|
( if list.last(Ancestors, Parent) then
|
|
map.lookup(DepsMap, ModuleName, deps(_, ModuleImports)),
|
|
map.lookup(DepsMap, Parent, deps(_, ParentImports)),
|
|
module_and_imports_get_source_file_name(ModuleImports, ModuleFileName),
|
|
module_and_imports_get_source_file_name(ParentImports, ParentFileName),
|
|
( if ModuleFileName = ParentFileName then
|
|
Kind = nested_submodule
|
|
else
|
|
Kind = separate_submodule
|
|
)
|
|
else
|
|
Kind = toplevel
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
generate_deps_map(Globals, ModuleName, Search, !DepsMap, !IO) :-
|
|
generate_deps_map_loop(Globals, map.singleton(ModuleName, []), Search,
|
|
!DepsMap, !IO).
|
|
|
|
:- pred generate_deps_map_loop(globals::in,
|
|
map(module_name, list(term.context))::in, maybe_search::in,
|
|
deps_map::in, deps_map::out, io::di, io::uo) is det.
|
|
|
|
generate_deps_map_loop(Globals, !.Modules, Search, !DepsMap, !IO) :-
|
|
( if map.remove_smallest(Module, ExpectationContexts, !Modules) then
|
|
generate_deps_map_step(Globals, Module, ExpectationContexts,
|
|
!Modules, Search, !DepsMap, !IO),
|
|
generate_deps_map_loop(Globals, !.Modules, Search, !DepsMap, !IO)
|
|
else
|
|
% If we can't remove the smallest, then the set of modules to be
|
|
% processed is empty.
|
|
true
|
|
).
|
|
|
|
:- pred generate_deps_map_step(globals::in,
|
|
module_name::in, list(term.context)::in,
|
|
map(module_name, list(term.context))::in,
|
|
map(module_name, list(term.context))::out,
|
|
maybe_search::in, deps_map::in, deps_map::out, io::di, io::uo) is det.
|
|
|
|
generate_deps_map_step(Globals, Module, ExpectationContexts,
|
|
!Modules, Search, !DepsMap, !IO) :-
|
|
% Look up the module's dependencies, and determine whether
|
|
% it has been processed yet.
|
|
lookup_dependencies(Globals, Module, ExpectationContexts, Search, Deps0,
|
|
!DepsMap, !IO),
|
|
|
|
% If the module hadn't been processed yet, then add its imports, parents,
|
|
% and public children to the list of dependencies we need to generate,
|
|
% and mark it as having been processed.
|
|
Deps0 = deps(Done0, ModuleImports),
|
|
(
|
|
Done0 = not_yet_processed,
|
|
Deps = deps(already_processed, ModuleImports),
|
|
map.det_update(Module, Deps, !DepsMap),
|
|
module_and_imports_get_c_j_cs_fims(ModuleImports, CJCsEFIMs),
|
|
% We could keep a list of the modules we have already processed
|
|
% and subtract it from the sets of modules we add here, but doing that
|
|
% actually leads to a small slowdown.
|
|
module_and_imports_get_module_name_context(ModuleImports,
|
|
ModuleNameContext),
|
|
module_and_imports_get_ancestors(ModuleImports, AncestorModuleNames),
|
|
ForeignImportedModuleNames = get_all_foreign_import_modules(CJCsEFIMs),
|
|
set.foldl(add_module_name_and_context(ModuleNameContext),
|
|
AncestorModuleNames, !Modules),
|
|
set.foldl(add_module_name_and_context(ModuleNameContext),
|
|
ForeignImportedModuleNames, !Modules),
|
|
|
|
module_and_imports_get_int_deps_map(ModuleImports, IntDepsMap),
|
|
module_and_imports_get_imp_deps_map(ModuleImports, ImpDepsMap),
|
|
module_and_imports_get_public_children_map(ModuleImports,
|
|
PublicChildren),
|
|
one_or_more_map.to_assoc_list(IntDepsMap, IntDepsModuleNamesContexts),
|
|
one_or_more_map.to_assoc_list(ImpDepsMap, ImpDepsModuleNamesContexts),
|
|
one_or_more_map.to_assoc_list(PublicChildren,
|
|
ChildrenModuleNamesContexts),
|
|
list.foldl(add_module_name_with_contexts,
|
|
IntDepsModuleNamesContexts, !Modules),
|
|
list.foldl(add_module_name_with_contexts,
|
|
ImpDepsModuleNamesContexts, !Modules),
|
|
list.foldl(add_module_name_with_contexts,
|
|
ChildrenModuleNamesContexts, !Modules)
|
|
;
|
|
Done0 = already_processed
|
|
).
|
|
|
|
:- pred add_module_name_and_context(term.context::in, module_name::in,
|
|
map(module_name, list(term.context))::in,
|
|
map(module_name, list(term.context))::out) is det.
|
|
|
|
add_module_name_and_context(Context, ModuleName, !Modules) :-
|
|
( if map.search(!.Modules, ModuleName, OldContexts) then
|
|
map.det_update(ModuleName, [Context | OldContexts], !Modules)
|
|
else
|
|
map.det_insert(ModuleName, [Context], !Modules)
|
|
).
|
|
|
|
:- pred add_module_name_with_contexts(
|
|
pair(module_name, one_or_more(term.context))::in,
|
|
map(module_name, list(term.context))::in,
|
|
map(module_name, list(term.context))::out) is det.
|
|
|
|
add_module_name_with_contexts(ModuleName - NewContexts, !Modules) :-
|
|
( if map.search(!.Modules, ModuleName, OldContexts) then
|
|
NewOldContexts = one_or_more_to_list(NewContexts) ++ OldContexts,
|
|
map.det_update(ModuleName, NewOldContexts, !Modules)
|
|
else
|
|
NewOldContexts = one_or_more_to_list(NewContexts),
|
|
map.det_insert(ModuleName, NewOldContexts, !Modules)
|
|
).
|
|
|
|
% Look up a module in the dependency map.
|
|
% If we don't know its dependencies, read the module and
|
|
% save the dependencies in the dependency map.
|
|
%
|
|
:- pred lookup_dependencies(globals::in,
|
|
module_name::in, list(term.context)::in, maybe_search::in,
|
|
deps::out, deps_map::in, deps_map::out, io::di, io::uo) is det.
|
|
|
|
lookup_dependencies(Globals, ModuleName, ExpectationContexts, Search, Deps,
|
|
!DepsMap, !IO) :-
|
|
( if map.search(!.DepsMap, ModuleName, DepsPrime) then
|
|
Deps = DepsPrime
|
|
else
|
|
read_dependencies(Globals, ModuleName, ExpectationContexts, Search,
|
|
ModuleImportsList, !IO),
|
|
list.foldl(insert_into_deps_map, ModuleImportsList, !DepsMap),
|
|
map.lookup(!.DepsMap, ModuleName, Deps)
|
|
).
|
|
|
|
insert_into_deps_map(ModuleImports, !DepsMap) :-
|
|
module_and_imports_get_module_name(ModuleImports, ModuleName),
|
|
Deps = deps(not_yet_processed, ModuleImports),
|
|
map.set(ModuleName, Deps, !DepsMap).
|
|
|
|
% Read a module to determine the (direct) dependencies of that module
|
|
% and any nested submodules it contains. Return the module_and_imports
|
|
% structure for the named module, and each of its nested submodules.
|
|
%
|
|
:- pred read_dependencies(globals::in, module_name::in, list(term.context)::in,
|
|
maybe_search::in, list(module_and_imports)::out, io::di, io::uo) is det.
|
|
|
|
read_dependencies(Globals, ModuleName, ExpectationContexts, Search,
|
|
ModuleAndImportsList, !IO) :-
|
|
% XXX If _SrcSpecs contains error messages, the parse tree may not be
|
|
% complete, and the rest of this predicate may work on incorrect data.
|
|
read_module_src(Globals, "Getting dependencies for module",
|
|
ignore_errors, Search, ModuleName, ExpectationContexts,
|
|
SourceFileName, always_read_module(dont_return_timestamp), _,
|
|
ParseTreeSrc, SrcSpecs, SrcReadModuleErrors, !IO),
|
|
parse_tree_src_to_module_and_imports_list(Globals, SourceFileName,
|
|
ParseTreeSrc, SrcReadModuleErrors, SrcSpecs, Specs,
|
|
_RawCompUnits, ModuleAndImportsList),
|
|
% XXX Why do we print out these error messages?
|
|
write_error_specs_ignore(Globals, Specs, !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
:- end_module parse_tree.deps_map.
|
|
%-----------------------------------------------------------------------------%
|