1! This file is an example to test the syntax highlighting file fortran-free.xml
2! (for fortran, free format)
3
4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
5!                      THIS IS AN EXAMPLE OF A MODULE                          !
6!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7module module_example
8
9  ! use 'implicit none' when you want all variables to be declared
10  implicit none
11
12!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
13! PUBLICS AND PRIVATES
14
15  ! In fortran 90 you can define your own operator
16  public :: operator(.norm.)
17  public :: operator(+) ! <-- you can also overload the usual operators
18  public :: factorial
19  public :: example_fn
20
21  private :: point3d_add
22  private :: point3d_norm
23
24!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
25! USER-DEFINED TYPES...
26
27  ! This is a definition to use in declarations of real variables,
28  ! parameters, etc.
29  integer, parameter, public :: kr = selected_real_kind(10)
30
31  ! This is a user-defined type
32  type, public :: point3d
33    real(kind=kr) :: x, y, z
34  end type point3d
35
36  ! This type is useless: it is only an example of type definition!
37  type, public :: example_type
38    complex(kind=kr)            :: c ! <-- a complex number (two reals of kind kr)!
39    real, dimension(-10:10)     :: & ! <-- this line does not end here!
40      r1, r2 ! <-- this is the final part of the previous line
41    real, pointer, dimension(:) :: pointer_to_array_of_real
42    real, dimension(:), pointer :: array_of_pointer_to_real
43  end type example_type
44
45!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
46! INTERFACES...
47
48  ! Interface for the norm of a 3-D vector
49  interface operator(.norm.)
50    module procedure point3d_norm
51  end interface
52
53  ! Interface for the operator '+'
54  interface operator(+)
55    module procedure point3d_add
56  end interface
57
58!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
59! SOME DECLARATIONS...
60
61  ! A real number can be declared with the following line:
62  real(kind=kr) :: real_var1
63  ! But if you are not interested on the precision of floating point numbers,
64  ! you can use simply:
65  real :: real_var2
66
67  ! An array can be declared in two ways:
68  real(kind=kr), dimension(1:10, -4:5), private :: a, b, c
69  real(kind=kr), private :: d(1:10, -4:5)
70
71  ! This is a string with fixed lenght
72  character(len=10) :: str_var
73
74  ! This is an allocatable array, which can be a target of a pointer
75  type(example_type), private, dimension(:), allocatable, target :: &
76   many_examples
77
78! Fortran 90 hasn't got its own preprocessor, it uses the C preprocessor!
79#ifdef XXX
80
81#endif
82
83contains
84
85
86  ! The sum of two points
87  pure function point3d_add(a, b) result(rs)
88    type(point3d) :: rs
89    type(point3d), intent(in) :: a, b
90    rs%x = a%x + b%x
91    rs%y = a%y + b%y
92    rs%z = a%z + b%z
93  end function point3d_add
94
95
96  ! The norm of a point
97  pure function point3d_norm(a) result(rs)
98    real(kind=kr) :: rs
99    type(point3d), intent(in) :: a
100    rs = sqrt(a%x * a%x + a%y * a%y + a%z * a%z)
101  end function point3d_norm
102
103
104  ! A simple recursive function
105  recursive function factorial(i) result (rs)
106    integer :: rs
107    integer, intent(in) :: i
108    if ( i <= 1 ) then
109      rs = 1
110    else
111      rs = i * factorial(i - 1)
112    end if
113  end function factorial
114
115
116  ! This is a useless function
117  subroutine example_fn(int_arg, real_arg, str_arg)
118    integer, intent(in) :: int_arg
119    real(kind=kr), intent(out) :: real_arg
120    character(len=*), intent(in) :: str_arg
121
122    type(example_type), pointer :: p
123    integer :: n, i, j
124    logical :: flag
125
126    flag = .true. ! .true. is not an operator!
127    if ( flag .and. flag ) then ! .and. is a pre-defined operator
128      print *, "blabla"
129    end if
130
131    ! Examples of inquiry functions: allocated, lbound, ubound.
132    if ( .not. allocated(many_examples) ) then
133      allocate( many_examples(10) )
134    end if
135    print *, "Lower bound = ", lbound(many_examples, 1)
136    print *, "Upper bound = ", ubound(many_examples, 1)
137
138    p => many_examples(5) ! <-- p is a pointer
139
140    ! A strange way to calculate i*i: add the first i odd numbers
141    i = 6
142    j = 0
143    do n = 1, i
144      j = j + (2*n - 1)
145    end do
146    print *, "i*i = ", i*i, j
147
148    real_arg = real(j) ! <-- here the highlighting is not very good:
149    ! it is unable to distinguish between this and a definition like:
150    !  real(kind=kr) :: a
151    deallocate( many_examples )
152  end subroutine example_fn
153
154end module module_example
155
156
157!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
158!                         THIS IS THE MAIN PROGRAM                             !
159!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
160program example
161  use module_example
162
163  ! this is another example of use of the 'implicit' keyword
164  implicit double precision (a-h,o-z)
165
166  real(kind=kr) :: var_out
167
168  type(point3d) :: &
169   a = point3d(0.0_kr, 1.0_kr, 2.0_kr), &
170   b = point3d(4.0_kr, 5.0_kr, 6.0_kr)
171
172  print *, "a + b = ", .norm. (a + b)
173  print *, "factorial of 5 = ", factorial(5)
174
175  call example_fn(1, var_out, "hello!")
176
177end program example
178