Page 1 of 1
Structures in Macros
Posted: Sat Dec 21, 2013 7:53 pm
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?
Re: Structures in Macros
Posted: Sat Dec 21, 2013 8:20 pm
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?
Re: Structures in Macros
Posted: Sat Dec 21, 2013 8:26 pm
by BorisTheOld
I've never had any problems using structures, or structure contents, as macro parameters.
What exactly are you trying to do?
Re: Structures in Macros
Posted: Sat Dec 21, 2013 8:43 pm
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
Re: Structures in Macros
Posted: Sat Dec 21, 2013 8:46 pm
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.
Re: Structures in Macros
Posted: Sat Dec 21, 2013 9:03 pm
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.
Re: Structures in Macros
Posted: Sat Dec 21, 2013 9:07 pm
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)
Re: Structures in Macros
Posted: Sat Dec 21, 2013 9:33 pm
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.
Re: Structures in Macros
Posted: Sat Dec 21, 2013 9:38 pm
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!
Re: Structures in Macros
Posted: Sat Dec 21, 2013 10:42 pm
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.
Re: Structures in Macros
Posted: Sat Dec 21, 2013 10:45 pm
by Thiefbrain
Thank you for you answers. These are really interesting things to know about structures.
Re: Structures in Macros
Posted: Sat Dec 21, 2013 11:01 pm
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
Re: Structures in Macros
Posted: Sat Dec 21, 2013 11:20 pm
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())