Structures in Macros

Just starting out? Need help? Post your questions and find answers here.
Thiefbrain
New User
New User
Posts: 8
Joined: Wed Apr 10, 2013 4:43 pm

Structures in Macros

Post by Thiefbrain »

Hello,

I stumbled across this problem today. I wanted to write a macro which resets the content of a structure, but it seems I can't use a variable with a structure as macro argument. Syntax check gives me an error when I try to do so. Why is this not possible? Or is there any workaround, except procedures?
User avatar
Demivec
Addict
Addict
Posts: 4282
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Structures in Macros

Post by Demivec »

Thiefbrain wrote:Hello,

I stumbled across this problem today. I wanted to write a macro which resets the content of a structure, but it seems I can't use a variable with a structure as macro argument. Syntax check gives me an error when I try to do so. Why is this not possible? Or is there any workaround, except procedures?
Do you have an code example of what you have tried already for the macro?
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Structures in Macros

Post by BorisTheOld »

I've never had any problems using structures, or structure contents, as macro parameters.

What exactly are you trying to do?
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
skywalk
Addict
Addict
Posts: 4262
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Structures in Macros

Post by skywalk »

Code: Select all

Structure Struc1
  i.i
  d.d
EndStructure
Macro InitMyStruc(myStruc)
  myStruc\i = -999
  myStruc\d = -999.0
EndMacro
Define x.Struc1
InitMyStruc(x)
Debug x\d
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Thiefbrain
New User
New User
Posts: 8
Joined: Wed Apr 10, 2013 4:43 pm

Re: Structures in Macros

Post by Thiefbrain »

Hello,

I just want to reset the variables in the structure to its default values (clearing lists, set strings to "", etc.)
With the given example code, line 6 (Macro ...) throws an syntax error in PB 5.21:

Code: Select all

Structure myStruct
    List myList.s()
    myLong.l
EndStructure

Macro resetStruct(variable.myStruct)
    NewList variable\myList()
    variable\myLong = 0
EndMacro

Define myVariable.myStruct
AddElement(myVariable\myList())
myVariable\myList() = "test"
myVariable\myLong = 10

Debug myVariable\myList()
Debug myVariable\myLong

resetStruct(myVariable)

Debug myVariable\myList() ; should throw an error
Debug myVariable\myLong
Edit: With skywalks solution it works, but you can't determinate which structure the variable is using. Thanks anyways.
User avatar
skywalk
Addict
Addict
Posts: 4262
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Structures in Macros

Post by skywalk »

Macros perform a 'Search and Replace' function before compiling. They are not 'Type' aware so no Macro parameters can have 'Type' defining elements. Macro(X$) would fail too.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Structures in Macros

Post by BorisTheOld »

Thiefbrain wrote:I just want to reset the variables in the structure to its default values (clearing lists, set strings to "", etc.)
Try using the ClearStructure statement instead of your macro.

Code: Select all

ClearStructure(@myVariable, myStruct)
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Thiefbrain
New User
New User
Posts: 8
Joined: Wed Apr 10, 2013 4:43 pm

Re: Structures in Macros

Post by Thiefbrain »

Hello,

but when I want to re-use that variable again, I have to call InitializeStructure after ClearStructure, right? At least as I understood it from the manuals.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Structures in Macros

Post by ts-soft »

Thiefbrain wrote:but when I want to re-use that variable again, I have to call InitializeStructure after ClearStructure, right?
No, ClearStructure clears only the content, not the structure itself!
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Structures in Macros

Post by BorisTheOld »

Thiefbrain wrote:but when I want to re-use that variable again, I have to call InitializeStructure after ClearStructure, right? At least as I understood it from the manuals.
No, it's as ts-soft said.

Normally, PB initializes the structure fields when a structured variable is created. But this doesn't happen when you dynamically allocate a block of memory and use it to hold a structure. The InitializeStructure statement allows you to correctly initialize all the structure fields to their default values. From that point on in your code you don't need to use InitializeStructure again with that structure.

Also, you don't normally need to use ClearStructure, because PB automatically de-allocates all the string, maps, etc., at the end of your program. However, you always have the option of using ClearStructure if you need to clear the structure during normal execution of your program.

Note: It's mandatory that you use ClearStructure before de-allocating a memory block that you used for a structure. If you don't do this, PB will not know that it should also de-allocate any associated strings, maps, etc., and as a result you will get memory leaks.
Last edited by BorisTheOld on Sat Dec 21, 2013 10:46 pm, edited 1 time in total.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Thiefbrain
New User
New User
Posts: 8
Joined: Wed Apr 10, 2013 4:43 pm

Re: Structures in Macros

Post by Thiefbrain »

Thank you for you answers. These are really interesting things to know about structures.
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: Structures in Macros

Post by BorisTheOld »

Thiefbrain wrote:Thank you for you answers. These are really interesting things to know about structures.
Here is some psuedo-code that shows how I use PB's structure features for the Create and Destroy functions in OOP classes:

Code: Select all

ExternalFunction(Create, typObject)
;
;  create a class instance
;
  Local(Me, strContainer)
  Me = AllocateMemory(SizeOf(strContainer))
  If IsObject(Me)
    InitializeStructure(Me, strContainer)
    ClassCall(Constructor)
  EndIf
  ProcedureReturn Me
EndFunction
;
;-----------------------------------------------
;
ExternalFunction(Destroy, typObject) (Me)
;
;  destroy a class instance
;
  If IsObject(Me)
    ClassCall(Destructor)
    ClearStructure(Me, strContainer)
    FreeMemory(Me)
  EndIf
  ProcedureReturn Nothing
EndFunction
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
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Structures in Macros

Post by netmaestro »

Edit: With skywalks solution it works, but you can't determinate which structure the variable is using. Thanks anyways.
Where there's a will there's a way:

Code: Select all

Structure this
  i.l
  j.a
  List groceries.s()
EndStructure

Structure that
  Array stuff.i(0)
EndStructure

Macro test(input)
  CompilerIf TypeOf(input) = #PB_Structure ; we know it's a structure
    CompilerIf SizeOf(input)=SizeOf(that)  ; if all your structures are sized differently 
      ReDim input\stuff(10)                ; you can know which it is. You can make sure this is the case with padding, align, etc.
    CompilerEndIf
  CompilerEndIf
EndMacro

var1.this
var2.that

test(var1) ; should be ignored by the macro
Debug ArraySize(var2\stuff())

test(var2) ; the macro should process this
Debug ArraySize(var2\stuff())
BERESHEIT
Post Reply