Переменное число аргументов в макросах
В паре своих исходников мне понадобилось решение с переменным числом аргументов в макросах. Например в макро ассемблере проверка использования аргумента макроса делается при помощи инструкции 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
В итоге , можно задавать любое кол-во аргументов и даже пропуская ненужные.