Is there any way, within the PureBasic Editor, to expand and view macros in place? It would improve readability during debugging, especially in the case of longer, more elaborate macros.
Thank you.

Hi luis; thanks for your answer and the tip. It's a real pity as my code is usually littered with macros, and reading source listings without them expanded could be quite tiresome.luis wrote:No AFAIK.
When I want to check how the macro is expanded, I put an error in it (a superfluous char at the end usually).
Surely the purpose of macros is to hide the messy details and to make the code more readable?TI-994A wrote:It's a real pity as my code is usually littered with macros, and reading source listings without them expanded could be quite tiresome.
When I first create a macro, I test it by putting a garbage character at the end of the statement that uses it. The pop-up error message contains the expanded code. After that, I never want to see the underlying PB code again.TI-994A wrote:I'm sure that others face this problem as well, and if someone has found any kind of solution, please do share.
Wow, this is really a GREAT tip unheard of !BorisTheOld wrote: When I first create a macro, I test it by putting a garbage character at the end of the statement that uses it. The pop-up error message contains the expanded code.
Hello BorisTheOld. Personally, I believe that macros are more for reducing repetitive tasks than for increasing readability. A laconic listing is just a bonus, but debugging such code can be very tiresome.BorisTheOld wrote:Surely the purpose of macros is to hide the messy details and to make the code more readable?
BorisTheOld wrote:...After that, I never want to see the underlying PB code again.
In another thread (link), you mentioned using some in-house tool for expanding macros. Seems that you too have a need for such a utility, and perhaps you'd be kind enough to share that with us?BorisTheOld wrote:...We use a simple text substitution macro facility in our code generator software...
But, only if you plan to write code that has bugs in it. A toolbox full of macros, modules, and classes, essentially eliminates coding errors.TI-994A wrote:Hello BorisTheOld. Personally, I believe that macros are more for reducing repetitive tasks than for increasing readability. A laconic listing is just a bonus, but debugging such code can be very tiresome.
There are macros, and then there are macros. We use different types for different purposes.TI-994A wrote:In another thread (link), you mentioned using some in-house tool for expanding macros. Seems that you too have a need for such a utility, and perhaps you'd be kind enough to share that with us?
Code: Select all
{for} iFromPtr {from} 1 {to} 19
{if} {getmid}sRegistrationNumber, iFromPtr, 1{/getmid} <> {c}CHAR_MINUS {then}
{incr}iToPtr{/incr}
{setmid}sWork, iToPtr, 1{setto}{getmid}sRegistrationNumber, iFromPtr, 1{/getmid}{/setmid}
{/if}
{/for}
Code: Select all
For iFromPtr = 1 To 19
If Mid$(sRegistrationNumber, iFromPtr, 1) <> $cCHAR_MINUS Then
Incr iToPtr
Mid$(sWork, iToPtr, 1) = Mid$(sRegistrationNumber, iFromPtr, 1)
End If
Next
Code: Select all
For iFromPtr = 1 To 19
If MidGet(sRegistrationNumber, iFromPtr, 1) <> #cCHAR_MINUS Then
Increment(iToPtr)
MidSet(sWork, iToPtr, 1, MidGet(sRegistrationNumber, iFromPtr, 1))
EndIf
Next
Code: Select all
For iFromPtr = 1 To 19
If Mid(sRegistrationNumber, iFromPtr, 1) <> #cCHAR_MINUS
iToPtr = iToPtr + 1
gloApp\subMidSet (@sWork, Len(sWork), iToPtr, 1, Mid(sRegistrationNumber, iFromPtr, 1), 1)
EndIf
Next
Hello again. Clearly, you're a much better coder, because regardless of the bevy of libraries and macros at my disposal, I'm still prone to making coding errors.BorisTheOld wrote:But, only if you plan to write code that has bugs in it. A toolbox full of macros, modules, and classes, essentially eliminates coding errors.
That's literally a whole new command set; don't see how it promotes readability.BorisTheOld wrote:There are macros, and then there are macros. We use different types for different purposes.Code: Select all
{for} iFromPtr {from} 1 {to} 19 {if} {getmid}sRegistrationNumber, iFromPtr, 1{/getmid} <> {c}CHAR_MINUS {then} {incr}iToPtr{/incr} {setmid}sWork, iToPtr, 1{setto}{getmid}sRegistrationNumber, iFromPtr, 1{/getmid}{/setmid} {/if} {/for}
Code: Select all
sWork = ReplaceString(sRegistrationNumber, #cCHAR_MINUS, "")
Code: Select all
Macro KeyIsDown(key)
GetAsyncKeyState_(key) & $8000
EndMacro
Macro KeyIsUp(key)
GetAsyncKeyState_(key)=0
EndMacro
Dear TI-994A, that's far too simple!TI-994A wrote:In any case, in the same spirit of triviality, here's the above script, in PureBasic form:![]()
Code: Select all
sWork = ReplaceString(sRegistrationNumber, #cCHAR_MINUS, "")
Like I said, there are macros, and then there are macros. The above example has its origins in code written over 35 years ago, when we were converting large Assembler applications to COBOL, then later from COBOL to Visual Basic, then from VB to PowerBasic, and now from PowerBasic to PureBasic. Along the way, the same in-house macro processor has been used to revert some of our code back to Assembler, and even to Pascal. When combined with the specifications in our Data Dictionary, these low level scripts can be used to generate code that is untouched by human hand. But most importantly, they create bug free code and provide a mechanism for filling gaps in the programming language.TI-994A wrote:That's literally a whole new command set; don't see how it promotes readability.BorisTheOld wrote:There are macros, and then there are macros. We use different types for different purposes.Code: Select all
{for} iFromPtr {from} 1 {to} 19 {if} {getmid}sRegistrationNumber, iFromPtr, 1{/getmid} <> {c}CHAR_MINUS {then} {incr}iToPtr{/incr} {setmid}sWork, iToPtr, 1{setto}{getmid}sRegistrationNumber, iFromPtr, 1{/getmid}{/setmid} {/if} {/for}
Code: Select all
PrivateSubroutine(XX2822Attach) (ByMe)
If NotObject(Me\proPanelXX2822)
Me\proPanelXX2822 = CreateObject(PanelItem)
Set(Me\proPanelXX2822, exoParent, Me\proAppPanel)
Set(Me\proPanelXX2822, exsTabText, "Site Options")
SetCallBack(Me\proPanelXX2822, expCBDesign, XX2822Design)
ObjectCall(Me\proPanelXX2822, Build) ()
Else
ObjectCall(Me\proPanelXX2822, Show) ()
EndIf
EndSubroutine
Code: Select all
Procedure clsDvsML06_subXX2822Attach (*Self.strDvsML06)
If *Self\proPanelXX2822 = 0
*Self\proPanelXX2822 = clsPanelItem_funCreate()
*Self\proPanelXX2822\setexoParent(*Self\proAppPanel)
*Self\proPanelXX2822\setexsTabText("Site Options")
*Self\proPanelXX2822\setexpCBDesign(1, @clsDvsML06_subXX2822Design())
*Self\proPanelXX2822\setexpCBDesign(2, *Self)
*Self\proPanelXX2822\subBuild ()
Else
*Self\proPanelXX2822\subShow ()
EndIf
EndProcedure
Hi PB. Firstly, lovely macros; clear and concise, and a very good example of increased readability.PB wrote:These totally increase readability a million-fold. I don't even haveCode: Select all
Macro KeyIsDown(key) GetAsyncKeyState_(key) & $8000 EndMacro Macro KeyIsUp(key) GetAsyncKeyState_(key)=0 EndMacro
to explain to you what they do, because they're so obvious.
Yes, although for such one-liners, simple comments would suffice. Furthermore, for added clarity, brevity, and functionality, it's better to encapsulate API functions into procedures, for example:PB wrote:Someone seeing "GetAsyncKeyState_(key) & $8000" and who isn't
familiar with Windows, will have no idea what that does; but when
seeing it as my macro, they know instantly.
Code: Select all
Procedure KeyIsDown(vKey)
If GetAsyncKeyState_(vKey)
ProcedureReturn GetAsyncKeyState_(vKey) & $8000
EndIf
EndProcedure
Hello again BorisTheOld. Point noted, although you're talking about ancient code-conversion macros, when we're discussing code-substitution macros within PureBasic.BorisTheOld wrote:... The above example has its origins in code written over 35 years ago, when we were converting large Assembler applications to COBOL, then later from COBOL to Visual Basic, then from VB to PowerBasic, and now from PowerBasic to PureBasic. ...
Not necessarily. With no knowledge of the macro parameter structures:BorisTheOld wrote:is easier to understand than:Code: Select all
PrivateSubroutine(XX2822Attach) (ByMe) If NotObject(Me\proPanelXX2822) Me\proPanelXX2822 = CreateObject(PanelItem) Set(Me\proPanelXX2822, exoParent, Me\proAppPanel) Set(Me\proPanelXX2822, exsTabText, "Site Options") SetCallBack(Me\proPanelXX2822, expCBDesign, XX2822Design) ObjectCall(Me\proPanelXX2822, Build) () Else ObjectCall(Me\proPanelXX2822, Show) () EndIf EndSubroutine
Code: Select all
Procedure clsDvsML06_subXX2822Attach (*Self.strDvsML06) If *Self\proPanelXX2822 = 0 *Self\proPanelXX2822 = clsPanelItem_funCreate() *Self\proPanelXX2822\setexoParent(*Self\proAppPanel) *Self\proPanelXX2822\setexsTabText("Site Options") *Self\proPanelXX2822\setexpCBDesign(1, @clsDvsML06_subXX2822Design()) *Self\proPanelXX2822\setexpCBDesign(2, *Self) *Self\proPanelXX2822\subBuild () Else *Self\proPanelXX2822\subShow () EndIf EndProcedure
Code: Select all
Set(Me\proPanelXX2822, exoParent, Me\proAppPanel)
Code: Select all
*Self\proPanelXX2822\setexoParent(*Self\proAppPanel)
Code: Select all
*Self\proPanelXX2822 = createNewPanelItem()
Code: Select all
Me\proPanelXX2822 = CreateObject(PanelItem)
Actually, it's PB's macro feature which is antiquated. It's close to being non-existant. It would be a lot more useful if it had the capabilities of the MASM macro feature from 30 years ago, which forms the basis of our data dictionary scripting language.TI-994A wrote:Hello again BorisTheOld. Point noted, although you're talking about ancient code-conversion macros, when we're discussing code-substitution macros within PureBasic.