Estimated hours taken: 220
Aditi update syntax, type and mode checking.
Change the hlds_goal for constructions in preparation for
structure reuse to avoid making multiple conflicting changes.
compiler/hlds_goal.m:
Merge `higher_order_call' and `class_method_call' into a single
`generic_call' goal type. This also has alternatives for the
various Aditi builtins for which type declarations can't
be written.
Remove the argument types field from higher-order/class method calls.
It wasn't used often, and wasn't updated by optimizations
such as inlining. The types can be obtained from the vartypes
field of the proc_info.
Add a `lambda_eval_method' field to lambda_goals.
Add a field to constructions to identify which RL code fragment should
be used for an top-down Aditi closure.
Add fields to constructions to hold structure reuse information.
This is currently ignored -- the changes to implement structure
reuse will be committed to the alias branch.
This is included here to avoid lots of CVS conflicts caused by
changing the definition of `hlds_goal' twice.
Add a field to `some' goals to specify whether the quantification
can be removed. This is used to make it easier to ensure that
indexes are used for updates.
Add a field to lambda_goals to describe whether the modes were
guessed by the compiler and may need fixing up after typechecking
works out the argument types.
Add predicate `hlds_goal__generic_call_id' to work out a call_id
for a generic call for use in error messages.
compiler/purity.m:
compiler/post_typecheck.m:
Fill in the modes of Aditi builtin calls and closure constructions.
This needs to know which are the `aditi__state' arguments, so
it must be done after typechecking.
compiler/prog_data.m:
Added `:- type sym_name_and_arity ---> sym_name/arity'.
Add a type `lambda_eval_method', which describes how a closure
is to be executed. The alternatives are normal Mercury execution,
bottom-up execution by Aditi and top-down execution by Aditi.
compiler/prog_out.m:
Add predicate `prog_out__write_sym_name_and_arity', which
replaces duplicated inline code in a few places.
compiler/hlds_data.m:
Add a `lambda_eval_method' field to `pred_const' cons_ids and
`pred_closure_tag' cons_tags.
compiler/hlds_pred.m:
Remove type `pred_call_id', replace it with type `simple_call_id',
which combines a `pred_or_func' and a `sym_name_and_arity'.
Add a type `call_id' which describes all the different types of call,
including normal calls, higher-order and class-method calls
and Aditi builtins.
Add `aditi_top_down' to the type `marker'.
Remove `aditi_interface' from type `marker'. Interfacing to
Aditi predicates is now handled by `generic_call' hlds_goals.
Add a type `rl_exprn_id' which identifies a predicate to
be executed top-down by Aditi.
Add a `maybe(rl_exprn_id)' field to type `proc_info'.
Add predicate `adjust_func_arity' to convert between the arity
of a function to its arity as a predicate.
Add predicates `get_state_args' and `get_state_args_det' to
extract the DCG state arguments from an argument list.
Add predicate `pred_info_get_call_id' to get a `simple_call_id'
for a predicate for use in error messages.
compiler/hlds_out.m:
Write the new representation for call_ids.
Add a predicate `hlds_out__write_call_arg_id' which
replaces similar code in mode_errors.m and typecheck.m.
compiler/prog_io_goal.m:
Add support for `aditi_bottom_up' and `aditi_top_down' annotations
on pred expressions.
compiler/prog_io_util.m:
compiler/prog_io_pragma.m:
Add predicates
- `prog_io_util:parse_name_and_arity' to parse `SymName/Arity'
(moved from prog_io_pragma.m).
- `prog_io_util:parse_pred_or_func_name_and_arity to parse
`pred SymName/Arity' or `func SymName/Arity'.
- `prog_io_util:parse_pred_or_func_and_args' to parse terms resembling
a clause head (moved from prog_io_pragma.m).
compiler/type_util.m:
Add support for `aditi_bottom_up' and `aditi_top_down' annotations
on higher-order types.
Add predicates `construct_higher_order_type',
`construct_higher_order_pred_type' and
`construct_higher_order_func_type' to avoid some code duplication.
compiler/mode_util.m:
Add predicate `unused_mode/1', which returns `builtin:unused'.
Add functions `aditi_di_mode/0', `aditi_ui_mode/0' and
`aditi_uo_mode/0' which return `in', `in', and `out', but will
be changed to return `di', `ui' and `uo' when alias tracking
is implemented.
compiler/goal_util.m:
Add predicate `goal_util__generic_call_vars' which returns
any arguments to a generic_call which are not in the argument list,
for example the closure passed to a higher-order call or
the typeclass_info for a class method call.
compiler/llds.m:
compiler/exprn_aux.m:
compiler/dupelim.m:
compiler/llds_out.m:
compiler/opt_debug.m:
Add builtin labels for the Aditi update operations.
compiler/hlds_module.m:
Add predicate predicate_table_search_pf_sym, used for finding
possible matches for a call with the wrong number of arguments.
compiler/intermod.m:
Don't write predicates which build `aditi_top_down' goals,
because there is currently no way to tell importing modules
which RL code fragment to use.
compiler/simplify.m:
Obey the `cannot_remove' field of explicit quantification goals.
compiler/make_hlds.m:
Parse Aditi updates.
Don't typecheck clauses for which syntax errors in Aditi updates
are found - this avoids spurious "undefined predicate `aditi_insert/3'"
errors.
Factor out some common code to handle terms of the form `Head :- Body'.
Factor out common code in the handling of pred and func expressions.
compiler/typecheck.m:
Typecheck Aditi builtins.
Allow the argument types of matching predicates to be adjusted
when typechecking the higher-order arguments of Aditi builtins.
Change `typecheck__resolve_pred_overloading' to take a list of
argument types rather than a `map(var, type)' and a list of
arguments to allow a transformation to be performed on the
argument types before passing them.
compiler/error_util.m:
Move the part of `report_error_num_args' which writes
"wrong number of arguments (<x>; expected <y>)" from
typecheck.m for use by make_hlds.m when reporting errors
for Aditi builtins.
compiler/modes.m:
compiler/unique_modes.m:
compiler/modecheck_call.m:
Modecheck Aditi builtins.
compiler/lambda.m:
Handle the markers for predicates introduced for
`aditi_top_down' and `aditi_bottom_up' lambda expressions.
compiler/polymorphism.m:
Add extra type_infos to `aditi_insert' calls
describing the tuple to insert.
compiler/call_gen.m:
Generate code for Aditi builtins.
compiler/unify_gen.m:
compiler/bytecode_gen.m:
Abort on `aditi_top_down' and `aditi_bottom_up' lambda
expressions - code generation for them is not yet implemented.
compiler/magic.m:
Use the `aditi_call' generic_call rather than create
a new procedure for each Aditi predicate called from C.
compiler/rl_out.pp:
compiler/rl_gen.m:
compiler/rl.m:
Move some utility code used by magic.m and call_gen.m into rl.m.
Remove an XXX comment about reference counting being not yet
implemented - Evan has fixed that.
library/ops.m:
compiler/mercury_to_mercury.m:
doc/transition_guide.texi:
Add unary prefix operators `aditi_bottom_up' and `aditi_top_down',
used as qualifiers on lambda expressions.
Add infix operator `==>' to separate the tuples in an
`aditi_modify' call.
compiler/follow_vars.m:
Thread a `map(prog_var, type)' through, needed because
type information is no longer held in higher-order call goals.
compiler/table_gen.m:
Use the `make_*_construction' predicates in hlds_goal.m
to construct constants.
compiler/*.m:
Trivial changes to add extra fields to hlds_goal structures.
doc/reference_manual.texi:
Document Aditi updates.
Use @samp{pragma base_relation} instead of
@samp{:- pragma base_relation} throughout the Aditi documentation
to be consistent with other parts of the reference manual.
tests/valid/Mmakefile:
tests/valid/aditi_update.m:
tests/valid/aditi.m:
Test case.
tests/valid/Mmakefile:
Remove some hard-coded --intermodule-optimization rules which are
no longer needed because `mmake depend' is now run in this directory.
tests/invalid/*.err_exp:
Fix expected output for changes in reporting of call_ids
in typecheck.m.
tests/invalid/Mmakefile
tests/invalid/aditi_update_errors.{m,err_exp}:
tests/invalid/aditi_update_mode_errors.{m,err_exp}:
Test error messages for Aditi updates.
tests/valid/aditi.m:
tests/invalid/aditi.m:
Cut down version of extras/aditi/aditi.m to provide basic declarations
for Aditi compilation such as `aditi__state' and the modes
`aditi_di', `aditi_uo' and `aditi_ui'. Installing extras/aditi/aditi.m
somewhere would remove the need for these.
Estimated hours taken: 2
compiler/typecheck.m:
Set the head_type_params field of class methods properly. (ie. add
the existentially quantified tvars as well).
compiler/hard_coded/typeclasses/typeclass_exist_method.m:
A test case for this.
compiler/hard_coded/typeclasses/Mmakefile:
Turn this test case on.
Estimated hours taken: 50
Add the infrastructure for assertions into the compiler.
compiler/error_util.m:
Output the correct pred name for assertions.
compiler/hlds_data.m:
Add the assertion_table structure.
compiler/hlds_module.m:
Get/set the assertion_table from the module_info.
compiler/hlds_out.m:
Modify hlds_out__write_pred_id to identify assertions.
compiler/hlds_pred.m:
Add the goal_type assertion.
compiler/make_hlds.m:
Transform the assertion to a HLDS data structure that can be
typechecked.
compiler/mercury_to_goedel.m:
compiler/module_qual.m:
Handle the assertion structure.
compiler/mercury_to_mercury.m:
Output assertions.
compiler/post_typecheck.m:
Add a predicate which must be called after typechecking of
assertions has been finished. Also document some possible problems
with typechecking assertions.
compiler/prog_data.m:
Add assertion to the type item.
compiler/prog_io.m:
Add the ability to parse assertions.
compiler/purity.m:
After finished typechecking assertions call
post_typecheck__finish_assertion.
compiler/typecheck.m:
Don't output inference messages for assertions.
compiler/notes/compiler_design.html:
Update documentation about exactly where quantification is done.
compiler/notes/glossary.html:
Define what an assertion is.
Estimated hours taken: 0.25
compiler/typecheck.m:
Do special error-handling for if-then-else in DCGs in the same
way that we currently do for ordinary (non-DCG) if-then-elses.
Estimated hours taken: 6
Allow construction unifications for existentially typed functors,
using the syntax "X = 'new foo'(Y)" rather than the usual "X = foo(Y)".
We need to use a special syntax for exisentially typed constructions
because type analysis and polymorphism need to know which occurrences
of existentially typed functors are constructors and which are deconstructors.
Note that we still don't yet support RTTI for existentially typed data types.
compiler/typecheck.m:
For existentially typed functors, allow the functor to have
a "new " prefix, and if so, make the quantifiers and constraints
universal rather than existential.
compiler/polymorphism.m:
For unifications with existentially typed functors,
check for a "new " prefix on the functor.
If the functor has such a prefix, strip off the prefix,
and treat the unification as a construction rather than
treating it as a deconstruction.
compiler/type_util.m:
Define a new predicate `remove_new_prefix', for use by typecheck.m
and polymorphism.m.
compiler/modecheck_unify.m:
For construction unifications, check that all the type_info
and typeclass_info arguments introduced by polymorphism.m
are ground.
tests/hard_coded/typeclasses/existential_data_types.m:
Change the test case to use this new feature,
rather than hacking it using the C interface.
doc/reference_manual.texi:
Document the new features.
Estimated hours taken: 4
Merge in the changes from the existential_types_2 branch.
This change adds support for mode re-ordering of code involving
existential types. The change required modifying the order of the
compiler passes so that polymorphism comes before mode analysis,
so that mode analysis can check the modes of the `type_info' or
`typeclass_info' variables that polymorphism introduces, so that
it can thus re-order the code accordingly.
This change also includes some more steps towards making existential data
types work. In particular, you should be able to declare existentially
typed data types, the compiler will generate appropriate unification
and compare/3 routines for them, and deconstruction unifications for them
should work OK. However, currently there's no way to construct them
except via `pragam c_code', and we don't generate correct RTTI for them,
so you can't use `io__write' etc. on them.
library/private_builtin.m:
compiler/accumulator.m:
compiler/bytecode_gen.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/code_util.m:
compiler/common.m:
compiler/dead_proc_elim.m:
compiler/dependency_graph.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_goal.m:
compiler/hlds_out.m:
compiler/hlds_pred.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/live_vars.m:
compiler/magic.m:
compiler/make_hlds.m:
compiler/mercury_compile.m:
compiler/mercury_to_c.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/mode_util.m:
compiler/modecheck_call.m:
compiler/modecheck_unify.m:
compiler/modes.m:
compiler/pd_cost.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/purity.m:
compiler/quantification.m:
compiler/rl_exprn.m:
compiler/rl_key.m:
compiler/simplify.m:
compiler/table_gen.m:
compiler/term_traversal.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unused_args.m:
compiler/notes/compiler_design.html:
doc/reference_manual.texi:
tests/hard_coded/typeclasses/Mmakefile:
tests/hard_coded/typeclasses/existential_data_types.m:
tests/hard_coded/typeclasses/existential_data_types.exp:
tests/warnings/simple_code.exp:
tests/hard_coded/Mmakefile:
tests/term/arit_exp.trans_opt_exp:
tests/term/associative.trans_opt_exp:
tests/term/pl5_2_2.trans_opt_exp:
tests/term/vangelder.trans_opt_exp:
tests/term/arit_exp.trans_opt_exp:
tests/term/associative.trans_opt_exp:
tests/term/pl5_2_2.trans_opt_exp:
tests/term/vangelder.trans_opt_exp:
tests/invalid/errors2.err_exp2:
tests/invalid/prog_io_erroneous.err_exp2:
tests/invalid/type_inf_loop.err_exp2:
tests/invalid/types.err_exp2:
tests/invalid/polymorphic_unification.err_exp:
tests/invalid/Mmakefile:
tests/warnings/simple_code.exp:
tests/debugger/queens.exp:
tests/hard_coded/Mmakefile:
tests/hard_coded/existential_reordering.m:
tests/hard_coded/existential_reordering.exp:
Merge in the changes from the existential_types_2 branch.
Estimated hours taken: 0.5
Allow HLDS dumps to contain references to the pointers used by tabling.
Without this chance, HLDS dumps can abort on modules containing tabled
procedures.
compiler/hlds_out.m:
Allow HLDS dumps to contain references to the pointers used by tabling.
This requires adding an extra argument to an exported procedure.
compiler/mode_errors.m:
compiler/typecheck.m:
Pass the extra argument that exported procedure.
Estimated hours taken: 20
These changes make `var' and `term' polymorphic. This allows us to make
variables and terms representing types of a different type to those
representing program terms and those representing insts.
These changes do not *fix* any existing problems (for instance
there was a messy conflation of program variables and inst variables,
and where necessary I've just called varset__init(InstVarSet) with
an XXX comment).
NEWS:
Mention the changes to the standard library.
library/term.m:
Make term, var and var_supply polymorphic.
Add new predicates:
term__generic_term/1
term__coerce/2
term__coerce_var/2
term__coerce_var_supply/2
library/varset.m:
Make varset polymorphic.
Add the new predicate:
varset__coerce/2
compiler/prog_data.m:
Introduce type equivalences for the different kinds of
vars, terms, and varsets that we use (tvar and tvarset
were already there but have been changed to use the
polymorphic var and term).
Also change the various kinds of items to use the appropriate
kinds of var/varset.
compiler/*.m:
Thousands of boring changes to make the compiler type correct
with the different types for type, program and inst vars and
varsets.
Estimated hours taken: 0.75
Report an error if the first argument of a `some' goal
is not a list of variables.
compiler/prog_io.m:
compiler/prog_io_util.m:
Move `parse_list_of_vars' from prog_io.m to prog_io_util.m.
compiler/prog_io_goal.m:
Check to make sure that the first argument to a some
goal is a list of variables. (If not, we don't report
an error here -- the error will be reported by typecheck.m.)
compiler/typecheck.m:
Report an proper error message if there is a call to an
undefined predicate `some/2'.
Also add `some/2' and `all/2' to the list of language builtins
for which we report a special error message if they occur as
undefined function symbols.
tests/invalid/Mmakefile:
tests/invalid/some.m:
tests/invalid/some.err_exp:
Regression test for the above change.
Estimated hours taken: 1
Minor improvements to some compiler error messages.
compiler/modules.m:
Fix a missing close-quote in an error message.
Also improve the wording of the message slightly.
compiler/check_typeclass.m:
compiler/typecheck.m:
Add quotes (`...') in a couple of places
tests/invalid/sub*.err_exp:
tests/invalid/typeclass_test*.err_exp:
Update to reflect the new error messages.
tests/invalid/Mmakefile:
Delete an obsolete comment about a poor error message.
Estimated hours taken: 6
Fix a bug where type errors were causing spurious mode errors,
compiler/post_typecheck.m:
Add new predicate post_typecheck__ill_typed_pred,
which just module-qualifies the pred declaration for that pred.
This is necessary to avoid spurious mode errors in predicates
that call the ill-typed pred.
compiler/typecheck.m:
Call post_typecheck__ill_typed_pred on ill-typed predicates
before calling module_info_remove_pred. We need to call it
here because later passes won't process the pred once it
has been removed.
tests/invalid/Mmakefile:
tests/invalid/spurious_mode_error.m:
tests/invalid/spurious_mode_error.err_exp:
Regression test for the above-mentioned bug.
Estimated hours taken: 4
compiler/typecheck.m:
Fix a bug which resulted in the compiler aborting with a
map_lookup failure for certain (ill-typed) code.
tests/invalid/Mmakefile:
tests/invalid/ext_type_bug.m:
tests/invalid/ext_type_bug.err_exp:
Regression test for the above-mention bug.
Estimated hours taken: 0.5
compiler/typecheck.m:
Fix a bug in conway's recent change to error reporting for
undefined explicitly qualified names: the current module is
always in scope, so don't say that it is not imported.
Estimated hours taken: 2
compiler/typecheck.m:
Don't get rid of an existentially quantified tvar if it is bound to
a type variable from the head of the predicate. If you do, you find
that, eg. :- some [T1] pred p(T1, T2) gets squashed into
:- some [T2] pred p(T2, T2) if T1 is internally bound to T2.
Estimated hours taken: 4
Keep track of which modules have been imported directly by the current module
so that later in type checking, if an explicitly qualified name is undefined,
we can issue an error message that gives a hint if the module has not been
imported.
compiler/hlds_module.m:
Add a pair of predicates for accumulating and retrieving the
imported module specifiers.
Add a field to module_sub_info to hold the set of imported
`module_specifier's.
compiler/make_hlds.m:
Add the module_specifier list to the set in the module_info if
appropriate.
compiler/typecheck.m:
When reporting undefined pred/symbol errors, if the symbol is
explicitly qualified, but the module isn't imported (and isn't
a parent of the current module) then add a hint to that effect
to the error message.
Estimated hours taken: 10
Improve the error messages generated by check_typeclass.m.
check_typeclass.m:
Write decent error messages, including term__contexts for the
appropriate lines, for the errors detected by this module. These errors
are missing or multiple definitions of instance methods and unsatisfied
superclass constraints on instance decls.
mercury_to_mercury.m:
Add predicates which convert class_constraints and types into strings.
This is needed so that an error message can be created as a string,
then formatted to fit the line, rather than writing out the error
message as you go.
hlds_data.m:
Add a term__context to the hlds_instance_defn.
base_typeclass_info.m:
dead_proc_elim.m:
higher_order.m:
hlds_out.m:
polymorphism.m:
typecheck.m:
Ignore the term__context field of the hlds_instance_defn.
make_hlds.m:
Insert the term__context field into the hlds_instance_defn when it
is created.
Estimated hours taken: 20
Fix a bug in the renaming of tvars in type class constraint proofs, and
generally clean up the handling of variable renaming in polymorphism.m.
Change the representation of constraint_proofs to only hold the number of an
instance declaration and not the hlds_instance_defn itself. This means that
polymorphism must look up the instance table to get at hlds_instance_defn,
then calculate the appropriate renamings and substitutions. The rationale
behind this is that the proofs for the superclasses, stored in the
hlds_instance_defn, also need to be renamed. However, we can't just rename
them during typecheck.m because they may not contain proofs for *all* their
ancestors --- that would require topologically sorting the instance defns
before check_typeclass.m.
Also delete the code which attempts to specialise class method calls because
Simon's recent change does this anyway.
hlds_data.m:
Change the constraint_proof representation to only hold instance
numbers, not definitions.
polymorphism.m:
When applying an instance decl, look it up in the instance table
rather than trying to use the half-renamed one in the proof.
Also, rather than trying to pass down a renaming substution into
polymorphism__make_typeclass_info_var, rename everything before
calling it.
type_util.m:
Add two new predicates: apply_subst_to_constraint_proofs and
apply_rec_subst_to_constraint_proofs.
typecheck.m:
Only store the instance number in the proof.
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: 3
Get rid of unnecessary type variables when creating the auxiliary predicate
for an instance method. This will hopefully be a little more robust than
the current approach since typecheck.m is now able to get rid of any unused
tvars... they *must* have been introduced by type inference.
library/varset.m:
Add a predicate varset__squash which gets rid of unused variables.
compiler/check_typeclass.m:
Call varset__squash to get rid of the unnecessary tvars.
compiler/typecheck.m:
Call varset__squash to get rid of the unnecessary tvars, rather than
doing it "manually".
compiler/type_util.m:
Add a new pred apply_variable_renaming_to_constraint.
configure.in:
Add a test to find the number of words needed to represent a
synchronization term.
boehm_gc/gc.h:
fix a declaration by replacing the args () with (void).
boehm_gc/solaris_pthreads.c:
add a missing include
check the return values of pthread calls.
compiler/*.m:
Add handling for the new HLDS goal type par_conj.
Add handling for the four new LLDS instructions:
init_sync_term
fork
join_and_terminate
join_and_continue
compiler/code_info.m:
add a new alternative for slot_contents - sync_term.
compiler/handle_options.m:
add .par as part of the grade
compiler/hlds_goal.m:
add the new goal type par_conj.
compiler/instmap.m:
add instmap__unify which takes a list of instmaps
and abstractly unifies them.
add unify_instmap_delta which tajes two instmap deltas
and abstractly unifies them.
compiler/llds.m:
add the new llds instructions.
compiler/mode_info.m:
add par_conj as a lock reason.
library/Makefile:
work around a bug in the solaris version pthread.h
library/benchmarking.m:
reference the stack zones from the engine structure
rather than from global variables.
library/{nc,sp}_builtin.nl:
add an op declaration for &.
library/std_util.m:
change references to global variables to references inside
the engine structure.
runtime/Mmakefile:
add mercury_thread.{c,h}
add THREADLIBS to the libraries
runtime/*.{c,h}
Remove some old junk from the previous processes/shrd-mem
changes that found their way into the repository.
Add MR_ prefixes to lots of names.
runtime/mercury_context.c:
Add init_thread_stuff for creating and initializing a
context structure for the current thread.
runtime/mercury_context.h:
add a field to the mercury context which stores the thread id
of the thread where this context originated.
add various macros for implementing the new llds instructions.
runtime/mercury_engine.c:
initialize the engine structure, rather than a bunch of globals.
runtime/mercury_engine.h:
declare the mercury_engine structure.
runtime/mercury_regorder.h:
if MR_THREAD_SAFE, and there is at least one global register
then use mr0 as a pointer to the mercury engine structure.
scripts/init_grade_options.sh-subr
add thread_safe
scripts/mgnuc.in
add THREAD_OPTS
scripts/ml.in:
add THREAD_LIBS
Estimated hours taken: 2
Improve the modularity of the code in purity.m by splitting it into two
modules and fix a purity-related bug by moving some code from typecheck.m
into the new module.
compiler/post_typecheck.m:
New module. Handles the typechecking stuff that happens
after typecheck.m.
compiler/purity.m:
Move the typechecking related code in purity.m into post_typecheck.m.
compiler/typecheck.m:
Move the code for copying clauses to the proc_infos, etc. into
new predicates in post_typecheck.m. This code is now called
from purity.m rather than from typecheck.m.
(I think the fact that it was being done in typecheck.m was a
bug -- it meant that the goal_info flags computed by purity.m
were not being copied across to the proc_infos.)
compiler/mercury_compile.m:
compiler/typecheck.m:
Don't pass the ModeError parameter down to typecheck_pred,
since with the above change it isn't needed anymore.
compiler/mercury_compile.m:
Run purity checking before writing the `.opt' files.
This is necessary because writing out the `.opt' files
requires that code in post_typecheck__finish_pred
(formerly in typecheck.m) has been run.
compiler/notes/compiler_design.html:
Document these changes.
Estimated hours taken: 15
Fix a bug where variable names were getting mixed up for certain introduced
instance method predicates.
compiler/check_typeclass.m:
Calculate the variables names correctly (ie. get the renaming
right).
compiler/typecheck.m:
Make typecheck_info_get_final_info also rename the declared
constraints for the predicate. After getting the final info, store
the new versions of the arg types and the renamed constraints,
regardless of whether we are doing type inference or not.
Although the intention was originally that the var numbers would
only be changed in typecheck_info_get_final_info when doing
inference (since that is the only time that redundant type vars
would be present), this is no longer the case. Preds introduced in
typecheck.m can also have redundant type vars in the varset at the
time of creation since they have the *class declarations's* tvarset.
This meant that typecheck_info_get_final_info was getting rid of
some variables, then updating the proofs, but not updating the
constraints, arg types etc.
Estimated hours taken: 6
Fix various invasions of the user's namespace by `mercury_builtin.m',
by splitting mercury_builtin.m into two modules, called builtin.m and
private_builtin.m, and ensuring that the latter is imported as if
by `:- use_module' rather than `:- import_module'.
library/builtin.m:
library/private_builtin.m:
Split mercury_builtin.m into two modules, builtin.m,
which contains stuff intended to be public,
and private_builtin.m, which contains implementation
details that are not supposed to be public.
library/mercury_builtin.m:
Add a comment saying that this module is no longer used, and
should eventually be removed. I have not removed it yet, since
that would prevent bootstrapping with the current compiler. It
will be removed as a seperate change later, once all the
changes have propagated.
compiler/prog_util.m:
Change the definition of mercury_private_builtin_module/1 and
mercury_public_builtin_module so that instead of automatically
importing mercury_builtin.m as if by `import_module', the
copiler will now automatically import builtin.m as if by
`import_module' and private_builtin.m as if by `use_module'.
compiler/polymorphism.m:
Change a call to mercury_private_builtin_module/1 for
unsafe_promise_unique to instead call mercury_public_builtin_module/1.
compiler/unify_proc.m:
Avoid hard-coding "mercury_builtin" by instead
calling one of mercury_{private,public}_builtin_module/1.
runtime/mercury_type_info.[ch]:
library/term.m:
library/std_util.m:
compiler/code_util.m:
Change a few hard-coded instances of "mercury_builtin"
to "builtin" or "private_builtin" as appropriate.
runtime/mercury_trace_util.c:
runtime/mercury_trace_internal.c:
library/prolog.m:
compiler/*.m:
Update comments that refer to "mercury_builtin" to instead
refer to either "builtin" or "private_builtin".
doc/Mmakefile:
Don't include the interface to private_builtin.m in the
library reference manual.
tools/bootcheck:
Add `-p'/`--copy-profiler' option. This is needed to get
the above changes to bootstrap.
tools/test_mercury:
Pass `-p' to tools/bootcheck.
tests/term/*.trans_opt_exp:
s/mercury_builtin/builtin/g
Estimated hours taken: 15
Re-implement the part of context reduction which seeks to eliminate a
typeclass constraint by using the fact that one class is a superclass of
another. This achieves two things:
- Fixes a bug, in that the new algorithm (correctly) searches the whole
superclass relation to find a path from one constraint to
another.
- It makes the algorithm the same as what we put in the type class
paper. :-)
compiler/check_typeclass.m:
Pass the super class table to the context reduction predicate
compiler/hlds_data.m:
Declare the types which (explicitly) hold the superclass information
compiler/hlds_module.m:
Store the superclass information explicitly in the module_info, rather
than just implicitly in the class_table
compiler/make_hlds.m:
Explicitly construct the superclass information as classes are added.
This saves re-computing it for each constraint in typecheck.m
compiler/typecheck.m:
Use the explicit superclass information for context reduction, rather
than just the class table.
When reducing the context using superclasses, recursively search the
whole superclass relation until a match is found.
Estimated hours taken: 4
A few more improvements to type class checking.
compiler/typecheck.m:
Ensure that we run a final pass of context reduction at the
end of typechecking each predicate (or function).
Change the way perform_context_reduction recovers after errors
to avoid reporting the same error more than once
(e.g. for tests/invalid/typeclass_test_2.m).
Simplify the code to check for and report unsatisfied
type class constraints.
Change write_type_assign so that it prints out the
type class constraints as well as the variable types.
tests/invalid/typeclass_test_*.err_exp:
Add a full stop that was missing at the end of
the "unsatisfied typeclass constraint" error message.
Estimated hours taken: 12
Fix some bugs in the handling of "non-simple" type class constraints
(ones for which the types being constrained are not just type variables).
compiler/prog_io_typeclass.m:
Ensure that constraints on type class declarations must be "simple".
This is needed the ensure termination of type checking.
(We already did this for instance declarations, but not for
superclass constraints on type class declarations.)
compiler/prog_data.m:
Document the invariant that the types in a type class constraint
must not contain any information in their term__context fields.
compiler/type_util.m:
compiler/equiv_type.m:
compiler/polymorphism.m:
compiler/prog_io_typeclass.m:
Enforce the above-mentioned invariant.
compiler/typecheck.m:
Allow the declared constraints to be a superset of the
inferred constraints.
When performing context reduction, eliminate declared
constraints at each step rather than only at the end.
Remove declared constraints and apply superclass rules
before applying instance rules.
When applying instance rules, make sure that it is a type
error if there is no matching instance rule for a ground
constraint.
If context reduction results in an error, restore the
original type assign set, to avoid repeating the same
error message at every subsequent call to perform_context_reduction.
compiler/check_typeclass.m:
Change the way we superclass conformance for instance declarations
to take advantage of the new "DeclaredConstraints" argument to
typecheck__reduce_context_by_rule_application.
Estimated hours taken: 2
compiler/typecheck.m:
Get type inference working for type classes.
tests/hard_coded/typeclasses/Mmakefile:
tests/hard_coded/typeclasses/inference_test.m:
tests/hard_coded/typeclasses/inference_test.exp:
Add a simple test case for type class inference.
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: 45
Assorted changes to make the HLDS type and mode correct
after lambda expansion. The HLDS is still not unique mode
correct after common structure elimination.
compiler/det_analysis.m
Make sure the inferred_determinism field of the proc_info is filled
in correctly for imported procedures and class methods.
compiler/mode_util.m
Fix a bug in recompute_instmap_delta_call to do with unreachable
instmaps. This caused an abort a couple of months ago when
compiling with --deforestation (not yet committed), but
can't currently be reproduced.
compiler/hlds_pred.m
compiler/lambda.m
Add a field to the proc_info to record which args_method
should be used for this procedure. Procedures directly
called by do_call_*_closure must be compiled with
the `compact' argument convention to avoid the need to permute
the arguments so inputs come before outputs.
compiler/lambda.m
compiler/higher_order.m
Remove permutation of argument variables of lambda expressions
so the HLDS is type and mode correct and mode analysis can
be rerun. Otherwise, rerunning mode analysis will fail on
tests/hard_coded/ho_order.m.
compiler/arg_info.m
Added arg_info__ho_call_args_method which returns
an args_method which can always be directly called by
do_call_*_closure (`compact').
Added arg_info__args_method_is_ho_callable to check that
a given args_method can be directly called.
compiler/unify_gen.m
Abort if a closure is created for a procedure compiled
with the simple argument convention.
compiler/hlds_goal.m
compiler/lambda.m
Mode analysis was not storing the non-locals list on which the
uni_modes field of the construction of a lambda goal was computed.
If the nonlocals were renamed, the sort order could change, and
the non-locals could be incorrectly matched with the arguments
of the introduced lambda expression, causing a mode error. The
argument list is now stored.
This caused rerunning mode-checking on tests/valid/lazy_list.m
after polymorphism to fail.
compiler/*.m
Fill in the args_method field of proc_infos with the value
from the globals.
Handle the extra argument to the lambda_goal unify_rhs.
compiler/follow_vars.m
Remove code to handle complicated unifications, since
they should be removed by polymorphism.m.
compiler/special_pred.m
library/mercury_builtin.m
Make the uniqueness of the comparison_result argument
of builtin_compare_* and the automatically generated
comparison procedures match that of compare/3. Unique mode
errors will still be introduced if polymorphism.m specializes
calls to any of the unique modes of compare/3 and then mode analysis
is rerun, since the compiler-generated comparison procedures
only implement the (uo, in, in) mode. (This is not yet a problem
because currently we don't rerun mode analysis.)
runtime/mercury_ho_call.c
Remove code in do_call_*_closure to deal with the
`simple' args_method. Since the output arguments no longer
need to be moved, the closure call is now a tailcall.
Remove some magic numbers.
compiler/modecheck_unify.m
Avoid some aborts and mode errors when rerunning mode analysis,
especially those resulting from not_reached insts being treated
as bound.
Avoid aborting on higher-order predicate constants with multiple
modes if lambda expansion has already been run.
tests/valid/higher_order.m
Add a test case for an abort in mode analysis when
compiling with --deforestation (not yet committed),
due to a predicate constant for a procedure with multiple
modes.
tests/valid/unreachable_code.m
Add a test case for bogus higher-order unification
mode errors in unreachable code.
Estimated hours taken: 4
compiler/typecheck.m:
Move the call to perform_context_reduction out of the if-then-else so
that it gets executed even in the presence of overloading.
compiler/hlds_out.m:
Remove a redundant comment
Estimated hours taken: 3.5
Bug fix. When adding a default mode for a class method function, also add the
pred-proc-id to the class-interface.
clause_to_proc.m:
Add the new proc_id as an extra return value from
maybe_add_default_mode.
make_hlds.m:
After adding the class interface, go through and find all the func
declarations and maybe_add_default_mode to each of them, collecting
the new proc-ids to go in the class interface.
*.m:
Ignore the extra return value from maybe_add_default_mode.
Estimated hours taken: 0.1
compiler/typecheck.m:
Fix a minor bug in one of the type class error messages:
one of lines of a multi-line error messages wasn't properly indented.
Estimated hours taken: 1.5
Fix a bug, introduced by my typeclass changes, which caused typecheck.m to
abort with a software error for certain programs containing type errors.
compiler/typecheck.m:
Bring back conv_args_type_assign_set which was deleted during the
typeclass changes. Update conv_args_type_assign to apply the bindings
to the class constraints, and factor out some duplicate code between
conv_args_type_assign_set and convert_args_type_assign_set,
Change a call to convert_args_type_assign_set back to
conv_args_type_assign_set, so that it does not bomb out spuriously.
Estimated hours taken: 40
Implement nondet pragma C codes.
runtime/mercury_stacks.h:
Define a new macro, mkpragmaframe, for use in the implementation
of nondet pragma C codes. This new macro includes space for a
struct with a given sruct tag in the nondet stack frame being created.
compiler/{prog_data.m,hlds_goal.m}:
Revise the representation of pragma C codes, both as the item and
in the HLDS.
compiler/prog_io_pragma.m:
Parse nondet pragma C declarations.
Fix the indentation in some places.
compiler/llds.m:
Include an extra argument in mkframe instructions. This extra argument
gives the details of the C structure (if any) to be included in the
nondet stack frame to be created.
Generalize the LLDS representation of pragma C codes. Instead of a
fixed sequence of <assign from inputs, user c code, assign to outputs>,
let the sequence contain these elements, as well as arbitrary
compiler-generated C code, in any order and possibly with repetitions.
This flexibility is needed for nondet pragma C codes.
Add a field to pragma C codes to say whether they can call Mercury.
Some optimizations can do a better job if they know that a pragma C
code cannot call Mercury.
Add another field to pragma C codes to give the name of the label
they refer to (if any). This is needed to prevent labelopt from
incorrectly optimizing away the label definition.
Add a new alternative to the type pragma_c_decl, to describe the
declaration of the local variable that points to the save struct.
compiler/llds_out.m:
Output mkframe instructions that specify a struct as invoking the new
mkpragmaframe macro, and make sure that the struct is declared just
before the procedure that uses it.
Other minor changes to keep up with the changes to the representation
of pragma C code in the LLDS, and to make the output look a bit nicer.
compiler/pragma_c_gen.m:
Add code to generate code for nondet pragma C codes. Revise the utility
predicates and their data structures a bit to make this possible.
compiler/code_gen.m:
Add code for the necessary special handling of prologs and epilogs
of procedures defined by nondet pragma C codes. The prologs need
to be modified to include a programmer-defined C structure in the
nondet stack frame and to communicate the location of this structure
to the pragma C code, whereas the functionality of the epilog is
taken care of by the pragma C code itself.
compiler/make_hlds.m:
When creating a proc_info for a procedure defined by a pragma C code,
we used to insert unifications between the headvars and the vars of
the pragma C code into the body goal. We now perform substitutions
instead. This removes a factor that would complicate the generation
of code for nondet pragma C codes.
Pass a moduleinfo down the procedures that warn about singletons
(and other basic scope errors). When checking whether to warn about
an argument of a pragma C code not being mentioned in the C code
fragment, we need to know whether the argument is input or output,
since input variables should appear in some code fragments in a
nondet pragma C code and must not appear in others. The
mode_is_{in,out}put checks need the moduleinfo.
(We do not need to check for any variables being mentioned where
they shouldn't be. The C compiler will fail in the presence of any
errors of that type, and since those variables could be referred
to via macros whose definitions we do not see, we couldn't implement
a reliable test anyway.)
compiler/opt_util.m:
Recognize that some sorts of pragma_c codes cannot affect the data
structures that control backtracking. This allows peepholing to
do a better job on code sequences produced for nondet pragma C codes.
Recognize that the C code strings inside some pragma_c codes refer to
other labels in the procedure. This prevents labelopt from incorrectly
optimizing away these labels.
compiler/dupelim.m:
If a label is referred to from within a C code string, then do not
attempt to optimize it away.
compiler/det_analysis.m:
Remove a now incorrect part of an error message.
compiler/*.m:
Minor changes to conform to changes to the HLDS and LLDS data
structures.
Estimated hours taken: 8
Clean up the handling of unbound type variables.
Fix a bug with unbound type variables in lambda expressions.
Run purity analysis, modechecking etc. even if there were type errors.
compiler/mercury_compile.m:
Run purity analysis, modechecking etc. even if there were type
errors. This fixes a bug (inconsistency between the code and
the comments) that seems to have been introduced in stayl's
change to mercury_compile.m (revision 1.25) to add intermodule
unused argument elimination: the comment said "continue,
even if type checking found errors", but the code did not
continue.
This change was needed to ensure that we still report a warning
message about unused type variables for tests/invalid/error2.m;
without it, we stop after type checking and don't do purity
analysis, and so don't report the warning.
compiler/typecheck.m:
compiler/purity.m:
Move the code for checking for unbound type variables
from typecheck.m to purity.m. It needs to be done
*after* type inference has been completed, so it
can't be done in the ordinary type checking/inference
passes. Add code to purity.m to bind the
unbound type variables to the builtin type `void'.
compiler/polymorphism.m:
Comment out old code to bind unbound type variables
to `void'; the old code was incomplete, and this
is now done in purity.m.
compiler/notes/compiler_design.html:
Document the above changes.
tests/valid/Mmakefile:
tests/valid/unbound_tvar_in_lambda.m:
Regression test for the above-mentioned bug with unbound type
variables in lambda expressions.
tests/warnings/singleton_test.exp:
tests/invalid/errors2.err_exp:
Change the expected warning message for unbound type variables.
The error context is not as precise as it used to be, I'm afraid:
we only know which function/predicate the error occurred in,
not which clause. Also it now comes out in a different order
relative to the other error messages.
tests/invalid/errors2.err_exp:
tests/invalid/funcs_as_preds.err_exp:
Add some new error/warning messages that are output now that
we run mode and determinism analysis even if there are type errors.
Estimated hours taken: 500 or so
This change implements typeclasses. Included are the necessary changes to
the compiler, runtime and library.
compiler/typecheck.m:
Typecheck the constraints on a pred by adding constraints for each
call to a pred/func with constraints, and eliminating constraints
by applying context reduction.
While reducing the constraints, keep track of the proofs so that
polymorphism can produce the tyepclass_infos for eliminated
constraints.
compiler/polymorphism.m:
Perform the source-to-source transformation which turns code with
typeclass constraints into code without constraints, but with extra
"typeclass_info", or "dictionary" parameters.
Also, rather than always having a type_info directly for each type
variable, sometimes the type_info is hidden inside a typeclass_info.
compiler/bytecode*.m:
Insert some code to abort if bytecode generation is used when
typeclasses are used.
compiler/call_gen.m:
Generate code for a class_method_call, which forms the body of a class
method (by selecting the appropriate proc from the typeclass_info).
compiler/dead_proc_elim.m:
Don't eliminate class methods if they are potentially used outside
the module
compiler/hlds_data.m:
Define data types to store:
- the typeclass definitions
- the instances of a class
- "constraint_proof". ie. the proofs of redundancy of a
constraint. This info is used by polymorphism to construct the
typeclass_infos for a constraint.
- the "base_tyepclass_info_constant", which is analagous the
the base_type_info_constant
compiler/hlds_data.m:
Define the class_method_call goal. This goal is inserted into the
body of class method procs, and is responsible for selecting the
appropriate part of the typeclass_info to call.
compiler/hlds_data.m:
Add the class table and instance table to the module_info.
compiler/hlds_out.m:
Output info about base_typeclass_infos and class_method_calls
compiler/hlds_pred.m:
Change the representation of the locations of type_infos from "var"
to type_info_locn, which is either a var, or part of a typeclass_info,
since now the typeclass_infos contain the type_infos for the type that
they constrain.
Add constraints to the pred_info.
Add constraint_proofs to the pred_info (so that typeclass.m can
annotate the pred_info with the reasons that constraints were
eliminated, so that polymorphism.m can in turn generate the
typeclass_infos for the constraints).
Add the "class_method" marker.
compiler/lambda.m:
A feable attempt at adding class ontexts to lambda expressions,
untested and almost certainly not working.
compiler/llds_out.m:
Output the code addresses for do_*det_class_method, and output
appropriately mangled symbol names for base_typeclass_infos.
compiler/make_hlds.m:
Add constraints to the types on pred and func decls, and add
class and instance declarations to the class_table and instance_table
respectively.
compiler/mercury_compile.m:
Add the check_typeclass pass.
compiler/mercury_to_mercury.m:
Output constraints of pred and funcs, and output typeclass and instance
declarations.
compiler/module_qual.m:
Module qualify typeclass names in pred class contexts, and qualify the
typeclass and instance decls themselves.
compiler/modules.m:
Output typeclass declarations in the short interface too.
compiler/prog_data.m:
Add the "typeclass" and "instance" items. Define the types to store
information about the declarations, including class contexts on pred
and func decls.
compiler/prog_io.m:
Parse constraints on pred and func declarations.
compiler/prod_out.m:
Output class contexts on pred and func decls.
compiler/type_util.m:
Add preds to apply a substitution to a class_constraint, and to
a list of class constraints. Add type_list_matches_exactly/2. Also
add typeclass_info and base_typeclass_info as types which should not
be optimised as no_tag types (seeing that we cheat a bit about their
representation).
compiler/notes/compiler_design.html:
Add notes on module qualification of class contexts. Needs expansion
to include more stuff on typeclasses.
compiler/*.m:
Various minor changes.
New Files:
compiler/base_typeclass_info.m:
Produce one base_typeclass_info for each instance declaration.
compiler/prog_io_typeclass.m:
Parse typeclass and instance declarations.
compiler/check_typeclass.m:
Check the conformance of an instance declaration to the typeclass
declaration, including building up a proof of how superclass
constraints are satisfied so that polymorphism.m is able to construct
the typeclass_info, including the superclass typeclass_infos.
library/mercury_builtin.m:
Implement that base_typeclass_info and typeclass_info types, as
well as the predicates type_info_from_typeclass_info/3 to extract
a type_info from a typeclass_info, and superclass_from_typeclass_info/3
for extracting superclasses.
library/ops.m:
Add "typeclass" and "instance" as operators.
library/string.m:
Add a (in, uo) mode for string__length/3.
runtime/mercury_ho_call.c:
Implement do_call_*det_class_method, which are the pieces of code
responsible for extracting the correct code address from the
typeclass_info, setting up the arguments correctly, then executing
the code.
runtime/mercury_type_info.h:
Macros for accessing the typeclass_info structure.
The purpose of this diff is to allow Mercury programs to contain
impure Mercury code without the compiler changing its behavior
inappropriately, while still allowing the compiler to aggressively
optimize pure code. To do this, we require impure predicates to be so
declared, and calls to impure predicates to be flagged as such. We
also allow predicates implemented in terms of impure predicates to be
promised to be pure; lacking such a promise, any predicate that calls
an impure predicate is assumed to be impure.
At the moment, we don't allow impure functions (only predicates),
though some of the work necessary to support them has been done.
Note that to make the operators work properly, the precedence of the
`pred' and `func' operators has been changed from 1199 to 800.
Estimated hours taken: 150
compiler/purity.m:
New compiler pass for purity checking.
compiler/hlds_goal.m:
Add `impure' and `semipure' to the goal_feature enum.
compiler/hlds_out.m:
compiler/typecheck.m:
compiler/special_pred.m:
Fixed code that prints predicate name to write something more
helpful for special (compiler-generated) predicates. Added
code to print new markers. Added purity argument to
mercury_output_pred_type. New public predicate
special_pred_description/2 provides an english description for
each compiler-generated predicate.
compiler/hlds_pred.m:
Add `impure' and `semipure' to marker enum. Added new
public predicates to get predicate purity and whether or not
it's promised to be pure.
compiler/prog_data.m:
compiler/mercury_to_mercury.m:
compiler/prog_io.m:
compiler/prog_io_goal.m:
compiler/prog_io_pragma.m:
compiler/prog_io_dcg.m:
compiler/prog_util.m:
compiler/equiv_type.m:
compiler/intermod.m:
compiler/mercury_to_c.m:
compiler/module_qual.m:
Add purity argument to pred and func items. Add new `impure'
and `semipure' operators. Add promise_pure pragma. Add
purity/2 wrapper to goal_expr type.
compiler/make_hlds.m:
compiler/mercury_to_goedel.m:
Added purity argument to module_add_{pred,func},
clauses_info_add_pragma_c_code, and to pred and func items.
Handle promise_pure pragma. Handle purity/2 wrapper used to
handle user-written impurity annotations on goals.
compiler/mercury_compile.m:
Add purity checking pass between type and mode checking.
compiler/mode_errors.m:
Distinguish mode errors caused by impure goals preventing
goals being delayed.
compiler/modes.m:
Don't delay impure goals, and ensure before scheduling an
impure goal that no goals are delayed. Actually, we go ahead
and try to schedule goals even if impurity causes a problem,
and then if it still doesn't mode check, then we report an
ordinary mode error. Only if the clause would be mode correct
except for an impure goal do we report it as an impurity problem.
compiler/simplify.m:
Don't optimize away non-pure duplicate calls. We could do
better and still optimize duplicate semipure goals without an
intervening impure goal, but it's probably not worth the
trouble. Also don't eliminate impure goals on a failing branch.
compiler/notes/compiler_design.html:
Documented purity checking pass.
doc/reference_manual.texi:
Document purity system.
doc/transition_guide.texi:
library/nc_builtin.nl:
library/ops.m:
library/sp_builtin.nl:
New operators and new precdence for `pred' and `func'
operators.
tests/hard_coded/purity.m
tests/hard_coded/purity.exp
tests/hard_coded/Mmakefile:
tests/invalid/purity.m
tests/invalid/purity_nonsense.m
tests/invalid/purity.err_exp
tests/invalid/purity_nonsense.err_exp
tests/invalid/Mmakefile:
Test cases for purity.
Estimated hours taken: 0.25
compiler/typecheck.m:
Fix a couple of small bugs in language_builtin/2 (used for
printing out error messages): the arity of `\+' and `not'
is 1, not 2.
Estimated hours taken: 2
compiler/typecheck.m:
Fix a problem with certain type error messages
(the ones produced by `report_error_functor_arg_types'),
where for e.g. `F = 2.3, [1] = [F]' it was saying
basically "F has type float, expected type was T"
instead of "F has type float, expected type was int".
I have also changed the layout of the message slightly;
instead of
...
foo.m:001: The types of the relevant arguments are
foo.m:001: argument 1 (F): actual `float', expected `T'
it now reads
...
foo.m:001: Argument 1 (F) has type `float',
foo.m:001: expected type was `int'.
This is more consistent with other type error messages
and in many cases avoids line wrap.
Estimated hours taken: 3
Clean up the handling of predicate markers (flags).
compiler/hlds_pred.m:
Delete the `marker_status' type. It was just adding complexity
which wasn't being used.
Change the "markers list" field of the pred_info from a
list(marker_status) to an abstract data type representing
a set of markers.
Add new access predicates for this ADT.
Currently the ADT is still implemented as a list, but it might
be a good idea to eventually change it to be an int, using a
different bit for each flag.
compiler/dnf.m:
Don't bother to record `done(dnf)' markers, since they're not needed.
compiler/make_hlds.m:
Change add_pred_marker so that it adds a single marker, rather
than a list of markers. Allowing a list of markers was just
adding extra complexity which wasn't being used.
compiler/dnf.m:
compiler/higher_order.m:
compiler/hlds_out.m:
compiler/intermod.m:
compiler/lambda.m:
compiler/make_hlds.m:
compiler/mode_errors.m:
compiler/modecheck_call.m:
compiler/modes.m:
compiler/simplify.m:
compiler/stratify.m:
compiler/term_util.m:
compiler/termination.m:
compiler/typecheck.m:
compiler/unused_args.m:
Update to use the new ADT.
Estimated hours taken: 2
compiler/options.m:
Add new options `--mode-inference-iteration-limit'
and `--type-inference-iteration-limit'.
compiler/typecheck.m:
Only perform a finite number of iterations of type inference,
to work around infinite loops for preds such as `p(p)'.
compiler/modes.m:
Use the new option rather than a hard-coded limit.
doc/user_guide.texi:
Document the new options.
Estimated hours taken: 2
Fix the handling of copy/2.
library/mercury_builtin.m:
Implement copy/2 properly, using deep_copy().
Add unsafe_promise_unique/2 with the same semantics
as the old copy/2.
library/io.m:
library/set_bbbtree.m:
compiler/handle_options.m:
compiler/typecheck.m:
compiler/mode_info.m:
Change some occurrences of copy/2 to call unsafe_promise_unique/2.
library/io.m:
Change io__get_stream_names and io__set_stream_names to not
use unique modes (this seems the simplest way for the moment
of avoiding some ugly calls to unsafe_promise_unique).
Estimated hours taken: 4
compiler/typecheck.m:
Emit better error messages when the type of a function symbol is known
and some of the arguments have the wrong type.
tests/invalid/type_mismatch.{m,err_exp}:
A new test case to exercise the new error messages.
tests/invalid/Mmakefile:
Enable the new test case.
Estimated hours taken: 2
Fix a bug: the compiler was not checking for unbound inst variables
in mode declarations.
compiler/typecheck.m:
compiler/inst_match.m:
Add code to check for unbound inst variables.
tests/invalid/Mmake:
tests/invalid/unbound_inst_var.m:
tests/invalid/unbound_inst_var.err_exp:
Regression test.