Testing LFortran string formatting

Thanks to Sarthak Gupta (@gptsarthak) LFortran now has a runtime string formatting for print and write statements. We did the initial round of testing ourselves, we fixed all the bugs that we found, so we are opening it for alpha testers for this feature. If you could test it out and report any bugs that you find, we would really appreciate it.

Here is an example:

program format_06

real :: a,b,c,d
a = 123.456
b = 123.45678
c = 12.34
d = 123.45

10 format(a,a)
20 format("Success!",/,10X,A6,"World!")
30 format(4a4)
40 format(A2,4(2X,A),I3)

print *, "a", "b"
print 10, "c", "d"
print 20, "Hello 123"
write (*,30) "dancing","in","the","moonlight"
write (*,40) "ab", "cdef", "ghi", "jkl","qwerty",12
print 50 , 123,456,12345,6789
print 60, 123.456, -123.45678, 12.34, -123.45
write (*,70) -a, b, -c, d
write (*,80) -a, b, -c, d

50 format(i3,i10.5,/i6.6,2x,i3)
60 format(d10.2,d15.6,d010.2,2x,d7.2)
70 format(1pd10.2,2pd15.6,1pd010.2,2x,1pd9.2)
80 format(-1pe10.2,-2pe15.6,1pe010.2,2x,1pe9.2)

! Checking different scopes
if ( a > 0) then
    print 90, "Hello "
    if ( b > 0) then
      write (*,100) "World!"
    end if
  100 format(a)
  end if
90 format (a)

end program

And results in LFortran and GFortran should be identical:

$ lfortran format_06.f90 
a b
cd
Success!
          Hello World!
danc   thmoon
ab  cdef  ghi  jkl  qwerty 12
123     00456
012345  ***
  0.12D+03  -0.123457D+03  0.12D+02  *******
 -1.23D+02   12.34568D+01 -1.23D+01   1.23D+02
 -0.01E+04   0.001235E+05 -1.23E+01   1.23E+02
Hello 
World!
$ gfortran format_06.f90 && ./a.out 
 ab
cd
Success!
          Hello World!
danc  in themoon
ab  cdef  ghi  jkl  qwerty 12
123     00456
012345  ***
  0.12D+03  -0.123457D+03  0.12D+02  *******
 -1.23D+02   12.34568D+01 -1.23D+01   1.23D+02
 -0.01E+04   0.001235E+05 -1.23E+01   1.23E+02
Hello 
World!

You can inline the formatting string as in print "(i5, f18.10)", 4, 5.5 as well.

The formatting itself is implemented in our runtime library, in C, starting here and the functions above that: https://github.com/lfortran/lfortran/blob/28934d8d2ab82c0f1c6105c55a3e7091987883ac/src/libasr/runtime/lfortran_intrinsics.c#L469

11 Likes

Here is the output from my locally installed LFortran, ran via a local instance of Compiler Explorer:

We should get LFortran into Compiler Explorer so that anyone can write tests!

4 Likes

:+1:

1 Like

Definitely agree. I find myself having to do the same, with compiler explorer.
I think there’s already an issue about this, see Get LFortran into the Compiler Explorer (godbolt.org) · Issue #623 · lfortran/lfortran · GitHub Not sure if there where any blockers from godbolt and this remained in limbo.

1 Like

A simple test:

program main
implicit none

integer :: a(4)
a = [1, 2, 3, 4]

print 10, a 
! Looping "Printing support is not available for *(i0 format."

print 20, a
! Works

print 30, a
! Does not work as expected

print 40, a
! Does not work as expected

10 format (*(i0, 1x))
20 format (4(i0, 1x))
30 format ('(', 4(i0, 1x), ')')
40 format ('(', 4(i0, ',', 1x), tl2, ')')
end program main

gfortran output:

1 2 3 4
1 2 3 4
(1 2 3 4 )
(1, 2, 3, 4)

lfortran output:

Printing support is not available for *(i0 format.
1 2 3 4 
(1 (2 (3 (4 
(1 (2 (3 (4 

The lfortran I am testing for:

> lfortran --version
LFortran version: 0.20.3
Platform: Linux
Default target: x86_64-conda-linux-gnu

It seems that lfortran does not handle parentheses very well. I have not looked into it, but as said in the replies above a Compiler Explorer support would be nice! BTW, thank you and your team for your hard work. A community driven compiler is desperately needed!

1 Like

@han190 thanks! Much appreciated. I forgot to say to use the latest master (we should have made a release). In there it’s mostly fixed:

$ lfortran a.f90 
1 
2 
3 
4 
1 2 3 4 
(1 2 3 4 )
Printing support is not available for , format.
Printing support is not available for , format.
(1, 2, 3, 4, )

But there are still some differences, so I reported this at: Format differences with GFortran · Issue #2477 · lfortran/lfortran · GitHub.

@certik do you perhaps know if an official Docker container for lfortran exists? (I could not find it on the repo, but maybe I was searching wrong). I did one Dockerfile at some point and it was extremly convenient, but it stopped working after some time, and I never found enough time to fix it. It would certainly be a huge help, given fast development of lfortran, to be able to quickly pull the repo, rebuild the image and play around with whatever new featur is introduced. :slight_smile:

1 Like

@gronki we currently don’t have it, but I just created an issue for it: CI: automatically build a docker image for the latest master · Issue #2478 · lfortran/lfortran · GitHub.

LFortran is now available on the Compiler Explorer site.
See, Compiler Explorer.

Feel free to report bugs to lfortran/lfortran, if you face any issues.

7 Likes

I was happy to see that it is also available in openSUSE repository. However, it seems it was not packaged correctly.

$ lfortran test.f90 -o test
/usr/bin/ld: cannot find -llfortran_runtime: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The command 'clang -o test test.tmp.o  -L"src/bin/../runtime" -Wl,-rpath,"src/bin/../runtime" -llfortran_runtime -lm' failed.

Good luck with this amazing project :slight_smile:

1 Like

@gronki not surprised it was not packaged correctly. We provide conda as our reference how to package it, and over time other distributions will get it right, or we can add some cmake build options to handle some cases that maybe do not occur in conda.

I will try conda today! Although, as discussed in another thread, my coding style is a bit heavy, but hopefully I will be able to at least find some bugs this way.

1 Like

The OOP support is very alpha. :slight_smile: The procedure style coding is quite solid alpha.