Expanded View of Macros

Working on new editor enhancements?
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Expanded View of Macros

Post by TI-994A »

Hello everyone. Firstly, sincere apologies if this has been asked before, although a quick search didn't yield any relevant results.

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. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
luis
Addict
Addict
Posts: 3876
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Expanded View of Macros

Post by luis »

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).

http://www.purebasic.fr/english/viewtop ... 56#p376056
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Expanded View of Macros

Post by TI-994A »

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).
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.

I'm sure that others face this problem as well, and if someone has found any kind of solution, please do share. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Expanded View of Macros

Post by BorisTheOld »

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.
Surely the purpose of macros is to hide the messy details and to make the code more readable? :)
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.
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.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
luis
Addict
Addict
Posts: 3876
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Expanded View of Macros

Post by luis »

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.
Wow, this is really a GREAT tip unheard of ! :D
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Expanded View of Macros

Post by TI-994A »

BorisTheOld wrote:Surely the purpose of macros is to hide the messy details and to make the code more readable? :)
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:...After that, I never want to see the underlying PB code again.
BorisTheOld wrote:...We use a simple text substitution macro facility in our code generator software...
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? :D
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Expanded View of Macros

Post by BorisTheOld »

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.
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: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? :D
There are macros, and then there are macros. We use different types for different purposes.

The text substitution macros, mentioned in the link, are used when writing templates for the code generators in our Data Dictionary software. We use a separate class of macros when writing actual PB code. These macros add clarity to the code and provide standard BASIC features that are missing from PB. In particular, supporting OOP without getting bogged down in PB syntax.

The following trivial statements in a Data Dictionary script:

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}
will produce the following source code for PowerBasic:

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
but will produce the following source code for PureBasic, which is readable:

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
which, with the application of our PB macros, reduces to the following PB code, which is not so readable:

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
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Expanded View of Macros

Post by TI-994A »

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.
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: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}
That's literally a whole new command set; don't see how it promotes readability.

Granted, you might have your reasons for using such mnemonics, but personally, I believe that proper use of macros should result in highly terse code, instead of a more verbose and cryptic one.

In any case, in the same spirit of triviality, here's the above script, in PureBasic form: :lol:

Code: Select all

 sWork = ReplaceString(sRegistrationNumber, #cCHAR_MINUS, "")
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Expanded View of Macros

Post by PB »

> I believe that macros are more for reducing repetitive tasks than for increasing readability

It depends. Consider these two macros that I use in all my apps:

Code: Select all

Macro KeyIsDown(key)
  GetAsyncKeyState_(key) & $8000
EndMacro

Macro KeyIsUp(key)
  GetAsyncKeyState_(key)=0
EndMacro
These totally increase readability a million-fold. I don't even have
to explain to you what they do, because they're so obvious. :)

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.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Expanded View of Macros

Post by Little John »

TI-994A wrote:In any case, in the same spirit of triviality, here's the above script, in PureBasic form: :lol:

Code: Select all

 sWork = ReplaceString(sRegistrationNumber, #cCHAR_MINUS, "")
Dear TI-994A, that's far too simple!
Everybody can do it that way. :mrgreen:
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Expanded View of Macros

Post by BorisTheOld »

TI-994A wrote:
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}
That's literally a whole new command set; don't see how it promotes readability.
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.

Since our applications exist as specifications in a database, the final code is only a convenience for customers, or others, who wish to have a copy of the source. And it's at this level of abstraction that we make use of other language-based macros to simplify or clarify the code. The type of macros that PB describes.

So that the following code:

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
is easier to understand than:

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
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Expanded View of Macros

Post by TI-994A »

PB wrote:

Code: Select all

Macro KeyIsDown(key)
  GetAsyncKeyState_(key) & $8000
EndMacro

Macro KeyIsUp(key)
  GetAsyncKeyState_(key)=0
EndMacro
These totally increase readability a million-fold. I don't even have
to explain to you what they do, because they're so obvious. :)
Hi PB. Firstly, lovely macros; clear and concise, and a very good example of increased readability.
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.
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:

Code: Select all

Procedure KeyIsDown(vKey)
  If GetAsyncKeyState_(vKey)
    ProcedureReturn GetAsyncKeyState_(vKey) & $8000
  EndIf
EndProcedure
Perhaps it simply boils down to personal preferences. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Expanded View of Macros

Post by TI-994A »

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. ...
Hello again BorisTheOld. Point noted, although you're talking about ancient code-conversion macros, when we're discussing code-substitution macros within PureBasic. :lol:
BorisTheOld wrote:

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
is easier to understand than:

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
Not necessarily. With no knowledge of the macro parameter structures:

Code: Select all

Set(Me\proPanelXX2822, exoParent, Me\proAppPanel)
is in no way more understandable than:

Code: Select all

*Self\proPanelXX2822\setexoParent(*Self\proAppPanel)
And, if the original function names were a little less cryptic to begin with, such substitutions serve very little purpose. For example, if clsPanelItem_funCreate() were named something like createNewPanelItem():

Code: Select all

*Self\proPanelXX2822 = createNewPanelItem()
is just as readable as

Code: Select all

Me\proPanelXX2822 = CreateObject(PanelItem)
eliminating the need for a clarifying macro. :lol:

But, like I mentioned earlier, perhaps it just boils down to personal preferences. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Expanded View of Macros

Post by TI-994A »

To reiterate, if anyone knows of a way, or has some utility that could expand PureBasic macros within the source listing, please do share.

Thank you. :D
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Expanded View of Macros

Post by BorisTheOld »

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. :lol:
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.

New is not always better. :wink:
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Post Reply