pure subroutine tree_graph__range(self)
implicit none
class(tree_t), intent(inout) :: self
character(:), allocatable :: buf
integer(int32) :: arg(2), ios, min, max
type(tree_node_t) :: left, node
ios = 0
buf = ''
arg(:) = INVALID_REPEAT_VAL
call self%tape%get_token()
do while (self%tape%current_token /= tk_rcurlybrace)
buf= buf//trim(self%tape%token_char)
call self%tape%get_token
if (self%tape%current_token == tk_end) then
self%code = SYNTAX_ERR_CURLYBRACE_MISSING
self%is_valid_pattern = .false.
return
end if
end do
if (buf(1:1) == ',') then
buf = "0"//buf
end if
read(buf, fmt=*, iostat=ios) arg(:)
! ios has a negative value if an end-of-record condition is encountered during non-advancing input,
! a different negative value if and endfile condition was detected on the input device, a positive value
! if an error was detected, or the value zero otherwise.
!
! cf. Michael Metcalf, John Reid and Malcolm Cohen (2018)
! - "Modern Fortran Explained--Incorporating Fortran 2018"
if (ios > 0) then
self%is_valid_pattern = .false.
return
end if
buf = adjustl(buf)
if (arg(1) == 0) then ! {,max}, {0,max}
if (buf(len_trim(buf):len_trim(buf)) == ',') then
min = arg(1)
max = INFINITE
else
min = 0
max = arg(2)
end if
else if (arg(2) == INVALID_REPEAT_VAL) then ! {min,}, {num}
if (buf(len_trim(buf):len_trim(buf)) == ',') then
min = arg(1)
max = INFINITE
else
min = arg(1)
max = arg(1)
end if
else
min = arg(1)
max = arg(2)
end if
if (max /= INVALID_REPEAT_VAL .and. max /= INFINITE .and. min > max) then
self%is_valid_pattern = .false.
return
end if
node = make_repeat_node(min, max)
left = self%get_top()
call self%register_connector(node, left, terminal)
end subroutine tree_graph__range