MODULE STACK_MODULE
 IMPLICIT NONE
 
 TYPE ELEMENT_TYPE
  INTEGER(4) :: VAL
  TYPE(ELEMENT_TYPE), POINTER :: PREV
 END TYPE ELEMENT_TYPE
 
 TYPE STACK_TYPE
  INTEGER(4) :: SIZE=0
  TYPE(ELEMENT_TYPE), POINTER :: LASTIN => NULL()
 END TYPE STACK_TYPE
 
 CONTAINS
  SUBROUTINE PUSH(VAL_,STACK)
   IMPLICIT NONE
   INTEGER(4), INTENT(IN) :: VAL_
   TYPE(STACK_TYPE), INTENT(INOUT) :: STACK
   TYPE(ELEMENT_TYPE),POINTER       :: CURRENT
   ! INIT CURRENT
   ALLOCATE(CURRENT)
   CURRENT%VAL = VAL_
   CURRENT%PREV => STACK%LASTIN
   ! ADD CURRENT TO STACK
   STACK%LASTIN => CURRENT
   STACK%SIZE = STACK%SIZE+1
   RETURN
  END SUBROUTINE PUSH
  
  SUBROUTINE POP(STACK,VAL_)
   IMPLICIT NONE
   TYPE(STACK_TYPE), INTENT(INOUT) :: STACK
   INTEGER(4)      , INTENT(OUT)   :: VAL_
   TYPE(ELEMENT_TYPE), POINTER     :: B4LASTIN
   !WRITE TO VAL_
   IF (ASSOCIATED(STACK%LASTIN)) THEN
    VAL_ = STACK%LASTIN%VAL
    !TAKE OUT THE LAST-IN ELEMENT
    B4LASTIN => STACK%LASTIN%PREV
    DEALLOCATE(STACK%LASTIN)
    STACK%LASTIN => B4LASTIN
    STACK%SIZE = STACK%SIZE-1 
   ELSE
    IF (STACK%SIZE.NE.0) THEN
     PRINT*, STACK%SIZE
     STOP 'MISMATCH BETWEEN STACKSIZE AND POINTER: BAD BOOK KEEPING!'
    END IF
   END IF
   RETURN
  END SUBROUTINE POP 
END MODULE STACK_MODULE

PROGRAM MAIN
 USE STACK_MODULE
 IMPLICIT NONE
 INTEGER(4) :: I,J
 TYPE(STACK_TYPE) :: STACK1
 !STACK1%LASTIN => NULL()
 DO I = 1,10
  CALL PUSH(I,STACK1)
 END DO
 DO WHILE (ASSOCIATED(STACK1%LASTIN))
  CALL POP(STACK1,J)
  PRINT*, J
 END DO
END PROGRAM