FEQParse_TokenStack.f90 Source File


Contents


Source Code

! FEQParse.F03
!
! Copyright 2020 Fluid Numerics LLC
! All rights reserved.
!
! Author : Joe Schoonover ( joe@fluidnumerics.com )
!
! EquationParser defines a public class that can be used to parse and evaluate strings
! representative of equations. An equation, written in infix form, is converted to
! postfix form and evaluated using a postfix calculator.
!
! //////////////////////////////////////////////////////////////////////////////////////////////// !

module FEQParse_TokenStack
  use iso_fortran_env

  implicit none

  type Token
    character(48) :: tokenString
    integer       :: tokenType
    integer       :: tokenIndex
  contains
    procedure :: Copy
  endtype

  type TokenStack
    type(Token),allocatable :: tokens(:)
    integer                  :: top_index = 0
  contains
    procedure :: Construct => Construct_TokenStack
    procedure :: Finalize => Finalize_TokenStack
    procedure :: Push => Push_TokenStack
    procedure :: Pop => Pop_TokenStack
    procedure :: IsEmpty => IsEmpty_TokenStack
    procedure :: TopToken
  endtype

contains

  subroutine Construct_TokenStack(stack,N)
    class(TokenStack),intent(out) :: stack
    integer,intent(in)            :: N

    allocate(stack%tokens(1:N))
    stack%top_index = 0

  endsubroutine Construct_TokenStack

  subroutine Finalize_TokenStack(stack)
    class(TokenStack),intent(inout) :: stack

    if(allocated(stack%tokens)) deallocate(stack%tokens)

  endsubroutine Finalize_TokenStack

  subroutine Push_TokenStack(stack,tok)
    class(TokenStack),intent(inout) :: stack
    type(Token),intent(in)         :: tok

    stack%top_index = stack%top_index+1
    stack%tokens(stack%top_index)%tokenString = tok%tokenString
    stack%tokens(stack%top_index)%tokenType = tok%tokenType
    stack%tokens(stack%top_index)%tokenIndex = tok%tokenIndex
  endsubroutine Push_TokenStack

  subroutine Pop_TokenStack(stack,tok)
    class(TokenStack),intent(inout) :: stack
    type(Token),intent(out)        :: tok

    if(stack%top_index <= 0) then
      print*,"Attempt to pop from empty token stack"
    else
      tok%tokenString = stack%tokens(stack%top_index)%tokenString
      tok%tokenType = stack%tokens(stack%top_index)%tokenType
      tok%tokenIndex = stack%tokens(stack%top_index)%tokenIndex
      stack%top_index = stack%top_index-1
    endif

  endsubroutine Pop_TokenStack

  logical function IsEmpty_TokenStack(stack)
    class(TokenStack) :: stack

    IsEmpty_TokenStack = .false.

    if(stack%top_index <= 0) then
      IsEmpty_TokenStack = .true.
    endif

  endfunction IsEmpty_TokenStack

  type(Token) function TopToken(stack)
    class(TokenStack) :: stack

    if(stack%top_index > 0) then
      TopToken%tokenString = stack%tokens(stack%top_index)%tokenString
      TopToken%tokenType = stack%tokens(stack%top_index)%tokenType
      TopToken%tokenIndex = stack%tokens(stack%top_index)%tokenIndex
    else
      TopToken%tokenString = ''
    endif

  endfunction TopToken

  function Copy(this) result(that)
    class(Token) :: this
    type(Token)  :: that

    that%tokenString = this%tokenString
    that%tokenType = this%tokenType
    that%tokenIndex = this%tokenIndex
  endfunction Copy

endmodule FEQParse_TokenStack