Defer would be really sweet, reaching for it now, have complex procedure that does several different allocations, hard to separate, prodding against messy win32 api.
Here is macro implementation with all its drawbacks a user land macro always has.
Code: Select all
DeclareModule Defer
EnableExplicit
Macro Defer
Global DeferLabelAddress#MacroExpandedCount = ?DeferLabel#MacroExpandedCount
Runtime DeferLabelAddress#MacroExpandedCount
CompilerIf Defined(DeferLabelStart, #PB_Variable)
DeferLabelCount + 1
CompilerElse
Protected DeferLabelStart, DeferLabelCount, DeferLabelReturn, DeferLabelAddress
DeferLabelStart = MacroExpandedCount
DeferLabelCount = MacroExpandedCount
CompilerEndIf
Goto DeferLabelJump#MacroExpandedCount
DeferLabel#MacroExpandedCount:
EndMacro
Macro EndDefer
CompilerIf #PB_Compiler_Backend = #PB_Backend_C
!goto *v_deferlabelreturn;
CompilerElse
EnableASM
jmp DeferLabelReturn
DisableASM
CompilerEndIf
DeferLabelJump#MacroExpandedCount:
EndMacro
Macro DeferRun()
DeferLabelReturn = ?DeferLabelReturn#MacroExpandedCount
DeferLabelReturn#MacroExpandedCount:
If DeferLabelCount >= DeferLabelStart
DeferLabelAddress = GetRuntimeInteger("DeferLabelAddress" + DeferLabelCount)
DeferLabelCount - 1
CompilerIf #PB_Compiler_Backend = #PB_Backend_C
!goto *v_deferlabeladdress;
CompilerElse
EnableASM
jmp DeferLabelAddress
DisableASM
CompilerEndIf
EndIf
EndMacro
Macro DeferReturn(ret = #Null)
DeferRun()
ProcedureReturn ret
EndMacro
EndDeclareModule
Module Defer
EndModule
UseModule Defer
Procedure Worker(value)
Static count = 0
count + 1
Debug #PB_Compiler_Procedure + " Call " + count
Debug #PB_Compiler_Procedure + " Call " + count + " Allocate memory"
Defer
Debug #PB_Compiler_Procedure + " Call " + count + " Defer 1 Free memory"
EndDefer
If value = #False
Debug #PB_Compiler_Procedure + " Call " + count + " Return"
DeferReturn(#False)
EndIf
Debug #PB_Compiler_Procedure + " Call " + count + " Allocate more memory"
Defer
Debug #PB_Compiler_Procedure + " Call " + count + " Defer 2 Free more memory"
EndDefer
Debug #PB_Compiler_Procedure + " Call " + count + " Return"
DeferReturn(#True)
EndProcedure
Procedure Main()
Debug #PB_Compiler_Procedure
Debug #PB_Compiler_Procedure + " Allocate memory"
Defer
Debug #PB_Compiler_Procedure + " Defer Free memory"
EndDefer
Debug #PB_Compiler_Procedure + " Call Worker"
Worker(#False)
Debug #PB_Compiler_Procedure + " Do stuff"
Debug #PB_Compiler_Procedure + " Call Worker again"
Worker(#True)
Debug #PB_Compiler_Procedure + " Return"
DeferReturn()
EndProcedure
Main()
Enjoy!
EDIT: Fix so that defers are called in Last In First Out order
EDIT: Added C backend support. Made variable names some what longer too minimize risk of collisions.