Shop OBEX P1 Docs P2 Docs Learn Events
Gosub — Parallax Forums

Gosub

Armored CarsArmored Cars Posts: 172
edited 2004-12-10 00:31 in BASIC Stamp
Will it create a problem to leave a subroutine repeatedly before RETURN is reached?

Ex.

SPEED:
· IF IN4=1 THEN GOBACK
· ect,
· ect.
· RETURN

Comments

  • dandreaedandreae Posts: 1,375
    edited 2004-12-09 19:24
    Hello,

    Yes, you can use the "IF Then" command and then perform a "RETURN", it will remember to go back to the line below the "GOSUB" command.

    Dave





    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Dave Andreae

    Tech Support
    dandreae@parallax.com
    www.parallax.com

    ·
  • allanlane5allanlane5 Posts: 3,815
    edited 2004-12-09 19:41
    Yes, it will create a problem, depending on how the run-time engine works.

    With a 'vanilla' PIC, you have 8 levels of return stack. If you 'GOSUB' in, then 'GOTO' out, you leave an address on the return stack. If you do this 8 times, then the first return value leaves the stack.

    This may only be a problem when you do the 8th 'RETURN' statement -- but it is a maintenance nightmare. Now, the BS2 run-time may have more than 8 levels of return stack -- but ANY return stack only has a limited number of return values.

    The correct way to implement this is:

    Speed:
    · IF IN4 = 1 THEN RETURN
    · ' ELSE...
    · ' Do more stuff here...
    · RETURN

    I believe this will work without side effects. If you are a devotee of one-entry, one-exit routines (which used to be a style convention), you might do:

    Speed:
    · IF In4 = 1 THEN ExitSpeed
    · ' ELSE
    · ' ... Do more stuff
    · ExitSpeed:
    · RETURN

    I am CERTAIN this will work without side effects.

    One more "Clever" way of doing it (note I generally don't approve of "Clever" very much) is:

    Speed:
    · IF IN4 = 1 THEN ReturnAll
    · '..
    · '.. Do more stuff
    · RETURN

    ReturnAll:
    · RETURN

    This uses the PBasic convention that a 'THEN <Label>' does a GOTO.· The target of your GOTO then has a single 'RETURN' statement -- thus satisfying the "RETURN for each GOSUB called" requirement.· You can then use "ReturnAll" as a target for many different Subroutines -- which could be a maintenance problem down the road.

    The second approach is really the preferred one.· It is MUCH more portable.


    Post Edited (allanlane5) : 12/9/2004 7:49:12 PM GMT
  • dandreaedandreae Posts: 1,375
    edited 2004-12-09 19:54
    In the case of the BASIC Stamp 2 or higher you can go 4 deep or 256 total.· In the case below is a psuedo code explaination:

    SPEED:
    · IF IN4=1 THEN GOBACK
    · ect,
    · ect.
    · RETURN

    Goback:
    ·ect,
    · ect.

    RETURN

    Both returns will jump back to the last GOSUB called.

    Dave

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Dave Andreae

    Tech Support
    dandreae@parallax.com
    www.parallax.com

    ·
  • allanlane5allanlane5 Posts: 3,815
    edited 2004-12-09 19:58
    Looking at the documentation for GOSUB, sure enough, the BS2 only has a·4-address deep return stack.· If you GOSUB 5 deep, you lose the first GOSUB return address.

    And by "256 total" do you mean you are only allowed 265 GOTO/GOSUB Labels in a program? If that is true, then the 'ReturnAll' technique looks like a good one, as it conserves labels.

    Post Edited (allanlane5) : 12/9/2004 8:00:36 PM GMT
  • Tom WalkerTom Walker Posts: 509
    edited 2004-12-09 20:05
    Armored Cars:
    I haven't given this more than a few seconds of thought, but I haven't come up with a reason to structure a task to REQUIRE the sort of program you're asking about. If you'd give us a slightly better ideea of what you're trying to accomplish (or give a little bit more time to reading about the elements of PBASIC style and programming in general) you might get more "useful" responses.

    In short, this sounds more like a program "flow" (aka design) problem, than anything which has to be disected with the "how many levels of gosub can the Stamp handle" type of research...





    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    XYZZY...PLUGH...*poof*

    Post Edited (Tom Walker) : 12/9/2004 8:07:12 PM GMT
  • Armored CarsArmored Cars Posts: 172
    edited 2004-12-09 20:08
    The only problem is that when the IF IN4=1 is true, it is sent to the actual program where it may be sent elsewhere, and then to somewhere else, ect.
    About the stacks, if the stack builds up will it slow down the stamp? I dont care if they stack up and dissapear, in my program once it leaves the subroutine it doesnt need to go back. If this doesnt slow the stamp too much Ill probably leave my program like it is.
  • Armored CarsArmored Cars Posts: 172
    edited 2004-12-09 20:15
    Tom you beat me to my post.

    I attatched my program, I realize it is pretty rough, but what Im concerned with right now is·cutting down on the redundacy of commands listed multiple times by using subroutines.· I am constantly expanding this program and want to conserve space so that later I wont run into problems.

    What Im mainly worried about is CHECK, SPEED, and CRASHCHECK.
  • allanlane5allanlane5 Posts: 3,815
    edited 2004-12-09 20:17
    It's not that it slows the stamp down. It's that somewhere, where you least expect it, far away from this erroneous line you've created, your stack may 'underflow'. The result of the 'underflow' will be to reset your program.

    The problem with a 'land-mine' is first that someone buried it there. If you don't step on it, it doesn't go off. Now, is that a problem or not? I would say it IS a problem. You don't want to plant land-mines in your code, whether you THINK you're going to step on them or not. Trying to mis-use the GOSUB/RETURN mechanism the way you are is burying a land-mine in your code.

    If you really never expect to 'RETURN' to a place in your code, then don't USE a 'GOSUB', use a 'GOTO'. You could have easily done:

    Speed:
    IF IN4 =1 THEN GoBack
    ' Do other stuff
    GOTO GoBack ' Or 'MAIN', or wherever else you want to return to.

    If you really-really are absolutely sure you want to 'flush' the current GOSUB context of the program, then you 'should' be able to do what you have suggested. That means you are guaranteeing to yourself you will NEVER have one more 'RETURN' executed than you have 'GOSUB's. But that's a really poor way to design your code.
  • allanlane5allanlane5 Posts: 3,815
    edited 2004-12-09 20:47
    Well, having analyzed your code, it looks like this approach will work. Your mix of GOTO and RETURN's looks like it will 'flush' the return stack quite often -- but with only 4 levels of GOSUB, it looks like this is what you had to do to get the behaviors you were after.

    I would find it difficult to maintain, or extend, but on the whole the approach you've taken looks quite clever.
  • Armored CarsArmored Cars Posts: 172
    edited 2004-12-10 00:31
    So as long as I dont hit an extra RETURN or execute 5 RETURNs it will be alright?

    I think I see what you are saying, though in this paticular program (if my question above is correct) it is only possible to get two on the stack before another GOSUB is executed, and consequently it should be fine. Ill keep in mind to watch for that in other programs though.
Sign In or Register to comment.