subroutine parse_number(unit, value)
use fson_value_m, only: TYPE_INTEGER, TYPE_REAL
implicit none
integer, intent(inout) :: unit
type(fson_value), pointer :: value
logical :: eof, negative, decimal, scientific
character :: c
integer :: integral, exp, digit_count
real(kind(1.0D0)) :: frac
! first character is either - or a digit
c = pop_char(unit, eof=eof, skip_ws=.true.)
if (eof) then
print *, "ERROR: Unexpected end of file while parsing number."
call exit (1)
else if ("-" == c) then
negative = .true.
else
negative = .false.
call push_char(c)
end if
! parse the integral
integral = parse_integer(unit)
decimal = .false.
scientific = .false.
do
! first character is either - or a digit
c = pop_char(unit, eof=eof, skip_ws=.true.)
if (eof) then
print *, "ERROR: Unexpected end of file while parsing number."
call exit (1)
else
select case (c)
case (".")
! this is already fractional number
if (decimal) then
! already found a decimal place
print *, "ERROR: Unexpected second decimal place while parsing number."
call exit(1)
end if
decimal = .true.
frac = parse_integer(unit, digit_count)
frac = frac / (10.0D0 ** digit_count)
case ("e", "E")
! this is already an exponent number
if (scientific) then
! already found a e place
print *, "ERROR: Unexpected second exponent while parsing number."
call exit(1)
end if
scientific = .true.
! this number has an exponent
exp = parse_integer(unit)
case default
! this is a integer
if (decimal) then
! add the integral
frac = frac + integral
if (scientific) then
! apply exponent
frac = frac * (10.0D0 ** exp)
end if
! apply negative
if (negative) then
frac = frac * (-1)
end if
value % value_type = TYPE_REAL
value % value_real = frac
value % value_double = frac
else
if (scientific) then
! apply exponent
integral = integral * (10.0D0 ** exp)
end if
! apply negative
if (negative) then
integral = integral * (-1)
end if
value % value_type = TYPE_INTEGER
value % value_integer = integral
!+PJK
! Following two lines are included in case the decimal point of
! a floating point number has been (accidentally) left out
value % value_real = integral
value % value_double = integral
!-PJK
end if
call push_char(c)
exit
end select
end if
end do
end subroutine parse_number