Page 1 of 1

How to emulate Beta BASIC's KEYIN?

Posted: Wed Apr 06, 2011 2:13 pm
by programandala.net
The BASICs written by Andy Wright (Beta BASIC for the ZX Spectrum; SAM BASIC and MasterBASIC for the SAM Coupé) have a nice command called KEYIN. It receives a string and "types" it in "virtually" into the command line. It simply evaluates the BASIC code and executes it. This feature makes it possible to write self-modifying programs (though the SAM Coupé's version of the command is quite buggy for this) and, more interesting, store BASIC code into arrays, files or DATAs and execute it at will (very useful for decision trees and many other things).

In order to use it in a program, I'm trying to replicate KEYIN in S*BASIC, without success.

First try, with DO:

Code: Select all

defproc keyin(sbasic_code$):rem first try
  rem Evaluate a string that contains S*BASIC code
  rem It doesn't work, because DO stops the program.
  loc file$,channel
  let file$="ram1_keyin_tmp"
  let channel=fop_over(file$)
  rem if channel<0:fatal_error "keyin: "&channel
  print #channel,sbasic_code$
  close #channel
  do file$
  delete file$
enddef
Second try, with MERGE:

Code: Select all

defproc keyin(sbasic_code$):rem second try
  rem Evaluate a string that contains S*BASIC code
  rem It doesn't work, because MERGE cannot be used inside a procedure or while any procedure is active.
  loc file$,merge_line,channel
  let file$="ram1_keyin_tmp"
  let merge_line=32767
  let channel=fop_over(file$)
  rem if channel<0:fatal_error "keyin: "&channel
  print #channel,merge_line&"defproc do_keyin:"&sbasic_code$&":enddef"
  close #channel
  merge file$
  do_keyin
  dline merge_line
  delete file$
enddef
I tried also the MERGE version in a subroutine, but no difference: MERGE cannot be used if the return stack is not empty (no mention about this in the manuals I have).

Any suggestion will be apreciated. I'm running out of ideas at the moment. I've searched for something similar in any toolkit I know of, but found nothing.

Re: How to emulate Beta BASIC's KEYIN?

Posted: Wed Apr 06, 2011 5:36 pm
by RWAP
Turbo Toolkit has the command TYPE_IN which is what you are looking for....

Re: How to emulate Beta BASIC's KEYIN?

Posted: Wed Apr 06, 2011 5:50 pm
by RWAP
As for the issues with MERGE and DO - the SBASIC/SuperBASIC Reference Manual is your friend here...
NOTE 3:
MERGE can become confused if used from within a PROCedure or FuNction. Minerva and Toolkit II both report 'Not Implemented'.
As for DO, unless you have SMSQ/e, when used from within a program, only the first line of a numberless program is executed - so you would have to get all of your BASIC statements onto one line.

The best bet is to use either a routine which calls on TYPE_IN (from the BTOOL toolkit or Turbo Toolkit), or FORCE_TYPE (from the TinyToolkit)

Re: How to emulate Beta BASIC's KEYIN?

Posted: Thu Apr 07, 2011 2:06 am
by programandala.net
RWAP wrote:As for the issues with MERGE and DO - the SBASIC/SuperBASIC Reference Manual is your friend here...
I think I will acquire it soon. I see it's really worth having.
As for DO, unless you have SMSQ/e, when used from within a program, only the first line of a numberless program is executed
I knew. No problem. I use both QPC2 and Q-emuLator for developing and testing.
The best bet is to use either a routine which calls on TYPE_IN (from the BTOOL toolkit or Turbo Toolkit), or FORCE_TYPE (from the TinyToolkit)
Thank you. I tried TYPE_IN years ago, but I didn't considered it now because it emulates actual typing in a console. (The Beta BASIC command does all the work internally, it feeds the interpreter at lower level). But I think I could do something to minimise the side effects of typing. As for FORCE_TYPE, I didn't knew it, I'll try too.