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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.