Issue with big macros in included files [fixed]

General FreeBASIC programming questions.
fxm
Moderator
Posts: 11961
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Jeff's request to fxm (issue reported on Discord)

Post by fxm »

Indeed, your latest code induces the residual behavior that I feared yesterday : only '*.pp.bas' compiles and executes.
coderJeff
Site Admin
Posts: 4226
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Jeff's request to fxm (issue reported on Discord)

Post by coderJeff »

Jattenalle wrote: Nov 20, 2023 14:28 Using the latest nightly build, I'm now getting errors that don't make any sense when trying to compile.
Currently, the macro tracing / error reporting is simplistic - i.e. mostly missing. The original source/line isn't tracked when macros are expanded in to a text buffer and the original context information is lost, so only the original line is reported, but with an error message for the problem code.

For the posted code:

Expected expression - careful: the line continuations and comments:

Code: Select all

		#if typeof(__FBLIST_PP_LISTTYPE)="BYTE" or _
			typeof(__FBLIST_PP_LISTTYPE)="UBYTE" or _
			typeof(__FBLIST_PP_LISTTYPE)="SINGLE" or _
			typeof(__FBLIST_PP_LISTTYPE)="DOUBLE" or _
			typeof(__FBLIST_PP_LISTTYPE)="STRING" or _
	'		typeof(__FBLIST_PP_LISTTYPE)="ZSTRING" or _	'// Doesn't work due to overloaded ptr and *ptr methods
			typeof(__FBLIST_PP_LISTTYPE)="SHORT" or _
			typeof(__FBLIST_PP_LISTTYPE)="USHORT" or _
			typeof(__FBLIST_PP_LISTTYPE)="LONG" or _
			typeof(__FBLIST_PP_LISTTYPE)="ULONG" or _
			typeof(__FBLIST_PP_LISTTYPE)="LONGINT" or _
			typeof(__FBLIST_PP_LISTTYPE)="ULONGINT" or _
			typeof(__FBLIST_PP_LISTTYPE)="INTEGER" or _
			typeof(__FBLIST_PP_LISTTYPE)="UINTEGER"
Expected Expression - subtle, but looks like is missing stringize operator:

Code: Select all

		#if __FBLIST_EXTEND="__FBLIST_PP_EXTENSIONBEGIN"
			#define __FBLIST_PP_LISTISEXTENDED
		#endif
the .pp.bas file may compile and execute, but take care that it was produced after errors & error recovery.
Jattenalle
Posts: 6
Joined: Nov 17, 2023 14:41
Contact:

Re: Jeff's request to fxm (issue reported on Discord)

Post by Jattenalle »

That did it!
I would've never found that, wouldn't even occur to me to look at the comment (Despite me stumbling on the other comment and macro related bug)
Code compiles and works now with 1.10.1N, cheers!
fxm
Moderator
Posts: 11961
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Jeff's request to fxm (issue reported on Discord)

Post by fxm »

For those who do not fully understand, it is therefore necessary in this case:

- Delete any comment line in a continuation line block.
Otherwise, in order to still keep the line as a comment, insert "_" or "_'" at the start of the line instead of "'":

Code: Select all

		#if typeof(__FBLIST_PP_LISTTYPE)="BYTE" or _
			typeof(__FBLIST_PP_LISTTYPE)="UBYTE" or _
			typeof(__FBLIST_PP_LISTTYPE)="SINGLE" or _
			typeof(__FBLIST_PP_LISTTYPE)="DOUBLE" or _
			typeof(__FBLIST_PP_LISTTYPE)="STRING" or _
	_'		typeof(__FBLIST_PP_LISTTYPE)="ZSTRING" or _	'// Doesn't work due to overloaded ptr and *ptr methods
			typeof(__FBLIST_PP_LISTTYPE)="SHORT" or _
			typeof(__FBLIST_PP_LISTTYPE)="USHORT" or _
			typeof(__FBLIST_PP_LISTTYPE)="LONG" or _
			typeof(__FBLIST_PP_LISTTYPE)="ULONG" or _
			typeof(__FBLIST_PP_LISTTYPE)="LONGINT" or _
			typeof(__FBLIST_PP_LISTTYPE)="ULONGINT" or _
			typeof(__FBLIST_PP_LISTTYPE)="INTEGER" or _
			typeof(__FBLIST_PP_LISTTYPE)="UINTEGER"
			#define __FBLIST_PP_ISOFBASICTYPE
		#endif

- Add the stringize preprocessor operator in the following test as follows:

Code: Select all

	'	#if __FBLIST_EXTEND="__FBLIST_PP_EXTENSIONBEGIN"
		#if #__FBLIST_EXTEND="__FBLIST_PP_EXTENSIONBEGIN"
			#define __FBLIST_PP_LISTISEXTENDED
		#endif
Jattenalle
Posts: 6
Joined: Nov 17, 2023 14:41
Contact:

Re: Jeff's request to fxm (issue reported on Discord)

Post by Jattenalle »

- Add the stringize preprocessor operator in the following test as follows:
Actually...

I broke it again:

Code: Select all

'// Inconsistent compare results
'// Non-intuitive comparisons
'// No way to check if an arg exists or not

#macro broken(foo...)
	#if #foo="BAR"
		#print "	#if #foo=""BAR"":	Yup!"
	#else
		#print "	#if #foo=""BAR"":	Nope"
	#endif
	#if foo=BAR
		#print "	#if foo=BAR:	Yup!"
	#else
		#print "	#if foo=BAR:	Nope"
	#endif
#endmacro

#print "broken(BAR)"
broken(BAR)
'        #if #foo="BAR": Yup!
'        #if foo=BAR:    Yup!
#print ""
#print "broken(""BAR"")"
broken("BAR")
'        #if #foo="BAR": Nope
'        #if foo=BAR:    Yup!
#print ""
#print "broken()"
broken()
'        #if #foo="BAR": Nope
'error 9: Expected expression, found '=' in 'broken()'
'        #if foo=BAR:    Nope

#print ""
#print ""

#macro numericbroken(foo...)
	#if #foo="1"
		#print "	#if #foo=""1"":	Yup!"
	#else
		#print "	#if #foo=""1"":	Nope"
	#endif
	#if foo=1
		#print "	#if foo=1:	Yup!"
	#else
		#print "	#if foo=1:	Nope"
	#endif
#endmacro

#print "numericbroken(1)"
numericbroken(1)
'        #if #foo="1":   Yup!
'        #if foo=1:      Yup!
#print ""
#print "numericbroken(""1"")"
numericbroken("1")
'        #if #foo="1":   Nope
'error 20: Type mismatch in 'numericbroken("1")'
'        #if foo=1:      Nope

#print ""
#print "numericbroken()"
numericbroken()
'        #if #foo="1":   Nope
'error 9: Expected expression, found '=' in 'numericbroken()'
'        #if foo=1:      Nope


#print ""
#print ""

#macro cantdetectmissingarg(foo...)
	#ifdef foo
		#if #foo="1"
			#print "	#if #foo=""1"":	Yup!"
		#else
			#print "	#if #foo=""1"":	Nope"
		#endif
		#if foo=1
			#print "	#if foo=1:	Yup!"
		#else
			#print "	#if foo=1:	Nope"
		#endif
	#else
		#print "	foo is undefined!"
	#endif
#endmacro

#print "cantdetectmissingarg()"
cantdetectmissingarg()
'error 3: Expected End-of-Line, found '#' in 'cantdetectmissingarg()'
'        #if #foo="1":   Nope
'error 9: Expected expression, found '=' in 'cantdetectmissingarg()'
'        #if foo=1:      Nope
'error 44: Illegal outside a compound statement, found 'else' in 'cantdetectmissingarg()'
'        foo is undefined!
'error 44: Illegal outside a compound statement in 'cantdetectmissingarg()'


sleep
end
Win32, FBC 1.10.1N
fxm
Moderator
Posts: 11961
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Jeff's request to fxm (issue reported on Discord)

Post by fxm »

'// No way to check if an arg exists or not

Code: Select all

#macro broken(foo...)
	#if #foo <> ""
		#if #foo="BAR"
			#print "	#if #foo=""BAR"":	Yup!"
		#else
			#print "	#if #foo=""BAR"":	Nope"
		#endif
		#if foo=BAR
			#print "	#if foo=BAR:	Yup!"
		#else
			#print "	#if foo=BAR:	Nope"
		#endif
	#endif
#endmacro

#print "broken(BAR)"
broken(BAR)
'        #if #foo="BAR": Yup!
'        #if foo=BAR:    Yup!
#print ""
#print "broken(""BAR"")"
broken("BAR")
'        #if #foo="BAR": Nope
'        #if foo=BAR:    Yup!
#print ""
#print "broken()"
broken()

sleep
coderJeff
Site Admin
Posts: 4226
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Jeff's request to fxm (issue reported on Discord)

Post by coderJeff »

Stringize operator converts source text to a string, even when the source text contains double quotes.

The preprocessor is not a programming language unto itself - it substitutes tokens for other tokens.

It's probably helpful to think of macro arguments as fragments of source code including being empty and having incomplete forms rather than having specific types or values or syntax. The interpretation of the source text as a value or statement or expression is only realized when the macro is fully expanded and passed to the parser. If the resultant parsed source text is an expression and is constant at compile time, then it can be used in #if statements.

Hopefully these examples can give an idea how the preprocessor sees macro arguments:

ARGUMENTS ARE SOURCE CODE FRAGMENTS

Code: Select all

#macro show( args... )
	scope
		var a = #args
		print "source is: " & a
	end scope
#endmacro

show()
show( some text with a "double quoted" word )
show( variadic,  args  ,list,is,exanded,as-is )
show( ,,, )
sleep

/'OUTPUT:
source is: 
source is: some text with a "double quoted" word
source is: variadic,args,list,is,exanded,as-is
source is: ,,,
'/
HOW MANY ARGUMENTS? IS ARGUMENT NO EMPTY?

Code: Select all

#macro howmany( args... )
	scope
		var a = #args
		var n = __fb_arg_count__(args)
		print n & " args in: " & a
	end scope
#endmacro

howmany()
howmany( some text with a "double quoted" word )
howmany( variadic,  args  ,list,is,exanded,as-is )
howmany( ,,, )
sleep

/'OUTPUT:
0 args in:
1 args in: some text with a "double quoted" word
6 args in: variadic,  args  ,list,is,exanded,as-is
4 args in: ,,,
'/
DID WE GET A STRING OR SOMETHING ELSE?

Code: Select all

#macro check( args... )
	print "source is: " & #args
	#if __fb_arg_count__( args ) = 0
		print "  no arguments"
	#elseif __fb_arg_count__( args ) = 1
		print "  one argument"
		#if asc(#args,1) = asc("""")
			print "  maybe it's a string"
		#else
			print "  probably not a string"
		#endif
	#else
		print "  has " & __fb_arg_count__( args ) & " args" 
	#endif
#endmacro

check()
check("some text")
check("some text" and other stuff)
check( some text with a "double quoted" word )
check( variadic,  args  ,list,is,exanded,as-is )
check( ,,, )
sleep

/'OUTPUT:
source is:
  no arguments
source is: "some text"
  one argument
  maybe it's a string
source is: "some text" and other stuff
  one argument
  maybe it's a string
source is: some text with a "double quoted" word
  one argument
  probably not a string
source is: variadic,  args  ,list,is,exanded,as-is
  has 6 args
source is: ,,,
  has 4 args
'/
SARG
Posts: 1709
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Issue with big macros in included files [fixed]

Post by SARG »

Title changed
Post Reply