vermaseren / form

The FORM project for symbolic manipulation of very big expressions
GNU General Public License v3.0
982 stars 118 forks source link

Preprocessor instructions inside #switch environment? #365

Open vsht opened 3 years ago

vsht commented 3 years ago

It seems that some (many?) preprocessor instructions silently get ignored when they appear inside a #switch environment before an explicit #case. Consider e.g. the following simple code

Auto S foo,bar;

L ex = 1;
#define CHOICE "foo2"

#switch `CHOICE'

#case foo1
#case foo2
#case foo3

multiply foo;
#break

#case bar1
#case bar2
#case bar3
multiply bar;
#break

#endswitch

print;

.end

This works as expected. But when the number of cases that should be handled in the same way (e.g. a set of loop integral topologies) becomes large, one would naturally like to employ preprocessor instructions here. Yet the following naive example doesn't work as expected

Auto S foo,bar;

L ex = 1;
#define CHOICE "foo2"

#switch `CHOICE'

#do i=1,10
#case foo`i'
#enddo

multiply foo;
#break

#case bar1
#case bar2
#case bar3
multiply bar;
#break

#endswitch

print;

.end

Also the following slight modification fails

#procedure foocases()
#case foo1
#case foo2
#case foo3
#endprocedure

Auto S foo,bar;

L ex = 1;
#define CHOICE "foo2"

#switch `CHOICE'

#call foocases()

multiply foo;
#break

#case bar1
#case bar2
#case bar3
multiply bar;
#break

#endswitch

print;

.end

Also replacing #call foocases() by something like #include myheader #foocases (i.e. loading a fold) doesn't work.

I'm wondering if there's a good workaround to avoid entering all cases by hand directly in the main script.

vermaseren commented 3 years ago

As things are at the moment, a few things have strict ’nesting’. Like the full construct of a #if or a #switch has to be inside the same procedure. But I admit that your case should be an exception. It might not be totally trivial to construct such exceptions. Somehow #do #case #enddo messes up the fundamentals of checking for bracketing. #do #case #break #enddo would be much simpler already, even though it would already be requiring a lot of care.

I have been thinking in the past of meta levels in the preprocessor. Consider for instance a loop of loops as in

do i = 1,`N’

do ji’ = 1,M’

enddo

do i = 1,`N’

enddo

enddo

This is clearly not going to work. It would need someting like

do i = 1,`N’

do ji’ = 1,M’

enddo

do i = 1,`N’

enddo

enddo

which would give a new preprocessor level. In that case your example would become

do i = 1,`N’

case foo`i'

enddo

and there would be no problem. It is however not entirely trivial to put this in and also the syntax is not that great when you consider ######do etc. Hence it should probably be more like #5#do or someting like that. My guess is that big parts of the preprocessor would need to be rewritten. I would need a volunteer for that. It is not simple.

Jos

On 7 Aug 2020, at 10:18, Vladyslav Shtabovenko notifications@github.com wrote:

It seems that some (many?) preprocessor instructions silently get ignored when they appear inside a #switch environment before an explicit #case. Consider e.g. the following simple code

Auto S foo,bar;

L ex = 1;

define CHOICE "foo2"

switch `CHOICE'

case foo1

case foo2

case foo3

multiply foo;

break

case bar1

case bar2

case bar3

multiply bar;

break

endswitch

print;

.end This works as expected. But when the number of cases that should be handled in the same way (e.g. a set of loop integral topologies) becomes large, one would naturally like to employ preprocessor instructions here. Yet the following naive example doesn't work as expected

Auto S foo,bar;

L ex = 1;

define CHOICE "foo2"

switch `CHOICE'

do i=1,10

case foo`i'

enddo

multiply foo;

break

case bar1

case bar2

case bar3

multiply bar;

break

endswitch

print;

.end Also the following slight modification fails

procedure foocases()

case foo1

case foo2

case foo3

endprocedure

Auto S foo,bar;

L ex = 1;

define CHOICE "foo2"

switch `CHOICE'

call foocases()

multiply foo;

break

case bar1

case bar2

case bar3

multiply bar;

break

endswitch

print;

.end Also replacing #call foocases() by something like #include myheader #foocases (i.e. loading a fold) doesn't work.

I'm wondering if there's a good workaround to avoid entering all cases by hand directly in the main script.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/vermaseren/form/issues/365, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJPCEQWIQDYXICI2P5XLCTR7O2ETANCNFSM4PXMMKVA.