library/io.m:
Add a version of io.write_line_cc that takes an explicit stream argument.
NEWS:
Announce the addition.
browser/interactive_query.m:
Use the new predicate.
library/hash_table.m:
library/stream.string_writer.m:
Fix code where a mode specialization (i.e. the specification of
a particular input function symbol for an argument) was applied
to the wrong argument.
library/random.system_rng.m:
Shift most of the #includes into a local foreign_decl pragma
so that they do not get included in the .mh file.
Position the C# and Java foreign code pragmas to the end of the file,
with the C one.
library/random.system_rng.m:
Document what sources of randomness are used by the C backends.
library/MODULES_DOC:
library/MODULES_UNDOC:
Include random.system_rng module in the library documentation.
NEWS:
Announce the random.system_rng module.
Ensure it is not possible to use a system RNG handle after it has been closed
with the arc4random() and rand_s() based implementations.
library/random.system_rng.m:
As above.
Ensure it is not possible to use a system RNG handle after it has been closed
in the C# and Java grades. This brings the implementation for these backends
into line with the /dev/urandom implementation on C. (The other C implementation
will be made to conform in a separate change.)
library/random.system_rng.m:
Add wrapper classes around the C# and Java system RNGs that allow
us to track if they have already been closed.
On Windows we implement the system RNG by calling the CRT's rand_s() function.
library/random.system_rng.m:
Implement the system RNG on Windows using rand_s().
runtime/mercury_std.h:
On Windows define the macro _CRT_RAND_S before the initial
inclusion of stdlib.h -- we must do this otherwise the declaration
of rand_s() will not be visible.
library/random.system_rng.m:
As above.
Use the arc4random() based implementation on FreeBSD >= 12.0
and macOS >= 10.12, falling back to the urandom approach on earlier
versions.
Always use the arc4random() approach on NetBSD and OpenBSD,
both of which have used ChaCha20 in their implementation
of arc4random() since 2014.
Add a system RNG implementation for the C backends that works by
reading random bits from /dev/urandom. We use this on Linux,
AIX and Solaris.
library/random.system_rng.m:
Add two implementations of the system RNG for the C backends, one that
reads from /dev/urandom and one that just aborts. The former is used
on Linux and the latter is used everywhere else (for now).
This is work-in-progress, currently only the C# and Java backends
are supported. Support for the C backends will be added separately.
library/random.system_rng.m:
A new submodule containing the system RNG.
library/random.m:
library/library.m:
Include the new submodule.
library/MODULES_UNDOC:
Do not generate documentation for the new submodule.
library/string.m:
We long had uint_to_hex_string and uint_to_uc_hex_string. Add
uint_to_lc_hex_string as well, and make uint_to_hex_string call it.
This way, users don't have to remember which of the upper and lower
case versions is defined, and which is missing.
Do the same for the 64 bit version.
NEWS:
Announce the new functions.
library/string.format.m:
Call the new functions.
This fix uses the approach discussed on m-dev 2020 nov 16/17 for fixing
github issue #72, whose core problem is a need for information flow
back to a the caller from a callee when the callee fills in the
argument of a function symbol whose representation is a direct_arg tag.
In most cases when the callee fills in the value of an argument,
the caller can see it because the argument is in a word on the heap,
but when the function symbol uses a direct_arg tag, that is not the case.
compiler/direct_arg_in_out.m:
A new module that implements the transformation proposed on m-dev.
It creates a fresh clone variable every time an argument of a direct_arg
tag function symbol is (or may be) updated. This can happen several
times if a type has more than one function symbol with a direct_arg tag.
Since the affected variable can be bound to only one function symbol
at the start, its argument can be filled in only once, but the
compiler cannot know in advance what function symbol the variable
contains, and therefore which of the possibly several fill-in sites
(which fill in the arguments of different function symbols) executed
in sequence will actually update the variable.
The transformation ensures that once a variable is cloned, it is
never referred to again. It also ensures that in a branched control
structure (if-then-else, disjunction or switch), all branches will use
the *same* variable to represent the latest version of each cloned
variable at the end, so that following code has a consistent view
regardless of through which branch execution has reached it.
There are three situations that the transformation cannot and does not
handle.
1. Situations in which the mode of an argument is either an inst variable,
or an abstract inst. In either case, the pass cannot know whether
it should apply its transformation to the argument.
2. Situations where a procedure that has such an argument is
exported to C code as a function. In that case, the C signature
of the function we would generate would be different from what
the user would normally expect. We could modify the documentation
of the export pragma, but I don't think there much point due to
lack of demand. (The problem cannot arise when targeting any language
other than C, because we use direct_arg tags only with the low level
data representation, which we only use for C.)
3. Situations where a procedure that has such an argument is defined
by foreign_proc. Again, dealing with the problem would require
nontrivial changes to the documented interface between code in
foreign_procs and the surrounding Mercury code, and I see no demand
for code that could benefit from that.
In these cases, this module generates error messages.
compiler/transform_hlds.m:
Include the new module in the transform_hlds package.
Delete unnecessary module qualification on some existing inclusions.
Put some existing inclusions into a more meaningful order.
compiler/notes/compiler_design.html:
Document the new pass. Fix some nearby prose.
compiler/lambda.m:
compiler/simplify_proc.m:
Use a predicate exported by direct_arg_in_out.m to test, for each
procedure, whether the procedure has any argument positions that are
subject to the problem that direct_arg_in_out.m addresses.
simplify_proc.m does this for all procedures it processes;
lambda.m does this for all the procedures it creates from
lambda expressions.
Give a predicate in simplify_proc.m a better name.
Sort a list of predicate names.
compiler/hlds_module.m:
Add a field to the module_info that simplify_proc.m and lambda.m
can use to tell direct_arg_in_out.m what work (if any) it needs to do.
compiler/mercury_compile_middle_passes.m:
Invoke direct_arg_in_out.m if the new field in the HLDS indicates
that it has some work to do. (In the vast majority of compiler invocations,
it won't have any.)
compiler/hlds_pred.m:
The new code in direct_arg_in_out.m creates a clone of each procedure
affected by the problem, before deleting the originals (to make sure that
no references to the unfixed versions of now-fixed procedures remain.)
Make it possible to create exact clones of both predicates and procedures
by adding two pairs of predicates, {pred,proc}_prepare_to_clone and
{pred,proc}_create.
Add the direct_arg_in_out transformation as a possible source
of transformed predicates.
library/private_builtin.m:
Add a new builtin operation, partial_inst_copy, that the new module
generates calls to.
configure.ac:
Require the installed compiler to recognize partial_inst_copy
as a no_type_info builtin.
compiler/builtin_ops.m:
Recognize the new builtin. (This was committed before the rest; the diff
to private_builtin.m can be done only once the change to builtin_ops.m
is part of the installed compiler.)
compiler/options.m:
Add a way to test whether the builtin_ops.m in the installed compiler
recognizes the new builtin.
compiler/dead_proc_elim.m:
Do not delete the new primitive before direct_arg_in_out.m has had
a chance to generate calls to it.
Add an XXX.
compiler/error_util.m:
Recognize the new module as a source of error messages.
compiler/pred_table.m:
Add a pair of utility predicates to be used when looking up
builtin predicates, for which the compiler writer knows that
there should be exactly one match. These are used in direct_arg_in_out.m.
compiler/simplify_goal_call.m:
Replace some existing code with calls to the new predicates
in pred_table.m.
compiler/hlds_goal.m:
Add modes to rename_vars_in_goal_expr that express the fact
that when an atomic goal_expr has some variables renamed inside it,
it does not suddenly become some *other* kind of goal_expr.
New code in direct_arg_in_out.m relies on this.
compiler/hlds_out_goal.m:
When the HLDS we are dumping out is malformed because it contains
calls to predicates that have been deleted, the compiler used to abort
at such calls. (I ran into this while debugging direct_arg_in_out.m.)
Fix this. When such calls are encountered, we now print out as much
information we can about the call, and prefix the call with an
unmistakable prefix to draw attention to the problem.
compiler/inst_util.m:
Fix a bug that prevented direct_arg_in_out.m from even being invoked
on some test code for it.
The bug was in code that we use to unify a headvar's initial inst
with its final inst. When the initial inst was a non-ground bound_inst
such as the ones used in tests/hard_coded/gh72.m, and the final inst
was simply "ground", this code quite properly returned a bound_inst
(which, unlike ground, can show the exact set of function symbols
that the headvar could be bound to). The problem was that it
reused the original bound_inst's test results, including the one
that said the final inst is NOT ground, which of course is wrong
for any inst unified with ground. Fix two instances of this bug.
compiler/modes.m:
Make some of the code I had to traverse to find the bug in inst_util.m
easier to read and understand.
Replace some uses of booleans with bespoke enum types.
Change the argument lists of some predicates to put related arguments
next to each other.
Give some variables more descriptive names.
compiler/layout_out.m:
Conform to the change in hlds_pred.m.
compiler/var_locn.m:
Fix a code generation bug. When filling-in the value of the argument
of a function symbol represented by a direct_arg tag, the code we
generated for it worked only if the direct_arg tag used 0
as its ptag value. In the test cases we initially used for
github issue 72, that was the case, but the new tests/hard_coded/gh72.m
has direct_tag args that use other ptag values as well.
Document the reason why the updated code works.
compiler/term_constr_initial.m:
Add the new primitive predicate added to private_builtin.m,
partial_inst_copy, to a table of builtins that do not take type_infos,
even though their signatures contain type variables.
Fix a bunch of old bugs: most other such primitives were not listed
either.
mdbcomp/program_representation.m:
Add partial_inst_copy to the master list of builtins that do not take
type_infos even though their signatures contain type variables. (Done
by an earlier commit.)
Document the fact that any updates here require updates to
term_constr_initial.m.
library/multi_map.m:
We have long had multi_map.add and multi_map.set as synonyms,
but we only had multi_map.reverse_set. Add multi_map.reverse_add
as a synonym for it.
Define the "set" versions in terms of the "add" versions,
instead of vice versa.
NEWS:
Document the new predicates in multi_map.m.
tests/hard_coded/gh72a.m:
Fix typo.
tests/hard_coded/gh72.{m,exp}:
A new, much more comprehensive test case than gh72a.m.
This one tries to tickle github issue 72 in as many forms of code
as I can think of.
tests/invalid/gh72_errors.{m,err_exp}:
A test case for testing the generation of error messages for
two out of the three kinds of situations that direct_arg_in_out.m
cannot handle. (Proposals for how to test the third category welcome.)
tests/hard_coded/Mmakefile:
tests/invalid/Mmakefile:
Enable the two new test cases, as well as two old ones, gh72[ab].m,
that previously we didn't pass.
tests/invalid/Mercury.option:
Do not compile gh72_error.m with --errorcheck-only, since its errors
are reported by a pass that --errorcheck-only does not invoke.
Zoltan's recent addition of support for formatting fixed size integer types
using string.format and friends works by casting the fixed size integer value
to an int or uint value and then re-using the existing code we already have for
formatting those. This works in all cases except when formatting 64-bit integer
types on systems where int / uint is a 32-bit quantity (notably, both the C#
and Java backends). This diff lifts that restrictions.
library/string.format.m:
Add support for formatting 64-bit integers without having to cast them
to an int or uint.
Export new format predicates for use by the code generated by
compiler/format_call.m.
compiler/format_call.m:
Generate calls to the 64-bit versions of the format_*_component predicates
where necessary.
compiler/simplify_proc.m:
Update the list of predicates that may be introduced by the compiler.
NEWS:
Delete the mention of the restriction.
tests/hard_coded/opt_format.{m,exp}:
Extend this test to cover 64-bit integers.
library/string.m:
Add functions for converting uint64s to strings of base 8 or base 16
digits. For most integer types we can cast to a uint and then use the
uint versions of these operations but for 64-bit types we cannot since
on some of our supported platforms uints are 32-bit.
NEWS:
Announce the additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/uint64_string_conv.{m,exp}:
Add a test of the new functions.
When library/store.m was compiled with LIBRARY_INTERMODULE = no,
it used to get these warnings:
store.m:264: Warning: predicate `store_equal'/2 mode 0 is never called.
store.m:270: Warning: predicate `store_compare'/3 mode 0 is never called.
The reason was that
- the only places that refer to these predicates are the "where equality is"
and "where comparison is" clauses of the foreign type definitions
for the store/1 type constructor,
- when the compiler constructs the unify and compare predicates for store/1,
it is supposed to make them call store_equal and store_compare respectively,
- BUT store/1 is listed as a builtin dummy type, along with io.state.
They are indeed dummy types in the sense that they don't need any
representation, but they are NOT dummy types in the sense that
they have one function symbol which is a constant.
- Nevertheless, because of this, the unify and compare predicates for store/1
used to get a clause body that always succeeds, since that is what is
appropriate for a type that has one function symbol which is a constant.
For I/O states, this does not matter, since the in,in mode of the arguments
of the unify and compare predicates means that any I/O state being compared
cannot be used either as a di input or as a uo output, so such erroneous
comparisons would always have been detected, though the error message
would have been misleading. For stores, any attempts to unify or compare them
would have silently succeeded. Even though store_equal and store_compare
were designed to abort the program in such an event, the old, wrong code in
unify_proc.m meant that they were never called.
This meant that store_equal and store_compare were never called, but with
intermodule optimization turned on (the default), the fact that the
foreign_type pragmas were opt_exported had suppressed such warnings.
library/io.m:
Specify clones of store_equal and store_compare as the type-specific
unify and compare predicates for I/O states.
compiler/unify_proc.m:
Now that both builtin dummy type ctors have type-specific unify
and compare predicates that always abort, construct their overall
unify and compare predicates from them; do not special case them.
Note a potential problem with applying an equality pre-test in
user-specified unify and compare predicates that always abort.
This includes io.state/0 and store.store/1, but may also include
other type constructors.
Currently, the Mercury implementation of string formatting handles uints by
casting them to ints and then using the code for formatting signed integers as
unsigned values. Add an implementation that works directly on uints and make
the code that formats signed integers as unsigned integers use that instead.
The new implementation is simpler and avoids unnecessary conversions to
arbitrary precision integers.
Add new functions for converting uint values directly to octal and hexadecimal
strings that use functionality provided by the underlying platforms; replace
the Mercury code that previously did that with calls to these new functions.
library/string.m:
Add the functions uint_to_hex_string/1, uint_to_uc_hex_string/1 and
uint_to_octal_string/1.
library/string.format.m:
Make format_uint/6 operate directly on uints instead of casting the value
to a signed int and calling format_unsigned_int/6.
Make format_unsigned_int/6 cast the int value to a uint and then call
format_uint/6.
Delete predicates and functions used to convert ints to octal and
hexadecimal strings. We now just use the functions exported by
the string module.
NEWS:
Announce the additions to the string module.
tests/hard_coded/Mmakefile:
tests/hard_coded/uint_string_conv.{m,exp*}:
Add a test of uint string conversion.
Right now, most parts of the compiler write to the "current output stream".
This was a pragmatic choice at the time, but has not aged well. The problem
is that the answer to the question "where is the current output stream going?"
is not obvious in *all* places in the compiler (although it is obvious in
most). When using such implicit streams, finding where the output is going
to in a given predicate requires inspecting not just the ancestors of that
predicate, but also all their older siblings (since any of them could have
changed the current stream), *including* their entire call trees. This is
usually an infeasible task. By constrast, if we explicitly pass streams
to all output operations, we need only follow the places where the variable
representing that stream is bound, which the mode system makes easy.
This diff switches large parts of the compiler over to doing output only
to explicitly passed streams, never to the implicit "current output stream".
The parts it switches over are the parts that rely to a significant degree
on the innermost change, which is to the "output" typeclass in
parse_tree_out_info.m. This is the part that has to be switched over to
explicit streams first, because (a) many modules such as mercury_to_mercury.m
rely on the output typeclass, and (b) most other modules that do output
call predicates in these modules. Starting anywhere else would be like
building a skyscraper starting at the top.
This typeclass, output(U), has two instances: output(io), and output(string),
so you could output either to the current output stream, or to a string.
To allow the specification of the destination stream in the first case,
this diff changes the typeclass to output(S, U) with a functional dependency
from U to S, with the two instances being output(io.text_output_stream, io)
and output(unit, string). (The unit arg is ignored in the second case.)
There is a complication with the output typeclass method, add_list, that
outputs a list of items. The complication is that each item is output
by a predicate supplied by the caller, but the separator between the items
(usually a comma) is output by add_list itself. We don't want to give
callers of this method the opportunity to screw up by specifying (possibly
implicitly) two different output streams for these two purposes, so we want
(a) the caller to tell add_list where to put the separators, and then
(b) for add_list, not its caller, tell the user-supplied predicate what
stream to write to. This works only if the stream argument is just before
the di,uo pair of I/O state arguments, which differs from our usual practice
of passing the stream at or near the left edge of the argument list,
not near the right. The result of this complication is that two categories
of predicates that are and are not used to print items in a list differ
in where they put the stream in their argument lists. This makes it easy
to pass the stream in the wrong argument position if you call a predicate
without looking up its signature, and may require *changing* the argument
order when a predicate is used to print an item in a list for the first time.
A complete switch over to always passing the stream just before !IO
would fix this inconsistency, but is far to big a change to make all at once.
compiler/parse_tree_out_info.m:
Make the changes described above.
Add write_out_list, which is a variant of io.write_list specifically
designed to address the "complication" described above. It also has
the arguments in an order that is better suited for higher-order use.
Make the same change to argument order in the class method add_list
as well.
Almost all of the following changes consist of passing an extra stream
argument to output predicates. In some places, where I thought this would
aid readability, I replaced sequences of calls to output predicates
with a single io.format.
compiler/prog_out.m:
This module had many predicates that wrote things to the current output
stream. This diff adds versions of these predicates that take an
explicit stream argument.
If the originals are still needed after the changes to the other modules,
keep them, but add "_to_cur_stream" to the end of their names.
Otherwise, delete them. (Many of the changes below replace
write_xyz(..., !IO) with io.write_string(Stream, xyz_to_string(...), !IO),
especially when write_xyz did nothing except call xyz_to_string
and wrote out the result.)
compiler/c_util.m:
Add either an explicit stream argument to the argument list, or a
"_current_stream" suffix to the name, of every predicate defined
in this module that does output.
Add a new predicate to print out the block comment containing
input for mkinit. This factors out common code in the LLDS and MLDS
backends.
compiler/name_mangle.m:
Delete all predicates that used to write to the current output stream,
after replacing them if necessary with functions that return a string,
which the caller can print to wherever it wants. (The "if necessary"
part is there because some of the "replacement" functions already
existed.)
When converting a proc_label to a string, *always* require the caller
to say whether the label prefix should be added to the string,
instead of silently assuming "yes, add it", as calls to one of the old,
now deleted predicates had it.
compiler/file_util.m:
Add output_to_file_stream, a version of output_to_file which
simply passes the output file stream it opens to the predicate
that is intended to define the contents of the newly created or
updated file. The existing output_to_file, which instead sets
and resets the current output stream around the equivalent
predicate call, is still needed e.g. by the MLDS backend,
but hopefully for not too long.
compiler/mercury_to_mercury.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_clause.m:
compiler/parse_tree_out_inst.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_tree_out_pred_decl.m:
compiler/parse_tree_out_term.m:
compiler/parse_tree_out_type_repn.m:
Change the code writing out parse trees to explicitly pass a stream
to every predicate that does output.
In some places, this allows us to avoid changing the identity
of the current output stream.
compiler/hlds_out.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_mode.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/intermod.m:
Change the code writing out HLDS code to explicitly pass a stream
to every predicate that does output. (The changes to these modules
belong in this diff because these modules call many of the output
predicates in the parse tree package.)
In hlds_out_util.m, delete some write_to_xyz(...) predicates that wrote
the result of xyz_to_string(...) to the current output stream.
Replace calls to the deleted predicates with calls to io.write_string
with the string being written being computed by xyz_to_string.
Add a predicate to hlds_out_util.m that outputs a comment containing
the current context, if it is valid. This factors out code that used
to be common to several of the other modules.
In a few places in hlds_out_module.m, the new code generates a
slighly different set of blank lines, but this should not be a problem.
compiler/layout_out.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_global.m:
compiler/llds_out_instr.m:
compiler/llds_out_util.m:
compiler/opt_debug.m:
compiler/rtti_out.m:
Change the code writing out the LLDS to explicitly pass a stream
to every predicate that does output. (The changes to these modules
belong in this diff because layout_out.m and rtti_out.m call
many of the output predicates in the parse tree package,
and through them, the rest of the LLDS backend is affected as well.)
compiler/make.module_dep_file.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
Replace code that sets and resets the current output stream
with code that simply passes an explicit output stream to a
predicate that now *takes* an explicit stream as an argument.
compiler/accumulator.m:
compiler/add_clause.m:
compiler/code_gen.m:
compiler/code_loc_dep.m:
compiler/cse_detection.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/error_msg_inst.m:
compiler/export.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/ite_gen.m:
compiler/lco.m:
compiler/liveness.m:
compiler/lp_rational.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_c_global.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/optimize.m:
compiler/passes_aux.m:
compiler/pd_debug.m:
compiler/pragma_c_gen.m:
compiler/proc_gen.m:
compiler/prog_ctgc.m:
compiler/push_goals_together.m:
compiler/rat.m:
compiler/recompilation.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/rtti.m:
compiler/saved_vars.m:
compiler/simplify_goal_conj.m:
compiler/stack_opt.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.domain.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/superhomogeneous.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_pass2.m:
compiler/term_constr_util.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/unneeded_code.m:
compiler/write_deps_file.m:
Conform to the changes above, mostly by passing streams explicitly.
compiler/hlds_dependency_graph.m:
Conform to the changes above, mostly by passing streams explicitly.
Move a predicate's definition next it only use.
compiler/Mercury.options:
Specify --warn-implicit-stream-calls for all the modules in which
this diff has replaced all implicit streams with explicit streams.
(Unfortunately, debugging this diff has shown that --warn-implicit-
stream-calls detects only *some*, and not *all*, uses of implicit
streams.)
library/term_io.m:
Fix documentation.
library/string.m:
Add {i,u}{8.16,32,64} as function symbols in the poly_type type,
each with a single argument containing an integer with the named
signedness and size.
The idea is that each of these poly_type values works exactly
the same way as the i(_) poly_type (if signed) or the u(_) poly_type
(if unsigned), with the exception that the value specified by the call
is cast to int or uint before being processed.
library/string.parse_runtime.m:
Parse the new kinds of poly_types. Change the representation of the result
of the parsing to allow recording of the sizes of ints and uints.
Put the code that does the parsing into a predicate of its own.
library/string.format.m:
Do a cast to int or uint if the size information recorded in the
specification of a signed or unsigned integer value calls for it.
Provide functions to do the casting that do not require the import
of {int,uint}{8,16,32,64}.m. This is to allow the compiler to generate
calls to do such casts without having to implicitly import those modules.
Abort if a 64 bit number is being cast to a 32 bit word.
compiler/parse_string_format.m:
Make the same changes as in string.parse_runtime.m, mutatis mutandis.
compiler/format_call.m:
Handle the new kinds of poly_types by adding a cast to int or uint
if necessary, using the predicates added to library/string.format.m.
Use a convenience function to make code creating instmap deltas
more readable.
library/io.m:
library/pprint.m:
library/string.parse_util.m:
tests/invalid/string_format_bad.m:
tests/invalid/string_format_unknown.m:
Conform to the changes above.
tests/string_format/string_format_d.m:
tests/string_format/string_format_u.m:
Test the printing of some of the new poly_types.
tests/string_format/string_format_d.exp2:
tests/string_format/string_format_u.exp2:
Update the expected output of these tests on 64-bit platforms.
tests/string_format/string_format_lib.m:
Update programming style.
library/rtti_implementation.m:
Make dummy definition of pseudo_type_info be a wrapper around
c_pointer. This is consistent with the dummy definitions of
type_ctor_info, type_info, typeclass_info, etc.
(Note: originally pseudo_type_info was defined as a true dummy type,
before being changed to a wrapper around int. I think it was a
mistake to use a true dummy type as pseudo_type_infos are not
supposed to be all the same.)
Make the stub definition of get_pti_from_arg_types compile without
constructing a dummy pseudo_type_info.
library/*.m:
Delete Erlang foreign code and foreign types.
Delete documentation specific to Erlang targets.
library/deconstruct.m:
Add pragma no_determinism_warning to allow functor_number_cc/3
to compile for now.
library/Mercury.options:
Delete workaround only needed when targetting Erlang.
browser/listing.m:
mdbcomp/rtti_access.m:
Delete Erlang foreign code and foreign types.
library/varset.m:
Provide a capability to delete the names of variables,
either individually, or en masse.
Unrelated change: replace two clauses with a switch.
NEWS:
Document the new functionality in varset.m.
compiler/convert_parse_tree.m:
Use the new functionality to delete the name of every variable
that has a default name in a clause in a .opt file. Document why
we do this.
... using an approach proposed by Peter, with an extra twist from Julien.
Instead of having two modules, getopt.m and getopt_io.m, with the former
defining predicates that do not take an I/O state pair, and the latter
defining predicates that do take an I/O state pair, put both kinds of
predicates into a single module. The versions with an I/O state pair
have an "_io" suffix added to their names for disambiguation.
Both versions are a veneer on top of a common infrastructure,
which relies on a simple type class to implement the operation
"give the contents of the file with this name". The predicate versions
with I/O state pairs have a normal implementation of this typeclass,
while the predicate versions that do not have I/O state pairs
have an implementation that always returns an error indication.
The above change just about doubles the number of exported predicates.
We already had two versions of most exported predicates that differed
in whether we returned errors in the form of a string, or in the form
of a structured representation, with names of the latter having
an "_se" suffix. Since we agreed that the structured representation
is the form we want to encourage, this diff deletes the string versions,
and deletes the "_se" suffix from the predicate names that used to have them.
(It still remains at the end of the name of a type.) This "undoubling"
should offset the effect of the doubling in the previous paragraph.
Eventually, we want to have just one module, getopt.m, containing
the updated code described above, but for now, we put the same code
into both getopt_io.m and getopt.m to prevent too big a shock to
people with existing code that uses getopt_io.m.
library/getopt.m:
library/getopt_io.m:
Make the changes described above.
library/Mmakefile:
Instead of building both getopt_io.m and getopt.m from getopt_template,
build getopt.m from getopt_io.m.
tools/bootcheck:
Delete references to getopt_template.
compiler/typecheck_errors.m:
When a type error involves one of the getopt/getopt_io predicates
whose interfaces are changed by this diff, tell the user about
how these changes could have caused the error, and thus what the
probable fix is.
compiler/handle_options.m:
browser/parse.m:
deep_profiler/mdprof_cgi.m:
deep_profiler/mdprof_create_feedback.m:
deep_profiler/mdprof_dump.m:
deep_profiler/mdprof_procrep.m:
deep_profiler/mdprof_report_feedback.m:
deep_profiler/mdprof_test.m:
profiler/mercury_profile.m:
slice/mcov.m:
slice/mdice.m:
slice/mslice.m:
slice/mtc_diff.m:
slice/mtc_union.m:
tests/hard_coded/space.m:
Use the updated getopt interface.
compiler/compile_target_code.m:
compiler/compute_grade.m:
compiler/deforest.m:
compiler/det_report.m:
compiler/format_call.m:
compiler/globals.m:
compiler/goal_expr_to_goal.m:
compiler/make.build.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/mercury_compile_main.m:
compiler/ml_top_gen.m:
compiler/module_cmds.m:
compiler/op_mode.m:
compiler/optimization_options.m:
compiler/options.m:
compiler/write_module_interface_files.m:
tools/make_optimization_options_middle:
tools/make_optimization_options_start:
Replace references to getopt_io.m with references to getopt.m.
tests/invalid/getopt_io_old.{m,err_exp}:
tests/invalid/getopt_old.{m,err_exp}:
tests/invalid/getopt_old_se.{m, err_exp}:
New test cases for the extra help
tests/invalid/Mmakefile:
Enable the new test cases.
library/array2d.m:
Add lookup and unsafe_lookup, in both function and predicate forms,
as alternatives to rafe's ^elem notation.
Use meaningful variable names in both code and documentation.
For example, use NumRows and NumColumns instead of M and N.
Replace the implementation of the function that converts a 2d array
back to lists. The new implementation has one loop over rows and one
loop over columns, while the old one had a single loop that did
both jobs. The new one returns [] (meaning no rows) for a 0x0 array,
while the old returned [[]] (meaning one row with no columns).
NEWS:
Announce the changes.
tests/hard_coded/test_array2d.m:
Use a lookup instead of ^elem.
tests/hard_coded/test_array2d.exp:
Expect the updated output from lists. Expect any exceptions to come
from lookup functions, not ^elem functions (since the latter now
just call the former).
library/getopt_template:
Avoid mutual recursion between process_arguments and handle_long_option.
This is not for performance, since for getopt that is not important,
but to make handle_long_option do *only* what its name says it does.
The handle_short_option and handle_negated_option predicates already do
only what their names say they do, so this change also improves uniformity.
This implements Mantis feature request #495.
NEWS:
Announce the change.
compiler/optimization_options.m:
A new module for managing optimization options.
It defines a separate bespoke type for every boolean optimization option
to make it harder to confuse them. It defines a tuple type (opt_tuple)
for accessing optimization options quickly. It implements the turning on
(but NOT turning off) of optimizations when a given optimization level
is selected.
tools/make_optimization_options_middle:
tools/make_optimization_options_db:
The script that generates the meat of optimization_options.m,
and the database of option names, kinds and initial values
that it uses as its input. The script also generates some code
for the special_handler predicate in compiler/options.m.
tools/make_optimization_options_start:
tools/make_optimization_options_end:
The handwritten initial and final parts of optimization_options.m.
tools/make_optimization_options:
The script that pulls these parts together to form optimization_options.m.
compiler/options.m:
Make every optimization option a special option, to be handled by
the special_handler predicate. That handling consists of simply
adding a representation of the option to the end of a cord of
optimization options, to be processed later by optimization_options.m.
That processing will record the values of these options in the opt_tuple,
which is where every other part of the compiler should get them from.
Change the interface of special_handler to make the above possible.
Add an "optopt_" (optimization option) prefix to the name of
every optimization option, to make them inaccessible to the rest
of the compiler under their old name, and thus help enforce the switch
to using the opt_tuple. Any access to these options to look up
their values would fail anyway, since the option data would no longer be
e.g. bool(yes), but bool_special, but the name change makes this failure
happen at compile time, not runtime.
Reclassify a few options to make the above make sense. Some options
(unneeded_code_debug, unneeded_code_debug_pred_name, and
common_struct_preds) were classified as oc_opt even though they
control only the *debugging* of optimizations, while some options
(c_optimize and inline_alloc) were not classified as oc_opt
even though we do set them automatically at some optimization levels.
Delete the opt_level_number option, since it was not used anywhere.
Delete the code for handling -ON and --opt-space, since that is now
done in optimization_options.m.
Add some XXXs.
compiler/handle_options.m:
Switch to using getopt_io.process_options_userdata_se, as required
by the new interface of the special_handler in options.m.
In the absence of errors, invoke optimization_options.m to initialize
the opt_tuple. Then update the opt_tuple incrementally when processing
option implications that affect optimization options.
compiler/globals.m:
Put the opt_tuple into a new field of the globals structure.
compiler/accumulator.m:
compiler/add_pragma_type_spec.m:
compiler/add_trail_ops.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/compile_target_code.m:
compiler/const_struct.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/disj_gen.m:
compiler/erl_code_gen.m:
compiler/format_call.m:
compiler/global_data.m:
compiler/grab_modules.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/ite_gen.m:
compiler/jumpopt.m:
compiler/libs.m:
compiler/llds_out_code_addr.m:
compiler/llds_out_data.m:
compiler/llds_out_file.m:
compiler/llds_out_instr.m:
compiler/llds_out_util.m:
compiler/matching.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_disj_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_optimize.m:
compiler/ml_proc_gen.m:
compiler/ml_simplify_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen_construct.m:
compiler/optimize.m:
compiler/pd_util.m:
compiler/peephole.m:
compiler/polymorphism.m:
compiler/proc_gen.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_scope.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/simplify_tasks.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/tag_switch.m:
compiler/tupling.m:
compiler/unify_gen_construct.m:
compiler/unneeded_code.m:
compiler/unused_args.m:
Conform to the changes above, mostly by looking up optimization options
in the opt_tuple. In some places, replace bools containing optimization
options with the bespoke type of that specific optimization option.
library/getopt_template:
Fix a bug that screwed up an error message.
The bug happened when processing a --file option. If one of the
options in the file was a special option whose special handler failed,
the code handling that failing option returned both an error indication,
and the rest of the argument list read in from the file. The code
handling the --file option then *ignored* the error indication from
the failed special option, and returned an error message of its own
complaining about the unconsumed remaining arguments in the file,
believing them to be non-option arguments, even though these arguments
were never looked it to see if they were options.
The fix is for the code handling --flag options to check whether
the code processing the file contents found any errors, and if so,
return that error *without* looking at the list of remaining arguments.
In an unrelated change, factor out a duplicate call.
library/Mmakefile:
Ensure that getopt.m and getopt_io.m are built in freshly checked out
workspaces before starting making the dependencies.
Include getopt_template as a source file when building the tags file.
tools/bootcheck:
Copy getopt_template to the stage 2 and 3 libraries, to allow
the rule for ensuring the existence of the tags file to work.
library/getopt_template:
Traditionally, we never returned an option table if option processing
found an error. This diff makes process_options_userdata{,_se} return
an option table even in the presence of such errors. The table returned
will reflect the options processed up to but not including the option
that was found to be in error.
----------------------------------------------------------------------------
The previous diff that this diff was built upon was accidentally committed
together with an unrelated change, whose log message naturally did not
document it. Here is the log message that was intended to go with it.
Build getopt.m and getopt_io.m from a template.
library/getopt_template:
Pretty much all changes in getopt.m have to be made to getopt_io.m as well,
and vice versa. By replacing both with this single new file from which
we can automatically generate both getopt.m and getopt_io.m, we avoid
the need for double maintenance.
library/getopt.m:
library/getopt_io.m:
Delete both files from git, though both will still exist in workspaces.
library/Mmakefile:
Add a phony rule named apply_getopt_template, intended to be invoked
only manually, for building getopt.m and getopt_io.m from getopt_template.
compiler/notes/c_coding_standard.html:
Describe module header comments just once, not twice.
Expand on what may be in such comments.
Fix some oversights. For example, until now we didn't say that
a developer needs git (!), and we didn't say where the definitions,
as opposed to declarations, of any global variables exported from
a module should go.)
Improve the wording of several explanations.
Make some lists of things into item lists.
Expand tabs.
compiler/notes/glossary.html:
Describe what HLDS, LLDS and MLDS mean in more detail.
compiler/notes/overall_design.html:
Delete the reference to the long-deleted analysis directory.
compiler/notes/allocation.html:
compiler/notes/reviews.html:
compiler/notes/upgrade_boehm_gc.html:
Fix indentation.
library/getopt_io.m:
Add process_options_userdata/process_options_userdata_se, which
allow callers to specify special option handlers that have
state threaded through them.
Generalize the internal infrastructure of getopt_io.m to support this.
Replace a multi-clause predicate with a single big disjunction
to make changes to the argument list easier.
Put related arguments next to each other. Give some variables
more appropriate names. Use state variables where relevant.