![]() |
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 StatesPosts: 405 |
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 StatesPosts: 3378 |
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 StatesPosts: 405 |
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 StatesPosts: 3378 |
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 StatesPosts: 405 |
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 StatesPosts: 3378 |
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 StatesPosts: 405 |
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: AustraliaPosts: 871 |
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 "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: AustraliaPosts: 6283 |
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: AustraliaPosts: 1642 |
This must surely be a bug? Try these two versions: Then this one: 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! Bill Keep safe. Live long and prosper. |
||||
Turbo46![]() Guru ![]() Joined: 24/12/2017 Location: AustraliaPosts: 1642 |
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: AustraliaPosts: 871 |
Thanks Jim, Cheers, Andrew |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
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 StatesPosts: 261 |
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: AustraliaPosts: 6283 |
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: AustraliaPosts: 6 |
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). 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: AustraliaPosts: 6283 |
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: FrancePosts: 435 |
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: AustraliaPosts: 6283 |
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 KingdomPosts: 4311 |
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 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |