From: Drew Adams
Subject: Franz to Common Lisp Translation (FTOC)
Date:
Message-ID: <2918@crcge1.UUCP>
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, ·····@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, ·····@crcge1.cge.fr