README.md 9.98 KB
Newer Older
Raymond Toy's avatar
Raymond Toy committed
1
# Welcome to f2cl - a Fortran to Common Lisp Translator
rtoy's avatar
rtoy committed
2
3
4
5

Contained in this directory are source code files and some documentation.
The translator is written in Common Lisp making installation simple.

Raymond Toy's avatar
Raymond Toy committed
6
7
# Installation

rtoy's avatar
rtoy committed
8
9
10
11
12
13

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
Raymond Toy's avatar
Raymond Toy committed
14
`f2cl.system`, and then finally run `(mk:oos "f2cl" :compile)`.  
rtoy's avatar
rtoy committed
15

Raymond Toy's avatar
Raymond Toy committed
16
17
A third method is to use asdf.  You can load `f2cl.asd` and run
`(asdf:oos 'asdf:load-op :f2cl)`.
rtoy's avatar
rtoy committed
18

19
20
Finally, a fourth method, if you have none of the above, is to
manually run everything as follows:
rtoy's avatar
rtoy committed
21

rtoy's avatar
rtoy committed
22
1. Start your favorite Common Lisp implementation use the function
Raymond Toy's avatar
Raymond Toy committed
23
   `compile-file` to compile each of the source files:
rtoy's avatar
rtoy committed
24

rtoy's avatar
rtoy committed
25
		f2cl0.l
rtoy's avatar
rtoy committed
26
27
28
29
30
31
32
33
34
		f2cl1.l
		f2cl2.l
		f2cl3.l
		f2cl4.l
		f2cl5.l
		f2cl6.l
		f2cl7.l
		macros.l

rtoy's avatar
rtoy committed
35
36
2. Load up all of the files

Raymond Toy's avatar
Raymond Toy committed
37
38
39
40
41
42
43
44
45
        (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")
rtoy's avatar
rtoy committed
46

rtoy's avatar
rtoy committed
47
48
49
   to load all the compiled files.


Raymond Toy's avatar
Raymond Toy committed
50
51
52
53
# Usage


## Converting Fortran Code
rtoy's avatar
rtoy committed
54
55

To use f2cl:
Raymond Toy's avatar
Raymond Toy committed
56
```
rtoy's avatar
rtoy committed
57
(f2cl:f2cl "<path>/fortran.f")
Raymond Toy's avatar
Raymond Toy committed
58
59
60
```
will convert the file `<path>/fortran.f` to Lisp code and places the
result in the file `<path>/fortran.lisp`.
rtoy's avatar
rtoy committed
61

rtoy's avatar
rtoy committed
62
Alternatively,
Raymond Toy's avatar
Raymond Toy committed
63
```
64
(f2cl:f2cl-compile "<path>/fortran.f")
Raymond Toy's avatar
Raymond Toy committed
65
66
```
will also run `compile-file` on the Lisp file so you can load it
rtoy's avatar
rtoy committed
67
directly into your lisp.
rtoy's avatar
rtoy committed
68
69


sds's avatar
sds committed
70
For those anxious to use the translator without studying the documentation
rtoy's avatar
rtoy committed
71
72
here is a short list of restrictions that may result in obscure errors:
 - input code is assumed to be valid Fortran 77
sds's avatar
sds committed
73
 - no tabs are permitted in the source,
rtoy's avatar
rtoy committed
74
75
76
 - $comments should only be turned on if the Fortran code has comments
   exclusively within subroutines,
 - linebreaks must occur within whitespace,
sds's avatar
sds committed
77
 - spaces are required to separate symbols.
Raymond Toy's avatar
Raymond Toy committed
78

rtoy's avatar
rtoy committed
79
80
81
Note also that an intermediate file called "prep.tmp" is produced by the
preprocessing stage of the translation.

Raymond Toy's avatar
Raymond Toy committed
82
### Options
rtoy's avatar
README:    
rtoy committed
83

Raymond Toy's avatar
Raymond Toy committed
84
These are the options available to `f2cl:f2cl` and `f2cl:f2cl-compile`
rtoy's avatar
README:    
rtoy committed
85

Raymond Toy's avatar
Raymond Toy committed
86
* `:OUTPUT-FILE`             
rtoy's avatar
README:    
rtoy committed
87
88
	File to contain Lisp code

Raymond Toy's avatar
Raymond Toy committed
89
* `:VERBOSE`                
rtoy's avatar
README:    
rtoy committed
90
91
	Verbose output. Default = NIL.  Mostly for debugging.

Raymond Toy's avatar
Raymond Toy committed
92
* `:PRUNE-LABELS`           
rtoy's avatar
README:    
rtoy committed
93
94
	Prune unused labels. Default = NIL.

Raymond Toy's avatar
Raymond Toy committed
95
* `:INCLUDE-COMMENTS`       
rtoy's avatar
README:    
rtoy committed
96
97
98
	Include Fortran comments in the Lisp output.
        Default = NIL

Raymond Toy's avatar
Raymond Toy committed
99
* `:AUTO-SAVE`              
rtoy's avatar
README:    
rtoy committed
100
101
102
	Variables in DATA statements are automatically SAVE'd. Default
	= T.

Raymond Toy's avatar
Raymond Toy committed
103
* `:RELAXED-ARRAY-DECLS`      
rtoy's avatar
README:    
rtoy committed
104
105
106
107
108
109
	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.

Raymond Toy's avatar
Raymond Toy committed
110
111
* `:COERCE-ASSIGNS`  
	If `T` or `:ALWAYS`, all assignment statements automatically
rtoy's avatar
README:    
rtoy committed
112
        coerce the RHS to the appropriate type for the assignment.  If
Raymond Toy's avatar
Raymond Toy committed
113
        `NIL` or `:NEVER`, coercion never happens.  If `:AS-NEEDED`, f2cl
rtoy's avatar
README:    
rtoy committed
114
        applies coercion if it thinks it is needed.  Default =
Raymond Toy's avatar
Raymond Toy committed
115
        `:AS-NEEDED`.
rtoy's avatar
README:    
rtoy committed
116

Raymond Toy's avatar
Raymond Toy committed
117
* `:EXTENSION`                 
rtoy's avatar
README:    
rtoy committed
118
	The extension to use for the output file, if needed.  Defaults
Raymond Toy's avatar
Raymond Toy committed
119
        to `*DEFAULT-LISP-EXTENSION*` or "lisp".
rtoy's avatar
README:    
rtoy committed
120

Raymond Toy's avatar
Raymond Toy committed
121
122
123
* `:KEEP-TEMP-FILE`
	If `T`, the temporary file is not deleted.  This is mostly for
	debugging f2cl. Default = `NIL`.
rtoy's avatar
README:    
rtoy committed
124

Raymond Toy's avatar
Raymond Toy committed
125
126
127
* `:ARRAY-TYPE`  
	The type of array f2cl should use.  Should be `:simple-array` or
        `:array`.  For some compilers, there can be significant speed up
rtoy's avatar
README:    
rtoy committed
128
129
        if the array can be declared as simple-arrays.  But this is
        incompatible with array-slicing, so care must be used if you
Raymond Toy's avatar
Raymond Toy committed
130
        choose `:simple-array`. Default = `:array.`
rtoy's avatar
README:    
rtoy committed
131

Raymond Toy's avatar
Raymond Toy committed
132
133
* `:ARRAY-SLICING`  
	When non-`NIL`, f2cl assumes that, whenever we do an array
rtoy's avatar
README:    
rtoy committed
134
135
136
        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
Raymond Toy's avatar
Raymond Toy committed
137
        is not modified.  Default = `T`.
rtoy's avatar
README:    
rtoy committed
138

Raymond Toy's avatar
Raymond Toy committed
139
* `:PACKAGE`  
rtoy's avatar
README:    
rtoy committed
140
	A string or symbol specifying what package the resulting code
Raymond Toy's avatar
Raymond Toy committed
141
142
        should be in. (Basically puts a `(in-package <p>)` at the top.)
        Default is "COMMON-LISP-USER".
rtoy's avatar
README:    
rtoy committed
143

Raymond Toy's avatar
Raymond Toy committed
144
145
* `:DECLAIM` 
	Declaim compilation options (Basically puts a `(declaim <declaim>)` at the top.)  Default is none.
rtoy's avatar
README:    
rtoy committed
146

Raymond Toy's avatar
Raymond Toy committed
147
148
* `:DECLARE-COMMON`  
	When non-`NIL`, any structures definitions for common blocks are
rtoy's avatar
README:    
rtoy committed
149
150
151
152
        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
Raymond Toy's avatar
Raymond Toy committed
153
        information. Default is `NIL`.
rtoy's avatar
README:    
rtoy committed
154

Raymond Toy's avatar
Raymond Toy committed
155
* `:FLOAT-FORMAT`              
rtoy's avatar
README:    
rtoy committed
156
	Float format to use when printing the result.  Default is
Raymond Toy's avatar
Raymond Toy committed
157
        `*READ-DEFAULT-FLOAT-FORMAT*`
rtoy's avatar
README:    
rtoy committed
158

Raymond Toy's avatar
Raymond Toy committed
159
* `:COMMON-AS-ARRAY`  
rtoy's avatar
README:    
rtoy committed
160
161
162
163
164
	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
Raymond Toy's avatar
Raymond Toy committed
165
	Fortran treats common blocks.  Default = `NIL`.
rtoy's avatar
README:    
rtoy committed
166

Raymond Toy's avatar
Raymond Toy committed
167
# Using Converted Code
rtoy's avatar
rtoy committed
168
169
170
171
172
173
174

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.

Raymond Toy's avatar
Raymond Toy committed
175
# Issues
rtoy's avatar
rtoy committed
176
177
178
179
180

For a more detailed list of issues and notes, see src/NOTES.

We highlight just a few issues here.

Raymond Toy's avatar
Raymond Toy committed
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
## 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.

## 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, one routine might have
Raymond Toy's avatar
Raymond Toy committed
203
```
rtoy's avatar
README:    
rtoy committed
204
        COMMON /foo/ a(10), b, i(4)
Raymond Toy's avatar
Raymond Toy committed
205
```
Raymond Toy's avatar
Raymond Toy committed
206

Raymond Toy's avatar
Raymond Toy committed
207
and another might say
Raymond Toy's avatar
Raymond Toy committed
208

Raymond Toy's avatar
Raymond Toy committed
209
```
rtoy's avatar
README:    
rtoy committed
210
        COMMON /foo/ b(9), c, d, j(2), k(2)
Raymond Toy's avatar
Raymond Toy committed
211
```
Raymond Toy's avatar
Raymond Toy committed
212

Raymond Toy's avatar
Raymond Toy committed
213
214
215
216
217
218
219
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
Raymond Toy's avatar
Raymond Toy committed
220
```
rtoy's avatar
README:    
rtoy committed
221
222
223
        (defstruct foo
          (part-0 (make-array 11 :element-type 'real))
          (part-1 (make-array 4 :element-type 'integer4)))
Raymond Toy's avatar
Raymond Toy committed
224
```
Raymond Toy's avatar
Raymond Toy committed
225
226
227
228
229
230
231
232
(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
Raymond Toy's avatar
Raymond Toy committed
233
```
rtoy's avatar
README:    
rtoy committed
234
235
236
237
238
239
240
241
242
243
244
245
246
          (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))
            ...)
Raymond Toy's avatar
Raymond Toy committed
247
```
Raymond Toy's avatar
Raymond Toy committed
248
249
250
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.
rtoy's avatar
README:    
rtoy committed
251
252
253
  


Raymond Toy's avatar
Raymond Toy committed
254
255
256
257
258
259
260
261
262
263
## 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.  
Raymond Toy's avatar
Raymond Toy committed
264

Raymond Toy's avatar
Raymond Toy committed
265
266
267
If this is not done, the user may have to modify either the
Fortran code or the resulting Lisp code to pass arguments
correctly.  
Raymond Toy's avatar
Raymond Toy committed
268

Raymond Toy's avatar
Raymond Toy committed
269
270
F2cl cannot always determine whether a slice of an array should be
used or just the single element.
rtoy's avatar
rtoy committed
271

272
273
274
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.
rtoy's avatar
rtoy committed
275
276


Raymond Toy's avatar
Raymond Toy committed
277
# Acknowledgments
rtoy's avatar
rtoy committed
278

rtoy's avatar
rtoy committed
279
280
281
282
283
284
285
286
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.
rtoy's avatar
rtoy committed
287

rtoy's avatar
rtoy committed
288
289
290
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.