<\body> Below, we list some important invariants, which have guided us in the implementation of the compiler. <\description> The main part of the compiler is devoted to associate unique meanings to each subexpression of the input program. Each symbol can have several meanings , , , depending on the context. These possible meanings , \ , are created during the declaration phase. For instance, expressions and might be compiled as and . The main routine associates a list of possible meanings of type to a subexpression of the input program of type . The constructor of the type takes both the resulting output program and its type as arguments (and optionally some priorities). In fact, each output program is unambiguous and therefore has a unique type. When constructing an instance of type , this type is cached, which allows subsequently for the automatic retrieval of the type of an output program. The symbols of an environment are bound to their possible meanings during the declaration phase. During the main compilation phase, these meanings can no longer change. In particular, the set of converters in the environment remains fixed, which allows us to cache inferred compositions of converters and the resolution of function applications for functions and arguments of given types. . If you don't have this file, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.>