Calling a Procedure using a Variable

Discussions about the BBC BASIC language, with particular reference to BB4W and BBCSDL
hinckleyj
Posts: 25
Joined: Sat 02 Jun 2018, 08:02

Re: Calling a Procedure using a Variable

Post by hinckleyj »

Thank you Zaphod.

Another excellent example.

Thank goodness for this forum!

John
Zaphod
Posts: 78
Joined: Sat 23 Jun 2018, 15:51

Re: Calling a Procedure using a Variable

Post by Zaphod »

Can I add a word of caution.

When you use EVAL you have to be very careful with variables or the default compiler option of abbreviating variables aka crunching can seriously screw things up. The easiest thing is just not use that particular compiler option and it will work as in the IDE. Or you can use the REM!Keep directive and stop those variables and procedure names from being crunched. But if it works in the IDE but not compiled look at what EVAL is producing and will it be the same as the PROC if there is crunching.
The program as it stands WILL compile just fine because the PROC names are so short they probably wont get crunched but if you move onto longer strings you might well run into trouble.
Say for example you decided to call your Procedures PROCmax1 and PROCmax2, then if you tried to write line 90 as:

Code: Select all

90   pptr%=EVAL("^PROCmax"+STR$(Selection%))
this would fail on compile because the PROCmax1 and PROCmax2 would be crunched to a shorter name and you would get an error.

Code: Select all

REM!Keep PROCmax1, PROCmax2 
will fix that.

And if you get more sophisticated and try sets of PROC calls such as "run" "jump' and 'skip'
then write:

Code: Select all

 
action$="jump"
pptr%=EVAL("^PROC"+action$+STR$(Selection%))
a similar situation will exist with a mismatch between the EVAL output and the crunched PROC name.

Another way is to put the addresses of the PROC's in an array and call them by the array index and that way you avoid the name crunching entirely.

Code: Select all

      PROC_Dummy
      DIM A%(2)
      A%(1)=^PROCsum
      A%(2)=^PROCdif
      REPEAT
        REPEAT
          CLS
          PRINT "1 - Menu Item 1"
          PRINT "2 - Menu Item 2"
          INPUT "Enter selection "; Selection%
        UNTIL Selection% >0 AND Selection% <3
        PROC(A%(Selection%))
        PRINT : PRINT "Run again Y/N? "
        REPEAT
          Key$ = GET$
        UNTIL INSTR("YNyn", Key$)
      UNTIL INSTR("Nn", Key$)
      QUIT
      REM Procedure 1
      DEF PROCsum
      INPUT "First number ";FirstNum%
      INPUT "Second number ";SecondNum%
      PRINT
      Answer% = FirstNum% + SecondNum%
      PRINT FirstNum%; "plus "; SecondNum%; " = ";Answer%
      ENDPROC
      REM -----------------------------
      REM Procedure 2
      DEF PROCdif
      INPUT "First number ";FirstNum%
      INPUT "Second number ";SecondNum%
      PRINT
      Answer% = FirstNum% - SecondNum%
      PRINT FirstNum%; " minus "; SecondNum%; " = ";Answer%
      ENDPROC
      REM -----------------------------
      DEF PROC_Dummy
      ENDPROC
I am still wondering why you need to use indirection in calling the procedures at all, but that is your call. I would have thought that a simple CASE statement would work as well and be much simpler.

Code: Select all

 
CASE Selections% OF
WHEN 1: PROC1
WNEN 2: PROC2
ENDCASE
but there may be more to this story...
Z
hinckleyj
Posts: 25
Joined: Sat 02 Jun 2018, 08:02

Re: Calling a Procedure using a Variable

Post by hinckleyj »

Hi Zaphod,

Thank you for taking the time and trouble to set out that explanation. I like the idea better than mine.

I am learning so much from you guys.

Thank you.
John
Zaphod
Posts: 78
Joined: Sat 23 Jun 2018, 15:51

Re: Calling a Procedure using a Variable

Post by Zaphod »

John,
you are welcome but it is always wise to check the manual because I am fallible as some will willingly attest.
On the subject of crunching variable names I have made assumptions about what does and does not get crunched in the previous posts based on my experience. Those assumption may not be valid though. Certainly single character variables in simple programs don't seem to get changed when compiled but there does not seem to be anything definitively written about that so don't take that as fact and treat them with the same caution that you would use on longer names.
There used to be a little routine by Jon Ripley that allowed you to print out the crunched output which might still be here in case you want to explore that topic or validate your code.
I note that although shown as not a valid link in the Home page, Jon Ripley's site Jonripley.com is online, at least as seen from here and has a few little gems on it.

Z