Ratfor90
Bare-bones Fortran is our most universal computer language for computational physics. For general programming, however, it has been surpassed by C. Ratfor is Fortran with C-like syntax. Ratfor was invented by the people who invented C. After inventing C, they realized that they had made a mistake (too many semicolons) and they fixed it in Ratfor, although it was too late for C. Otherwise, Ratfor uses C-like syntax, the syntax that is also found in the popular languages C++ and Java .
At SEP we supplemented Ratfor77 by preprocessors to give Fortran77 the ability to allocate memory on the fly. These abilities are built into Fortran90 and are seamlessly included in Ratfor90. To take advantage of Fortran90's new features while maintaining the concise coding style provided by Ratfor required us to write a new Ratfor preprocessor, Ratfor90, which produces Fortran90, rather than Fortran77 code.
You should be able to read Ratfor if you already know Fortran or any similar computer language. Writing Ratfor is easy if you already know Fortran. In general written Fortran is valid Ratfor, the only. Ratfor uses C style definition of lines and {} for expanded statements. To maximize the amount of Ratfor, you will need to know its rules. Here they are:
Statements on a line may be separated by ";". Statements may be grouped together with braces "{ }". Do loops do not require statement numbers because "{ }" defines the range. Given that if( ) is true, the statements in the following { } are done. else{ } does what you expect. We may not contract else if to elseif. We may omit the braces { } where they contain only one statement. break (equivalent to the Fortran90 exit) causes premature termination of the enclosing { }. while( ) { } repeats the statements in { } while the condition ( ) is true. Ratfor recognizes a looping statement more general than do. It is for(initialize; condition; reinitialize){ }. repeat { ... } until( ) is a loop that tests at the bottom. next causes skipping to the end of any loop and a retrial of the test condition. next (equivalent to the Fortran90 cycle statement) is rarely used, and the Ratfor90 programer may write either next or cycle. With the cycle statement we encounter an inconsistency between Fortran and C-language. Where Ratfor uses next, the C-language uses continue (which in Ratfor and Fortran is merely a place holder for labels). The Fortran relational operators .gt., ge., .ne. , etc. may be written >, >=, !=, etc. The logical operators .and. and .or. may be written && and ||. Anything from a # to the end of the line is a comment. A line may be continued in Ratfor by ending it with the underscore charactor " _'' or Fortran90's &.
Indentation in Ratfor is used for readability.
It is not part of the Ratfor language.
Choose your own style.
There are two pitfalls associated with indentation.
The beginner's pitfall is to assume that a do loop ends where
the indentation ends.
The loop actually ends after the first statement.
A larger scope for the do loop is made by enclosing
multiple statements in braces.
The other pitfall arises
in any construction like if() ... if() ... else.
The else goes with the last if() regardless of indentation.
If you want the else with the earlier if(),
you must use braces like if() { if() ... } else ....
There are two rarely used features of Ratfor77
that were not implemented in Ratfor90.
break 2 which escapes from {{ }}. This feature can easily be replaced
by the loop naming features supported in Fortran90.
Ratfor77 allows & and | for the logical operators && and ||.
While attractive, it is not part of the C family of languages
and we had to drop it because Fortran90 adopts & for line continuation.
Changing all the code that generated illustrations for
four textbooks (of various ages) also turned up a few more issues:
Fortran90 uses the words scale and matmul as intrinsics.
Old Fortran77 programs using those words as variable names must be changed.
Ratfor77 unwisely allowed variables of intrinsic (undeclared) types.
We no longer allow this. Ratfor90 forces implicit none.
In Ratfor90
bracketed type, subroutine, function, and module procedures
are interpreted.
In some ways this a further step towards the C, C++, Java model.
It makes complicated modules,
subroutines inside subroutines,
and other advanced features of Fortran90 easier to interpret.
Ratfor90 recognizes a+=b as a=a+b and the similar
construct -=.
Ratfor90 has better error messages than Ratfor77.
Besides using stderr, a new file (ratfor_problem)
marks the difficulty. In addition, the output of Ratfor90 is much
more readable than the Ratfor77 version.
SEP has a considerable amount of legacy Ratfor77 code which used
two home-grown preprocessors to get around Fortran77's memory
allocation problems. Ratfor90 allows the conventions established
by these preprocessors, interpreting them into standard Fortran90.
temporary real*4 data(n1,n2,n3), convolution(j+k-1)
These declarations must follow other declarations and precede
the executable statements.
Automatic arrays are supported in Fortran90.
To allow full code compatibility
Ratfor90 simply translates this statement to
real*4 data(n1,n2,n3), convolution(j+k-1).
You can convert from Ratfor90 to Fortran90 on the command line by:
Changes and general backward compatibility issues
SEP-specific backward compatibility issues
Memory allocation in subroutines
For backward compatibility we allow
the "temporary" memory allocation introduced by our Ratfor77 processor
for example:
Examples
Below are two simple Ratfor subroutines for
finding the signum function sgn(x) = |x|
(signum()),
and (tcaf) a fortran90 module that uses overloading to
transient convolution.
Math funcion
Transient convolution
The main program environment
Ratfor90 supports some traditional
SEP local memory allocation and data base I/O
statements.
In addition it
calls an essential seplib initialization routine initpar(),
organizes the self-doc, and simplifies data-cube input.
The basic syntax for memory allocation is
allocate: real x(n1,n2).
Ratfor90 translates this syntax into
a call to dynamically allocate a allocatable array.
See the on-line self-documentation or the manual pages for full details.
Following is a complete Ratfor program for a simple task:
#
Downloading/Installing
You can download ratfor90 from here. You might need to change
the first line of the code indicating where perl is on your system.
prompt%ratfor90 < input.r90 > output.f90
If you wish to use expanded SEP comand line, history file manipulation,
and self-documentation abilities
add the -sep -SOURCE /my/source/location flags.
Sample Output
Here is a Ratfor90 code that serves no useful purpose other than
demonstrating a number of the features of ratfor
#
#
# test.x
#%
program test{
integer i1,i2,n1,n2,count
real,pointer,dimension(:,:) :: input
from either: integer n1=5,n2=5
allocate(input(n1,n2))
input=0.; count=0
loop1: do i2=1,n2{
for(i1=1; i1 <5 ; i1+=2){
count++
if(i1==3 && i2==4) break loop1
else input(i1,i2) += count
}
}
where(input == 0) input=-15.
write(0,*) input
}
And the resulting Fortran90 code:
!
!
!test.x
!%
program test
integer i1,i2,n1,n2,count
real,pointer,dimension(:,:) :: input
integer fetch, putch
call initpar()
call doc('/homes/sep/bob/test.rs90')
if (0==fetch('n1','d',n1))then
n1=5
end if
if (0/=putch('From either: n1','d',n1))then
call seperr('trouble writing n1 to history file')
end if
if (0==fetch('n2','d',n2))then
n2=5
end if
if (0/=putch('From either: n2','d',n2))then
call seperr('trouble writing n2 to history file')
end if
allocate(input(n1,n2))
input=0.
count=0
loop1: do i2=1,n2
i1=1
do
if( .not. (i1<5)) then
exit
end if
count = count+1
do
if( .not. (i1<5)) then
exit
end if
count = count+1
if (i1 .eq. 3 .and. i2 .eq. 4)then
exit loop1
else
input(i1,i2) = input(i1,i2) + count
end if
i1=i1+2
end do
end do loop1
where(input .eq. 0)
input=-15.
end where
write(0,*) input
end program
References
Claerbout, J., 1990,
Introduction to seplib and SEP utility software:
SEP-70, 413-436.
Claerbout, J., 1986,
A canonical program library:
SEP-50, 281-290.
Cole, S., and Dellinger, J.,
Vplot: SEP's plot language:
SEP-60, 349-389.
|
Department of Geophysics Stanford University |
|