Skip to content

Conversation

@skyfish4tb
Copy link
Contributor

@skyfish4tb skyfish4tb commented May 15, 2021

In the macro definition (#define/#macro), "##" is used to indicate the dynamic addition of a line continuation character (""), Causes the compiler to delay parsing the line continuation.This allows multiple lines of code in the input file to be combined into a single statement.For example:

Type _MAP_ENTRY
	id As integer
	pA As integer
End Type
#macro BEGIN_ENTRIESMAP()
Function _GetMapEntries() As _MAP_ENTRY Ptr
		Static As _MAP_ENTRY _entries(0 To ...) = { ##_
#endmacro
#macro END_ENTRIESMAP()
		(0, 0)}
		Return @_entries(0)
	End Function
#endmacro
#define _INTERFACE_ENTRY(x, y) (x, y), ##_

BEGIN_ENTRIESMAP()
_INTERFACE_ENTRY(1, 2)
_INTERFACE_ENTRY(3, 4)
_INTERFACE_ENTRY(5, 6)
END_ENTRIESMAP()

/' Compiler parsing results:
Function _GetMapEntries() As _MAP_ENTRY Ptr
Static As _MAP_ENTRY _entries(0 To ...) = { _
(1, 2), _
(3, 4), _
(5, 6), _
(0, 0)}
Return @_entries(0)
End Function
'/

…he dynamic addition of a line continuation character ("_"), Causes the compiler to delay parsing the line continuation.This allows multiple lines of code in the input file to be combined into a single statement. For example:

Type _MAP_ENTRY
	id As integer
	pA As integer
End Type
#macro BEGIN_ENTRIESMAP()
	Function _GetMapEntries() As _MAP_ENTRY Ptr
		Static As _MAP_ENTRY _entries(0 To ...) = { ##_
#endmacro
#macro END_ENTRIESMAP()
		(0, 0)}
		Return @_entries(0)
	End Function
#endmacro
#define _INTERFACE_ENTRY(x, y) (x, y), ##_

BEGIN_ENTRIESMAP()
	_INTERFACE_ENTRY(1, 2)
	_INTERFACE_ENTRY(3, 4)
	_INTERFACE_ENTRY(5, 6)
END_ENTRIESMAP()

/' Compiler parsing results:
	Function _GetMapEntries() As _MAP_ENTRY Ptr
		Static As _MAP_ENTRY _entries(0 To ...) = { _
		(1, 2), _
		(3, 4), _
		(5, 6), _
		(0, 0)}
		Return @_entries(0)
	End Function
'/
@jayrm
Copy link
Member

jayrm commented May 16, 2021

This looks OK to me - using '##_' to escape the line continuation character '_' in macro definitions. However, it does highlight some short-comings of fbc's lexer/parser. The line continuation '_' character and token pasting operator '##' are not actual tokens and are nearly entirely handled within the lexer. And currently single '_' character token pasting doesn't work; everything after a single '_' is ignored as in:

#print first-part _ ignored-part
second-part
'' output "first-part second-part"

I think we would like the following to work (which currently does not) as well:

#define join1(a,b) a##_ b
#define join2(a,b) a _##b
#define join3(a,b) a##_##b

#print join1(X,Y)
#print join2(X,Y)
#print join3(X,Y)

I have a follow-up commit that should fix the single '_' character token pasting. I think is necessary to go along with this change otherwise can end up with some very difficult compiler errors for the user to figure out if '##' and '_' are misplaced or don't do what is expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants