!
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
!
!         <<<<<---------------------------------------------->>>>>
!         <<<<<  2.  E X P R E S S I O N S    A N D          >>>>>
!         <<<<<      A S S I G N E M E N T S                 >>>>>
!         <<<<<---------------------------------------------->>>>>
!
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&


! We have seen how to buil "words". We shall now see how to build 
! "sentences" 

!   EXPRESSION = a combination of tokens (operand) and operators 
!                that depend on the specific tokens

!   The expression may then be assigned to a variable

! Example 1: operand OPERATOR operand

  X + Y   ! Dyadic (binary)

! Example 2: OPERATOR operand

  -Y      ! Monadic

! The rules : parts of expressions without parentheses are evaluated
!             sucessively from left to right for operators of equal 
!             precedence (e.g. + and - ) with the exception of the 
!             exponentiation ( **). If it is necessary to 
!             evaluate part of an expression (or sub-expression) 
!             separately, parentheses should be used


! Examples

  X / Y + Z   ! equivalent to 

              ! Do X / Y first and then add Z 

  X/Y/Z       ! Equivalent to X / (Y * Z )
                 

!***********************************************************************
!  SCALAR NUMERIC EXPRESSIONS
!***********************************************************************

! Expression whose operands are one of the three numeric data types
! (integer, real, complex) and the operators are 

   **     ! exponentiation
   * /    ! multiplication, division
   _ -    ! addition, subtraction

! The minus sign is permitted as UNARY operators, like in 

 +X 
 -Y

! However they are not permitted without parentheses after another 
! operator 

! Example: The expression x to the negative power y :

  X**-Y    ! WRONG !!
  X**(-Y)  ! CORRECT

!=======================================================================
! ORDER

  -X + Y + Z  ! is equivalent to (-X + Y ) + Z 

  X ** Y ** Z ! will be evaluated as X ** (Y ** Z), note that in this 
              ! case the expression is evaluated from right to left
              
!======================================================================= 

! For integers the result of any division will be truncated towards zero

  6 / 3 ! will give 2
  8 / 3 ! will give 2
 -8 / 3 ! will give -2 

! It is important to bear this in mind: ATTENTION

 2 ** 3   ! will give 8

 2**(-3)  ! will not give what you want, will give 
          !
          ! 1/(2**3) = 0   


!=======================================================================
! MIXED EXPRESSIONS
!=======================================================================

! expressions involving different data types are permitted. 
! 
! The object of the simpler (weaker) data type will be converted
! (coerced) into the stronger one. The result will be of the 
! strongest type. 
!
! Example

  INTEGER I
  REAL X

  X * I    ! the result of multiplying a real by an integer will be 
           ! a REAL

! THE RULES for a .op. b
!
! I = integer
! R = real
! C = complex
!
!
!    Type of a       Type of b         Type of result
!======================================================
!       I                I                   I 
!       I                R                   R 
!       I                C                   C            
!------------------------------------------------------  
!       R                I                   R 
!       R                R                   R 
!       R                C                   C 
!------------------------------------------------------  
!       C                I                   C 
!       C                R                   C 
!       C                C                   C     
!------------------------------------------------------  


!=======================================================================
! DEFINED AND UNDEFINED VARIABLES
!=======================================================================

! A variable is called into existence

 REAL X

! but is UNDEFINED  (it has no value assigned). 
!
! A common way to make it DEFINED is through an assignment

 X = 2.673547

! Then operations can be performed meaningfully, e.g.

 X * 0.5
 
! Variables can become undefined during the execution of a program.


!***********************************************************************
! SCALAR NUMERIC ASSIGMENT
!***********************************************************************

! variable = expression

  X = 2.734576
  I = 2
  Y = I * 2 


! RULES
!
! 
! Type of VARIABLE      Value assigned
!============================================
! INTEGER               INT(expr,KIND(var)) 
! REAL                  REAL(expr,KIND(var))
! COMPLEX               CMPLX(expr,KIND(var))
!=============================================

! Examples. Note the differences
!

  INTEGER I 
  I = 7                 ! OK
  I = 7.3               ! Loss of the decimal part

  REAL Y
  COMPLEX C
  Y = 2.33              ! OK
  Y = (2.536, -0.256)   ! Y will be assigned the value 2.536
                        ! Loss of imaginary part
  C = (2.536, -0.256)   ! OK 


!***********************************************************************
! SCALAR RELATIONAL OPERATORS
!*********************************************************************** 

! In CONDITIONAL statements, expressions are compared to test whether
! their values bear a certain relation to each other

  !--------------------------------------------
  ! List of relational operators in Fortran 90  
  !--------------------------------------------
    .LT.    <     ! less than 
    .LE.    <=    ! less than or equal 
    .EQ.    ==    ! equal
    .NE.    /=    ! not equal
    .GT.    >     ! greater than 
    .GE.    >=    ! greater than or equal 
  !--------------------------------------------

! If either or both of the expressions are complex,
! only the operators == and /= are available 

! The result of a comparison made with one of such operators
! is one of the logical values 
!
  .TRUE.   
  .FALSE.

!########################################################
! SUCH TESTS ARE EXTREMELY IMPORTANT IN CONTROLLING THE 
! FLOW OF A PROGRAM  
!########################################################

! Examples of relational expressions

 INTEGER I, J 
 REAL A, B
 CHARACTER(1) CHAR1
 
 
 I .LT. J 
 A < B
 A+B < I+J

 CHAR1 = 'A'
 CHAR1 == 'A'    ! ---> .TRUE.

 CHAR1 = 'V'
 CHAR1 == 'A'    ! ---> .FALSE.
 

 
! Note that mixed-type relational expressions can be used 
! such as the third one above. In this case the two expressions 
! to be compared are both converted to the data type of theri sum
! before performing the comparison ( I+J will be converted to 
! real before comparing to A+B ) 


!***********************************************************************
! SCALAR LOGICAL EXPRESSIONS AND ASSIGNMENTS
!*********************************************************************** 

! Logical operators in decreasing order of precedence

!***** UNARY OPERATORS

 .NOT.           ! Logical negation
 
!***** BINARY OPERATORS

 .AND.           ! Logical intersection
 .OR.            ! Logical union
 .EQV.  .NEQV.   ! Logical equivalence (non-equivalence)

! EXAMPLES

 LOGICAL I,J,K,L

 .NOT. J                 ! Valid. If J is .TRUE. ---> .NOT. J is .FALSE.
 J .AND. K               ! VALID
 I OR. L .AND. .NOT. J   


! The result of any logical expression is the value true or false 
! and may then be assigned to a logical variable


  LOGICAL, DIMENSION(10) :: FLAG
  LOGICAL J

  J = .TRUE.                  
  FLAG(3) = .NOT. J 

! The results of several relational expressions may be combined 
! into logical expressions

 REAL A,B,X,Y
 LOGICAL COND

 COND = A>B .OR. X<0 .AND. Y>1
   

!***********************************************************************
! SCALAR CHARACTER EXPRESSIONS AND ASSIGNMENTS
!*********************************************************************** 
 
! The only intrinisc operator for character expression is 
! the concatenation operator 

  'AB'//'CD'   ! this produces the string 'ABCD'

! The result of such an operation can be assigned to 
! another character variable of the same kind

  CHARACTER(LEN=4) CHAR1,CHAR2
  CHARACTER(LEN=6) RESULT

  CHAR1 = 'WHAT'
  CHAR2 = 'EVER'
  RESULT = CHAR1//CHAR2

! The strings are filled from left to right. If in an assignement
! the string on the right is shorter, the string on the left will
! be filled from left and contain blanks at the end. Conversely,
! if the string on the right is longer, the string on the left will 
! be truncated (from the left). 

! Examples

  CHARACTER(LEN=5) CHAR

  CHAR = 'MOI'   ! The string CHAR will be 'MOI  '
!                                              ^^
!                                              These are two blanks

  CHARACTER(LEN=5) CHAR

  CHAR = 'J"en ai marre'   ! The string CHAR will be 'J"en '


!***********************************************************************
! ARRAY EXPRESSIONS AND ASSIGNMENTS
!*********************************************************************** 
 
! In Fortran 90 operations are allowed between arrays of the    
! same SHAPE (i.e. RANK and DIMENSION). Two arrays of the same
! shape are said to be CONFORMABLE.
! 
! The following are allowed operations between conformable arrays

  REAL, DIMENSION(10,50) :: A,B
  REAL, DIMENSION(10)    :: V

  A / B             ! An array whose (i,j) element is A(i,j) / B(i,j)
  V + 1.            ! An array whose i-th element is V(i) + 1.
  5./V + A(1:10,4)  ! An array whose i-th element is 
                    !
                    ! 5./V(i) + A(i,4) 
                    !
  A .EQ. B          ! This means A(i,j) .EQ. B(i,j)   

! Note that the correspondence is by POSITION and not by subscript 
! value. Look at the example below


  A(2:4,7:10) + B(7:9,1:4) 

! the result is the array

  A(I+1,J+6) + B(I+6,J)    ! I=1,2,3   and  J=1,2,3,4

! Try to draw it pictorially. Draw the matrices A and B and 
! identify the two sub-blocks that we are summing      


!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! ARRAY ASSIGNMENTS
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

! An array EXPRESSION may be ASSIGNED to an array VARIABLE of 
! the same SHAPE (RANK and DIMENSION, remember).

! If a scalar expression is used, this will be broadcast to all
! elements of the array (which will be identical as a consequence)

  A(4,2:11) = V   ! The fourth row of matrix A is assigned the 
                  ! vector (one-dimensional array) V

  A = A * 2.      ! The matrix A is replaced by a matrix where 
                  ! all elements have been multiplied by 2.

  V(5:10) = V(1:6)  ! The last six elements of the array V are 
                    ! replaced by the first six elements of the 
                    ! array V prior to the commencement of the 
                    ! assignment
 
