library/string.format.m:
Delete the old predicates for formatting ints as unsigned values;
these are now unused.
configure.ac:
Require the use of a compiler that does not generate references
to the deleted predicates.
compiler/introduced_call_table.m:
Delete the above predicates from the introduced call table.
library/string.m:
For each predicate and function whose name includes "codepoint",
- create a version in which "codepoint" is replaced by "code_point",
- make this version the main implementation, making the "codepoint"
versions forward to the "code_point" versions,
- add obsolete pragmas for the "codepoint" versions, though these are
commented out for now. This is so that an installed compiler containing
this change will already have the recommended alternative available
when the commenting-out is removed (maybe in a week or so).
NEWS.md:
Announce the new predicates and functions.
compiler/c_util.m:
compiler/const_prop.m:
compiler/inst_check.m:
compiler/parse_tree_out_term.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/write_error_spec.m:
library/pprint.m:
library/pretty_printer.m:
library/string.format.m:
Replace all uses of the "codepoint" versions with the "code_point"
versions.
The current implementation of the unsigned conversion specifiers (i.e. %x, %X,
%o, %u) for fixed-size 8-, 16- and 32-bit signed integers works by casting
theses values into (word-sized) ints and then using the existing code for
formatting ints as unsigned values. This does not work for negative values as
they are being sign extended when converted to ints. For example,
io.format("%x", [i8(min_int8)], !IO)
prints:
ffffffffffffff80 (on a 64-bit machine)
rather than just:
80
Fix the above problem by casting ints, int8s, int16s etc. that are being
formatted as unsigned values to uints and using the uint formatting code.
NOTE: the formatting code for 64-bit integers follows a different code path
and is not affected by any of this.
library/string.format.m:
Implement unsigned conversion specifiers for non-64-bit signed
integers by casting to uint and using the uint formatting code.
Add predicates for converting signed integers into uints.
The format_unsigned_int_* predicates can be deleted after this change
is installed.
compiler/format_call.m:
Implement unsigned conversion specifiers for non-64-bit signed
integers by casting to uint and using the uint formatting code.
compiler/introduced_call_table.m:
Update the table of introduced predicates.
compiler/options.m:
Add an option that can be used to test whether this fix is
installed.
tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
tests/hard_coded/opt_format_sign_extend.{m,exp}:
Test that formatting code introduced by the compiler does not
accidentally sign-extend negative values.
tests/string_format/string_format_{o,x,u}.{m,exp,exp2}:
Make these tests much more comprehensive then they previously
were.
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.
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.
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.
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/*.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/string.format.m:
Use the constant functions exported by the integer module
for small integers where possible; this avoids having to
construct those integers at runtime.
library/integer.m:
Add constant functions returning 8 and 16 as arbitrary
precision integers.
NEWS:
Announce the above additions.
compiler/simplify_proc.m:
Update the above list to include those introduced for formatting uints.
library/string.format.m:
Add a note about updating the above list if new formatting predicates
are introduced here.
Extend the operations that perform formatted conversion, such as
string.format/2, to be able to handle values of type uint directly. We have
always supported formatting values of type int as unsigned values, but
currently the only way to format uint values is by explicitly casting them to
an int. This addresses Mantis issue #502.
library/string.m:
Add a new alternative to the poly_type/0 type that wraps uint
values.
Update the documentation for string.format. uint values may
now be formatted using the u, x, X, o or p conversion specifiers.
library/string.format.m:
Add the necessary machinery for handling formatting of uint values.
library/string.parse_runtime.m:
library/string.parse_util.m:
Handle uint poly_types.
library/io.m:a
Handle uint values in the write_many predicates.
library/pprint.m:
Handle uint values in the poly/1 function.
compiler/format_call.m:
compiler/parse_string_format.m:
Conform to the above changes.
compiler/options.m:
Add a way to detect if a compiler supports this change.
NEWS:
Announce the above changes.
tests/hard_coded/stream_format.{m,exp}:
Extend this test to cover uints.
tests/invalid/string_format_bad.m:
tests/invalid/string_format_unknown.m:
Conform to the above changes.
tests/string_format/Mmakefile:
tests/string_format/string_format_uint_o.{m,exp,exp2}:
tests/string_format/string_format_uint_u.{m,exp,exp2}:
tests/string_format/string_format_uint_x.{m,exp,exp2}:
Add tests of string.format with uints.
library/io.m:
library/string.m:
Add warnings that Mercury strings are not limited to valid UTF-8 or
UTF-16.
library/string.m
library/string.format.m
library/term_io.m
Note some current behaviours of predicates/functions when passed
strings containing invalid UTF-8 or UTF-16, and what to do about it.
runtime/mercury_string.h:
Note behaviour of MR_utf8_encode.
browser/collect_lib.m:
browser/declarative_execution.m:
browser/dl.m:
browser/io_action.m:
compiler/make.util.m:
compiler/pickle.m:
compiler/process_util.m:
compiler/prog_event.m:
library/array.m:
library/benchmarking.m:
library/bit_buffer.m:
library/builtin.m:
library/char.m:
library/deconstruct.m:
library/dir.m:
library/erlang_rtti_implementation.m:
library/int.m:
library/int16.m:
library/int32.m:
library/int64.m:
library/int8.m:
library/io.m:
library/math.m:
library/mutvar.m:
library/private_builtin.m:
library/profiling_builtin.m:
library/rtti_implementation.m:
library/store.m:
library/string.format.m:
library/string.m:
library/table_builtin.m:
library/term_size_prof_builtin.m:
library/thread.m:
library/time.m:
library/type_desc.m:
library/uint16.m:
library/uint32.m:
library/uint64.m:
library/uint8.m:
ssdb/ssdb.m:
As above. This mostly involved two things.
The first was grouping foreign_procs by predicate instead of by language.
In a few cases, this revealed that some predicates *had* no foreign_proc
for a language, while related predicates did have one that just aborted
if called. This diff adds similar aborting foreign_procs to predicate/
language combinations that were missing them, when this seemed obviously
the right thing to do.
The second was moving pragmas about a predicate from the middle of the
block of clauses of that predicate to the start of that block.
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.
COPYING.LIB:
Add a special linking exception to the LGPL.
*:
Update references to COPYING.LIB.
Clean up some minor errors that have accumulated in copyright
messages.
Many predicates that do their jobs via foreign_procs in C have a fallback
Mercury clause for non-C backends, which usually throws an exception.
When compiled in non-C grades, these often get a warning that their
determinism declaration could have been tigther, e.g. erroneous instead of det.
*.m:
Add no_determinism_warnings pragmas before such fallback clauses.
library/dir.m:
As above, but also remove the unnecessary "dir." prefix on many predicate
declarations and clause heads.
compiler/erl_code_util.m:
compiler/structure_reuse.direct.choose_reuse.m:
library/erlang_rtti_implementation.m:
library/rtti_implementation.m:
Fix missing cases having to do with unsigned ints.
compiler/pd_util.m:
library/string.format.m:
Make clear that some switches are complete.
library/integer.m:
Add to_int/2 which fails instead of throwing an exception if the
value cannot be represented as an `int'.
Deprecate function int/1.
Add a function with a more explicit name det_to_int/1.
Deprecate semidet function from_string/1.
Add a replacement predicate from_string/2.
Deprecate semidet function from_base_string/2.
Add a replacement predicate from_base_string/3.
library/string.format.m:
Conform to changes.
NEWS:
Announce changes.
library/string.parse_runtime.m:
Replace the two previous two level scheme for representing format string
components with a simpler one level scheme, which should avoid some
memory allocations, and which should also make switches faster.
library/string.format.m:
Conform to the change in string.parse_runtime.m.
compiler/parse_string_format.m:
Replace the two previous two level scheme for representing format string
components with a one level scheme, as in string.parse_runtime.m.
Record the context of all the values to be printed.
compiler/format_call.m:
Previously, when we replaced calls to format predicates with calls
that formatted each value to be printed, we used term.context_init as
the context of the replacement goals. We now use the contexts recorded for
the value. Likewise, for the calls to predicates that concatenated the
results together, we now use the context of the original call.
This should give more useful information to anyone who uses the deep
profiler on code that was transformed by format_call.m.
Avoid unnecessary updates to the conj_maps, which should make
the operation of format_call.m itself faster.
Gather identified format call sites immediately even inside disjunctions,
instead of creating a list of the sites inside each disjunct, and then
appending it to the end of the list of sites so far. This should also
improve the speed of format_call.m.
library/maybe.m:
Add a maybe_errors type, which is like maybe_error, but in which the
error case contains one OR MORE error indications.
NEWS:
Mention the new maybe_errors type.
Previously, we specialized calls to string.format and io.format only if
the format string specified no flags, widths, precisions or non-default
bases for any conversion. We now specialize calls to those predicates
regardless of the format string. To make this possible, we now have two
copies of the code to parse format strings.
library/string.parse_runtime.m:
This new module, carved out out library/string.format.m, contains
one of those copies. As the name suggests, this copy is used by
the runtime system.
compiler/parse_string_format.m:
This new module contains the other copy. As its location suggests,
this copy is used by the compiler. The separate copy is necessary
because the compiler's parsing needs are different from the runtime's.
The main reason for the separation is that the compiler needs to be
able to handle cases where widths and predicates are given by manifest
constants, as well as when they are given by the values of variables
at runtime (when the format string contains conversion specifiers
such as "%*d"). Having the runtime handle this extra complexity
would have inevitably increased the runtime's format string interpretation
overhead, which is undesirable.
The other reason is that compiler can afford to postprocess the result
of the parsing in order to avoid having to concatenate two or more
constant strings at runtime.
library/string.parse_util.m:
Types and predicates that are common to the library and compiler copies
of the format string parsing code.
compiler/format_call.m:
We used to check whether format strings match the supplied list
of values to be printed by invoking string.format on dummy inputs
of the supplied types, and seeing whether you got an exception.
We now call parse_string_format.m instead. Not only does this
avoid shenanigans with exceptions (which the deep profiler cannot
yet handle), but it also allows us to specialize all calls
to string.format and io.format. We therefore do so.
We used to specialize calls to io.format by creating a single string
to be printed (using the machinery needed to specialize calls to
string.format), and then printing that. This did unnecessary memory
allocations to hold the intermediate strings. We now simply print
each component one after the other, which avoids this overhead.
library/string.format.m:
Add versions of the predicates that print chars, strings, ints and floats
that are specialized to each possible situation about whether the caller
specifies a width and/or a precision. This means that format_call.m
doesn't have to generate code that allocates cells on the heap.
Remove the code that was moved to new submodules of string.m.
compiler/simplify_proc.m:
List the predicates in string.format.m that the compiler
may generate calls to in the list of such predicates that we maintain
to prevent dead_pred_elim from deleting them before format_call.m
gets a chance to do its work.
compiler/module_imports.m:
If the code of the module calls a predicate named "format" that
may refer to string.format or io.format, then implicitly import
the modules that contain the types and predicates that the code
generated by format_call.m will refer to. Note that since this
module_imports.m works on Mercury code that has not been module
qualified yet, we have to use a conservative approximation.
Reorganize the way we discover what library modules we have to
implicitly import. Instead of a separate boolean for each piece
of functionality that needs an implicit import, put them together
into a structure. Due to Peter's work on argument packing some
years back, this is now more efficient as well as more convenient
that passing around a bunch of booleans. Also switch to passing
around the structure as an accumulator, instead of having to do
bool.ors all over the place.
Since the code for computing the list of modules to be implicitly
imported can sometimes add a library module to the list twice,
sort that list and remove any duplicates.
To make this possible, remove the version of the main predicate
that appends the implicitly imported module names to a list of
module names passed by our caller, since we don't want to sort
THAT list of module names.
Give the remaining version of that predicate that does this
a name that better matches the names of related predicates.
compiler/modules.m:
Conform to the change in module_imports.m. Mark some suspicious code
with XXXs.
Remove some redundant comments.
compiler/options.m:
doc/user_guide.texi:
Add a new option that tells format_call.m what it should do
when it finds more than one problem with a format string: whether
it should print a message only for the first problem, or for all
the problems. (The default is the latter.)
library/MODULES_DOC:
A list of the all the Mercury source files in the library that
should be included in the user guide.
library/MODULES_UNDOC:
A list of the all the Mercury source files in the library that
should NOT be included in the user guide.
library/library.m:
Include the new publicly visible new submodule of string.m,
(string.parse_util). And both string.parse_util and string.parse_runtime
(which is NOT visible from outside string.m) to the list of modules
in the Mercury standard library.
Update the rules for where new library modules should be documented
to account for non-publically-visible submodules, which we haven't had
before. Document the need to include new modules in either MODULES_DOC
or MODULES_UNDOC.
mdbcomp/builtin_modules.m:
Provide convenient access for format_call.m to the names of the
submodules of string.m that it needs access to.
library/Mmakefile:
Add a new target, check_doc_undoc, which checks whether any source files
are missing from MODULES_DOC or MODULES_UNDOC.
doc/Mmakefile:
Read the list of modules to be documented from MODULES_DOC. This replaces
old code that tried to list all the undocumented modules, but missed one:
it referred to erlang_conf.m instead of erlang_builtin.m.
When creating the library documentation, filter out any lines that
contain the string NOTE_TO_IMPLEMENTORS. We now use this mechanism
to include reminders to implementors in what would otherwise be a
publically visible part of string.m.
tools/bootcheck:
Copy MODULES_DOC and MODULES_UNDOC to the stage 2 and 3 library
directories, since the check_doc_undoc target, which is invoked by
"make all" in the library directory, needs them.
compiler/hlds_out_module.m:
When dumping out the table of types, dump out discriminated union types
in a style that follows our recommended coding style.
library/string.format.m:
Provide target predicates that format_call.m can call.
Assume that we are running on at least a 32 bit platform.
Convert (C->T;E) to (if C then T else E).
Shorten too long lines.
library/string.m:
Group the predicates in this module into groups of related predicates,
and put those groups of predicates into a logical order. Document
this order.
Remove some unnecessary promise_equivalent_clauses declarations.
Give some variables and predicates better names, e.g. change the _2
suffix on predicates that do loops to _loop.
Move a predicate to string.format.m, since it is not exported, and
it is not used anywhere else.
Avoid overlong lines.
library/string.format.m:
Add the moved predicate, with a better name and better variable names.
library/string.format.m:
We used to parse format strings, and pair up format specifiers with
the list of input poly_types, using semidet code, throwing
exceptions with generic messages if the semidet code failed.
This diff switches to using det code that returns a list of
situation-specific error messages. Since errors after the first
may be caused by the first error, we now throw exceptions whose
message is a detailed description of the first error, but that
decision is easily changeable.
Simplify some existing code.
tests/general/string_format_test_{2,3}.{exp,exp2,exp3,...}:
tests/invalid/string_format_bad.err_exp:
tests/invalid/string_format_unknown.err_exp:
Update the expected error messages.
library/string.format.m:
Instead of deriving the settings of some parameters from the kind
of unsigned integer conversion requested and then using those parameters,
use the kind of requested conversion directly. It turned out that some
of those parameters were being used only in some cases, but of course
they were being set in all cases.
Do not test for the same condition twice in a row. If you decide you
need to reserve room for a prefix, why test again (using the same
condition) whether you need to add the prefix?
Avoid using arbitrary precision arithmetic if fixed arithmetic will do
on all platforms that are at least 16 bit.
Give some predicates better names.
library/string.format.m:
We used to convert Mercury ints to strings by doing arithmetic on
(arbitrary precision) integers. This diff changes things so we now
compute only one one digit this way; the rest we compute using
arithmetic on ints, not integers. In most cases, we should be able
to avoid doing arithmetic on arbitrary-precision integers at all,
but that is a more involved change.
library/string.format.m:
Switch the representation of flags from a list of chars
to a tuple of enums. This should make it easier to construct flags
at compile time.
Factor out the commonalities in handling the different format specifiers
for printing unsigned ints, and for printing floats. This gives us
predicates (such as gen_format_float) that format_call.m can generate
calls to.
Give some predicates, types and variables more meaningful names.
Reorder some predicates' arguments to conform with the usual convention
of inputs before outputs.
Remove some unnecessary #includes in C code.
Add XXXs as reminders of opportunities for further improvements.
library/string.m:
Fix white space.
There are no algorithmic changes, though there are some name changes.
library/string.format.m:
New submodule of string.m. Contains the parts of old string.m
that implement string.format. About 1500 lines.
library/string.to_string.m:
New submodule of string.m. Contains the parts of old string.m
that implement string.string, string.string_ops and
string.string_ops_noncanon. About 500 lines.
library/string.m:
Replace the code that is now in the new submodules with includes
of those submodules.
library/library.m:
List the two new submodules. Fix some bitrot about where
new library modules may need to be listed.
doc/Mmakefile:
Do not document the two new submodules, since they are implementation
details.