1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
|
Welcome to f2cl - a Fortran to Common Lisp Translator
Contained in this directory are source code files and some documentation.
The translator is written in Common Lisp making installation simple.
Installation
------------
If this has been extracted as a part of CLOCC, the way to build f2cl
is to simply run "make system" from a shell, as is usual with CLOCC
packages.
A second method is to use defsystem from CLOCC. Then load
f2cl.system, and then finally run (mk:oos "f2cl" :compile).
A third method is to use asdf. You can load f2cl.asd and run
(asdf:oos 'asdf:load-op :f2cl).
Finally, a fourth method, if you have none of the above, is to
manually run everything as follows:
1. Start your favorite Common Lisp implementation use the function
"compile-file" to compile each of the source files:
f2cl0.l
f2cl1.l
f2cl2.l
f2cl3.l
f2cl4.l
f2cl5.l
f2cl6.l
f2cl7.l
macros.l
2. Load up all of the files
(load "f2cl0.l")
(load "f2cl1.l")
(load "f2cl2.l")
(load "f2cl3.l")
(load "f2cl4.l")
(load "f2cl5.l")
(load "f2cl6.l")
(load "f2cl7.l")
(load "macros.l")
to load all the compiled files.
Usage
-----
Converting Fortran Code
-----------------------
To use f2cl:
(f2cl:f2cl "<path>/fortran.f")
will convert the file "<path>/fortran.f" to Lisp code and places the
result in the file "<path>/fortran.lisp".
Alternatively,
(f2cl:f2cl-compile "<path>/fortran.f")
will also run compile-file on the Lisp file so you can load it
directly into your lisp.
For those anxious to use the translator without studying the documentation
here is a short list of restrictions that may result in obscure errors:
- input code is assumed to be valid Fortran 77
- no tabs are permitted in the source,
- $comments should only be turned on if the Fortran code has comments
exclusively within subroutines,
- linebreaks must occur within whitespace,
- spaces are required to separate symbols.
Note also that an intermediate file called "prep.tmp" is produced by the
preprocessing stage of the translation.
Options
-------
These are the options available to f2cl:f2cl and f2cl:f2cl-compile
:OUTPUT-FILE
File to contain Lisp code
:VERBOSE
Verbose output. Default = NIL. Mostly for debugging.
:PRUNE-LABELS
Prune unused labels. Default = NIL.
:INCLUDE-COMMENTS
Include Fortran comments in the Lisp output.
Default = NIL
:AUTO-SAVE
Variables in DATA statements are automatically SAVE'd. Default
= T.
:RELAXED-ARRAY-DECLS
Declarations of array sizes are relaxed in formal
parameters to functions. That is, any array
length declarations (except lower limits) are
ignored if possible, like old Fortran used
to. Default = T.
:COERCE-ASSIGNS
If T or :ALWAYS, all assignment statements automatically
coerce the RHS to the appropriate type for the assignment. If
NIL or :NEVER, coercion never happens. If :AS-NEEDED, f2cl
applies coercion if it thinks it is needed. Default =
:AS-NEEDED.
:EXTENSION
The extension to use for the output file, if needed. Defaults
to *DEFAULT-LISP-EXTENSION* or "lisp".
:KEEP-TEMP-FILE
If T, the temporary file is not deleted. This is mostly for
debugging f2cl. Default = NIL.
:ARRAY-TYPE
The type of array f2cl should use. Should be :simple-array or
:array. For some compilers, there can be significant speed up
if the array can be declared as simple-arrays. But this is
incompatible with array-slicing, so care must be used if you
choose :simple-array. Default = :array.
:ARRAY-SLICING
When non-NIL, f2cl assumes that, whenever we do an array
reference in a call to a subroutine or function, we are really
passing a subarray to the routine instead of just the single
value, unless f2cl knows the function takes a scalar arg that
is not modified. Default = T.
:PACKAGE
A string or symbol specifying what package the resulting code
should be in. (Basically puts a (in-package <p>) at the top.)
Default is COMMON-LISP-USER.
:DECLAIM
Declaim compilation options (Basically puts a (declaim
<declaim>) at the top.) Default is none.
:DECLARE-COMMON
When non-NIL, any structures definitions for common blocks are
defined when converting this file. Otherwise, the structures
for the common blocks are expected to be defined elsewhere.
This should be used only once for one subprogram that will be
used to define the common block. See below for more
information. Default is NIL.
:FLOAT-FORMAT
Float format to use when printing the result. Default is
*READ-DEFAULT-FLOAT-FORMAT*
:COMMON-AS-ARRAY
Instead of defining a common block as a structure with the
same slot names as variables in the common block, the common
block is defined as a set of arrays. The actual common block
variables are defined as offsets into these arrays. For more
information see below. This mimics the memory layout of how
Fortran treats common blocks. Default = NIL.
Using Converted Code
--------------------
Once you've converted the code, you do not need to load up all of f2cl
to use the converted code. In fact, you only need f2cl0.l and
macros.l to define the necessary packages and functions used by the
converted code. Actually, you really only need the defpackage for
f2cl-lib in f2cl0.l.
Issues
------
For a more detailed list of issues and notes, see src/NOTES.
We highlight just a few issues here.
o Block data statements.
In Fortran, block data statments are used to initialize common
blocks. Since Fortran executables are loaded and run just once,
this is not a problem. However, in Lisp, this might not be true,
and you may want to run the main program many times. Thus, it is
up to you to run the block data initializer at the right time, as
needed. f2cl cannot know when and where to call the initializer.
o Common blocks.
F2cl converts common blocks to structures. However, common blocks
may be referenced in several different files, so the user must
tell f2cl when to define the structure. Use the :declare-common
parameter to tell f2cl to define the structure. This should be
done exactly once for each common block that is defined. This
should also be done for the first file that is compiled and
loaded, so that subsequent files know about the definition.
In addition, there is another option, :common-as-array. This
changes how f2cl handles common blocks. A rather common use of
common blocks has the same common block using different variable
names. For example, on routine might have
COMMON /foo/ a(10), b, i(4)
and another might say
COMMON /foo/ b(9), c, d, j(2), k(2)
In Fortran, this is perfectly acceptable. Normally, f2cl expects
all common blocks to use the same variable names, and then f2cl
creates a structure for the common block using the variable names
as the names of the slots. However, for a case like the above,
f2cl gets confused. Hence, :common-as-array. We treat the common
block as an array of memory. So this gets converted into a
structure somewhat like
(defstruct foo
(part-0 (make-array 11 :element-type 'real))
(part-1 (make-array 4 :element-type 'integer4)))
(In a more general case, we group all contiguous variables of the
same type into one array. f2cl and Lisp cannot handle the case
where a real and integer value are allocated to the same piece of
memory.)
Then in the individual routines, symbol-macrolets are used to
create accessors for the various definitions. Hence, for the
second version, we would do something like
(symbol-macrolet
(b (make-array 9 :displaced-to
(foo-part-0 *foo*)
:diplaced-offset 0))
(c (aref (foo-part-0 *foo*) 9))
(d (aref (foo-part-0 *foo*) 10))
(j (make-array 2 :displaced-to
(foo-part-1 *foo*)
:displaced-offset 0))
(k (make-array 2 :displaced-to
(foo-part-1 *foo*)
:displaced-offset 2))
...)
Thus, we access the right parts of the common block, independent
of the name. Note that this has a performance impact since we
used displaced arrays.
o Conversion order.
While not necessary, f2cl can do a significantly better job in
generating code if the functions are compiled in the correct
order. This means any function, F, that is called by another
function, G, should compiled first. In this way, f2cl can
determine the calling conventions for F, and generate the
appropriate call for F in G. This is important if F takes an
array argument and G passes a slice of an array to F, or
conversely if F takes a simple variable, and G calls F with an
array reference.
If this is not done, the user may have to modify either the
Fortran code or the resulting Lisp code to pass arguments
correctly.
F2cl cannot always determine whether a slice of an array should be
used or just the single element.
See also the file src/NOTES which contains a change log. But there
are also various notes about about restrictions and enhancements on
various features supported by f2cl.
Acknowledgments:
The translator was written by Kevin Broughan and Diane Koorey Willcock
at the University of Waikato. Reports should be sent to
kab@waikato.ac.nz and should include examples of Fortran code which
fails to translate or which translates incorrectly.
Major changes have be written by Raymond Toy and the entire translator
is now part of CLOCC, with permission from Kevin Broughan. Send bug
reports and other comments to http://clocc.sourceforge.net.
The code is also placed under the GPL, by permission of Kevin
Broughan. The exception is macros.l which is released under the LGPL
so that it can be incorporated into other packages.
|