See the long comment in pervasives.ml for an explanation of the
change. The short summary is that we need to prove more elaborate
properties between the format types involved in the typing of %(...%),
and that proving things by writing GADT functions in OCaml reveals
that Coq's Ltac is a miracle of usability.
Proofs on OCaml GADTs are runtime functions that do have a runtime
semantics: it is legitimate to hope that those proof computations are
as simple as possible, but the current implementation was optimized
for feasability, not simplicity. François Bobot has some interesting
suggestions to simplify the reasoning part (with more equality
reasoning where I used transitivity and symmetry of the
relation profusely), which may make the code simpler in the future
(and possibly more efficient: the hope is that only %(...%) users will
pay a proof-related cost).
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14897 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
This should make the type-checking of formats simpler and more robust:
instead of trying to find a pair as previously, we can now use the
path of the format6 type directly.
A nice side-effect of the change is that the internal definition of
formats (as a pair) is not printed in error messages anymore.
Because format6 is in fact defined in the CamlinternalFormatBasics
submodule of Pervasives, and has an alias at the toplevel of
Pervasives, error messages still expand the definition:
> Error: This expression has type
> ('a, 'b, 'c, 'd, 'd, 'a) format6 =
> ('a, 'b, 'c, 'd, 'd, 'a) CamlinternalFormatBasics.format6
> but an expression was expected of type ...
Passing the option `-short-paths` does avoid this expansion and
returns exactly the same error message as 4.01:
> Error: This expression has type ('a, 'b, 'c, 'd, 'd, 'a) format6
> but an expression was expected of type ...
(To get this error message without -short-paths, one would need to
define format6 directly in Pervasives; but this type is mutually
recursive with several GADT types that we don't want to add in the
Pervasives namespace unqualified. This is why I'll keep the alias
for now.)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14868 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Given that there still remains a small incompatibility (typing of
%(..%)), I decided to keep the legacy mode enabled for now. This means
that any failure related to format can be traced to this
incompatiblity (or unknown regressions), which will simplify the
monitoring and handling of changes considerably. As soon as the %(..%)
typing is generalized, we can turn the legacy mode off (or maybe
simply add warnings for ignored formats).
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14841 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
(printf {%foo%} bar) will print the string representation of the
format type of both `foo` and `bar`, instead of printing `bar`
(for this purpose one can just use %s). `bar` content is ignored, but
the typer should check that its type is compatible with the one of
`foo`.
This semantics allows to use (printf %{..%}) for testing/debugging the
use of %(...%): put in the brackets what you believe to be the format
type you want to use, and as argument the format you wish to pass, and
you'll get type-checking confidence and the "canonical" representation
of the format string which you can use in the %(...%) -- note that
using the canonical format type is not mandatory.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14840 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
This simplifies the charset-handling code, as camlinternalFormat is
allowed to depend on Bytes and String instead of re-importing the
needed primitives.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14837 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
The legacy implementation doesn't support "%+_", "%-_" etc. which were
accepted by Benoît's patches. This creates a discrepancy (though not
a regression) that is not necessarily desirable (and in any case makes
fuzz-testing for difference return non-bugs). Long-term, I think that
we're good with the previous, simpler structure where "_" must always
be the first flag.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14827 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
When the OCAML_LEGACY_FORMAT environment variable is set, the compiler
will try to emulate the behaviour of the previous implementation of
format.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14813 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
To finish the bootstrap cycle, run:
make library-cross
make promote
make partialclean
make core
make library-cross
make promote-cross
make partialclean
make ocamlc ocamllex ocamltools
make library-cross
make promote
make partialclean
make core
make compare
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14810 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
After applying this patch, you should run:
make library-cross
make promote-cross
make partialclean
make ocamlc ocamllex ocamltools
and then immediately apply the following patches until the "second
part of Benoît Vaugon's format+gadts patch"; the bootstrap cycle is
not finished yet.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14806 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
- The internal [backtrace_slot] type is not exposed anymore, instead
accessors function return orthogonal information
(is_raise, location). This is both more extensible and more
user-friendly.
- The [raw_backtrace_slot] is exposed separately as a low-level type
that most users should never use. The unsafety of marshalling is
documented. Instead of defining
[raw_backtrace = raw_backtrace_slot array], I kept [raw_backtrace]
an abstract type with [length] and [get] functions for
random-access. This should allow us to change the implementation in
the future to be more robust wrt. marshalling (boxing the trace in
a Custom block, or even possibly the raw slots at access time).
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14784 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
(Patch by Jacques-Henri Jourdan)
There are several changes:
- `raw_backtrace` is no longer an abstract type, but rather an
`raw_backtrace_slot array`, where `raw_backtrace_slot` is a new
abstract type. `raw_backtrace_slot` elements are hashable and
comparable. At runtime, values of this type contain either
a bytecode pointer or a frame_descr pointer. In order to prevent the
GC from walking through this pointer, the low-order bit is set to
1 when stored in the array.
- The old `loc_info` type is know public, renamed into `backtrace_slot`:
type backtrace_slot =
| Known_location of bool (* is_raise *)
* string (* filename *)
* int (* line number *)
* int (* start char *)
* int (* end char *)
| Unknown_location of bool (*is_raise*)
- new primitive :
val convert_raw_backtrace_slot: raw_backtrace_slot -> backtrace_slot
Rather than returning an option, it raises Failure when it is not
possible to get the debugging information. It seems more idiomatic,
especially because the exceptional case cannot appear only for a part
of the executable.
- the caml_convert_raw_backtrace primitive is removed; it is more
difficult to implement in the C side because of the new exception
interface described above.
- In the bytecode runtime, the events are no longer deserialized once
for each conversion, but once and for all at the first conversion,
and stored in a global array (*outside* the OCaml heap), sorted by
program counter value. I believe this information should not take
much memory in practice (it uses the same order of magnitude memory
as the bytecode executable). It also makes location lookup much more
efficient, as a dichomoty is used instead of linear search as
previously.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14776 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Also removes __FILE_OF__ and __MODULE_OF__, since they are not more precise
than __FILE__ and __MODULE__
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14715 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02