Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:08 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Gosub addressing fix

Author Message
Chrisk

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 122
Posted: 12:42am 09 Feb 2018
Copy link to clipboard 
Print this post

Hi all
This may be so simple but I am trying out this small test program with gosub
but I get "Error: Expected a number"
Without the brackets it says it cannot find the label.
Can someone suggest what is required for correct operation.

Thanks Chris K

ABC$ = "two"
x=0
do
pause 100
Print
x=x+1
Print x
if x=10 then
gosub (ABC$)
else
loop


sub one
Print "This is one"
end
sub two
Print "This is two"
end
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 12:51am 09 Feb 2018
Copy link to clipboard 
Print this post

A number of problems with your test program.
You have IF

ELSE

but no ENDIF

You are trying to call the old style Subroutines that use labels and RETURN but have the newer SUB... END SUB (without the END SUB)
Even with those issues fixed, you have the main problem - you cannot use a variable as the target for a GOSUB

  Quote   ABC$ = "two"
x=
0
DO
PAUSE 100
PRINT
x=x+
1
PRINT x
IF x=10 THEN
GOSUB two
ELSE
'
ENDIF
LOOP
END

one:
PRINT "This is one"
RETURN

two:
PRINT "This is two"
RETURN

END



Jim

VK7JH
MMedit
 
Azure

Guru

Joined: 09/11/2017
Location: Australia
Posts: 446
Posted: 01:03am 09 Feb 2018
Copy link to clipboard 
Print this post

It is more readable if you include the code witin in the code option. You should also get in the habit of indenting to improve readability and following the code flow.

In you code there are 2 problems:
1. You cannot call a subroutine name with a variable it must be a label. Check the manual for the correct syntax to use GOSUB. There is also the ON command that might help.
2. In your code you have an multiline IF and an empty ELSE with no END IF. Once again check the MMBasic manual for the correct syntax.

Here it your code with the syuntax for those items corrected and indenting.
ABC$ = "two"
x=0
do
pause 100
Print
x=x+1
Print x
if x=10 then
gosub two
else
gosub one
end if
loop

sub one
Print "This is one"
end sub

sub two
Print "This is two"
end sub


@tassyjim, sorry we must have both been typing a response at the time.
Edited by Azure 2018-02-10
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1993
Posted: 03:41am 09 Feb 2018
Copy link to clipboard 
Print this post

If you use GOSUB should the subroutine not be

ONE:
Print "This is one"
Return


"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
Chrisk

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 122
Posted: 04:45am 09 Feb 2018
Copy link to clipboard 
Print this post

Hi Guys
Azure and TassyJim have pointed out that you cannot use a variable as the target for a GOSUB as I had attempted to do in line 1.

I wasn't sure whether it was possible or not. So that answers my question.

Paul - I usually write it as you suggested but looking at some subroutines on TBS I thought that written your suggested way might be the cause of my problem.
It seems to work either way.

Thanks guys for the quick replies.


Chris K
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 09:01am 09 Feb 2018
Copy link to clipboard 
Print this post

Hi ChrisK

Confusingly you don't call a SUB with GOSUB

the target of a GOSUB is a "sub-routine", where as the target for SUB is a "sub-program" - a completely separate little program within a program. It can share bits of the outside world though. A subtle difference but once you get it you'll wonder how you ever lived without them.

GOSUB was old school basic and would jump to a part of your program... at the end of that section you had to use RETURN to go back to where you were... it is a direct analogue of the machine code calling system with a LIFO stack and all.

Modern basics (including MMBasic) support declared SUB programs in their own right and they really are separate from the main chunk of code. They can have their own variables and everything and you mark the end of the sub program with END SUB. This allows you to write "new" words for your basic programs, just like the ones Basic uses all the time...

To Recap:

Old School (shouldn't do this anymore but MMBasic still supports it

'Main chunk of code
....
GOSUB Fred ' this is the line to jump to
....


Fred: ' this is a line identifier
... processor jumps to here but shares all the variables with the main chunk - easy to break things accidentally
...
RETURN takes you back to where you were before (after the corresponding GOSUB)


New method - you should use this as it is far more efficient and has big advantages


'Main chunk of code
....
Fred ' just use the name of the sub program - it is a "new" word to MMBasic
....


SUB Fred(argument list)
LOCAL (variables private to Fred)
...
END SUB


As you can see, you can pass values directly to a sub program without setting a variable before (you can still do that if you wish) and you can have variables inside the SUB that are private to it - this means stuff like if you have a common name that you use all the time as a counter, you can define it as LOCAL here and then Fred won't trample all over the one in the main chunk of code. It will use its own local version (even though they can have the same name)

It makes reading code really easy too - no more lines and lines of GOSUBs

hth

h







Edited by CaptainBoing 2018-02-10
 
Phil23
Guru

Joined: 27/03/2016
Location: Australia
Posts: 1667
Posted: 09:12am 09 Feb 2018
Copy link to clipboard 
Print this post

Better to ditch Gosub in my opinion & create Subs with appropriate names.

As far a using a variable as a target for a sub is concerned, as the others say it don't work.

But a Case Statement might do what you want to achieve.

  Quote   ABC$ = "two"
'...
'...
Select Case ABC$

Case "one"
Print "This is one"
'Do this stuff

Case "two"
Print "This is two"

end Select



Not sure I have all the syntax right on a Friday night but you should get the gist.

Cheers


 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025