Gosub uu
End
uu:
jk=MessageRequester("","---aaaa---",#PB_MessageRequester_Warning|#PB_MessageRequester_YesNoCancel )
Select jk
Case #PB_MessageRequester_No
Goto uu
Case #PB_MessageRequester_Cancel
Goto re3
Case #PB_MessageRequester_Yes
Goto uu
EndSelect
re3:
Return
Macro Gosub(label,depth=0) ;depth is needed to jmp and return out and in of nested selects
CompilerIf depth
CompilerIf SizeOf(integer) = 8
!label#_a=depth ;set a fasm preprocesor variable for the nest depth
!repeat label#_a
!pop rax ;assmebless pop rax
!end repeat
CompilerElse
!label#_a=depth
!repeat label#_a
!pop eax
!end repeat
CompilerEndIf
CompilerElse
!label#_a=0
CompilerEndIf
!jmp label
!if ~ defined label#__return | defined @f ;defines the return label if it's not defined
!label#__return: ;assembles return label
!@@: ;assembles anonymous label
!end if
EndMacro
Macro Return(label)
!if label#_a > 0
CompilerIf SizeOf(integer) = 8
!repeat label#_a
!push rax
!end repeat
CompilerElse
!repeat label#_a
!push eax
!end repeat
CompilerEndIf
!end if
!jmp label#__return
EndMacro
Macro Goto(label,depth=0) ;depth is needed to jmp and return out and in of nested selects
CompilerIf depth
CompilerIf SizeOf(integer) = 8
!repeat depth
!pop rax
!end repeat
CompilerElse
!repeat depth
!pop eax
!end repeat
CompilerEndIf
CompilerEndIf
!jmp label
EndMacro
Macro label(name)
!name#:
EndMacro
;example
Procedure b()
Protected v.i=5 ,x=6
Repeat
Select x
Case 6
Select v
Case 5
Gosub(l1,2) ;we are nested in 2 selects and exiting 2 levels to l1
Debug "after gosub Select l1 "+Str(v)
Case 6
Gosub(l2,2) ;
Debug "after gosub select l2 "+Str(v)
Default
Goto(l3,2) ;we are nested in 2 selects and exiting 2 levels to l3
EndSelect
EndSelect
ForEver
label(l3)
ProcedureReturn v
!l1: ;we jumped here from within the select statement using Gosub(l1,2) the stack pointer is ballanced
v+1 ;without the stack adjustment the protected variables wouldn't be accessible after the jump
Return(l1);l,2) ;return back to the select statement which is nested 2 levels using Return(l1,2) and restore the stack pointer
!l2:
v+1
Return(l2); ;comment out
Debug "goto l3"
Goto(l3) ;if you commented out Return(l2,2) you will jump to l3 from here no need to adjust depth
;you got here having exited the Select at Case 6 of Select v
EndProcedure
Procedure c()
w.s=Chr(65)
For i=Asc("B") To Asc("Z")
Gosub(cc)
Gosub(cc1)
w+Chr(i)
Next i
Debug w
ProcedureReturn
!cc:
w.s+"-"
Gosub(ee)
Return(cc)
!cc1:
w.s+"-"
Return(cc1)
!ee:
w.s+"."
Return(ee)
EndProcedure
b()
c()
Debug "done"
Gosub(uu)
Debug "bye"
End
!uu:
jk=MessageRequester("","---aaaa---",#PB_MessageRequester_Warning|#PB_MessageRequester_YesNoCancel )
Select jk
Case #PB_MessageRequester_No
Debug "no"
Goto(uu,1)
Case #PB_MessageRequester_Cancel
Debug "cancel"
Goto(re3,1)
Case #PB_MessageRequester_Yes
Debug "yes"
Goto(uu,1)
EndSelect
!re3:
Return(uu)
Gosub uu
End
uu:
jk=MessageRequester("","---aaaa---",#PB_MessageRequester_Warning|#PB_MessageRequester_YesNoCancel )
Select jk
Case #PB_MessageRequester_No
Goto uu
Case #PB_MessageRequester_Cancel
Goto re3
Case #PB_MessageRequester_Yes
Goto uu
EndSelect
;TODO add:{
End
;}
re3:
Return
Last edited by gurj on Sun Apr 21, 2019 8:56 pm, edited 1 time in total.
Gosub uu
End
uu:
jk=MessageRequester("","---aaaa---",#PB_MessageRequester_Warning|#PB_MessageRequester_YesNoCancel )
Select jk
Case #PB_MessageRequester_Yes
FakeReturn
Goto uu
Case #PB_MessageRequester_No
FakeReturn
Goto uu
Case #PB_MessageRequester_Cancel
FakeReturn
Goto re3
EndSelect
;TODO add:{
End
;}
re3:
Return
I know you didn't ask and Josh's solution addresses technical things well but I just thought I would throw out another variation in duplicating the same program flow of your test snippet:
Gosub uu
End
uu:
Repeat
status = #False
jk=MessageRequester("","---aaaa---",#PB_MessageRequester_Warning|#PB_MessageRequester_YesNoCancel )
Select jk
Case #PB_MessageRequester_Yes
Continue
Case #PB_MessageRequester_No
Continue
Case #PB_MessageRequester_Cancel
status = #True
Break
EndSelect
ForEver
If status: Goto re3: EndIf
;TODO add:{
End
;}
re3:
Return
thanks Demivec !
your code fit this:
in pb's doc:
Note: To exit a loop safely, you always must use Break instead of Goto, and never use it inside a Select/EndSelect block (Unless you have the ability to manage the stack yourself, correctly.)