mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-09 19:02:18 +00:00
Estimated hours taken: 50
Branches: main
Add support for foreign enumerations to Mercury. These allow the
programmer to assign foreign language values as the representation of
enumeration constructors.
e.g.
:- type status
---> optimal
; infeasible
; unbounded
; unknown.
:- pragma foreign_enum("C", status/0, [
optimal - "STATUS_OPTIMAL",
infeasible - "STATUS_INFEASIBLE",
unbounded - "STATUS_UNBOUNDED",
unknown - "STATUS_UNKNOWN"
]).
The advantage of this is that when values of type status/0 are passed to
foreign code (C in this case) no translation is necessary. This should
simplify the task of writing bindings to foreign language libraries.
Unification and comparison for foreign enumerations are the usual
unification and comparison for enumeration types, except that the default
ordering on them is determined by the foreign representation of the
constructors. User-defined equality and comparison also work for foreign
enumeration types.
In order to implement foreign enumerations we have to introduce two
new type_ctor representations. The existing ones for enum type do not
work since they use the value of an enumeration constructor to perform
table lookups in the RTTI data structures. For foreign enumerations
we need to perform a linear search at the corresponding points. This
means that some RTTI operations related to deconstruction are more
expensive.
The dummy type optimisation is not applied to foreign enumerations as
the code generators currently initialise the arguments of non-builtin
dummy type foreign_proc arguments to zero. For unit foreign enumerations
they should be initialised to the correct foreign value. (This is could be
implemented but in practice it's probably not going to be worth it.)
Currently, foreign enumerations are only supported by the C backends.
compiler/prog_io_pragma.m:
Parse foreign_enum pragmas.
Generalise the code used to parse association lists of sym_names
and strings since this is now used by the code to parse foreign_enum
pragmas as well as that for foreign_export_enum pragmas.
Fix a typo: s/foreign_expor_enum/foreign_export_enum/
compiler/prog_item.m:
Represent foreign_enum pragmas in the parse tree.
compiler/prog_type.m:
Add a new type category for foreign enumerations.
compiler/modules.m:
Add any foreign_enum pragmas for enumeration types defined in the
interface of a module to the interface files.
Output foreign_import_module pragmas in the interface file
if any foreign_enum pragmas are included in it. This ensures that
the contents that any foreign declarations that are needed by the
foreign_enum pragmas are visible.
compiler/make_hlds_passes.m:
compiler/add_pragma.m:
Add pragma foreign_enum items to the HLDS after all the types
have been added. As they are added, error check them.
Change the constructor tag values of foreign enum types to their
foreign values.
compiler/module_qual.m:
Module qualify pragma foreign_enum items.
compiler/mercury_to_mercury.m:
Output foreign_enum pragmas.
Generalise some of the existing code for writing out association
lists in foreign_export_enum pragmas for use with foreign_enum
pragmas as well.
compiler/hlds_data.m:
Add the alternative `is_foreign_type' to the type enum_or_dummy/0.
Add new type of cons_tag, foreign_tag, whose values are directly
embedded in the target language.
compiler/intermod.m:
Write out any foreign_enum pragmas for opt_exported types.
(The XXX concerning attaching language information to foreign tags
will be addressed in a subsequent change.)
compiler/llds.m:
compiler/mlds.m:
Support new kinds of rval constants: llconst_foreign and
mlconst_foreign respectively. Both of these represent tag values
as strings that are intended to be directly embedded in the target
language.
compiler/llds_out.m:
Add code to write out the new kind of rval_const.
s/Integer/MR_Integer/ in a spot.
s/Float/MR_Float/ in a spot.
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/type_ctor_info.m:
Add support the RTTI required by foreign enums.
compiler/switch_util.m:
Handle switches on foreign_enums as-per normal enumerations.
compiler/table_gen.m:
Tabling of foreign_enums is also like normal enumerations.
compiler/type_util.m:
Add a predicate that tests whether a type is a foreign enumeration.
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/ml_unify_gen.m:
Handle unification and comparison of foreign enumeration values.
They are treated like normal enumerations for the purposes of
implementing these operations.
compiler/ml_type_gen.m:
Handle foreign enumerations when generating the MLDS representation
of enumerations.
compiler/ml_util.m:
Add a function to create an initializer for an object with a
foreign tag.
compiler/mlds_to_c.m:
Handle mlconst_foreign/1 rval constants.
compiler/bytecode_gen.m:
compiler/dupproc.m:
compiler/erl_rtti.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/hlds_out.m:
compiler/higher_order.m:
compiler/inst_match.m:
compiler/jumpopt.m:
compiler/llds_to_x86_64.m:
compiler/ml_code_util.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/mlds_to_java.m:
compiler/mlds_to_managed.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/polymorphism.m:
compiler/recompilation.version.m:
compiler/term_norm.m:
compiler/trailing_analysis.m:
Conform to the above changes.
doc/reference_manual.texi:
Document the new pragma.
Fix some typos: s/pramga/pragma/, s/behavior/behaviour/
library/construct.m:
Handle the two new type_ctor reps.
Break an over-long line.
library/rtti_implementation.m:
Support the two new type_ctor reps.
(XXX The Java versions of some of this cannot be implemented until
support for foreign enumerations is added to mlds_to_java.m.)
Reformat the inst usereq/0 and extend it to include foreign enums.
runtime/mercury_type_info.h:
Add two new type_ctor reps. One for foreign enumerations and
another for foreign enumerations with user equality.
Define new types (and extend existing ones) in order to support
RTTI for foreign enumerations.
runtime/mercury_unify_compare_body.h:
Implement generic unify and compare for foreign enumerations.
(It is the same as that for regular enumerations.)
runtime/mercury_construct.[ch]:
runtime/mercury_deconstruct.h:
Handle (de)construction of foreign enumeration values.
runtime/mercury_deep_copy_body.h:
Implement deep copy for foreign enumerations.
runtime/mercury_table_type_body.h:
runtime/mercury_term_size.c:
Handle the new type_ctor representations.
java/runtime/ForeignEnumFunctorDesc.java:
Add a Java version of the MR_ForeignEnumFuntorDesc structure.
(Note: this is untested, as the java grade runtime doesn't work
anyway.)
java/runtime/TypeFunctors.java:
Add a constructor method for foreign enumerations.
(Likewise, untested.)
NEWS:
Announce pragma foreign_enum.
vim/syntax/mercury.vim:
Highlight the new pragma appropriately.
tests/hard_coded/.cvsignore:
Ignore executables generated by the new tests.
Ignore a bunch of other files create by the Mercury compiler.
tests/hard_coded/Mmakefile:
tests/hard_coded/foreign_enum_rtti.{m,exp}:
Test RTTI for foreign enumerations.
tests/hard_coded/foreign_enum_dummy.{m,exp}:
Check that dummy type optimisation is disabled for foreign
enumerations.
tests/hard_coded/Mercury.options:
tests/hard_coded/foreign_enum_mod1.{m,exp}:
tests/hard_coded/foreign_enum_mod2.m:
Test that foreign_enum pragmas are hoisted into interface files
and that they are handled correctly in optimization interfaces.
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/foreign_enum_import.{m,err_exp}:
tests/invalid/foreign_enum_invalid.{m,err_exp}:
Test that errors in foreign_enum pragmas are reported.
tests/tabling/Mmakefile:
tests/hard_coded/table_foreign_enum.{m,exp}:
Test case for tabling of foreign enumerations.