How t pass arrays into procedures?

discussion of beeb/electron applications, languages, utils and educational s/w
BitSeeker
Posts: 44
Joined: Fri Mar 30, 2018 1:18 pm
Contact:

How t pass arrays into procedures?

Postby BitSeeker » Mon Apr 16, 2018 11:23 am

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.

User avatar
lurkio
Posts: 1502
Joined: Tue Apr 09, 2013 11:30 pm
Location: Doomawangara
Contact:

Re: How t pass arrays into procedures?

Postby lurkio » Mon Apr 16, 2018 12:50 pm

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:

BitSeeker
Posts: 44
Joined: Fri Mar 30, 2018 1:18 pm
Contact:

Re: How t pass arrays into procedures?

Postby BitSeeker » Mon Apr 16, 2018 4:11 pm

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.

User avatar
Elminster
Posts: 1679
Joined: Wed Jun 20, 2012 8:09 am
Location: Essex, UK
Contact:

Re: How t pass arrays into procedures?

Postby Elminster » Mon Apr 16, 2018 7:26 pm

Passing an Array as a parameter was added to BASIC V aka Advanced BASIC but that is not standard on a BBC.

BitSeeker
Posts: 44
Joined: Fri Mar 30, 2018 1:18 pm
Contact:

Re: How t pass arrays into procedures?

Postby BitSeeker » Tue Apr 17, 2018 12:30 pm

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.

User avatar
billcarr2005
Posts: 1184
Joined: Fri Sep 09, 2005 3:01 pm
Location: UK
Contact:

Re: How t pass arrays into procedures?

Postby billcarr2005 » Tue Apr 17, 2018 1:04 pm

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)? :?

User avatar
lurkio
Posts: 1502
Joined: Tue Apr 09, 2013 11:30 pm
Location: Doomawangara
Contact:

Re: How t pass arrays into procedures?

Postby lurkio » Tue Apr 17, 2018 1:17 pm

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:

BitSeeker
Posts: 44
Joined: Fri Mar 30, 2018 1:18 pm
Contact:

Re: How t pass arrays into procedures?

Postby BitSeeker » Tue Apr 17, 2018 11:10 pm

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?
Last edited by BitSeeker on Tue Apr 17, 2018 11:45 pm, edited 1 time in total.

User avatar
ctr
Posts: 128
Joined: Wed Jul 16, 2014 2:53 pm
Contact:

Re: How t pass arrays into procedures?

Postby ctr » Tue Apr 17, 2018 11:35 pm

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.

BitSeeker
Posts: 44
Joined: Fri Mar 30, 2018 1:18 pm
Contact:

Re: How t pass arrays into procedures?

Postby BitSeeker » Wed Apr 18, 2018 12:01 am

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.

User avatar
Elminster
Posts: 1679
Joined: Wed Jun 20, 2012 8:09 am
Location: Essex, UK
Contact:

Re: How t pass arrays into procedures?

Postby Elminster » Wed Apr 18, 2018 12:07 am

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.

User avatar
Lardo Boffin
Posts: 933
Joined: Thu Aug 06, 2015 6:47 am
Contact:

Re: How t pass arrays into procedures?

Postby Lardo Boffin » Wed Apr 18, 2018 4:43 am

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.
BBC model B 32k issue 4, 16k sideways RAM, Watford 12 ROM board, Retroclinic Datacentre + HDD, Viglen twin 40/80 5.25" discs, acorn cassette, Acorn 6502 coproc
BBC model B 32k issue 7, turboMMC, Opus Challenger 3 512k, Pi 3 coproc
BBC Master

User avatar
lurkio
Posts: 1502
Joined: Tue Apr 09, 2013 11:30 pm
Location: Doomawangara
Contact:

Re: How t pass arrays into procedures?

Postby lurkio » Wed Apr 18, 2018 4:29 pm

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

https://archive.org/stream/BBCUG/BBCMUG#page/n485/mode/1up

:idea:

User avatar
Lardo Boffin
Posts: 933
Joined: Thu Aug 06, 2015 6:47 am
Contact:

Re: How t pass arrays into procedures?

Postby Lardo Boffin » Wed Apr 18, 2018 7:05 pm

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
BBC model B 32k issue 4, 16k sideways RAM, Watford 12 ROM board, Retroclinic Datacentre + HDD, Viglen twin 40/80 5.25" discs, acorn cassette, Acorn 6502 coproc
BBC model B 32k issue 7, turboMMC, Opus Challenger 3 512k, Pi 3 coproc
BBC Master

BitSeeker
Posts: 44
Joined: Fri Mar 30, 2018 1:18 pm
Contact:

Re: How t pass arrays into procedures?

Postby BitSeeker » Thu Apr 19, 2018 4:38 pm

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.