VIF - VIntage Fortran compiler
------------------------------

Copyright 2020-2025 J. Marcel van der Veer <algol68g@xs4all.nl>.

VIF is an 'early FORTRAN' dialect, encompassing a large subset of 
FORTRAN II/IV and FORTRAN 66/77.

VIF is a front end using a gcc compatible C99 compiler as back end. 
VIF uses gcc extensions to C, and also gcc's libquadmath.
Intermediate C code is written to file, that doubles as listing file.

A design goal for VIF was to make high precision data types available. 
It implements REAL*32 and COMPLEX*64, which VIF implements through 
HPAlib (which VIF totes).

Important differences between VIF and early FORTRAN are described below.

* Independent compilation.

  VIF is not designed for large projects, though it can compile libraries.
  Preferably all source files in a project are compiled together and linked 
  into one executable, so gcc can optimize globally. VIF can declare most 
  C objects 'static' and many equivalenced objects as 'const' pointers 
  which improves optimisation by backend gcc. 

* Formatting of source text and reserved words.
  
  VIF is fixed format like early FORTRAN but symbols cannot span records.
  Record length is 500 (formerly maximum length of a C source line) 
  compared to 80 characters in early FORTRAN. VIF is case insensitive,
  except in character strings.

  Early FORTRAN knows no reserved words - context determines meaning.
  VIF knows reserved words and requires reserved words to be separated 
  from variable names by whitespace. Reserved words can mostly be used 
  as variable names though.

  Early FORTRAN limits the length of variable and subprogram names to 6 
  characters. VIF limits this to the record length. Also a name may contain
  underscores, but cannot start with one.

* Types and internal representation of data.
 
  VIF depends on 'gcc' and 'libquadmath' that comes with it.
  VIF generates code for the 'gcc' hardware representation as follows:

    INTEGER*2  -> int16_t        -> int_2
    INTEGER*4  -> int            -> int_4
    INTEGER*8  -> int64_t        -> int_8
    LOGICAL*4  -> unsigned       -> logical_4
    REAL*4     -> float          -> real_4
    REAL*8     -> double         -> real_8
    REAL*16    -> __float128     -> real_16
    COMPLEX*8  -> complex        -> complex_8
    COMPLEX*16 -> double complex -> complex_16
    COMPLEX*32 -> __complex128   -> complex_32
    REAL*32    ->                -> real_32    // Software implementation, HPALIB
    COMPLEX*64 ->                -> complex_64 // Software implementation, HPALIB

  VIF implements any CHARACTER*n length as a C string.
  CHARACTER strings are null-terminated as in C, not padded with spaces.
  A single CHARACTER is a string of two bytes.

* 'Jurassic' features obsoleted in modern Fortran and VIF.

  * Alternate ENTRY and alternate RETURN are F77 constructs that were never
  considered good programming practice. VIF does not implement them.
  Like EQUIVALENCE, ENTRY was a tool to minimize storage footprint. 
  That was important in the 1950's, but nowadays, nobody cares. 

* Not implemented (yet, and probably never).

  * Namelist IO.

  * List-directed niceties and sugar as for example repetition counts for
  input items. You can however read free-format with e.g. READ (*, *) I, Z.
  A repetition count for DATA items is implemented.

* Deviations from early FORTRAN.

  * VIF allows recursion, which is not supported by early FORTRAN.
    IO statements are not re-entrant however.

  * Early FORTRAN does not allow two adjacent operator symbols with 
    exceptions for practical combinations as .AND..NOT. etcetera.
    Hence in early FORTRAN, I--1 must be strictly written as I-(-1).
    VIF does not pose this restriction. 

  * Subprograms can declare variables in (named) COMMON blocks,
    and VIF merges all declarations to form the COMMON blocks after
    compilation. Hence there is no need to specify in every subprogram
    all variables per block in the correct order.

  * VIF constant lists in DATA statements are circular, like format
    lists. Hence after INTEGER ROW(100) you can initialize the array
    with DATA ROW /0/ in VIF while in early FORTRAN this only initializes 
    the first element.

  * VIF has a DO REPEAT ... END DO construct where 'UNTIL (condition)'
    terminates it when TRUE. There can be multiple UNTIL statements.

  * In the intermediate language (C), labels in principle have function 
    scope. VIF has the same feature. Hence next snippet would be 
    invalid early FORTRAN, but is accepted by VIF:

    IF (condition) THEN
      ...
      GOTO 1
      ...
    ELSE
      ...
  1   ...
      ...
    ENDIF

    Needless to say that this is not a recommended coding style.

  * VIF allows Fortran 90 statements 'EXIT' and 'CYCLE'.

  * Vintage operators like .EQ. and .NE. can be denoted as '==', '!=', etcetera.
    Also .AND. can be denoted as '&', .OR. as '|', .XOR. as '^' and .NOT. as '!'.

  * VIF allows CRAY-1 FORTRAN two-branch arithmetic if-statements and 
    indirect logical-if statements.

