mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-20 16:31:04 +00:00
Estimated hours taken: 16 Branches: main Add support for "implementation-defined literals" $file, $line, $module, $pred, $grade which are replaced constants by the compiler. library/lexer.m: Add a new type of token. Read "$foo" as a `implementation_defined' token instead of two name tokens. library/term.m: library/term_io.m: Add a new type of constant, `implementation_defined'. library/parser.m: Handle `implementation_defined' tokens from the lexer. compiler/check_hlds.m: compiler/implementation_defined_literals.m: compiler/mercury_compile.m: Add a new pass to replace implementation-defined literals in program clauses. Call the new pass. compiler/notes/compiler_design.html: Document the new module. compiler/prog_data.m: Add a new option to `cons_id', namely `implementation_defined_const'. compiler/typecheck.m: Tell the typechecker the types of the supported implementation-defined literals. compiler/prog_io_util.m: Make `convert_bound_inst' fail if implementation-defined literals appear in inst definitions so that an error will be issued. compiler/bytecode_gen.m: compiler/ctgc.selector.m: compiler/dead_proc_elim.m: compiler/dependency_graph.m: compiler/erl_unify_gen.m: compiler/fact_table.m: compiler/higher_order.m: compiler/hlds_code_util.m: compiler/hlds_out.m: compiler/inst_check.m: compiler/mercury_to_mercury.m: compiler/mode_util.m: compiler/module_qual.m: compiler/prog_rep.m: compiler/prog_type.m: compiler/prog_util.m: compiler/rbmm.execution_path.m: compiler/unused_imports.m: compiler/xml_documentation.m: Conform to addition of `implementation_defined_const'. doc/reference_manual.texi: Document implementation-defined literals. NEWS: Announce the new feature. tests/hard_coded/Mmakefile: tests/hard_coded/impl_def_lex.exp: tests/hard_coded/impl_def_lex.m: tests/hard_coded/impl_def_lex_string.exp: tests/hard_coded/impl_def_lex_string.m: tests/hard_coded/impl_def_literal.exp: tests/hard_coded/impl_def_literal.m: tests/invalid/Mmakefile: tests/invalid/impl_def_literal_syntax.err_exp: tests/invalid/impl_def_literal_syntax.m: tests/invalid/undef_impl_def_literal.err_exp: tests/invalid/undef_impl_def_literal.m: Add test cases.
211 lines
7.8 KiB
Mathematica
211 lines
7.8 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2002-2008 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: hlds_code_util.m.
|
|
%
|
|
% Various utilities routines for use during HLDS generation.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module hlds.hlds_code_util.
|
|
:- interface.
|
|
|
|
:- import_module hlds.hlds_data.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module list.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Are equivalence types fully expanded on this backend?
|
|
%
|
|
:- pred are_equivalence_types_expanded(module_info::in) is semidet.
|
|
|
|
% Find out how a function symbol (constructor) is represented
|
|
% in the given type.
|
|
%
|
|
:- func cons_id_to_tag(module_info, mer_type, cons_id) = cons_tag.
|
|
|
|
% Given a list of types, mangle the names so into a string which
|
|
% identifies them. The types must all have their top level functor
|
|
% bound, with any arguments free variables.
|
|
%
|
|
:- pred make_instance_string(list(mer_type)::in, string::out) is det.
|
|
|
|
% Succeeds iff this inst is one that can be used in a valid
|
|
% mutable declaration.
|
|
%
|
|
:- pred is_valid_mutable_inst(module_info::in, mer_inst::in) is semidet.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module check_hlds.mode_util.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module libs.compiler_util.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.options.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module parse_tree.prog_type.
|
|
|
|
:- import_module bool.
|
|
:- import_module char.
|
|
:- import_module map.
|
|
:- import_module set.
|
|
:- import_module string.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
are_equivalence_types_expanded(ModuleInfo) :-
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, highlevel_data, HighLevelData),
|
|
HighLevelData = yes,
|
|
globals.get_target(Globals, Target),
|
|
( Target = target_il
|
|
; Target = target_java
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
cons_id_to_tag(ModuleInfo, Type, ConsId) = Tag:-
|
|
(
|
|
ConsId = int_const(I),
|
|
Tag = int_tag(I)
|
|
;
|
|
ConsId = float_const(F),
|
|
Tag = float_tag(F)
|
|
;
|
|
ConsId = string_const(S),
|
|
Tag = string_tag(S)
|
|
;
|
|
ConsId = implementation_defined_const(_),
|
|
unexpected(this_file, "cons_id_to_tag: implementation_defined_const")
|
|
;
|
|
ConsId = pred_const(ShroudedPredProcId, EvalMethod),
|
|
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId),
|
|
Tag = pred_closure_tag(PredId, ProcId, EvalMethod)
|
|
;
|
|
ConsId = type_ctor_info_const(ModuleName, TypeName, Arity),
|
|
Tag = type_ctor_info_tag(ModuleName, TypeName, Arity)
|
|
;
|
|
ConsId = base_typeclass_info_const(ModuleName, ClassName, _Instance,
|
|
EncodedArgs),
|
|
Tag = base_typeclass_info_tag(ModuleName, ClassName, EncodedArgs)
|
|
;
|
|
( ConsId = type_info_cell_constructor(_)
|
|
; ConsId = typeclass_info_cell_constructor
|
|
),
|
|
Tag = unshared_tag(0)
|
|
;
|
|
ConsId = tabling_info_const(ShroudedPredProcId),
|
|
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId),
|
|
Tag = tabling_info_tag(PredId, ProcId)
|
|
;
|
|
ConsId = deep_profiling_proc_layout(ShroudedPredProcId),
|
|
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId),
|
|
Tag = deep_profiling_proc_layout_tag(PredId, ProcId)
|
|
;
|
|
ConsId = table_io_decl(ShroudedPredProcId),
|
|
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId),
|
|
Tag = table_io_decl_tag(PredId, ProcId)
|
|
;
|
|
ConsId = cons(Name, Arity),
|
|
(
|
|
% Handle the `character' type specially.
|
|
Type = builtin_type(builtin_type_character),
|
|
Name = unqualified(ConsName),
|
|
string.char_to_string(Char, ConsName)
|
|
->
|
|
char.to_int(Char, CharCode),
|
|
Tag = int_tag(CharCode)
|
|
;
|
|
% Tuples do not need a tag. Note that unary tuples are not treated
|
|
% as no_tag types. There's no reason why they couldn't be, it is
|
|
% just not worth the effort.
|
|
type_is_tuple(Type, _)
|
|
->
|
|
Tag = single_functor_tag
|
|
;
|
|
type_to_ctor_det(Type, TypeCtor),
|
|
% Given the type_ctor, lookup up the constructor tag table
|
|
% for that type.
|
|
module_info_get_type_table(ModuleInfo, TypeTable),
|
|
map.lookup(TypeTable, TypeCtor, TypeDefn),
|
|
hlds_data.get_type_defn_body(TypeDefn, TypeBody),
|
|
(
|
|
TypeBody = hlds_du_type(_, ConsTagTable, _, _, _, _, _, _)
|
|
;
|
|
( TypeBody = hlds_eqv_type(_)
|
|
; TypeBody = hlds_foreign_type(_)
|
|
; TypeBody = hlds_solver_type(_, _)
|
|
; TypeBody = hlds_abstract_type(_)
|
|
),
|
|
unexpected(this_file, "cons_id_to_tag: type is not d.u. type?")
|
|
),
|
|
|
|
% Finally look up the cons_id in the table.
|
|
map.lookup(ConsTagTable, cons(Name, Arity), Tag)
|
|
)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
make_instance_string(InstanceTypes, InstanceString) :-
|
|
% Note that for historical reasons, builtin types are treated as being
|
|
% unqualified (`int') rather than being qualified (`builtin.int')
|
|
% at this point.
|
|
list.map(type_to_string, InstanceTypes, InstanceStrings),
|
|
string.append_list(InstanceStrings, InstanceString).
|
|
|
|
:- pred type_to_string(mer_type::in, string::out) is det.
|
|
|
|
type_to_string(Type, String) :-
|
|
( type_to_ctor_and_args(Type, TypeCtor, _) ->
|
|
TypeCtor = type_ctor(TypeName, TypeArity),
|
|
TypeNameString = sym_name_to_string_sep(TypeName, "__"),
|
|
string.int_to_string(TypeArity, TypeArityString),
|
|
String = TypeNameString ++ "__arity" ++ TypeArityString ++ "__"
|
|
;
|
|
unexpected(this_file, "type_to_string: invalid type")
|
|
).
|
|
|
|
%----------------------------------------------------------------------------%
|
|
|
|
is_valid_mutable_inst(ModuleInfo, Inst) :-
|
|
set.init(Expansions),
|
|
is_valid_mutable_inst_2(ModuleInfo, Inst, Expansions).
|
|
|
|
:- pred is_valid_mutable_inst_2(module_info::in, mer_inst::in,
|
|
set(inst_name)::in) is semidet.
|
|
|
|
is_valid_mutable_inst_2(_, any(shared, _), _).
|
|
is_valid_mutable_inst_2(ModuleInfo, bound(shared, BoundInsts), Expansions) :-
|
|
list.member(bound_functor(_, Insts), BoundInsts),
|
|
list.member(Inst, Insts),
|
|
is_valid_mutable_inst_2(ModuleInfo, Inst, Expansions).
|
|
is_valid_mutable_inst_2(_, ground(shared, _), _).
|
|
is_valid_mutable_inst_2(ModuleInfo, defined_inst(InstName), Expansions0) :-
|
|
not set.member(InstName, Expansions0),
|
|
Expansions = set.insert(Expansions0, InstName),
|
|
inst_lookup(ModuleInfo, InstName, Inst),
|
|
is_valid_mutable_inst_2(ModuleInfo, Inst, Expansions).
|
|
|
|
%----------------------------------------------------------------------------%
|
|
|
|
:- func this_file = string.
|
|
|
|
this_file = "hlds_code_util.m".
|
|
|
|
%----------------------------------------------------------------------------%
|
|
:- end_module hlds_code_util.
|
|
%----------------------------------------------------------------------------%
|