Abort command
Richard S.
Posts: 70
I have a·method·called PUB INITIALIZE that calls PUB MENU_1 that in turn calls through a menu choice·PUB MENU_2 that in turn calls through a menu choice·PUB MENU_3 and etc.· I would like to use ABORT to terminate any given menu level,·clear the stack, and return to the caller.· No return value is needed.···If I replace the menu choice ESC MENU_1·with ABORT...when ESC is pressed the program returns to the caller but then hangs.··I must be missing something.· Help would be appreciated!
PUB·INITIALIZE
· \Menu_1 ' caller
PUB MENU_1
· · repeat
···· · input := kb.getkey
······ case input
········· $31: ' 1
·········· · display_results
······· · $32: ' 2
··········· ·MENU_2
········· $33: '·3
··········· ·MENU_3
········· $CB: ' esc· ' return to·menu_1
············ MENU_1· ' change to ABORT
PUB MENU_2
· · repeat
···· · input := kb.getkey
······ case input
········· $31: ' 1
·············DETONATE
··········$32: ' 2
··········· ·BEEP
··········$33: ' 3· ' turn on lights
············ MENU_3
········· $CB: ' esc· ' return to menu_1
············ MENU_1· ' change to ABORT
PUB MENU_3
· · repeat
····· ·input := kb.getkey
······ case input
········· $31: ' 1
·············TURN_ON_LIGHT_1
··········$32: ' 2
·············TURN_ON_LIGHT_2
········· $33: '·3
·············TURN_ON_LIGHT_3
········· $CB: ' esc· ' return to menu_1
············ MENU_1· ' change to ABORT
...terminal end of menu commands are to be·replaced with...
········· $CB: 'esc
············· ABORT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Richard in Michigan
PUB·INITIALIZE
· \Menu_1 ' caller
PUB MENU_1
· · repeat
···· · input := kb.getkey
······ case input
········· $31: ' 1
·········· · display_results
······· · $32: ' 2
··········· ·MENU_2
········· $33: '·3
··········· ·MENU_3
········· $CB: ' esc· ' return to·menu_1
············ MENU_1· ' change to ABORT
PUB MENU_2
· · repeat
···· · input := kb.getkey
······ case input
········· $31: ' 1
·············DETONATE
··········$32: ' 2
··········· ·BEEP
··········$33: ' 3· ' turn on lights
············ MENU_3
········· $CB: ' esc· ' return to menu_1
············ MENU_1· ' change to ABORT
PUB MENU_3
· · repeat
····· ·input := kb.getkey
······ case input
········· $31: ' 1
·············TURN_ON_LIGHT_1
··········$32: ' 2
·············TURN_ON_LIGHT_2
········· $33: '·3
·············TURN_ON_LIGHT_3
········· $CB: ' esc· ' return to menu_1
············ MENU_1· ' change to ABORT
...terminal end of menu commands are to be·replaced with...
········· $CB: 'esc
············· ABORT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Richard in Michigan
Comments
My repeat loop only has 1 get key command but 3 sets of case statements
if (mymenu == 1)
case xxxxx
if (mymenu == 2)
case yyyyy
if (mymenul == 3)
case zzzzz
To proceed to the next menu, I simply: menuLevel = menuLevel + 1
The previous is: menuLevel = menuLevel - 1
you might want to clear the input after changing the 'menu' variable otherwise 2 menus might execute.
so, using your code as a guide: (I only show menu #2)
PUB MENU
MENU = 1
repeat
input := kb.getkey
if (MENU == 1)
blah blah blah
if (MENU == 2)
case input
$31: ' 1
DETONATE
$32: ' 2
BEEP
$33: ' 3 ' turn on lights
MENU = 3
$CB: ' esc ' return to menu_1
MENU = 1 ' change to ABORT
if (MENU == 3)
blah blah blah
The ABORT is behaving exactly as it should. All calls are unwound back to the call with the "\" in front of it. In your case, that call is followed by the end of the INITIALIZE method (which returns to somewhere). If you want the calls to stop somewhere earlier, you have to prefix the other calls to MENU_n with "\" as well.
Mark, I have looked at your approach to menu design. I will experiment with it. Appreciate the new approach!
Mike, I would have expected 'abort' would return to caller "menu_1' and executed that command...which would have continued the program chain. It does not appear to do so. Having the caller be an expression such as "x := 0" just before "menu_1" does not allow the program to continue either. mpark's idea of using a loop ... 'repeat' '/menu_1' ... does work.
Mike, I have been studying your Propeller "OS" document, the PUB enterDoCommand section. You use quite afew \xxx and abort commands. It appears abort can return to a caller within a method. Would you be so kind to further explain the negative error string address ... abort -string("missing file") ?
Thanx to all for the help.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Richard in Michigan
A better idea
The argument to the ABORT statement is returned as the result of the aborted method call. I use it to return an explanation of the error. Sometimes I use a negative address, particularly when a normal return may return a zero or positive value. In some cases, any non-zero return value indicates an error, so I may take the absolute value and use that as the address of a message.
Mike
mpark...with multiple branches and depth to 3-4 submenus...I am not certain I can make your approach functional.· At least at this point I can only see it working well with a single nonbranching menu tree.
Mike, thanx for the explanation!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Richard in Michigan
''
'' menu tester
''
PUB Start
··· ' Do some stuff, display results then do the following if key is pressed:
··· if kb.gotkey
····· repeat
······· \Menu1· ' Call Menu1.· Menu1 may call Menu2 which in turn may call Menu3, etc.·
··············· ' Each level of submenu should return to the menu just above it or return 'home'
··············· ' to Menu1 when finished.
··············· ' 'home' to Menu1 when finished.
PUB Menu1
· repeat
··· input := kb.getkey
··· case input
····· $30: ' 0
······· Display_results ·' this goes to a a repeat loop to constantly
····· $31: ' 1··········· ·' update and display results unless interrupted
······· Beep_once······ ' by a keypress...then it drops into the menu system
····· $32: ' 2············ ' (see above)
······· Blink_once
····· $33: ' 3
······· Menu2
····· $34: ' 4
······· Menu8···
····· $CB: ' esc
······· ' quit menu tree and do something else
····· $C4: ' home
······· abort
·······
PUB Menu2
· repeat
··· input := kb.getkey
··· case input
····· $30: ' 0
······· Ping_net
····· $31: ' 1
······· Beep_2
····· $32: ' 2
······· Blink_2
····· $33: ' 3
······· Menu3
····· $34: ' 4
······· Menu10···
····· $CB: ' esc
······· menu1
····· $C4: ' home
······· abort
··········
PUB Menu3
· repeat
··· input := kb.getkey
··· case input
····· $30: ' 0
······· detonate
····· $31: ' 1
······· Beep_3
····· $32: ' 2
······· Blink_3
····· $33: ' 3
······· Menu4
····· $34: ' 4
······· Menu5
····· $35: ' 5
······· Menu6·····
····· $CB: ' esc
······· menu2
····· $C4: ' home
······· abort
'' Still deeper levels of menus if needed. Note that the menu tree has multiple
'' branches
······
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Richard in Michigan
You've got the possibility for unlimited recursion. Is that really what you want? Essentially you're using a call when it sounds like you want a goto and just a two level system (basically an array of menus). I would do something like this:
Now, this doesn't give you a multi-level structure, but is that what you really wanted?
Perhaps you need another loop around the whole thing, otherwise when it returns, it's done. (I think that's what Mark was trying to say)
i.e.:
repeat
if kb.gotkey
repeat
\Menu1 ' Call Menu1. Menu1 may call Menu2 which in turn may call Menu3, etc.
' Each level of submenu should return to the menu just above it or return 'home'
' to Menu1 when finished.
' 'home' to Menu1 when finished.
I'm sure that the experts will correct me if I'm wrong.
John