I would like to change mlds_to_c_*.m from writing stuff out directly
to using a string builder. However, the existing string.builder.m
won't work, because when writing out .c/.mh/.mih files with --line-numbers,
we need to generate #line directives before and after the MLDS statements
generated for foreign_procs.
The #line directive before is no problem: the context it writes is
the context of the pragma foreign_proc. The #line directive after, however,
wants to output the line number *in the file we are writing the C code to*.
The usual string builder has no way to peek into the component strings
accumulated so far without destroying its uniqueness. We *could* use
unsafe promises of uniqueness to get around this, but I don't think
that would be a good idea. This is because counting the newline chars
in the component strings so far once for *every* foreign_proc would have
0.5 N*M complexity, where N and M are the number of foreign_procs
and the total length of the generate C file respectively, and for
the kinds of programs we use as stress tests, both can be huge.
It would be better to do in a string builder what the Mercury stream
implementation already does: count the newlines in each string
as it is being written out, and update the current line number
accordingly. This is better because its complexity is linear,
*and* because it has better locality. This diff does that.
compiler/lines_builder.m:
This new module is a near-copy of string.builder.m. It differs in
- keeping the (unchanging) filename and the (continually updated)
line number in the string builder state,
- adding a filename and an initial line number (usually 1)
as parameters of the state init function,
- having a predicate that returns the filename and the line number
in a given state,
- to make that predicate possible, threading the state through
all operations as in/out pairs, not di/uo pairs, and
- due to that change in modes, NOT having this kind of string builder
be an instance of the stream typeclasses that the existing
string builder type is an instance of.
compiler/libs.m:
Include the new module in this package.
compiler/notes/compiler_design.html:
Document the new module.
Mercury
Mercury is a logic/functional programming language which combines the clarity and the expressiveness of declarative programming with advanced static analysis and error detection features.
More information is available on the website's about pages, in other README files in the source code repository, and in the documentation.
Small sample programs written in Mercury can be found in the samples and extras directories of the source code repository.
README files
The Mercury compiler has two different backends and works on different operating systems. Specific information is contained in individual README files:
-
Bootstrapping discusses how to get Mercury installed.
This is important, as the Mercury compiler is written in Mercury.
-
C Low-level backend
This backend works well with GCC but also works with:
-
High-level backend targets
-
Supported operating systems
-
Other platform information
Other information
See the current release notes for the latest stable release. The news file lists any recent changes. The history file is relevant if you want to find out more about the past development of Mercury. The limitations file lists some ways in which the Mercury implementation does not yet meet its goals.
Information for developers
If you are considering contributing to the Mercury project, the website contains some documents that may be helpful. These include a document about contributions in general and specific information about contributing such as coding styles.
Contact
See our contact page.