Page 1 of 1

How t pass arrays into procedures?

Posted: Mon Apr 16, 2018 11:23 am
by BitSeeker
This may be a simple question and forgive me if it has been asked before, but I couldn't find an answer - at least not for native Acorn BASIC. I have noticed while programming on the BBC Micro that Acorn BASIC will recognize globally declared array variables (e.g. scores%(10)) inside a "first level" PROC. However if I call another PROC from within the first one and try to use that same array variable, it it no longer recognized and an error is produced. Generally it is bad practice to reference global variable within an array. The preferred method is to pass the variables as parameters in the procedure definition. On the BBC Micro this works OK for simple variables such as NAME$ or A%, but I could not get it to work for arrays.

If I try to pass scores% as a parameter, this seems to be treated as a new separate single variable not an array. If I pass it as score%(), then I get a 'No such variable' error.

So is there a way of passing arrays either by name or by reference?
Programming around this might be possible but the code gets a little long winded and messy.

Re: How t pass arrays into procedures?

Posted: Mon Apr 16, 2018 12:50 pm
by lurkio
BitSeeker wrote:I have noticed while programming on the BBC Micro that Acorn BASIC will recognize globally declared array variables (e.g. scores%(10)) inside a "first level" PROC. However if I call another PROC from within the first one and try to use that same array variable, it it no longer recognized and an error is produced.
Are you sure?:
  • image.jpeg
BitSeeker wrote:So is there a way of passing arrays either by name or by reference?
I don't think so. I think you can only pass string variables or numeric variables, but not arrays:
:idea:

Re: How t pass arrays into procedures?

Posted: Mon Apr 16, 2018 4:11 pm
by BitSeeker
Hmmm.. just tried that on mine, both emulator and actual Beeb and it worked OK as well. I also tried with a string-var and a num-var with a similar result so they can be 'seen' by the PROC as well. Thanks for the reference to PROC - I didn't think to look there. It does clearly say string-var or num-var so I guess that confirms arrays cannot be passed. There must be something else going on so I will go back and check my code.

Re: How t pass arrays into procedures?

Posted: Mon Apr 16, 2018 7:26 pm
by Elminster
Passing an Array as a parameter was added to BASIC V aka Advanced BASIC but that is not standard on a BBC.

Re: How t pass arrays into procedures?

Posted: Tue Apr 17, 2018 12:30 pm
by BitSeeker
I think the problem was an ovelap between variable names (e.g. I% in FOR ..NEXT loops) inside the procedure and global variables. I have decided to use capitals for global variables and small letters for those inside procedures , that way there is no overlap and so far no errors. Since I added another procedure unfortunately I am now getting 'Not enough room'. Since there is still quite a bit of coding to be done, I guess I will have to switch to an 8k two color mode.

Re: How t pass arrays into procedures?

Posted: Tue Apr 17, 2018 1:04 pm
by billcarr2005
Are you typing the BASIC program in with the PAGE at &1900?
If it's the final program, ie. no more will need to be loaded afterwards, tape could be enabled and the PAGE dropped to &E00.
If under emulation, might be worth developing on the BBC Master initially to keep PAGE low?
Although it's only a saving of &B00, whereas the mode change would save &2800 (or more)? :?

Re: How t pass arrays into procedures?

Posted: Tue Apr 17, 2018 1:17 pm
by lurkio
BitSeeker wrote:I think the problem was an ovelap between variable names (e.g. I% in FOR ..NEXT loops) inside the procedure and global variables. I have decided to use capitals for global variables and small letters for those inside procedures , that way there is no overlap
Or use LOCAL variables inside procedures/functions if you can.

:idea:

Re: How t pass arrays into procedures?

Posted: Tue Apr 17, 2018 11:10 pm
by BitSeeker
billcarr2005 wrote:Are you typing the BASIC program in with the PAGE at &1900?
If it's the final program, ie. no more will need to be loaded afterwards, tape could be enabled and the PAGE dropped to &E00.
If under emulation, might be worth developing on the BBC Master initially to keep PAGE low?
Although it's only a saving of &B00, whereas the mode change would save &2800 (or more)? :?
Yes, indeed I was. I checked the value of PAGE in the emulator and it returned a value of 6400 (&1900). I set it to &0E00 and issued a *TAPE but the emulator froze when I tried to load my program. However, after reset it then reported PAGE at 3584 (&0E00) so perhaps a reset is required to change filing system mode. After that, my program loaded and worked. I actually added a bit to my program tonight but was able to save space overall by combining the functions of two procedures into one. Switching PAGE will perhaps give me a bit of headroom for a while, but I suspect that ultimately it will not be enough. My program is now 7.9kb on disk and I still need to add quite a bit, although I have not yet made any attempt at crunching.
lurkio wrote: Or use LOCAL variables inside procedures/functions if you can.

:idea:
That's a fair point. I was getting a bit paranoid about the work LOCAL taking up another five bytes, although apparently it can be abbreviated to LOC. just as COLOUR can be shortened to COL. BBC Basic for Windows expands them back to their full length automatically when I type them in. Its something I will look at a bit later.

Is there a list of keywords and their abbreviations anywhere please?

Re: How t pass arrays into procedures?

Posted: Tue Apr 17, 2018 11:35 pm
by ctr
On a real beeb keywords like COLOUR and PRINT are tokenised to a single byte when you enter a line of code, so abbreviating them doesn't make any difference to the memory used.

Re: How t pass arrays into procedures?

Posted: Wed Apr 18, 2018 12:01 am
by BitSeeker
Thanks for reminding me about that. Someone did mention it before and I had already forgotten! It does actually make sense because when I type say P. on the Beeb or emulator in a BASIC program this does get automatically expended to PRINT when I list the program. Tokenizing makes sense when you have limited memory.

How much difference does it really make using A% instead of A? The User manual states using integer variables rather than real causes things to run faster. Apart from comments, blank lines and spaces, I could probably save quite a bit of memory just by removing the % character from all of the variables! I guess what I really need to know is how much memory my program is using when it is loaded and tokenized.

Re: How t pass arrays into procedures?

Posted: Wed Apr 18, 2018 12:07 am
by Elminster
I waste loads of space making the program readable, then run it through a basic code cruncher. Best of both worlds then. Readable, maintainable but still small.

Re: How t pass arrays into procedures?

Posted: Wed Apr 18, 2018 4:43 am
by Lardo Boffin
BitSeeker wrote:Thanks for reminding me about that. Someone did mention it before and I had already forgotten! It does actually make sense because when I type say P. on the Beeb or emulator in a BASIC program this does get automatically expended to PRINT when I list the program. Tokenizing makes sense when you have limited memory.

How much difference does it really make using A% instead of A? The User manual states using integer variables rather than real causes things to run faster. Apart from comments, blank lines and spaces, I could probably save quite a bit of memory just by removing the % character from all of the variables! I guess what I really need to know is how much memory my program is using when it is loaded and tokenized.
A% variable take 4 bytes of storage (I think) and A% to Z% are resident variables and therefore faster to access than AA% for example as they are stored in a fixed location. All other variables are stored in the heap.
A would use 5 bytes as it is a real number. Real numbers (i.e. decimals) are much slower to work with.

Try using timing loops to see the difference:-

1 TIME=0
10 FOR A=1 TO 10000
20 B=A*2
30 NEXT
40 T=TIME:PRINT T/100

This will print how long it takes in seconds.

Now do the same but using A% and B%.

Then try again using AA% and BB%.

Also try changing line 30 to be NEXT A or NEXT A% etc. and see how much that slows it down.

If you put lines 10 to 30 on a single line you will also save a few bytes (for the line numbers etc.) and it will run a bit faster.

Re: How t pass arrays into procedures?

Posted: Wed Apr 18, 2018 4:29 pm
by lurkio
BitSeeker wrote:Is there a list of keywords and their abbreviations anywhere please?
https://archive.org/stream/BBCUG/BBCMUG ... 5/mode/1up

:idea:

Re: How t pass arrays into procedures?

Posted: Wed Apr 18, 2018 7:05 pm
by Lardo Boffin
Hi Bitseeker

If you don’t have a user guide I have a spare one you can have for p&p. Just let me know if you are interested.

Lardo

Re: How t pass arrays into procedures?

Posted: Thu Apr 19, 2018 4:38 pm
by BitSeeker
Lardo Boffin wrote:Hi Bitseeker

If you don’t have a user guide I have a spare one you can have for p&p. Just let me know if you are interested.

Lardo
Thank you for the kind offer. I do have the PDF version on the iPad although sometimes I wish I had the paper version as it is so much easier to turn over pages!
Lardo Boffin wrote: A% variable take 4 bytes of storage (I think) and A% to Z% are resident variables and therefore faster to access than AA% for example as they are stored in a fixed location. All other variables are stored in the heap.
A would use 5 bytes as it is a real number. Real numbers (i.e. decimals) are much slower to work with.

Try using timing loops to see the difference:-

1 TIME=0
10 FOR A=1 TO 10000
20 B=A*2
30 NEXT
40 T=TIME:PRINT T/100

This will print how long it takes in seconds.

Now do the same but using A% and B%.

Then try again using AA% and BB%.

Also try changing line 30 to be NEXT A or NEXT A% etc. and see how much that slows it down.

If you put lines 10 to 30 on a single line you will also save a few bytes (for the line numbers etc.) and it will run a bit faster.
I just did those test and am stunned to find that using A%/B% the program completed in 10.23sec, whereas using A/B it took 26.88seconds, so almost 3 times longer! I had not considered that using AA% might also be slower than A% although the difference here is only some 2.5seconds so far less significant although thats still around 20% slower. Using NEXT A% made 0.7sec difference, whereas when using NEXT AA% the difference was around 1.7 seconds. Clearly using A%/B% is always faster and no doubt the best choice where time is of the essence.