Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 10:38 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 : Apparent Bug in BASIC 5.05.03

     Page 1 of 2    
Author Message
William Leue
Guru

Joined: 03/07/2020
Location: United States
Posts: 405
Posted: 04:30pm 25 Jul 2020
Copy link to clipboard 
Print this post

There seems to be a serious bug in BASIC 5.05.03 on my CMM2: passing arguments to a subroutine by reference does not work!  For instance, the example in the CMM2 user manual:

dim integer a = 2
dim integer b = 3

Swap a, b

print "a = " + str$(a)
print "b = " + str$(b)

end

sub Swap a,b
 local integer t
 t = a
 a = b
 b = t
end sub

This does NOT swap a and b's values: the values are the same as the initial assignment.

I hope this can get fixed soon; it is a pretty crippling bug when it comes to trying to keep some structure in a large program.

-Bill Leue
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 04:55pm 25 Jul 2020
Copy link to clipboard 
Print this post

I have to admit, I don't understand this. In SWAP, it appears to be treating a and b as local. I added SWAP2, with nothing passed, and the swap occurs as expected.

dim integer a = 2
dim integer b = 3

Swap(a, b)

print "3 a = " + str$(a)
print "3 b = " + str$(b)
print ""

swap2

print "6 a = " + str$(a)
print "6 b = " + str$(b)

end

sub Swap(a,b)
local integer t
print "1 a = " + str$(a)
print "1 b = " + str$(b)

t = a
a = b
b = t
print "2 a = " + str$(a)
print "2 b = " + str$(b)

end sub

sub Swap2
local integer t
print "4 a = " + str$(a)
print "4 b = " + str$(b)

t = a
a = b
b = t
print "5 a = " + str$(a)
print "5 b = " + str$(b)

end sub

1 a = 2
1 b = 3
2 a = 3
2 b = 2
3 a = 2
3 b = 3

4 a = 2
4 b = 3
5 a = 3
5 b = 2
6 a = 3
6 b = 2

It works the same way in MMBasic for DOS.

If you add "as integer", it works as expected:

sub Swap(a as integer,b as integer)

~
Edited 2020-07-26 03:11 by lizby
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
William Leue
Guru

Joined: 03/07/2020
Location: United States
Posts: 405
Posted: 05:11pm 25 Jul 2020
Copy link to clipboard 
Print this post

Well, of course it works in Swap2, you are just using the global variables. But it is supposed to work in Swap. According to the Reference Manual, all primitive variables are passed by reference into subroutines. But clearly that is false: they are being passed by value, because the swapped values are not being passed back to the caller.

Geoff and Peter, can you comment?

Thanks!
-Bill Leue
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 05:13pm 25 Jul 2020
Copy link to clipboard 
Print this post

I added to my post:

If you add "as integer", it works as expected:

sub Swap(a as integer,b as integer)
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
William Leue
Guru

Joined: 03/07/2020
Location: United States
Posts: 405
Posted: 05:18pm 25 Jul 2020
Copy link to clipboard 
Print this post

Wow! That is pretty weird, because trying to qualify subroutine parameters using the 'as' terminology causes issues for me in other areas.

Too bad the User Manual does not mention this little trick!

Nice catch, and thanks!
-Bill Leue
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 05:22pm 25 Jul 2020
Copy link to clipboard 
Print this post

Also works if at the top you have "Option default integer".

I guess I have always just included the "as" clause, because I would have expected the original program to work. I (kind of) understand why it didn't, but would be interested to know the rationale for it working the way it does (if it is not in fact a bug). Perhaps there's some behind-the-scenes casting going on.

~
Edited 2020-07-26 03:27 by lizby
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
William Leue
Guru

Joined: 03/07/2020
Location: United States
Posts: 405
Posted: 05:41pm 25 Jul 2020
Copy link to clipboard 
Print this post

Yes, and it turns out you have to use the 'as integer' qualification on each integer argument separately. So if you have, say, 5 arguments, you are very close to running over the maximum line length.

It certainly seems to me that it should not be necessary to provide those type qualifications for arguments. If they are passed in as integer, it should be possible for the BASIC interpreter to remember and use the variable type info without having to be reminded.

As long as I am on the subject, it would sure be nice if functions could return an array as well as a primitive type. This would go a long way toward easing the lack of C-type structs, and make it unnecessary to use ugly workarounds like packing multiple data values into an integer and then unpacking them in the caller code.

Oh well, I can live with things as they are.

-Bill Leue
 
Andrew_G
Guru

Joined: 18/10/2016
Location: Australia
Posts: 871
Posted: 05:34am 28 Jul 2020
Copy link to clipboard 
Print this post

Hi Lizby, Bill et al,
You got me thinking - I still don't think it is entirely consistent with the manual, and I'm not sure you are meant to have to add the "as integer" for each variable.
But I do think that the snippet below is closer to what is intended. It works and the values of a and b are passed into and out of the sub as expected.

(is there anyone out there who can clarify our confusion?)

Cheers,

Andrew
{Edit: Bill, is there a reason for the:
PRINT STR$(a), STR$(b) rather than just PRINT a, b  }



dim integer a = 2
dim integer b = 3

print
print "Before swapping: "; a, b
Swap a, b
print "After swapping : "; a, b
end

sub Swap aa as integer, bb as integer
local integer t
t = aa
aa = bb
bb = t
end sub

Edited 2020-07-28 15:37 by Andrew_G
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 06:33am 28 Jul 2020
Copy link to clipboard 
Print this post

The default type is FLOAT
This means that your SUB was expecting floats.

Normally the interpreter would throw an error if you try and use the same name for INTEGERs and FLOATs but because it was tied up in the SUB definition, the error was not flagged.

The sub therefore considered your a and b to be different variables to the a and b in the sub so the swap wasn't passed back.

option default integer
dim integer a = 2
dim integer b = 3

Swap a, b

print "a = " + str$(a)
print "b = " + str$(b)

end

sub Swap a,b
local integer t
t = a
a = b
b = t
end sub


You can set the default type to INTEGER if you don't want to specify types in the code.
You can also use the % suffix to signify integers.

Jim
VK7JH
MMedit
 
Turbo46

Guru

Joined: 24/12/2017
Location: Australia
Posts: 1642
Posted: 06:34am 28 Jul 2020
Copy link to clipboard 
Print this post

This must surely be a bug?

Try these two versions:
  Quote  dim integer a = 2
dim integer b = 3

print "Before"
print "a = " ;a
print "b = " ;b
Swap a, b
print "After"
print "a = " ;a
print "b = " ;b

end

sub Swap a,b
local integer t
print : print "Swapping"
t = a :
print "t = "; t
a = b :
print "a = "; a
b = t :
print "b = "; b
print
end sub


Then this one:
  Quote  a = 2
b =
3

print "Before"
print "a = " ;a
print "b = " ;b
Swap a, b
print "After"
print "a = " ;a
print "b = " ;b

end

sub Swap a,b
local t
print : print "Swapping"
t = a :
print "t = "; t
a = b :
print "a = "; a
b = t :
print "b = "; b
print
end sub


The first version DOES seem to be treating a and b inside the SUB as LOCAL but in the second one a and b are not defined as INTEGERs and it works

Then I thought I'd try floats, and guess what, IT WORKS!

  Quote  dim float a = 2
dim float b = 3

print "Before"
print "a = " ;a
print "b = " ;b
Swap a, b
print "After"
print "a = " ;a
print "b = " ;b

end

sub Swap a,b
local float t
print : print "Swapping"
t = a :
print "t = "; t
a = b :
print "a = "; a
b = t :
print "b = "; b
print
end sub


Bill
Keep safe. Live long and prosper.
 
Turbo46

Guru

Joined: 24/12/2017
Location: Australia
Posts: 1642
Posted: 06:38am 28 Jul 2020
Copy link to clipboard 
Print this post

Thanks Jim,

Of course! That explains why the FLOAT version works too. But because they are NOT defined as LOCAL shouldn't the interpreter treat them as globals and check for them as Such?

Bill
Edited 2020-07-28 16:45 by Turbo46
Keep safe. Live long and prosper.
 
Andrew_G
Guru

Joined: 18/10/2016
Location: Australia
Posts: 871
Posted: 07:26am 28 Jul 2020
Copy link to clipboard 
Print this post

Thanks Jim,

Cheers,

Andrew
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 07:36am 28 Jul 2020
Copy link to clipboard 
Print this post

This is really an omission in the documentation.

To pass a value by reference the variable passed to the sub/fun must be the same type as defined in the sub/fun's declaration.  If it differs the passed value will be converted to that expected by the sub/fun and will therefor not point back to the original variable.

I will update the documentation.

Geoff
Geoff Graham - http://geoffg.net
 
mkopack73
Senior Member

Joined: 03/07/2020
Location: United States
Posts: 261
Posted: 12:01pm 28 Jul 2020
Copy link to clipboard 
Print this post

I also highly recommend using different variable names inside your function rather than the names used in the caller, otherwise it’s very easy to get yourself (and apparently the interpreter) confused as to whether you are working with the parameter or global variables.

Max line length?? First I’ve heard of this... how big is it??

Is it possible/legal to break up big if/the expressions (ones that have a large number of and/or clauses) like this:

If ( something
   And somethingelse
   And somethingelse
   Or yet more) then

???

Or must it all be one 1 line?

(I could just try it but I’m laying in bed at the moment deciding if I want to get up and start the day..)


Also, ugh I don’t know which dialect of BASIC was the starting point for MMBAsic but the use of % for integers and () for arrays drives me nuts. Every version I ever touched used % for floats and [] for arrays.  Just seems very backwards but obviously way too late in the game to change that...
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 10:18pm 28 Jul 2020
Copy link to clipboard 
Print this post

  mkopack73 said  
Max line length?? First I’ve heard of this... how big is it??

Maximum line length is 255 characters. There is no line continuation character.


MMBasic is based on GW Basic.
That is where the % for integer and ! for float suffixes come from.
Also &h, &o and &b for HEX, OCTAL and BINARY.

Jim
VK7JH
MMedit
 
at67
Newbie

Joined: 02/07/2020
Location: Australia
Posts: 6
Posted: 02:38am 29 Jul 2020
Copy link to clipboard 
Print this post

  mkopack73 said  Is it possible/legal to break up big if/the expressions (ones that have a large number of and/or clauses) like this:

If ( something
   And somethingelse
   And somethingelse
   Or yet more) then

???

Or must it all be one 1 line?

The typical way to breakup complex AND relational logic is to separate out the elements into individual lines. e.g.
' complex AND
IF something
   IF somethingelse1
       IF somethingelse2
           CALL blah
       ENDIF
   ENDIF
ENDIF

' complex OR
IF something
   CALL blah
ELSEIF somethingelse1
   CALL blah
ELSEIF somethingelse2
   CALL blah
ENDIF

This may or may not make your code bigger/less efficient, it completely depends on the interpreter/compiler. For example, using my Gigatron BASIC compiler the expanded patterns generally produce smaller code when used with branches and the complex relational logic produce smaller code when using jumps; but the expanded pattern always produces faster code as it only has to perform one SUB/BRA pair per IF, compared to the more complex boolean combination of multiple SUB/CONV pairs. (Choosing the outer IF correctly can be vital in maximising speed).

  mkopack73 said  Also, ugh I don’t know which dialect of BASIC was the starting point for MMBAsic but the use of % for integers and () for arrays drives me nuts. Every version I ever touched used % for floats and [] for arrays.  Just seems very backwards but obviously way too late in the game to change that...


Not sure how many BASIC's you used in the 80's, but almost all of them booted up by default using floating point as their default numeric, (most of them were Microsoft BASIC derivatives or ports). Some of them even provided integer support as an extension, (usually through the % modifier). Also, most of them used the () syntax to denote arrays.

So, if the CMM2 is supposed to be a modern adaptation/re-incarnation of the typical 80's PC, I personally think they, (Geoff, Peter, Et al), have done more than a reasonable job.
Edited 2020-07-29 13:10 by at67
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 07:35am 29 Jul 2020
Copy link to clipboard 
Print this post

  TassyJim said  
  mkopack73 said  
Max line length?? First I’ve heard of this... how big is it??

Maximum line length is 255 characters. There is no line continuation character.

Make that:
255 characters when entering at the command line, 240 characters when in a program.

Jim
VK7JH
MMedit
 
goc30

Guru

Joined: 12/04/2017
Location: France
Posts: 435
Posted: 01:57am 31 Jul 2020
Copy link to clipboard 
Print this post

hi all

it seem that i have a problem with function "option ram"
but maybe I take a mistake
version: 5.05.04 rc14
first:
"option ram off" do nothing


ooption ram on
> option list
CURRENT VGA mode 800x600 RGB332
CURRENT DISPLAY 50,100
OPTION AUTORUN ON
OPTION USBKEYBOARD FR
OPTION RAM ON


after


> option ram off
> option list
CURRENT VGA mode 800x600 RGB332
CURRENT DISPLAY 50,100
OPTION AUTORUN ON
OPTION USBKEYBOARD FR
OPTION RAM ON



but "option flash on" is ok


second:
I run my program in option flash.
it give that

> memory
Flash:
 34K ( 6%) Program (1355 lines)
482K (94%) Free

RAM:
 52K ( 0%) 151 Variables
  0K ( 0%) General
5132K (100%) Free



with "option ram on" it give that

> memory
Flash:
 34K ( 6%) Program (1355 lines)
482K (94%) Free

RAM:
 52K ( 1%) 151 Variables
  0K ( 0%) General
4620K (99%) Free


but in doc, you said that "option ram" load progam in RAM
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 02:23am 31 Jul 2020
Copy link to clipboard 
Print this post

goc30,
The command to change program location is:
OPTION RAM to store the program in RAM. This reserves 512k of the RAM for your program which is why the RAM available for variables etc is less when you have OPTION RAM set.

To change back to flash storage, use OPTION FLASH (not OPTION RAM OFF)
When you use OPTION FLASH, you can specify the starting flash page. This is to allow you to change flash pages if you ever wear the flash out.
Using FLASH gives you back the extra 512k of ram for variables etc.

Don't get too worried about wearing out the flash.
As a test I loaded programs 130,000+ times and my flash is still working fully.
I wouldn't recommend trying that but someone had to do it...

To be technically correct, the memory command should not say "Flash:" when the program is in ram but it is a way of differentiating between available ram and available program memory space.

Jim
VK7JH
MMedit
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 09:49am 31 Jul 2020
Copy link to clipboard 
Print this post

  TassyJim said  Don't get too worried about wearing out the flash.
As a test I loaded programs 130,000+ times and my flash is still working fully.
I wouldn't recommend trying that but someone had to do it...


Thanks Jim, have sent beer money for your trouble.

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025