Skip to main content

Fortiel Compiler / Fortran Preprocessor

Project description

fortiel — Fortran preprocessor and metaprogramming engine

Fortiel (mixed Fortran and Cockatiel) is a Fortran preprocessor.

Installation

Fortiel can be install as the PyPI package:

pip3 install fortiel

Preprocessor language

Directives

Common directive syntax is:

#fpp directiveName directiveArguments

where directiveName is one of the known preprocessor directives. The #fpp directive header is treated as a single token, so no whitespaces are allowed between # and fpp.

Both fpp and directiveName are case-insensitive (Python expressions and file paths although are case-sensitive), so the following lines are equivalent:

#fpp use 'filename'
! and
#FpP uSe 'filename'

Continuation Lines

Fortran-style continuation lines & are supported within the preprocessor directives:

#fpp directivePart &
        anotherDirectivePart
! and
#fpp directivePart &
        & anotherDirectivePart

include directive

directly the contents of the file located at filePath into the current source:

#fpp include 'filePath'
! or
#fpp include "filePath"
! or
#fpp include <filePath>

use directive

is the same as include, but it skips the non-directive lines:

#fpp use 'filePath'
! or
#fpp use "filePath"
! or
#fpp use <filePath>

let directive

declares a new named variable:

#fpp let var = expression

expression should be a valid Python 3 expression, that may refer to the previously defined variables, Fortiel builtins and Python 3 builtins.

Functions can be also declared using the let directive:

#fpp let fun([argument[, anotherArgument]*]) = expression

del directive

undefines the names, previously defined with the let directive:

#fpp del var[, anotherVar]*

Builtin names like __FILE__ or __LINE__ cannot be undefined.

if/else if/else/end if directive

is a classic conditional directive:

#fpp if condition
  ! Fortran code.
#fpp else if condition
  ! Fortran code.
#fpp else
  ! Fortran code.
#fpp end if

Note that else if, elseif and elif directives, end if and endif directives are respectively equivalent.

do/end do directive

substitutes the source lines multiple times:

#fpp do var = first, last[, step]
  ! Fortran code.
#fpp end do

first, last and optional step expressions should evaluate to integers. Inside the loop body a special integer variable __INDEX__ is defined, which is equal to the the current value of var.

Note that end do and enddo directives are equivalent.

line directive

changes current line number and file path:

#fpp [line] lineNumber 'filePath'
! or
#fpp [line] lineNumber "filePath"

In-line substitutions

`x` substitutions

Consider the example:

#fpp let x = 'b'
a`x`   ! evaluates to ab;
`3*x`a ! evaluates to bbba.

@x substitution

is a special substitution that becomes handy inside the #fpp do loops:

@var[,]
! or
@:[,]

This substitution spawns the token after @ (an identifier or colon character), and an optional trailing comma, the __INDEX__ amount of times.

Consider the example:

#fpp do i = 0, 2
@a, b
#fpp end do
! evaluates to
b
a, b
a, a, b

Examples

Generic programming

module Distances
    
  implicit none

#fpp let NUM_RANKS = 2

  interface computeSquareDistance
#fpp do rank = 0, NUM_RANKS
    module procedure computeSquareDistance{rank}
#fpp end do    
  end interface computeSquareDistance

contains

#fpp do rank = 0, NUM_RANKS
  function computeSquareDistance`rank`(n, u, v) result(d)
    integer, intent(in) :: n
    real, intent(in) :: u(@:,:), v(@:,:)
    real :: d
    integer :: i
    d = 0.0
    do i = 1, n
    #fpp if rank == 0
      d = d + (u(i) - v(i))**2
    #fpp else
      d = d + sum((u(@:,i) - v(@:,i))**2)
    #fpp end if
    end do
  end function computeSquareDistance`rank`
#fpp end do    

end module Distances
module Distances
    
  implicit none

  interface computeSquareDistance
    module procedure computeSquareDistance0
    module procedure computeSquareDistance1
    module procedure computeSquareDistance2
  end interface computeSquareDistance

contains

  function computeSquareDistance0(n, u, v) result(d)
    integer, intent(in) :: n
    real, intent(in) :: u(:), v(:)
    real :: d
    integer :: i
    d = 0.0
    do i = 1, n
      d = d + (u(i) - v(i))**2
    end do
  end function computeSquareDistance0
  function computeSquareDistance1(n, u, v) result(d)
    integer, intent(in) :: n
    real, intent(in) :: u(:,:), v(:,:)
    real :: d
    integer :: i
    d = 0.0
    do i = 1, n
      d = d + sum((u(:,i) - v(:,i))**2)
    end do
  end function computeSquareDistance1
  function computeSquareDistance2(n, u, v) result(d)
    integer, intent(in) :: n
    real, intent(in) :: u(:,:,:), v(:,:,:)
    real :: d
    integer :: i
    d = 0.0
    do i = 1, n
      d = d + sum((u(:,:,i) - v(:,:,i))**2)
    end do
  end function computeSquareDistance2

end module Distances

Missing features

  • Continuation lines in in-line substitutions.
  • Long lines folding.
  • CLI.
  • GFortiel documentation.
  • Builtin variables.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fortiel-0.0.12.tar.gz (10.6 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page