Переменное число аргументов в макросах

В паре своих исходников мне понадобилось решение с переменным числом аргументов в макросах. Например в макро ассемблере проверка использования аргумента макроса делается при помощи инструкции ifnb. Я пытался отыскать решение на FreeBasic, далее на GAS , но что-то ничего путного не находил. В итоге состряпал такое решение:

#MACRO Q(a,b,c, d... )
   
   Dim As a  a##b##c##p1 = rnd*10
   
   Dim As b  a##b##c##p2 = rnd*10
   
   Dim As c a##b##c##p3 = a##b##c##p1 & a##b##c##p2
   
   Dim As Byte a##b##c##__pp__(d)
   
      ? a##b##c##p1, a##b##c##p2 , a##b##c##p3

   If Ubound(a##b##c##__pp__) <> -1 Then
   
      ? "Parameter d = "; Ubound(a##b##c##__pp__)
      
   Else
   
      ? "Parameter d not defined "

   Endif   

#EndMacro

Q(Integer,Integer ,String , 1  ) ' with 4 parameter

? "-----------"
?
? "-----------"

Q(Byte,Integer ,String   ) ' without 4 parameter

Sleep


Но позднее пользователь fxm , который по совместительству является ГУРУ документации и полновесных знаний о языке,  дополнил документацию и предоставил очень хорошее решение.

Сам по себе макрос можно присвоить строковой переменной так:

#MACRO average(arg...)
        Dim As String s = #arg
#EndMacro

и далее с помощью обычных строковых функций получить информацию о кол-ве аргументов макроса. Пример я взял из справки , но немного переписал:

#MACRO average(arg...)
   Scope
      Dim As String sMacro = #arg
      Dim As Long iStart = 1 , iRes , iNparameter
      Do
         iRes = Instr(iStart,sMacro,",")
         If iRes  Then
            Var sTemp = Mid(sMacro , iStart, iRes - iStart)
            iNparameter+=1
            If Len(sTemp) Then
               ?  "Number parameter=" ; iNparameter , "value= " ; Val(sTemp)
            Else
               ?  "Number parameter=" ; iNparameter , "not used"
            Endif
            iStart = iRes+1
         Elseif iStart <> iRes Then
            iNparameter+=1
            ? "Number parameter=" ; iNparameter , "value= " ; Val(Mid(sMacro , iStart, iRes - iStart))
            Exit Do
         Else
            Exit Do
         Endif
      Loop
   End Scope
#EndMacro

average(10,,,20)
Sleep

В итоге , можно задавать любое кол-во аргументов и даже пропуская ненужные.