Estimated hours taken: 0.75
Allow the #include "mercury_imp.h" in generated header files to be
avoided (#define MERCURY_IMP_H isn't quite enough because it will still
look for mercury_imp.h in the include path).
We need this because we want to use these prototypes in C++, but don't
want to start including the Mercury header files (in fact, I'd prefer
to keep the include paths quite separate).
compiler/export.m:
Generate
#ifndef MERCURY_EXCLUDE_IMP_H
#include "mercury_imp.h"
#endif
in the generated .h file for exported Mercury predicates.
Estimated hours taken: 6
(plus another 80 or so already recorded for
my commits on the existential_types branch)
Merge in the changes from the existential types branch,
and make some modifications to address dgj's code review comments.
These changes add support for existentially quantified type variables
and type class constraints on functions and predicates.
(Existential data types, however, are not supported -- see below.)
Existentially quantified type variables are introduced with
an explicit `some [T]', e.g. `:- some [T] pred foo(T)'.
Existentially quantified type class constraints are introduced
with `&' instead of `<=', e.g. `:- some [T] (pred foo(T) & ord(T))'.
There's still several limitations:
0. XXX It's not yet documented in the language reference manual.
1. XXX It doesn't do any mode checking or mode reordering.
If you write code that uses existentially typed procedures in the
wrong order, then you'll get an internal error in polymorphism.m
or in the code generator. (Cases where a type_info has no
producer at all are caught by the check for unbound type
variables in post_typecheck.m.)
To support this, we need to change things so that polymorphism.m
gets invoked before mode checking.
2. Using `in' modes on arguments of existential type won't work.
If you try, you will get a compile error.
It would be nice to extend things to allow this kind of
"implied mode" for type_infos, where an existential type
becomes a universal type if some value of that type is
input. Supporting this would require first fixing
limitation 1 (described above) and then
3. There's no support for `pragma c_code' for procedures
with existential type class constraints.
(In fact, there's not really any support for `pragma c_code'
for procedures with universal type class constraints either --
the C code has no way of getting access to the type class info.)
4. XXX Taking the address of something which is existentially typed
should be illegal, but we don't check this.
In addition, these changes in this batch make a start towards allowing
existentially typed data types. The compiler now accepts existential
quantifiers and type class constraints on type definitions, and type
checks them accordingly (assuming all functor occurrences are
deconstructors, not constructors -- see limitation 2 above). But
there's no special handling for them in polymorphism.m, so if you try
to use them, it will abort with an internal error.
The changes also includes fixes for a couple of bugs in typechecking
and polymorphism that I discovered while making the above changes,
and an improvement to the error reporting from typecheck.m in one case.
Those changes are listed separately below.
compiler/prog_data.m:
Add a new type `class_constraints', which holds two different
lists of constraints, namely the existentially quantified constraints
and the universally quantified ones.
Add a new field to the parse tree representation of pred and
func declarations to hold a list of the existentially quantified
type variables, and change the `list(class_constraint)' into
`class_constraints' so that we can store existential constraints too.
Add new fields to the `constructor' data type (formerly just a pair)
to hold the existentially quantified type variables and
type class constraints.
compiler/hlds_pred.m:
Add several new fields to the pred_info:
- a list of the existentially quantified type variables;
- a list of the "HeadTypeParams": type variables which
cannot be bound by this predicate (i.e. those whose type_infos
come from this pred's caller or are returned from
other preds called by this one);
- and a list of unsatisfied type class constraints.
Add a predicate pred_info_get_univ_quant_tvars to compute the
universally quantified type variables.
Change the pred constraints field from `list(class_constraint)'
to `class_constraints' so that it can hold existential constraints too.
compiler/hlds_data.m:
Add new fields to hlds_cons_defn to hold the existentially
quantified type variables and type class constraints.
compiler/*.m:
Minor changes to reflect the above-mentioned data structure
changes in prog_data.m, hlds_pred.m, and hlds_data.m.
compiler/prog_io.m:
Add code to parse the new constructs.
Also rewrite the code for parsing purity specifiers,
type quantifiers and type class constraints, using basically
the method suggested by Peter Schachte: treat these as
"declaration attributes", and have parse_decl strip off
all the declaration attributes into a seperate list and
then pass that list to process_decl, which for each different
kind of declaration processes the attributes which are
appropriate for that declaration and then calls check_no_attributes
to ensure that there were no inappropriate attributes.
The purpose of this rewrite was to allow it to handle the new
constructs properly, and to avoid unnecessary code duplication.
compiler/mercury_to_mercury.m:
Add code to pretty-print the new constructs.
compiler/make_hlds.m:
Copy the new fields in the parse tree into the
corresponding new fields in the pred_info.
Add code to check for various misuses of quantifiers.
compiler/hlds_out.m:
Print out the new fields in the pred_info (except the
unsatisfied type class constraints -- if these are non-empty,
post_typecheck.m will print them out in the error message).
When printing out types, pass the AppendVarNums parameter down,
so that HLDS dumps will distinguish between different type
variables that have the same name.
Delete hlds_out__write_constructor, since it was doing exactly
the same thing as mercury__output_ctor.
compiler/typecheck.m:
Lots of changes to handle existential types and existential
type class constraints.
compiler/post_typecheck.m:
When checking for unbound type variables,
use the value of HeadTypeParams from the pred_info.
compiler/type_util.m:
Delete `type_and_constraint_list_matches_exactly', since it was not
used. Add various `apply_variable_renaming_to_*' predicates for
renaming constraints.
compiler/polymorphism.m:
Lots of changes to handle existential types and existential
type class constraints.
Also some changes to make the code more maintainable:
compiler/prog_data.m:
compiler/hlds_goal.m:
compiler/mercury_to_mercury.m:
Put curly braces around the definitions of 'some'/2 and '&'/2 functors
in `:- type' definitions, to avoid them being misinterpreted as
existential type constraints.
compiler/goal_util.m:
compiler/polymorphism.m:
compiler/hlds_pred.m:
compiler/lambda.m:
Include type_infos for existentially quantified type variables
and type_class_infos for existential constraints
in the set of extra variables computed by
goal_util__extra_type_info_vars.
compiler/inlining.m:
Change inlining__do_goal to handle inlining of calls to
existentially typed predicates -- for them, instead of not
binding any type variables at all in the caller, it allows the
call to bind any type variables in the caller except for those
that are universally quantified.
compiler/inlining.m:
compiler/deforest.m:
Call pred_info_get_univ_quant_tvars and pass the
result to inlining__do_inline_goal.
tests/hard_coded/Mmakefile:
tests/hard_coded/existential_types_test.{m,exp}:
tests/hard_coded/typeclasses/Mmakefile:
tests/hard_coded/typeclasses/existential_type_classes.{m,exp}:
Test cases for the use of existential types and
existential type class constraints.
----------
Improve an error message.
compiler/typecheck.m:
Improve error reporting by checking type class constraints for
satisfiability as we go and thus reporting unsatisfiable constraints
as soon as possible, rather than only at the end of the clause.
Previously we already did that for the case of ground constraints,
but they are not the only unsatsfiable constraints: constraints
on head type params (type variables which cannot be bound) are
also unsatisfiable if they can't be eliminated straight away
by context reduction.
tests/invalid/Mmakefile:
tests/invalid/typeclass_test_7.{m,err_exp}:
Regression test for the above change.
----------
Avoid problems where type inference was reporting some
spurious errors for predicates using type classes,
because the check for unsatisfied type class constraints
was being done before the final pass of type inference
had finished.
compiler/hlds_pred.m:
Add new field to the pred_info containing the unproven
type class constraints.
compiler/typecheck.m:
When inferring type class constraints, make sure that before
we save the results back in the pred_info, we restrict the
constraints to the head type variables. Constraints
on other type variables should be treated as
unsatisfied constraints.
Don't check for unsatisfied type class constraints at the
end of each pass; instead, just save the unproven type class
constraints in the pred_info.
compiler/post_typecheck.m:
Check for unsatisfied type class constraints, using
the new field in the pred_info.
tests/hard_coded/typeclasses/Mmakefile:
tests/hard_coded/typeclasses/inference_test_2.{m,exp}:
tests/invalid/Mmakefile:
tests/invalid/typeclass_test_8.{m,err_exp}:
Add regression tests for this change.
----------
Fix a bug with the computation of the non-locals for
predicates with more than one constraint on the same type variable --
it was only including one of the type-class-infos, rather than all of them.
compiler/goal_util.m:
Change `goal_util__extra_nonlocal_typeinfos' so that it gets
passed the TypeClassInfoVarMap and uses this to include all
the appropriate typeclass infos in the extra nonlocals.
compiler/hlds_pred.m:
compiler/lambda.m:
compiler/polymorphism.m:
Pass the TypeClassInfoVarMap to `goal_util__extra_nonlocal_typeinfos'.
tests/hard_coded/typeclasses/Mmakefile:
tests/hard_coded/typeclasses/lambda_multi_constraint_same_tvar.{m,exp}:
Regression test for the above-mentioned bug.
Estimated hours taken: 0.1
compiler/export.m:
Fix a warning about `list' being imported in the interface
section but only used in the implementation section.
Estimated hours taken: 5
Implement compiler support for nested sub-modules.
(Mmake support is still missing, so you have to compile by hand.
Also you must use `ml' to link rather `mmc', because
`mmc' doesn't link all the object files that it generates.)
compiler/prog_io.m:
Fix a couple of bugs in the parsing of `module' and `end_module'
declarations.
compiler/mercury_to_mercury.m:
Handle output of `:- module' and `:- end_module' declarations.
compiler/modules.m:
Add predicate split_into_submodules, which takes the item_list
for a module and splits it into a list of item_lists for each
submodule.
compiler/mercury_compile.m:
Change the code for creating interface files and generating
LLDS fragments so that it calls split_into_submodules and then
iterates over each submodule.
That means that we now generate a seperate HLDS for each submodule, and
compile that to a seperate LLDS and a seperate C file. It would be
more efficient to combine the LLDS fragments for each submodule after
code generation, generate a single C file, and thus only invoke the C
compiler once. In view of this goal, I have done some cleaning up of
the HLDS/LLDS distinction, so that we don't need to pass the HLDS to
the various LLDS output routines. (However, I haven't actually gotten
as far as combining the LLDS code fragments.)
compiler/llds.m:
Add type `c_interface_info' which contains information from the
HLDS that is used during the LLDS output pass.
compiler/mercury_compile.m:
Add a predicate `get_c_interface_info' which gets the relevant
info from the HLDS that is needed for LLDS output.
compiler/export.m:
Add `export__get_c_export_decls', and rename
`export__get_pragma_exported_procs' as `export__get_c_export_defns'.
Change export__produce_header_file so that it takes a `c_export_decls'
(part of the `c_interface_info') instead of an HLDS.
Estimated hours taken: 11
Finish off the centralization of the file name handling code, and
add support for generating intermediate files in subdirectories.
scripts/mmake.in:
Add a new boolean option `--use-subdirs';
if enabled, it just sets the environment variable MMAKE_USE_SUBDIRS
to `yes' before invoking Make.
Also add negative versions of the various options
(`--no-use-subdirs', `--no-verbose', `--no-save-makefile').
scripts/Mmake.rules:
Add code to handle generating intermediate file names
in subdirectories. If MMAKE_USE_SUBDIRS=yes, we add
`--use-subdirs' to MCFLAGS, and most of the pattern rules
are changed to use subdirectories.
Note that getting this to work required a bit of a hack:
due to what seem to be bugs in GNU Make, `mmake depend'
needs to do `mmc --make-short-interface *.m' to get things
started. But once the int3s are there, the dependencies
seem to work OK.
compiler/options.m:
Add a new boolean option `--use-subdirs'.
compiler/modules.m:
Add new predicate `fact_table_file_name'.
Add an extra argument to `module_name_to_file_name',
specifying whether or not to create any directories
needed for the file name.
Change all the file-name-creating predicates here
to go through a single new predicate `choose_file_name',
and add code in that predicate to handle the `--use-subdirs'
option.
Also if the `--use-subdirs' option is set, don't use the
compact dependencies format, since it can't work in that case.
compiler/fact_table.m:
Call `fact_table_file_name' rather than using `string__append'.
compiler/mercury_compile.m:
Change `link_module_list' and `join_module_list'
so that they create file names by calling `module_name_to_file_name'.
compiler/export.m:
compiler/intermod.m:
compiler/llds_out.m:
compiler/mercury_compile.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/termination.m:
compiler/trans_opt.m:
compiler/unused_args.m:
Change all calls to `module_name_to_file_name' to pass
the extra argument specifying whether or not to make
any directories needed for the file name.
library/Mmakefile:
Change the rule for `mmake install_ints' so that it
creates a `Mercury' subdirectory with symbolic links
`ints', `int2s', `int3s', `opts', and `trans_opts'
which just point to `..'. This is needed for the
`--use-subdirs' option to work, because Mmake currently
does not support mixing libraries compiled with and
without `--use-subdirs'.
doc/user_guide.texi:
Document the above changes.
Estimated hours taken: 4.5
Change things so that almost all the places which create file names
do so via just a few predicates (such as module_name_to_file_name)
in modules.m. Centralising the file handling in this way
will make future changes to the file naming convention simpler.
(The one place which still creates file names other than via the predicates
declared at the start of modules.m is mercury_compile__link_module_list.
It creates them based on the value of the `-o <filename>' option.
I didn't change that because I am not yet sure what the semantics of
the `-o <filename>' option ought to be.)
compiler/modules.m:
Add three extra arguments to module_name_to_file_name/2:
the file extension, and an io__state pair.
Add new predicates module_name_to_lib_file_name/6,
module_name_to_split_c_file_name/6, and
module_name_to_make_var_name/2.
compiler/export.m:
compiler/intermod.m:
compiler/llds_out.m:
compiler/mercury_compile.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/termination.m:
compiler/trans_opt.m:
compiler/unused_args.m:
Change all calls to module_name_to_file_name/2 to instead
call one of the above-mentioned predicates in modules.m.
compiler/llds_out.m:
Add new predicate llds_out__make_init_name/2 which returns
the name of the initialization function for a module,
for use by modules.m.
compiler/modules.m:
A few minor changes to the generated .dep files:
- add a new phony target `foo.trans_opt',
to match `foo.opt';
- change the generated rule for `change_clean'
so that it removes `.pic_o' files;
- add `.PHONY' declarations for phony targets;
- change the generated rule for making `foo.init'
so that it used the names returned by
llds_out__make_init_name/2, rather than
using "mercury__`basename foo.m .m`__init";
- fix a bug in the generated rule for making `libfoo.a':
it had `rm -f foo.a' instead of `rm -f libfoo.a'.
Estimated hours taken: 50
Add support for nested modules.
- module names may themselves be module-qualified
- modules may contain `:- include_module' declarations
which name sub-modules
- a sub-module has access to all the declarations in the
parent module (including its implementation section).
This support is not yet complete; see the BUGS and LIMITATIONS below.
LIMITATIONS
- source file names must match module names
(just as they did previously)
- mmc doesn't allow path names on the command line any more
(e.g. `mmc --make-int ../library/foo.m').
- import_module declarations must use the fully-qualified module name
- module qualifiers must use the fully-qualified module name
- no support for root-qualified module names
(e.g. `:parent:child' instead of `parent:child').
- modules may not be physically nested (only logical nesting, via
`include_module').
BUGS
- doesn't check that the parent module is imported/used before allowing
import/use of its sub-modules.
- doesn't check that there is an include_module declaration in the
parent for each module claiming to be a child of that parent
- privacy of private modules is not enforced
-------------------
NEWS:
Mention that we support nested modules.
library/ops.m:
library/nc_builtin.nl:
library/sp_builtin.nl:
compiler/mercury_to_mercury.m:
Add `include_module' as a new prefix operator.
Change the associativity of `:' from xfy to yfx
(since this made parsing module qualifiers slightly easier).
compiler/prog_data.m:
Add new `include_module' declaration.
Change the `module_name' and `module_specifier' types
from strings to sym_names, so that module names can
themselves be module qualified.
compiler/modules.m:
Add predicates module_name_to_file_name/2 and
file_name_to_module_name/2.
Lots of changes to handle parent module dependencies,
to create parent interface (`.int0') files, to read them in,
to output correct dependencies information for them to the
`.d' and `.dep' files, etc.
Rewrite a lot of the code to improve the readability
(add comments, use subroutines, better variable names).
Also fix a couple of bugs:
- generate_dependencies was using the transitive implementation
dependencies rather than the transitive interface dependencies
to compute the `.int3' dependencies when writing `.d' files
(this bug was introduced during crs's changes to support
`.trans_opt' files)
- when creating the `.int' file, it was reading in the
interfaces for modules imported in the implementation section,
not just those in the interface section.
This meant that the compiler missed a lot of errors.
library/graph.m:
library/lexer.m:
library/term.m:
library/term_io.m:
library/varset.m:
compiler/*.m:
Add `:- import_module' declarations to the interface needed
by declarations in the interface. (The previous version
of the compiler did not detect these missing interface imports,
due to the above-mentioned bug in modules.m.)
compiler/mercury_compile.m:
compiler/intermod.m:
Change mercury_compile__maybe_grab_optfiles and
intermod__grab_optfiles so that they grab the opt files for
parent modules as well as the ones for imported modules.
compiler/mercury_compile.m:
Minor changes to handle parent module dependencies.
(Also improve the wording of the warning about trans-opt
dependencies.)
compiler/make_hlds.m:
compiler/module_qual.m:
Ignore `:- include_module' declarations.
compiler/module_qual.m:
A couple of small changes to handle nested module names.
compiler/prog_out.m:
compiler/prog_util.m:
Add new predicates string_to_sym_name/3 (prog_util.m) and
sym_name_to_string/{2,3} (prog_out.m).
compiler/*.m:
Replace many occurrences of `string' with `module_name'.
Change code that prints out module names or converts
them to strings or filenames to handle the fact that
module names are now sym_names intead of strings.
Also change a few places (e.g. in intermod.m, hlds_module.m)
where the code assumed that any qualified symbol was
fully-qualified.
compiler/prog_io.m:
compiler/prog_io_goal.m:
Move sym_name_and_args/3, parse_qualified_term/4 and
parse_qualified_term/5 preds from prog_io_goal.m to prog_io.m,
since they are very similar to the parse_symbol_name/2 predicate
already in prog_io.m. Rewrite these predicates, both
to improve maintainability, and to handle the newly
allowed syntax (module-qualified module names).
Rename parse_qualified_term/5 as `parse_implicit_qualified_term'.
compiler/prog_io.m:
Rewrite the handling of `:- module' and `:- end_module'
declarations, so that it can handle nested modules.
Add code to parse `include_module' declarations.
compiler/prog_util.m:
compiler/*.m:
Add new predicates mercury_public_builtin_module/1 and
mercury_private_builtin_module/1 in prog_util.m.
Change most of the hard-coded occurrences of "mercury_builtin"
to call mercury_private_builtin_module/1 or
mercury_public_builtin_module/1 or both.
compiler/llds_out.m:
Add llds_out__sym_name_mangle/2, for mangling module names.
compiler/special_pred.m:
compiler/mode_util.m:
compiler/clause_to_proc.m:
compiler/prog_io_goal.m:
compiler/lambda.m:
compiler/polymorphism.m:
Move the predicates in_mode/1, out_mode/1, and uo_mode/1
from special_pred.m to mode_util.m, and change various
hard-coded definitions to instead call these predicates.
compiler/polymorphism.m:
Ensure that the type names `type_info' and `typeclass_info' are
module-qualified in the generated code. This avoids a problem
where the code generated by polymorphism.m was not considered
type-correct, due to the type `type_info' not matching
`mercury_builtin:type_info'.
compiler/check_typeclass.m:
Simplify the code for check_instance_pred and
get_matching_instance_pred_ids.
compiler/mercury_compile.m:
compiler/modules.m:
Disallow directory names in command-line arguments.
compiler/options.m:
compiler/handle_options.m:
compiler/mercury_compile.m:
compiler/modules.m:
Add a `--make-private-interface' option.
The private interface file `<module>.int0' contains
all the declarations in the module; it is used for
compiling sub-modules.
scripts/Mmake.rules:
scripts/Mmake.vars.in:
Add support for creating `.int0' and `.date0' files
by invoking mmc with `--make-private-interface'.
doc/user_guide.texi:
Document `--make-private-interface' and the `.int0'
and `.date0' file extensions.
doc/reference_manual.texi:
Document nested modules.
util/mdemangle.c:
profiler/demangle.m:
Demangle names with multiple module qualifiers.
tests/general/Mmakefile:
tests/general/string_format_test.m:
tests/general/string_format_test.exp:
tests/general/string__format_test.m:
tests/general/string__format_test.exp:
tests/general/.cvsignore:
Change the `:- module string__format_test' declaration in
`string__format_test.m' to `:- module string_format_test',
because with the original declaration the `__' was taken
as a module qualifier, which lead to an error message.
Hence rename the file accordingly, to avoid the warning
about file name not matching module name.
tests/invalid/Mmakefile:
tests/invalid/missing_interface_import.m:
tests/invalid/missing_interface_import.err_exp:
Regression test to check that the compiler reports
errors for missing `import_module' in the interface section.
tests/invalid/*.err_exp:
tests/warnings/unused_args_test.exp:
tests/warnings/unused_import.exp:
Update the expected diagnostics output for the test cases to
reflect a few minor changes to the warning messages.
tests/hard_coded/Mmakefile:
tests/hard_coded/parent.m:
tests/hard_coded/parent.child.m:
tests/hard_coded/parent.exp:
tests/hard_coded/parent2.m:
tests/hard_coded/parent2.child.m:
tests/hard_coded/parent2.exp:
Two simple tests case for the use of nested modules with
separate compilation.
Estimated hours taken: 20
Add support for `pragma import', which is a simplified form of
`pragma c_code'. With `pragma import', the user specifies only
the C function name, rather than a C code fragment, and the
Mercury compiler handles the argument-passing automatically.
TODO
- add documentation to doc/reference_manual.texi.
WISHLIST
- change `pragma import' and `pragma export'
to take an additional parameter indicating the language
(e.g. C, Prolog, Ada, Fortran, etc.) and/or calling
convention
compiler/prog_data.m:
Add `pragma import' to the parse tree data structure.
compiler/prog_io_pragma.m:
Add code to parse `pragma import' declarations.
compiler/mercury_to_mercury.m:
Add code to pretty-print `pragma import' declarations.
compiler/module_qual.m:
Add code to module-qualify `pragma import' declarations.
compiler/make_hlds.m:
Add code to process `pragma import' declarations,
by converting them to clauses with HLDS `c_code' instructions.
compiler/export.m:
Declare `export__exclude_argument_type' in the interface,
for use by the code for handling `pragma import' in make_hlds.m.
Change the documentation to say that this procedure is used for
both exported and imported procedures.
compiler/notes/compiler_design.html:
Document how the compiler handles `pragma import' declarations.
tests/hard_coded/Mmakefile:
tests/hard_coded/pragma_import.m:
tests/hard_coded/pragma_import.exp:
Add some test cases for `pragma import'.
Estimated hours taken: 0.01
compiler/export.m:
Fix a problem that broke the SICStus version of the compiler:
s/get_proc_label/llds_out__get_proc_label/.
Estimated hours taken: 50
Generate stack layouts for accurate garbage collection.
compiler/base_type_layout.m:
Change the order of some arguments so that threaded data
structures are more often in the final two arguments (allows
easy use of higher order predicates).
Simplify some code using higher order preds.
Export base_type_layout__construct_pseudo_type_info, as
stack_layout.m needs to be able to generate pseudo_type_infos
too.
Fix problems with cell numbers being re-used -- get the next
cell number from module_info, and update module_info
after processing base_type_layouts.
compiler/code_gen.m:
Add information about each procedure to the continuation info.
Handle new field in c_procedure.
compiler/continuation_info.m:
Redesign most of this module to deal with labels
that are continuation points for multiple calls.
Change the order of some arguments so that threaded data
structures are in the final two arguments.
Cleaned up and documented code.
compiler/dupelim.m:
compiler/exprn_aux.m:
Handle new label_entry data type.
compiler/export.m:
compiler/opt_debug.m:
Handle new label_entry and general data types.
compiler/llds_out.m:
Add an argument to get_proc_label to control whether a
"mercury_" prefix is wanted.
Handle new label_entry and general data types.
compiler/llds.m:
Add a new alternative for data_const - a label_entry.
Add a new alternative for data_name - general, which
allows any sort of data, with names generated elsewhere.
Add the pred_proc_id as a field of c_procedure.
compiler/optimize.m:
compiler/llds_common.m:
compiler/optimize.m:
Handle new field in c_procedure.
compiler/mercury_compile.m:
Generate layout information after code has been generated,
and output stack layouts.
compiler/notes/compiler_design.html:
Document new stack_layout module.
compiler/stack_layout.m:
New file - generates the LLDS code that defines
global constants to hold the stack_layout structures.
compiler/options.m:
compiler/handle_options.m:
Add --stack-layout option which outputs stack layouts.
Make accurate gc imply stack_layout.
Estimated hours taken: 2
compiler/export.m:
When exporting procedures to C, don't include procedure arguments
with type `io__state' or `store__store' or with mode `unused'
in the arguments of the C function.
doc/reference_manual.texi:
Document the above change.
runtime/init.h:
A temporary hack to allow the compiler to bootstrap.
A proper change to modify the interface to ML_io_init_state()
and ML_io_finalize_state() to reflect the above change to
export.m will follow.
Estimated hours taken: 14
Implemented a :- use_module directive. This is the same as
:- import_module, except all uses of the imported items
must be explicitly module qualified.
:- use_module is implemented by ensuring that unqualified versions
of items only get added to the HLDS symbol tables if they were imported
using import_module.
Indirectly imported items (from `.int2' files) and items declared in `.opt'
files are treated as if they were imported with use_module, since all uses
of them should be module qualified.
compiler/module_qual.m
Keep two sets of type, mode and inst ids, those which can
be used without qualifiers and those which can't.
Renamed some predicates which no longer have unique names since
'__' became a synonym for ':'.
Made mq_info_set_module_used check whether the current item is in
the interface, rather than relying on its caller to do the check.
Removed init_mq_info_module, since make_hlds.m now uses the
mq_info built during the module qualification pass.
compiler/prog_data.m
Added a pseudo-declaration `used', same as `imported' except uses of
the following items must be module qualified.
Added a type need_qualifier to describe whether uses of an item
need to be module qualified.
compiler/make_hlds.m
Keep with the import_status whether current item was imported
using a :- use_module directive.
Use the mq_info structure passed in instead of building a new one.
Ensure unqualified versions of constructors only get added to the
cons_table if they can be used without qualification.
compiler/hlds_module.m
Added an extra argument to predicate_table_insert of type
need_qualifier.
Only add predicates to the name and name-arity indices if they
can be used without qualifiers.
Changed the structure of the module-name-arity index, so that
lookups can be made without an arity, such as when type-checking
module qualified higher-order predicate constants. This does not
change the interface to the module_name_arity index.
Factored out some common code in predicate_table_insert which
applies to both predicates and functions.
compiler/hlds_pred.m
Removed the opt_decl import_status. It isn't needed any more
since all uses of items declared in .opt files must now be
module qualified.
Added some documentation about when the clauses_info is valid.
compiler/intermod.m
Ensure that predicate and function calls in the `.opt' file are
module qualified. Use use_module instead of import_module in
`.opt' files.
compiler/modules.m
Handle use_module directives.
Report a warning if both use_module and import_module declarations
exist for the same module.
compiler/mercury_compile.m
Collect inter-module optimization information before module
qualification, since it can't cause conflicts any more. This means
that the mq_info structure built in module_qual.m can be reused in
make_hlds.m, instead of building a new one.
compiler/prog_out.m
Add a predicate prog_out__write_module_list, which was moved
here from module_qual.m.
compiler/typecheck.m
Removed code to check that predicates declared in `.opt' files
were being used appropriately, since this is now handled by
use_module.
compiler/*.m
Added missing imports, mostly for prog_data and term.
NEWS
compiler/notes/todo.html
doc/reference_manual.texi
Document `:- use_module'.
tests/valid/intermod_lambda_test.m
tests/valid/intermod_lambda_test2.m
tests/invalid/errors.m
tests/invalid/errors2.m
Test cases.
Estimated hours taken: 250
Implemented `:- pragma fact_table' for string, int and float
argument types. Facts can have any combination of input and output modes.
Hash tables are used to lookup facts in modes that have input
arguments.
compiler/fact_table.m:
Added code for outputting `pragma c_code' to access facts in all
mode/determinism combinations in `pragma fact_table's.
Added code to build and output hash tables (as C arrays) for
input modes of fact tables.
Many other changes and rearrangements in the module to support the
above.
compiler/export.m:
Moved declarations for `convert_type_from_mercury/3' and
`convert_type_to_mercury/3' to the interface so they can be
used by `fact_table.m'.
compiler/handle_options.m:
Add a check to `postprocess_options' to ensure that arguments
to `--fact-table-hash-percent-full' are integers in the range
1 to 100.
compiler/inlining.m:
Stop `model_non' `pragma c_code' being inlined unless it has
the new `extra_pragma_info' field (which hasn't been fully
implemented yet). This ensures that code such as the lookup
code generated for nondet and multidet modes of `pragma
fact_table's works with inlining turned on.
compiler/make_hlds.m:
Added arguments to the calls to predicates in fact_table.m
where necessary.
Add `c_header_code' returned by `fact_table_compile_facts' to
the module_info.
compiler/mode_util.m:
Added two new predicates:
`mode_is_fully_input' which is true iff the initial
inst of the mode is ground.
`mode_is_fully_output' which is true iff the inital inst is
free and the final inst is ground.
compiler/modules.m:
Added a dependency to `.d' files to ensure that fact table C
files are recompiled whenever they are recreated.
compiler/options.m
Added new options:
`--fact_table_max_array_size <n>' where n is the
maximum size array to use for `pragma fact_table'
data. (default 1024)
`--fact_table_hash_percent_full <n>' where n is how
full the `pragma fact_table' hash tables should
be allowed to get, given as an integer percentage
(between 1 and 99). (default 90).
Documentation for these options has been added to the usage
message but is commented out at the moment.
support them because NU-Prolog couldn't support them.)
This required two main changes:
(a) eliminating places where we explicitly assumed that character codes
ranged from 1 to 127.
(b) making sure that all conversions from `Char' to `Integer' are done
by first explicitly casting to `UnsignedChar'. This is necessary
to avoid potential problems on C compilers for which `char' is signed.
library/char.m:
library/char.nu.nl:
Replace the implementation of char__to_int as a big table
with an implementation using pragma c_code, so that it doesn't
assume that character codes range from 1 to 127.
Move the old implementation into a new file char.nu.nl,
since it's still needed for Prolog support.
Add new predicates char__min_char_value/1 and char__max_char_value/1.
library/Mmakefile:
Add char.nu.nl to the list of files needed for Prolog support.
library/lexer.m:
Rewrite io__get_token_[12] in the original (less efficient) way
that they were written before conway's change in revision 1.17,
to avoid assuming anything about the range of character codes.
(Once this change has bootstrapped, it might be worth going back
to the efficient version, modified of course to assume that
character codes range from 0..255 rather than 1..127.
However, at least for bootstrapping we need to use the less
efficient version.)
runtime/mercury_string.h:
Add `UnsignedChar' typedef.
library/string.m:
In string__to_int_list, make sure that the conversion from
`Char' to `Integer' is done by first explicitly casting to
`UnsignedChar'.
Also a few other minor fixes:
- remove an old XXX by using make_aligned_string()
- use `size_t' rather than `Word' for a string length;
- add a missing `const'
- remove an unnecessary cast to (char)
- change a `while (--p >= Str) { ...' to
`while (p > Str) { p--; ...', because pointing to
one before the start of an array is not strictly
ANSI-conformant.
compiler/switch_detection.m:
compiler/dense_switch.m:
Use char__min_char_value and char__max_char_value to avoid
assuming 7-bit chars. (We still don't get cross-compilation
between platforms with different size characters right yet,
but that's not a major issue right now.)
compiler/export.m:
Make sure that conversions from `Char' to `Word'
are done by first explicitly casting to `UnsignedChar'.
NEWS:
Mention that we now support 8-bit characters.
Mention the new predicates char__min_char_value/1 and
char__max_char_value/1, as well as int__int_min, int__int_max,
int__bits_per_int (which were added previously, with different
names, but not mentioned in the NEWS file).
Also make minor cleanups to a few of the other messages.
Estimated hours taken: 2
Fix a bug introduced in my previous change.
compiler/export.m:
For exported Mercury functions, make sure we grab the Mercury
return value from its register *before* restoring the C registers.
Estimated hours taken: 1.5
Allow `pragma export' declarations for imported predicates.
compiler/prog_io_pragma.m:
Don't require the module name for `pragma export' declarations
to match the name of the current module.
compiler/export.m:
Use pred_info_arg_types to get the argument types,
rather than proc_info_var_types; this way is simpler,
and works for imported predicates.
Estimated hours taken: 0.5
compiler/export.m:
Add support for C++: wrap the declarations in the
generated header file inside `extern "C" { ... }'
(but only #ifdef __cplusplus, of course).
callee-save registers (as global register variables) and not restoring
them before returning to the C code.
compiler/export.m:
Use the new macros to save the C registers to a local array
before entering Mercury code and restore them afterwards.
Estimated hours taken: 4
Allow `pragma export' for semidet predicates and for det/semidet functions.
(Previously it only worked for det predicates.)
prog_data.m:
Add a pred_or_func field to the pragma_export struct.
prog_io.m:
Add code to parse `pragma export' declarations for functions,
e.g. `pragma export(foo(in) = out, "foo")'.
mercury_to_mercury.m:
Add code to print out `pragma export' declarations for functions.
module_qual.m:
Change export/3 to export/4.
export.m:
Handle semidet procedures -- the C function returns TRUE/FALSE
depending on whether the Mercury procedure succeeded or failed.
Handle functions -- for det functions whose return value has
mode `out', the Mercury function return value is returned as the C
function return value.
Don't call save_registers() after returning from call_engine(),
since call_engine() now saves them itself.
When generating header files, don't make up argument names
for the function prototypes, instead just leave the arguments
unnamed. Also, make sure the `#ifndef HEADER_NAME_H' comes
at the very start of the file, before #include "imp.h".
Estimated hours taken: 4
passes_aux:
Flesh out the code already here for traversing module_infos,
making it suitable to handle all the passes of the back end.
mercury_compile:
Use the traversal code in passes_aux to invoke the back end passes
over each procvedure in turn. Print a one-line message for each
predicate if -v is given (this fixes a long-standing bug).
excess.m, follow_code.m, follow_vars.m, live_vars.m, lveness.m, store_alloc.m:
Remove the code to traverse module_infos, since it is now unnecessary.
export.m:
Remove an unused argument from export__produce_header_file_2.
others:
Move imports from interfaces to implementations, or in some cases
remove them altogether.
Estimated hours taken: 3
Handle float and string arguments to procs which are exported to C functions
by a pragma(export, ...) dec.
export.m:
When copying the input arguments from C variable to Mercury registers,
wrap a `float_to_word()' around floats and cast strings to (Word).
When copying the output arguments from Mercury registers, to C variables
wrap a `word_to_float()' around floats and cast strings to (String).
Estimated hours taken: 1.5
Split llds into two parts. llds.m defines the data types, while llds_out.m
has the predicates for printing the code.
Removed the call_closure instruction. Instead, we use calls to the
system-defined addresses do_call_{det,semidet,nondet}_closure. This is
how call_closure was implemented already. The advantage of the new
implementation is that it allows jump optimization of what used to be
call_closures, without new code in jumpopt.
Estimated hours taken: 30 (?)
Its...
The C to Mercury Interface.
The following changes provide a C to Mercury interface. By making a declaration
such as
:- pragma(export, foo(in, in, out), "FunctionName").
you will be able to call the C function "FunctionName" from C. The arguments
are the same as the Mercury arguments, with outputs passed as pointers.
XXX We don't handle floats or strings properly.
A function prototype is output into <modulename>.h
Execution still has to start in Mercury.
Something went wrong with CVS when I tried to abort a commit just then, and it
thinks I've already commited some files... but here's a description of all
my changes anyway:
compiler/garbage_out.m:
Ignore c_export c_modules.
compiler/hlds_module.m:
Add an annotation to the hlds, indicating which procs are exported
to C.
compiler/llds.m:
Change the way labels are emitted - instead of emitting the label
directly, it first generates a string and then prints the string. This
is useful because I only want the string (to print later). The
preds which return a string are now part of the interface.
compiler/make_hlds.:
Take note of which procs are to be exported to C.
compiler/mercury_compile.pp:
Generate a <module>.h file if necessary.
compiler/mercury_to_mercury.m:
Spit out :- pragma(export, ...) decs.
compiler/prog_io.m:
Read in :- pragma(export, ...) decs.
compiler/export.m:
Handle the outputting of C exports. This includes the generation of
the .h files and the generation of the C functions.