Next: , Previous: , Up: Mercury grades   [Contents][Index]


3.2 The importance of consistency

In general, a Mercury program consists of many modules. These modules must be compiled in a manner that allows the resulting files codes to be linked together. For example if you compile e.g. module module_a to module_a.java and module module_b to module_b.c, which the Java and C implementations compile further to module_a.jar and module_b.o. This is not just because JAR files and object files have different formats; the more fundamental reason is that the codes in them make fundamentally different assumptions about how the different modules of a program are supposed to communicate and cooperate with each other. This is why if you compile both module module_a and module module_b to C, but compile module module_a using the LLDS backend and andmodule_b using the MLDS backend, any attempt to link module_a.o and module_b.o will still fail. It will fail because the two backends use different naming schemes for the C code they generate, so that the name of the C function that implements e.g. the predicate module_b.q will be different from the name by which a call from module_a.p will try to refer to module_b.q. This difference is deliberate. This is because any attempt to “cure” such link failures by having the two backends use the same C naming scheme would address only incidental incompatibilities; the fundamental incompatibilities, such as the LLDS backend managing its own stacks (two of them) while the MLDS backend relies on the standard C stack, would still remain.

The mmc option --target controls which of its target languages the Mercury compiler will generate code for. With --target c, Mercury will generate C code; with --target java, Mercury will generate Java code; and with --target c#, Mercury will generate C# code. When generating C, the option --high-level-code controls whether code generation will use the LLDS or the MLDS backend, generating assembly code in C syntax or idiomatic C code respectively. (Since you cannot write assembly-level code in either Java or C#, the compiler will always use the MLDS backend when generating Java or C# target code.) What the previous paragraph is saying is that if you compile all the modules of a program, an attempt to link the resulting files together can succeed only if all the modules were compiled using the exact same values of --target and --high-level-code options.

These are not the only options that have this property. There are other options as well, and in fact Mercury has more such options than most other languages. This is why unlike most other languages, Mercury has an explicit name for this concept: it calls each set of compatible values of those options a grade.

A Mercury grade succinctly specifies the value of roughly twenty options (depending on when you count them; we add new ones from time to time). Each grade consists of a base grade (which must be present) and zero or more other grade modifiers (which are therefore optional). The names of the grade modifiers all start with period; the names of the base grades do not. The name of a grade is a concatenation of the selected base grade and the selected grade modifiers. For example, hlc.tr.gc specifies the base grade hlc (meaning high level C code) and the grade modifiers .tr and .gc (which respectively call for the use of trailing and of the Boehm-Demers-Weiser garbage collector).


Next: , Previous: , Up: Mercury grades   [Contents][Index]