aradi / fypp

Python powered Fortran preprocessor

Home Page:http://fypp.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Macro changes

luflarois opened this issue · comments

I have a code:

#:if defined("SINGLE_PRECISION")
#:def MACRO(A) 
   call bcast_doubles(dminfo,size($A$),$A$)
#:enddef MACRO
#:else
#:def MACRO(A) 
   call bcast_reals(dminfo,size($A$),$A$)
#:enddef MACRO
#:endif

module init

contains

subroutine tst()

   real :: ah2onw(2)
   real :: dminfo

   ah2onw =2.0
   dminfo = 1.0

   MACRO(ah2onw) !!! <<<------ in this line !!!!

end subroutine tst

subroutine bcast_reals(dminfo,n,a)
   real, INTENT(IN) :: dminfo,a(:)
   integer, intent(in) :: n

   print *,'real'

end subroutine bcast_reals

subroutine bcast_doubles(dminfo,n,a)
   real, INTENT(IN) :: dminfo,a(:)
   integer, intent(in) :: n

   PRINT *,'doubles'

end subroutine bcast_doubles

end module init

And my goal is that the FYPP makes the change of "DM_BCAST_MACRO(ah2onw)" by the macro defined at beginning of code. How can I make it?

Please note, that you must apply the macro, best with the @: prefix (direct call). Otherwise, it is probably nicer, to have the #:if within the macro, as defining it twice. The following code would make, what you are intended, I guess:


#:def MACRO(A) 
#:if defined("SINGLE_PRECISION")
  call bcast_reals(dminfo,size($A$),$A$)
#:else
  call bcast_doubles(dminfo,size($A$),$A$)
#:endif
#:enddef MACRO


module init

contains

subroutine tst()

   real :: ah2onw(2)
   real :: dminfo

   ah2onw =2.0
   dminfo = 1.0

   @:MACRO(ah2onw)

end subroutine tst

subroutine bcast_reals(dminfo,n,a)
   real, INTENT(IN) :: dminfo,a(:)
   integer, intent(in) :: n

   print *,'real'

end subroutine bcast_reals

subroutine bcast_doubles(dminfo,n,a)
   real, INTENT(IN) :: dminfo,a(:)
   integer, intent(in) :: n

   PRINT *,'doubles'

end subroutine bcast_doubles

end module init

Dear Aradi, It works, but not in right way. I did what You suggested, but the result (after FYPP) was:

module init

contains

subroutine tst()

   real :: ah2onw(2)
   real :: dminfo

   ah2onw =2.0
   dminfo = 1.0

  call bcast_doubles(dminfo,size($A$),$A$) !<----  here 

end subroutine tst

subroutine bcast_reals(dminfo,n,a)
   real, INTENT(IN) :: dminfo,a(:)
   integer, intent(in) :: n

   print *,'real'

end subroutine bcast_reals

subroutine bcast_doubles(dminfo,n,a)
   real, INTENT(IN) :: dminfo,a(:)
   integer, intent(in) :: n

   PRINT *,'doubles'

end subroutine bcast_doubles

See in comment (I did in code) that the FYPP put "call bcast_doubles(dminfo,size($A$),$A$)" instead "call bcast_doubles(dminfo,size(ah2onw),ah2onw)"

I try to use ${A}$ instead, but the preprocessor ask for the set of ah2onw. If I put #:set ah2onw = "ah2onw" in definition it works, but I think is a little bit more complicated to read. In CPP is direct, for example:

#ifdef SINGLE_PRECISION
#define MACRO(A) call bcast_doubles(dminfo,size(A),A)
#else
#define MACRO(A) call bcast_reals(dminfo,size(A),A)
#endif

module init

contains

subroutine tst()

   real :: ah2onw(2)
   real :: dminfo

   ah2onw =2.0
   dminfo = 1.0

   MACRO(ah2onw)

end subroutine tst

I would like to exchange CPP by FYPP. But I need all features that I have in original code working in FYPP too.

Sorry, I have concentrated on the #if and the macro execution, and have overseen one more error of yours. You have to use, indeed ${A}$ in the macro, to substitute the argument value:

#:def MACRO(A) 
#:if defined("SINGLE_PRECISION")
  call bcast_reals(dminfo,size(${A}$),${A}$)
#:else
  call bcast_doubles(dminfo,size(${A}$),${A}$)
#:endif
#:enddef MACRO


module init

contains

subroutine tst()

   real :: ah2onw(2)
   real :: dminfo

   ah2onw =2.0
   dminfo = 1.0

   @:MACRO(ah2onw)

end subroutine tst

subroutine bcast_reals(dminfo,n,a)
   real, INTENT(IN) :: dminfo,a(:)
   integer, intent(in) :: n

   print *,'real'

end subroutine bcast_reals

subroutine bcast_doubles(dminfo,n,a)
   real, INTENT(IN) :: dminfo,a(:)
   integer, intent(in) :: n

   PRINT *,'doubles'

end subroutine bcast_doubles

end module init