adams@crcge1.UUCP (Drew Adams) (09/15/87)
We have a Franz-TO-Common Lisp translation program (FTOC) written three years ago. It's written in Common Lisp and has run under Kyoto CL and Sun CL. It's basically a macro expander and consists of a (*large*) collection of rewrite rules in the form of macros. A rule specifies the CL form that corresponds to a given input Franz Lisp form. These defining macros have not been tested out completely, and there may of course be more than one "correct" or desirable translation for any given form. A few definitions are known to be incorrect. It is in general a simple matter to change such translation rules. Aside from the correction of particular definitions, the general functioning of the program has been tested. FTOC was written for an older Franz version (38, 39, 40?), before Franz included such things as packages and keywords. Naturally, completely automatic translation Franz -> Common is impossible. FTOC tries to remain conservative and not second-guess the programmer's original intent, which means that the resultant CL code is often unduly wordy, (simulating Franz's type-checking of numbers etc.) The bottom line is that FTOC may be useful for a first pass (i.e. an *aid* to translation). It may also be useful interactively as an aid to Franz programmers converting to Common habits: typing in a Franz expression allows a quick view of a possible Common correspondant. Example of wordiness: (+ 2 (+ 3 (+ 4 1))) in Franz is translated to: (flet ((franz.+ (&optional (n 1 0) &rest n2etc) "equivalent to Franz Lisp '+'." (check-type n fixnum) (mapc #'(lambda (n) (check-type n fixnum)) n2etc) (if (endp n2etc) n1 (+ n1 (reduce #'+ n2etc))))) (franz.+ 2 (flet ((franz.+ (&optional (n 1 0 .... and so on ... (franz.+ 3 (flet (( ... and so on .... (franz.+ 4 1)))))) Such a translation is of course generally absurd, or at least of questionable utility. At least it's possible to easily locate such absurdities (via the name "franz.+") and replace them by whatever the programmer really did intend. As the translation is done via rewrite rules, it would of course be easy to replace such conservative translation by rules assuming a little "common sense" at the risk of occasional blunders. Whenever an expression translation is straightforward and the input may clearly be recognized in the output, simple replacement is done, rather than creating a temporary (flet) function such as "franz.+". Thus, e.g., "(typep ...)" is simply translated to "(type-of...)". Some expressions are simply untranslatable and a translation error is signalled. Examples of such functions are UNIX system calls etc.. An example of a rewrite rule is: (typep type-of NIL ((x) `(type-of ,x))) The items in this list are: 1. The FL function name typep 2. The corresponding CL name or "nil" if no simple type-of correspondance holds (used in translations of "quote" and "function") 3. A flag indicating whether ("t") or not ("nil") nil the CL calling sequence is different from the FL sequence (e.g. different argument order) (used in translations of "quote" and "function") 4. The parameter list of the FL function (x) 5. The translation rule proper `(type-of ,x) The macros used as rewrite rules are local (similar to "macrolet" definitions), so that there is no problem of interference with CL names in the current environment that may be the same as Franz names (but e.g. with different arguments). Aside from function (macro etc.) applications, special symbols are translated via lookup in a separate table. Thus, e.g., "errport" is translated to "*error-output*". Some general translation problems include: * STATIC VS. DYNAMIC SCOPING: This is of course the single biggest headache and FTOC makes no attempt to wrestle with the problem. It is (wisely?) ignored; i.e. it must be dealt with manually. * TYPE PREDICATES, after translation, refer to *CL* types. E.g. Franz's "(bigp...)" is translated to CL's "(typep bignum...)". * CODE WHICH CREATES CODE ETC.: Macros in the code may optionally by expanded at translation time. Otherwise, code-creating code continues to create *Franz* code at execution time. * FUNCTION NAMES AS ARGUMENTS ETC.: Translating mapped etc. named functions is straightforward as long as the function name itself may be simply translated. Thus, "typep" goes over into "type-of", but "+" has no single named function equivalent. Such translation of function names is done while translating "quote" and "function" expressions. If no single name applies no translation of the name occurs and a warning is issued. * USER-DEFINED RESERVED NAMES: A Franz programmer may have defined her own function or other object with a name which is reserved (predefined) in CL (e.g. "write"). FTOC does not currently check for such names. Such detection could easily be added, but it would surely be costly in translation time. Such a check might better be done in a separate pass only when it is suspected to be necessary. Various modes of use of FTOC are available. FTOC is made freely available for "test purposes", which means it can be used, isn't guaranteed and won't be maintained by us and can't be sold, copied, distributed etc. by others. The source is copyrighted. Comments on and improvements to the program are welcomed. ---------- Drew ADAMS, Laboratoires de Marcoussis, Centre de Recherche de la Compagnie Generale d'Electricite, Route de Nozay, 91460 MARCOUSSIS, FRANCE Tel. 64.49.11.54, adams@crcge1.cge.fr -- Drew ADAMS, Laboratoires de Marcoussis, Centre de Recherche de la Compagnie Generale d'Electricite, Route de Nozay, 91460 MARCOUSSIS, FRANCE Tel. 64.49.11.54, adams@crcge1.cge.fr