FOREST was a preprocessor for FORTRAN that allowed FORTRAN programs to be defined as though written in a structured programming language.
At Atlas, the preprocessor was redefined in a translator writing system called META II.
FOREST, a structured FORTRAN preprocessor, is available to users and is described in a later document. The complete FOREST program is written in FORTRAN and contains a number of facilities not available in the system defined in META. The main purpose of the META implementation is to illustrate the use of the system as a preprocessor.
The standard FORTRAN language is enhanced by the following constructs:
.IF <(condition)> .THEN
<statements>
.ENDIF
.IF <(condition)> .THEN
<statements>
.ELSE
<statements>
.ENDIF
.WHILE <(condition)>
<statements>
.ENDWH
.SWITCH(I,3)
.CASE(l)
<statements>
.CASE(2)
<statements>
.CASE(3)
<statements>
.ENDSW
.LOOP
<statements>
.EXITIF <(condition)>
<statements>
.EXITIF
<(condition)>
.ENDLP
.CYCLE 1=1,10
<statements>
.ENDCY
.CYCLE I=1,10
<statements>
.EXITIF <(condition)>
<statements>
.ENDCY
.CYCLE 1=1,10
<statements>
.EXITIF <(condition)>
<statements>
.REPEAT
<statements>
.ENDCY
.WRITE(l, [215]) I,J
Most of these constructs are self=evident. The EXITIF construct may appear several times in a LOOP or CYCLE. The .REPEAT facility in the .CYCLE construct allows a set of statements to be defined which are obeyed assuming the cycle is completed without jumping out by an EXITIF command. The EXITIF always jumps to the statement following the ENDCY command.
Each FOREST routine finishes with a .END statement and the set of FOREST routines is terminated by a .FINISH command. An example of a FOREST program and the preprocessed FORTRAN code is given below:
SUBROUTINE FRED
C
C IF
.IF(A .GT. B) .THEN
C=D
.ENDIF
C IF THEN ELSE C
.IF(E .GT. F) .THEN
X=l
.ELSE
Y=l
.ENDIF
C WHILE
.WHILE(A .GT. B)
A=A-B
.ENDWH
C SWITCH
.SWITCH(I,3)
.CASE (1)
A=B
.CASE(2)
A=C
.CASE(3)
A=D
.ENDSW
C LOOP
.LOOP
A=B
.EXITIF(G .GT. H)
G=G+B
.ENDLP
C CYCLE
.CYCLE 1=1,7,2
A=A+I
.EXITIF(H .GT 9.0)
.REPEAT
H=0.0
.ENDCY
C WRITE
.WRITE(l, [215]) I,J C
C END
.END
.FINISH
The preprocessed code for the above program is:
SUBROUTINE FRED
C IF
IF(.NOT. (A .GT. B) )GOTO 2001
C=D
2001 CONTINUE
C IF THEN ELSE
IF ( .NOT (A .GT. B ))GOTO 2002
X=1
GOTO 3001
2002 CONTINUE
Y=1
3001 CONTINUE
C WHILE
2003 CONTINUE
IF(.NOT. (A .GT. B) GOTO 3002
A=A-B
GOTO 2003
3002 CONTINUE
C SWITCH
GOTO(2004,2005,2006),I
2004 CONTINUE
A=B
GOTO 3003
2005 CONTINUE
A=C
GOTO 3003
2006 CONTINUE
A=D
GOTO 3003
3003 CONTINUE
C LOOP
2007 CONTINUE
A=B
IF(G .GT. H)GOTO 3004
G=G+B
GOTO 2007
3004 CONTINUE
C CYCLE
DO 2008 I=1,7,2
A=A+I
IF(H .GT. 9.0)GOTO 3005
2008 CONTINUE
H=0.0
3005 CONTINUE
C WRITE
WRITE(1,2009) I,J
2009 FORMAT(2I5)
C END
END
The FOREST preprocessor is defined by the META program stored in FRSTDF:
.INIT ' 2 3' TABSET=6 CRIN=187 .INITEND
.SYNTAX FOREST
FOREST= $ (.NOT ' .FINISH' .BUT ROUTINE) ;
ROUTINE= $ (.NOT '.END' .BUT STMT) ';' [*T ' END' % ] ;
STMT = .COMNST [*B % ] / .CONTST [*B % ] /
.LABEL (
'.IF(' [ ' ' * ] IFST /
'.SWITCH('[ ' ' * ] SWST /
'.WHILE(' [ ' ' * *T 'CONTINUE' % ] WHST /
'.LOOP' [ ' ' * *T 'CONTINUE' % ] LPST /
'.WRITE(' [ ' ' * ] WRST /
'.READ(' [ ' ' * ] RDST /
'.CYCLE' [ ' ' * ] CYST /
'FORMAT' [ ' ' * ] FMST /
'CONTINUE' ';' [' ' * *T 'CONTINUE' % ] /
[' ' *] . ID FOST ) /
( '.IF' IFST /
'.SWITCH(' SWST /
'.WHILE(' WHST /
'.LOOP' LPST /
'.WRITE(' WRST /
'.READ(' RDST /
'.CYCLE' CYST /
.ID FOST ) ;
IFST = ..'.THEN' ';' [*T 'IF(.NOT.(' * ')GOTO ' *1 %]
$STMT
( '.ENDIF' ';' [ ' ' *1 *T 'CONTINUE' % ] /
'.ELSE' ';' [*T 'GOTO ' *2 %] [ ' ' *1 *T 'CONTINUE' % ]
$STMT '.ENDIF' ';' [' ' *2 *T 'CONTINUE' % ] ) ;
SWST = .ID [*->1] ',' .NUMBER ')' ';'
[*T 'GOTO(' *1 .. '),' *<-1 * % ]
$ ( '.CASE(' .NUMBER ')' ';' [ ' ' *1+ *T 'CONTINUE' %]
$ STMT [ *T 'GOTO ' *2 % ])
'.ENDSW' ';' [ ' ' *2 *T 'CONTINUE' %];
WHST = ..';' [ ' ' *1 *T 'CONTINUE' % *T 'IF(.NOT.(' *B
')GOTO ' *2 % ]
$ STMT
'.ENDWH' ';' [*T 'GOTO ' *1 % ] [ ' ' *2 *T 'CONTINUE' % ] ;
LPST = ';' [ ' ' *1 *T 'CONTINUE' % ]
$ ( '.EXITIF(' ..';' [*T 'IF(' *B 'GOTO ' *2 %] /STMT)
'.ENDLP' ';' [*T 'GOTO ' *1 % ' ' *2 *T 'CONTINUE' % ] ;
WRST = (.ID/.NUMBER) [*T 'WRITE(' * ',' *1 ] ','
'[' .. ']' [*->2] ..';' [*B %]
[*1 *T 'FORMAT(' *<-2 * ')' % ] ;
RDST = (.ID/.NUMBER) [*T 'READ(' * ',' *1 ] ','
'[' .. ']' [*->2] .. ';' [*B %]
[*1 *T 'FORMAT(' *<-2 * ')' % ] ;
CYST = ..';' [*T 'DO' ' ' *1 *B 5 ]
$( '.EXITIF(' ..';' [*T 'IF(' *B 'GOTO ' *2 %] / STMT)
('.REPEAT' ';' [ ' ' *1 *T 'CONTINUE' % ] $ STMT
'.ENDCY' ';' [ ' ' *2 *T 'CONTINUE' % ] /
'.ENDCY' ';' [' ' *1 *T 'CONTINUE' % ' ' *2 *T 'CONTINUE' % ] ) ;
FOST = [*T *]..';' [ *B % ] ;
FMST = [*T 'FORMAT'] ..';' [*B %] ;
.END
A macro called FOREST is available to preprocess and compile FOREST programs. For example, to compile the FOREST program FRED requires:
$FOREST FRED OK,SEG #METF GO COMMAND: BININ FRSTBN COMMAND: EXECTE FRED COMMAND: FREDFL FINISH ****STOP OK,FTN FREDFL GO FREDFL OK, DELETE FREDFL GO OK, CO TTY OK,
The user just types the first line $FOREST FRED. The system can be used as an alternative to FOREST. It runs about three times faster and does not pollute the file store with numerous files. Its main drawback is that error handling is less comprehensive than FOREST. Note also the notational difference in the way the EXITIF construct is written. The equivalent FOREST command is:
.IF (<condition>) .EXIT