Running a BAS file from the command line

by Richard Russell, April 2019

It is straighforward to run a BASIC program from the command line, using either the BBC BASIC for Windows or BBC BASIC for SDL 2.0 run-time engine:

\path\to\bbcwrun6 \path\to\myprog.bbc
/path/to/bbcsdl /path/to/myprog.bbc

But this only works when the program is in internal 'tokenised' format, i.e. a .BBC file. If you attempt to use the same method to run a program in 'plain text' (.BAS) format you will receive a 'Bad program' error message.

Fortunately there is a relatively simple solution, by using a helper program. Save the program listed below as basrun.bbc, then run the BAS file as follows (the quotes are important):

\path\to\bbcwrun6 "\path\to\basrun.bbc" \path\to\myprog.bas
/path/to/bbcsdl "/path/to/basrun.bbc" /path/to/myprog.bas

Here is the helper program, save it from the IDE as basrun.bbc:

      REM. Find address of string accumulator:
      IF INKEY(-256)<>&57 IF @platform% AND &40 Accs%% = ]332 ELSE Accs%% = !332
 
      REM. Allocate a 256-byte string buffer:
      DIM Buff%% 255
 
      REM. Find BAS file name:
      IF ASC@cmd$=&22 P% = INSTR(@cmd$,"""",2) ELSE P% = INSTR(@cmd$," ",2)
      IF P% = 0 ERROR 0, "No BAS filename specified"
 
      REM. Open BAS file:
      F% = OPENIN MID$(@cmd$,P%+1)
      IF F% = 0 ERROR 0, "Couldn't open file " + MID$(@cmd$,P%+1)
 
      REM. Allocate space for program:
      DIM Prog%% EXT#F% + 255
      Prog%% = (Prog%% + 255) AND -256
      PAGE = Prog%%
 
      REM. Read and tokenise BAS file:
      WHILE NOT EOF#F%
        $Buff%% = GET$#F%
        IF $Buff%%<>"" THEN
          N% = VAL$Buff%%
          WHILE ?Buff%%=&20 OR ?Buff%%>=&30 AND ?Buff%%<=&39 $Buff%% = MID$($Buff%%,2) : ENDWHILE
          REPEAT I%=INSTR($Buff%%,".") : IF I% MID$($Buff%%,I%,1) = CHR$17
          UNTIL I%=0 : REPEAT I%=INSTR($Buff%%,"\") : IF I% MID$($Buff%%,I%,1) = CHR$18
          UNTIL I%=0 : IF EVAL("1RECTANGLERECTANGLE:"+$Buff%%) $Buff%% = $(Accs%%+4)
          REPEAT I%=INSTR($Buff%%,CHR$18) : IF I% MID$($Buff%%,I%,1) = "\"
          UNTIL I%=0 : REPEAT I%=INSTR($Buff%%,CHR$17) : IF I% MID$($Buff%%,I%,1) = "."
          UNTIL I%=0 : L% = LEN$Buff%% + 4 : IF L%>255 ERROR 0, "Line too long"
          $Prog%% = CHR$(L%)+CHR$(N%MOD256)+CHR$(N%DIV256)+$Buff%% : Prog%% += L% : ?Prog%% = 0
        ENDIF
      ENDWHILE
      CLOSE #F% : !Prog%% = &FFFF00
      F% = 0 : I% = 0 : L% = 0 : N% = 0 : P% = 0 : RUN