basic macros (built-in macros)

Forum for discussion about the documentation project.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: basic macros (built-in macros)

Post by fxm »

I am waiting for all this to stabilize before maybe adding in the documentation an example directly calling '__FB_QUERY_SYMBOL__'.


[edit]
I could draw heavily from your example above, but simplifying it a bit to be more accessible to any user:

Code: Select all

#include once "fbc-int/symbol.bi"

Function dataclassToStr( Byval classid As fbc.FB_DATACLASS ) as string
    Static As Zstring Ptr classnames _
        ( fbc.FB_DATACLASS.FB_DATACLASS_INTEGER to fbc.FB_DATACLASS.FB_DATACLASS_UDT ) _
        = { @"integer", @"float", @"string", @"udt" }
        
    Select Case classid
    Case Lbound(classnames) To Ubound(classnames)
        Return *classnames(classid)
    Case Else
        Return "*invalid*"
    End Select
End Function 

#macro show_dataclass( sym )
    Scope
        Var classid = __FB_QUERY_SYMBOL__( fbc.FB_QUERY_SYMBOL.dataclass, sym )
        Print Left( "   [" & classid & "] " & dataclassToStr(classid) + Space(16), 16 ) & ": ";
        Print #sym  
    End Scope 
#endmacro

Dim As Byte b
Dim As Double d
Dim As String s

Type T
    Dim As Long l
End Type
Dim As T t1

Print "EXAMPLES OF '__FB_QUERY_SYMBOL__( fbc.FB_QUERY_SYMBOL.dataclass, sym )':" 

show_dataclass( b )
show_dataclass( d )
show_dataclass( s )
show_dataclass( T )
show_dataclass( T.l )
show_dataclass( t1 )
show_dataclass( t1.l )

Sleep

Code: Select all

EXAMPLES OF '__FB_QUERY_SYMBOL__( fbc.FB_QUERY_SYMBOL.dataclass, sym )':
   [0] integer  : b
   [1] float    : d
   [2] string   : s
   [3] udt      : T
   [0] integer  : T.l
   [3] udt      : t1
   [0] integer  : t1.l
I did not consider 'FB_DATACLASS_PROC' because it does not work.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: basic macros (built-in macros)

Post by coderJeff »

fxm wrote: Dec 28, 2022 18:58 I did not consider 'FB_DATACLASS_PROC' because it does not work.
Ah yes. FB_DATACLASS_PROC can be a bit of a complicated one.

FB_DATACLASS_PROC is the internal data class for "FUNCTION". However, any symbol exposed to the user will have the type FUNCTION+POINTER, so it shows up in the INTEGER data class since the value itself is stored as a pointer in memory. And pointers are part of the integer data class.

Code: Select all

#include "fbc-int/symbol.bi"

sub test()
end sub

var ptest = procptr(test)
var dtype = __FB_QUERY_SYMBOL__( fbc.FB_QUERY_SYMBOL.datatype, ptest )

print "dtype      = "; dtype
print "type only  = "; fbcTypeGetDtOnly( dtype ); " (FB_DATATYPE_FUNCTION)"  
print "ptr count  = "; fbcTypeGetPtrCnt( dtype )
In other words:
- FB_DATATYPE_FUNCTION has a data class of FB_DATACLASS_PROC
- FB_DATATYPE_FUNCTION + POINTER has a data class of FB_DATACLASS_INTEGER

Conversion from FB_DATATYPE to FB_DATACLASS is done by a simple indexed lookup table using fbcTypeGet( dtype ) as the index. But can see from the definition of fbcTypeGet() that it returns types as a pointer type if it is a pointer.

If curious about the look-up table: src/compiler/symb-data.bas
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: basic macros (built-in macros)

Post by coderJeff »

Recent updates should improve the handling of optional parenthesis feature in macros. Function-like (aka single line) macros were not well handling optional parenthesis.

If a function-like macro is used in an expression and the parens are optional, then something other than parens are need to make the decision of where the macro argument list starts and ends.

If the macro is function-like (single-line) and parens are optional, then:
- if the character following the macro name is a left paren '(' then the parens are expected to wrap the argument list
- if the character following the macro name is a space (or tab) then whatever is next is the first argument
- arguments are separated by commas
- the last argument is based on number of expected arguments for the macro
- however, variadic arguments are also allowed, and will consume all remaining tokens up to the next right paren ')' or end of line - though this has not been very much tested.

For example:

Code: Select all

#macro join ? ( a, b )
	a & b
#endmacro

dim s1 as string = join  "W", join  "X", "Y"
dim s2 as string = join( "W", join( "X", "Y") )
dim s3 as string = join join "W", "X", "Y"

print s1  '' WXY
print s2  '' WXY
print s3  '' WXY

sleep
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: basic macros (built-in macros)

Post by fxm »

Code above to be tested without then with this latest change:
- fbc: basic-macros: improve the handling of optional parens in function like macros by ending a macro argument list on the number of arguments expected (non-variadic macros only). => fbc: basic-macros: improve optional parens in macros.
Post Reply