Good find, wallyg. This is part feature request & part bug.
fbc does not support recursive
#macro or
#define, but also doesn't error in non-trivial cases either.
Example #1, simulates what we are trying to do:
Code: Select all
#macro MX( X, args... )
#print " MX()"
#print " X = " #X
#print " args = " #args
#if len( #args ) > 0
#print " len(" #args) > 0"
#else
#print " len(" #args) = 0"
#endif
#endmacro
#macro M( X, args... )
#print "M()"
#print " X = " #X
#print " args = " #args
MX(X, args )
#endmacro
M(A,B,C)
M(A,B)
M(A)
Output:
Code: Select all
M()
X = $"A"
args = $"B,C"
MX()
X = $"A"
args = $"B,C"
len( $"B,C") >0"
M()
X = $"A"
args = $"B"
MX()
X = $"A"
args = $"B"
len( $"B") >0"
M()
X = $"A"
args = ""
MX()
X = $"A"
args = ""
len( "") =0"
Example #2, directly add recursion. fbc can detect this trivial form of
#macro recursion and generates an error:
Code: Select all
#macro MX( X, args... )
#print " MX()"
#print " X = " #X
#print " args = " #args
#if len( #args ) > 0
#print " len(" #args) > 0"
MX(args)
#else
#print " len(" #args) = 0"
#endif
#endmacro
#macro M( X, args... )
#print "M()"
#print " X = " #X
#print " args = " #args
MX(X, args )
#endmacro
M(A,B,C)
Output:
Code: Select all
M()
X = $"A"
args = $"B,C"
MX()
X = $"A"
args = $"B,C"
len( $"B,C") >0"
macro.bas(20) error 89: Recursive DEFINE not allowed, found 'MX' in 'M(A,B,C)'
macro.bas(20) error 3: Expected End-of-Line, found '#' in 'M(A,B,C)'
len( $"B,C") =0"
Example #3, adding the
#if tricks fbc (it doesn't detect the recursion), and actually causes fbc to hang, never ending it's own internal recursive expansion of
MX() -- BUG
Code: Select all
#macro MX( X, args... )
#print " MX()"
#print " X = " #X
#print " args = " #args
#if len( #args ) > 0
#print " len(" #args ) > 0
MX(args)
#else
#print " len(" #args ) = 0
#endif
#endmacro
#macro M( X, args... )
#print "M()"
#print " X = " #X
#print " args = " #args
#if len( #args ) > 0
#print " len(" #args ) > 0
MX(X, args )
#endif
#endmacro
M(A,B,C)
Output:
Code: Select all
M()
X = $"A"
args = $"B,C"
len( $"B,C" ) >0
MX()
X = $"A"
args = $"B,C"
len( $"B,C" ) >0
MX()
X = $"B"
args = $"C"
len( $"C" ) >0
MX()
X = $"C"
args = ""
... hang forever ....
I couldn't come up with a work-around. Either fbc should track the macro expansions and error (bug), or allow recursion (feature). Though if macro recursion were allowed, it should eventually error on some maximum depth, otherwise, it would just crash the compiler.