# Expressions and assignments

by Michael Metcalf / CERN CN-AS

The rules for scalar numeric expresions and assignments, as known from FORTRAN 77, are extended to accommodate the non-default kinds we encountered in Part 1. Thus, the mixed-mode numeric expression and assignment rules incorporate different kind type parameters in an expected way:

```             real2 = integer + real1
```
converts integer to a real value of the same kind as real1; the result is of same kind, and is converted to the kind of real2 for assignment.

For scalar relational operations, there is a set of new, alternative operators:

```             <   <=   ==   /=   >   >=
```
so we can write expressions such as
```        IF (a < b .AND. i /= j) THEN ! for numeric variables
flag = flag == semaphore     ! for logical variables
```

In the case of scalar characters, two old restrictions are lifted. Given

```        CHARACTER(8) result
```
it is now legal to write
```        result(3:5) = result(1:3)    ! overlap allowed
result(3:3) = result(3:2)    ! no assignment of null string
```

For an operation between derived-data types, or between a derived type and an intrinsic type, we must define the meaning of the operator. (Between intrinsic types, there are intrinsic operations only.) Given

```             TYPE string
INTEGER       length
CHARACTER(80) value
END TYPE string
CHARACTER    char1, char2, char3
TYPE(string) str1,  str2,  str3
```
we can write
```             str3  = str1//str2       ! must define operation
str3  = str1.concat.str2 ! must dedine operation
char3 = char2//char3     ! intrinsic operator only
str3  = char1            ! must define assignment
```
For the first two cases, assignment applies on a component-by-component basis (but can be overridden), and they also require us to define the exact meaning of the // symbol. We see here the use of an intrinsic symbol and of a named operator, .concat. . A difference is that, for an intrinsic operator token, the usual precedence rules apply, whereas for named operators their precedence is the highest as a unary operator or the lowest as a binary one. In
```             vector3 = matrix    *    vector1  + vector2
vector3 =(matrix .times. vector1) + vector2
```
the two expresions are equivalent only if appropriate parentheses are added as shown. In each case, we have to provide, in a module, procedures defining the operator and assignment, and make the association by an interface block, also in the module (we shall return to this later). For the moment, here is an example of an interface for string concatenation
```             INTERFACE OPERATOR(//)
MODULE PROCEDURE string_concat
END INTERFACE
```
and an example of part of a module containing the definitions of character-to-string and string-to-character assignment. The string concatenation function was shown already in Part 1.
``` MODULE string_type
TYPE string
INTEGER length
CHARACTER(LEN=80)   :: string_data
END TYPE string
INTERFACE ASSIGNMENT(=)
MODULE PROCEDURE c_to_s_assign, s_to_c_assign
END INTERFACE
INTERFACE OPERATOR(//)
MODULE PROCEDURE string_concat
END INTERFACE
CONTAINS
SUBROUTINE c_to_s_assign(s, c)
TYPE (string)      :: s
CHARACTER(LEN=*)   :: c
s%string_data = c
s%length = LEN(c)
END SUBROUTINE c_to_s_assign
SUBROUTINE s_to_c_assign(c, s)
TYPE (string)      :: s
CHARACTER(LEN=*)   :: c
c = s%string_data(1:s%length)
END SUBROUTINE s_to_c_assign
FUNCTION string_concat(s1, s2)
:
END FUNCTION string_concat
END MODULE string_type
```
Defined operators such as these are required for the expressions that are allowed too in structure constructors (see Part 1):
``` str1 = string(2, char1//char2)  ! structure constructor
```

So far we have discussed scalar variables. In the case of arrays then, as long as they are of the same shape (conformable), operations and assignments are extended in an obvious way, on an element-by-element basis. For

```   REAL, DIMENSION(10, 20) :: a, b, c
REAL, DIMENSION(5)      :: v, w
LOGICAL                    flag(10, 20)
```
can write
```   a = b                    ! whole array assignment
c = a/b                  ! whole array division and assignment
c = 0.                   ! whole array assignment of scalar value
w = v + 1.               ! whole array addition to scalar value
w = 5/v + a(1:5, 5)      ! array division, and addition to section
flag = a==b              ! whole array relational test and assignment
c(1:8, 5:10) = a(2:9, 5:10) + b(1:8, 15:20)
! array section addition and assignment
v(2:5) = v(1:4)          ! overlapping section assignment
```
The order of expression evaluation is not specified in order to allow for optimization on parallel and vector machines. Of course, any operators for arrays of derived type must be defined.

There are some new real intrinsic functions that are useful for numeric computations:

```        CEILING         FLOOR         MODULO (also integer)
EXPONENT        FRACTION
NEAREST         RRSPACING     SPACING
SCALE           SET_EXPONENT
```
Like all FORTRAN 77 functions (SIN, ABS, etc.), except LEN, these are array valued for array arguments (i.e. are elemental).