In article <···@tarski.albany.edu> ······@cs.albany.edu (Tushar Saxena) writes:
>
>I am trying to convert a huge file written in Franz Lisp into Common Lisp.
>I am doing it the brute force method which is fast becoming painful. Is
>there any good method or package or even a book which highlights the diff-
>-erences such that my task will be made easy ?
We have a Franz-TO-Common Lisp translation program (FTOC) written in
1985. It's written in Common Lisp and has run under Kyoto CL and
Lucid 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: ·····@aar.alcatel-alsthom.fr, Tel. +33 (1) 64.49.11.54
ALCATEL ALSTHOM Recherche, Route de Nozay, 91460 MARCOUSSIS, FRANCE
``Faith, faith is an island in the setting sun.
But proof, yes, Proof is the bottom line for everyone.'' -- Paul Simon
--
Drew ADAMS: ·····@aar.alcatel-alsthom.fr, Tel. +33 (1) 64.49.11.54
ALCATEL ALSTHOM Recherche, Route de Nozay, 91460 MARCOUSSIS, FRANCE
``Faith, faith is an island in the setting sun.
But proof, yes, Proof is the bottom line for everyone.'' -- Paul Simon