Using GOSUB

Post Reply
Doctor Watson
Posts: 8
Joined: Wednesday 22nd August 2018 7:55am

Using GOSUB

Post by Doctor Watson » Tuesday 09th April 2019 11:40am

I would lke to include some 'subroutines' using GOSUB but can't get it to work. I searched all of Gambas documentation (Wikis, ...) but nothing I find there works.
So here is the most simple code that works in most other Basics, but doesn’t in Gambas:
------------------------------------------------------------------------------------
' Gambas class file
Public Sub Form_Open()
GoSub Display
End

Display:
'Execute some code and return
Return
-------------------------------------------------------------------------------------
When I try to run this, I get “Missing AS in Fmain.Class:10”
'10' being the line number of Display:

This will look peanuts to an experienced Gambas user ... :shock:

User avatar
Cedron
Posts: 38
Joined: Thursday 21st February 2019 5:02pm
Location: The Mitten State
Contact:

Re: Using GOSUB

Post by Cedron » Tuesday 09th April 2019 12:04pm

I love GOSUBS. They make BASIC better than any other language. Java used to have them in the byte codes, but never implementtted and now deprecated.

Gosubs are local within a routine, just like with VB.
'==================================='
Sub This()

    blah
    blah
    
    GoSub A
    
    blah 
    
    Return
    
'-----------------------------------'
A:

    more blah

    Return

End
'==================================='
The separator lines aren't necessary, but I usually run them out to column 79.

The "Return" statement is used for both an "Exit Sub" and a gosub "Return", determined by context. The scope of variable is determined by the sub, that's what is so nice about them.

Ced

Doctor Watson
Posts: 8
Joined: Wednesday 22nd August 2018 7:55am

Re: Using GOSUB

Post by Doctor Watson » Tuesday 09th April 2019 12:16pm

Quod erat demonstrandum.
Let's see if I can put it to use.
Thanks Cedron

User avatar
cogier
Site Admin
Posts: 251
Joined: Wednesday 21st September 2016 2:22pm
Location: Guernsey, Channel Islands

Re: Using GOSUB

Post by cogier » Wednesday 10th April 2019 10:55am

I find the trouble with GOSUB is that you can only use it in the subroutine your in. If you create another subroutine instead you can call it from any part of your program. Example: -
Public Sub Form_Open()

For iLoop As Integer = 33 To 126
  Print GetAscii(iLoop)
Next

End

Public Sub GetAscii(iValue As Integer) As String
Dim sReturn, sCase As String

sReturn = Chr(iValue) & " is ASCII value " & Str(iValue)
If IsLower(Chr(iValue)) Then sCase = " lower case"
If IsUpper(Chr(iValue)) Then sCase = "n upper case"
If IsNumber(Chr(iValue)) Then sReturn &= " and is a" & sCase & " number"
If IsLetter(Chr(iValue)) Then sReturn &= " and is a" & sCase & " letter"
If IsPunct(Chr(iValue)) Then sReturn &= " and is punctuation"

Return sReturn

End

User avatar
Cedron
Posts: 38
Joined: Thursday 21st February 2019 5:02pm
Location: The Mitten State
Contact:

Re: Using GOSUB

Post by Cedron » Thursday 11th April 2019 7:36pm

GoSubs allow you to completely avoid overburdened control structures.

I've seen them, you've seen them, "If" statements that span pages. "If" and "Do" and "Select"s and "For" structures nested way too many levels deep.

Suppose a monster like this starts growing in your code. You add features, make exceptions, etc. etc., the code grows. So, to tame it, you want to take a chunk of it out, put it aside under a label, and leave the label behind.

In most languages, other than BASIC and Assembly, you only have one choice in the kind of label to put it behind. A full blown separate procedure, complete with calling arguments needing to be defined at the call, at the definition, maybe other overhead, etc. etc. The threshold for this being rather high is the reason you see so many overburdened control structures.

Of course this solution is available in BASIC, but BASIC also gives you the GoSub. Simply cut and past the code to the bottom of your sub. Place a "Return" line in front, a label for the Gosub, your pasted code, another "Return", then put "Gosub label" where the code was and you are done. Well, you'll likely change the indentation and comment it more. If it isn't the first GoSub, the first "Return" won't be necessary. It is cheap at runtime too, (I presume this is true for Gambas as well).

So how do you decide which type of GoSub to use? It depends mostly on two criteria:

1) How many local variables are in the code that you will need to define references for?

2) Is it useful as a generally available sub?

Those criteria aren't quite independent either, so most the time the decision is easy.

Here's an example from the GamePad test program I am working on.
'=============================================================================
Public Sub TimerTick(ArgDisplayLB As ListBox, ArgTagNamesCB As CheckBox[])
        
        Dim theOutcome As Integer
        
        Do   
           theOutcome = myGamePad.GetFancyEvent()
           If theOutcome < 0 Then Break
           GoSub ShowInDisplayListBox
           GoSub HandleGamePadEvent
        Loop

        Return
        
'-----------------------------------------------------------------------------
ShowInDisplayListBox:

        ArgDisplayLB.Add(myGamePad.EventToString())
        
'---- Maybe Reduce Event Display Size

        If ArgDisplayLB.count > 1000 Then
           ArgDisplayLB.Remove(0, 100)
        Endif

'---- Position Display At End

        ArgDisplayLB.Index = ArgDisplayLB.Count - 1

        Return
        
'-----------------------------------------------------------------------------
HandleGamePadEvent:

        Dim n, v, k, e As Integer
        
        n = myGamePad.MyGPE.Number
        v = myGamePad.MyGPE.Value
        k = myGamePad.MyGPE.Kind

There are many more lines, and a few more gosubs that follow. All too big to fit in the read loop. Yes, in this case there weren't too many parameters to worry about, but keeping it local keeps it neater and the external interface cleaner.

It's really nice to have GoSubs as an option.

Post Reply