Coder Social home page Coder Social logo

Comments (12)

awvwgk avatar awvwgk commented on July 19, 2024 1

While a somewhat unsatisfying solution, it seems to pass the TOML testsuite. Since those branches are only relevant for reading exceptional values they are possibly not performance critical, so this should be an okay-ish solution for the time being.

from toml-f.

awvwgk avatar awvwgk commented on July 19, 2024 1

I know, I only removed cases in the library and not the tests.

from toml-f.

awvwgk avatar awvwgk commented on July 19, 2024

The ieee_value function is used to create values for NaN, Inf and -Inf at

toml-f/src/tomlf/de/lexer.f90

Lines 1297 to 1309 in 6290b0b

if (match(lexer, first, "n")) then
val = ieee_value(val, ieee_quiet_nan)
return
end if
if (match(lexer, first, "i")) then
if (match(lexer, token%first, char_kind%minus)) then
val = ieee_value(val, ieee_negative_inf)
else
val = ieee_value(val, ieee_positive_inf)
end if
return
end if

If there is a standard conforming way to implement these without ieee_value I'm happy to use those. Note that the TOML standard requires a compliant parser to provide support for IEEE 754 binary64 values (see here).

from toml-f.

awvwgk avatar awvwgk commented on July 19, 2024

One quick hack would be to replace the values with BOZ literals. But this might actually be less portable, since it does not account for endianess.

 if (match(lexer, first, "n")) then 
    val = real(z'7FF8000000000001', tfr)
    return 
 end if 
  
 if (match(lexer, first, "i")) then 
    if (match(lexer, token%first, char_kind%minus)) then 
       val = real(z'FFF0000000000000', tfr)
    else 
       val = real(z'7FF0000000000000', tfr)
    end if 
    return 
 end if 

from toml-f.

barracuda156 avatar barracuda156 commented on July 19, 2024

@awvwgk Unfortunately I cannot come up with any suggestions as long as Fortran goes. (C++ has implementations for those.)

Using code which does not account for endianness would be a step backward IMO. That will break more platforms than we have broken now :)
To be clear, I am actually looking for a generally optimal solution here, not for a hack to make it work for me. For me it works, I have an experimental fix for gfortran which allows building ieee_arithmetic module. (The error I quoted is from Rosetta system; the same version of fpm builds fine on my PowerMac with kinda-fixed gfortran.)

from toml-f.

awvwgk avatar awvwgk commented on July 19, 2024

At least gfortran will create errors in case one tries to use the tricks described in the C++ docs to create exceptional values:

❯ cat exceptional.f90
program exceptional
  implicit none

  print '(g0)', &
    acos(2.0), &
    log(-1.0), &
    sqrt(-1.0)

  print '(g0)', &
    huge(1.0)*2
end program exceptional
❯ gfortran exceptional.f90&& ./a.out
exceptional.f90:5:9:

    5 |     acos(2.0), &
      |         1
Error: Argument of ACOS at (1) must be between -1 and 1
exceptional.f90:6:8:

    6 |     log(-1.0), &
      |        1
Error: Argument of LOG at (1) cannot be less than or equal to zero
exceptional.f90:7:9:

    7 |     sqrt(-1.0)
      |         1
Error: Argument of SQRT at (1) has a negative value
exceptional.f90:10:8:

   10 |     huge(1.0)*2
      |        1
Error: Arithmetic overflow at (1)

from toml-f.

awvwgk avatar awvwgk commented on July 19, 2024

Currently I cannot come up with a better solution other than ieee_value which is the standard conforming way to obtain those values (in Fortran there is usually one way and only one way to archive most things).

from toml-f.

awvwgk avatar awvwgk commented on July 19, 2024

The only more general fix I can come up with is an internal read, which I am actually trying to avoid in this piece of the code...

 if (match(lexer, first, "n")) then 
    read("NaN", *) val
    return 
 end if 
  
 if (match(lexer, first, "i")) then 
    read("Inf", *) val
    if (match(lexer, token%first, char_kind%minus)) then 
       val = -val
    end if 
    return 
 end if 

from toml-f.

barracuda156 avatar barracuda156 commented on July 19, 2024

The only more general fix I can come up with is an internal read, which I am actually trying to avoid in this piece of the code...

 if (match(lexer, first, "n")) then 
    read("NaN", *) val
    return 
 end if 
  
 if (match(lexer, first, "i")) then 
    read("Inf", *) val
    if (match(lexer, token%first, char_kind%minus)) then 
       val = -val
    end if 
    return 
 end if 

Is the fallback code feasible or too complicated? Some macro that gonna determine if ieee_arithmetic is supported by the compiler, if not, then use suboptimal, but still working code.

from toml-f.

barracuda156 avatar barracuda156 commented on July 19, 2024

@awvwgk Thank you!

from toml-f.

barracuda156 avatar barracuda156 commented on July 19, 2024

@awvwgk Turned out, there are more instances:

/opt/local/var/macports/build/_opt_PPCRosettaPorts_fortran_toml-f/toml-f/work/build/_deps/test-drive-src/test/test_select.F90:15:20:

   15 |   use, intrinsic :: ieee_arithmetic, only : ieee_value, ieee_quiet_nan
      |                    1
Fatal Error: Cannot find an intrinsic module named 'ieee_arithmetic' at (1)
compilation terminated.
/opt/local/var/macports/build/_opt_PPCRosettaPorts_fortran_toml-f/toml-f/work/build/_deps/test-drive-src/test/test_check.F90:25:20:

   25 |   use, intrinsic :: ieee_arithmetic, only : ieee_value, ieee_quiet_nan
      |                    1

from toml-f.

barracuda156 avatar barracuda156 commented on July 19, 2024

I know, I only removed cases in the library and not the tests.

Got it, thanks. Maybe add an option to build without tests then? Now it is unconditional:

# add the testsuite
enable_testing()
set(fpm-toml "${PROJECT_SOURCE_DIR}/fpm.toml")
add_subdirectory("test")

from toml-f.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.