REM Example BASIC source file to demonstrate !Whizz. All supported commands
REM are included here along with some notes on there use. Please read through
REM this file before using !Whizz on your own code. To look up a command do
REM a search for *<command>*.
:
ON ERROR PRINT REPORT$;" at line ";STR$ERL:END:REM Not supported by compiler
:
REM =========================================================================
:
REM *PRINT* command (print to screen, see PRINT# for file printing). Nice and
REM easy one to start with. Print is partially supported in that no TABs or
REM semi-colons can be used in a PRINT statement. Strings can be concatenated
REM using a '+'.

PRINT "Hello world !!"                   : REM A simple string
PRINT "Hello again, "+"world"+" !!"      : REM Some joined strings
string$="Goodbye"                        : REM A string var
PRINT string$+" everyone"                : REM Joining a string var to a str
PRINT "Here is a number : "+STR$(1234)   : REM Using the STR$ command
PRINT "And again  : " : PRINT 1234       : REM Printing an immediate integer
PRINT "Converting to hex : "+STR$~1234   : REM Printing a hex number

REM End of *PRINT* command.
:
REM =========================================================================
:
REM Different methods for specifying numbers (denary, hex and binary)

number%=100                  : REM A denary number
number2%=&123                : REM A hex number
number3%=%110011             : REM A binary number
number4%=4<<8                : REM A shifted number
 
PRINT number%
PRINT number2%
PRINT number3%
PRINT number4%

REM =========================================================================
:
REM *ABS* command (in-built BASIC function which returns the ABSolute value
REM of a number, eg ABS(-3) = 3).

original_number%=-3
absolute_value%=ABS(original_number%)

PRINT "The original number was "+STR$original_number%
PRINT "The new number is "+STR$absolute_value%
PRINT "What was it again, "+STR$(ABS(original_number%))+" ?"

REM End of *ABS* command
:
REM =========================================================================
:
REM *ASC* command (returns the ASCII character of the first character in a
REM string). *CHR$* (returns the ASCII character with the given code)

PRINT "The ASCII value of A is "+STR$ASC("A")
string$="This is a string. The ASCII value of the first character is : "
ascii_code%=ASC(string$)
PRINT string$+STR$ascii_code%

PRINT "The character with an ASCII code of 65 is "+CHR$65
PRINT "The character after A is "+CHR$(ASC("A")+1)

REM End of *ASC* and *CHR$* commands
:
REM ========================================================================
:
REM *DIV* and *MOD* (return the whole number (DIV) and the remainder (MOD)
REM after a division).

number1%=14
number2%=6

PRINT "Dividing "+STR$number1%+" by "+STR$number2%
PRINT "Gives "+STR$(number1% DIV number2%)+" remainder "+STR$number2%

REM End of *DIV* and *MOD*
:
REM ========================================================================
:
REM *FOR* *TO* *STEP* *NEXT* (FOR..NEXT loops)

FOR loop%=1 TO 10
    PRINT loop%       : REM A simple loop
NEXT

start%=5
end%=50
step%=5

FOR loop%=start% TO end% STEP step%
        IF (loop% MOD 10) = 0 THEN
                 PRINT STR$loop%+" is divisible by 10"
        ENDIF
NEXT

REM End of FOR..NEXT loops
:
REM ========================================================================
:
REM *LEFT$(* *RIGHT$(* *MID$(* (string manipulation)

string$="Hello"
PRINT LEFT$(string$,2)    : REM Leftmost 2 characters of the string
PRINT LEFT$(string$)      : REM Leftmost LEN-1 characters of the string
LEFT$(string$,1)="G"
PRINT string$

string$="Hello"
PRINT RIGHT$(string$,2)    : REM Rightmost 2 characters of the string
PRINT RIGHT$(string$)      : REM Rightmost character
RIGHT$(string$,2)="p!"
PRINT string$

string$="Hello"
PRINT MID$(string$,2,3)    : REM Starting from second char prints 3 chars
PRINT MID$(string$,4)      : REM Gives rest of string after 3rd character
MID$(string$,4,2)="p!"     : REM Alters the 4th and 5th characters
PRINT string$

REM End of string manipulation functions
:
REM ========================================================================
:
REM *INSTR(* *LEN* (string info functions)

string$="This is a string"
PRINT "The string : "+string$
PRINT "The length of the string is "+STR$LENstring$+" characters"

PRINT "'is a' occurs at position "+STR$INSTR(string$,"is a")
position%=INSTR(string$,"s",9)
PRINT "The first 's' after pos. 8 in the string is at pos. "+STR$position%

REM End of *INSTR(* and *LEN*
:
REM ========================================================================

REM *STR$* (converting numbers into text)

number%=1024
PRINT "The number in denary = "+STR$number%
PRINT "The number in hex = "+STR$~number%

:
REM ========================================================================

REM *SWAP* (swapping the contents of two variables)

number1%=10
number2%=20

PRINT "Number 1 = "+STR$number1%
PRINT "Number 2 = "+STR$number2%
PRINT "After swapping the numbers..."
SWAP number1%,number2%
PRINT "Number 1 = "+STR$number1%
PRINT "Number 2 = "+STR$number2%

REM ========================================================================

REM *CASE* *OF* *WHEN* *OTHERWISE* *ENDCASE (CASE construct)

FOR loop%=1 TO 10
        CASE loop% OF
                 WHEN 1,2,3,4,5 : PRINT "Number is 1-5"
                 WHEN 6         : PRINT "Number is 6"
                 OTHERWISE      : PRINT "Number is 7-10"
        ENDCASE
NEXT

REM End of CASE construct
:
REM ========================================================================

REM *DIM*. Dimensioning arrays and areas of memory. Note : the size of all
REM arrays and areas of memory MUST be an absolute value (eg. you can't have
REM DIM array%(size%) or DIM block% size%)

DIM integer_array%(10)
DIM integer_array2%(5,2)
DIM string_array$(5)
DIM string_array2$(5,2)

string_array$(0)="Hello"
string_array2$(2,2)=" to everyone. "+CHR$65+" is the first letter of the "
string_array2$(2,2)+="alphabet !"

integer_array%(1)=50
integer_array2%(5,1)=100

PRINT STR$(integer_array%(1)+integer_array2%(5,1))
PRINT string_array$(0)+string_array2$(2,2)

DIM block% 256
?block%=128
block%?1=64
block%!4=256
$(block%+8)="This is a string dumped in a dimensioned area of memory"

PRINT "The block is at the address &"+STR$~block%+" in memory"
PRINT "The byte at block% holds the value "+STR$(?block%)
PRINT "The byte after holds the value "+STR$block%?1
PRINT "The word at block%+4 holds the value "+STR$block%!4

PRINT "The string in the block is :"
PRINT $(block%+8)

REM End of *DIM*

:
REM ========================================================================

REM *OSCLI*. Performing CLI (*) commands from a BASIC program.

OSCLI("Help")
string$="Help"
OSCLI(string$+" syntax")

REM End of *OSCLI*
:
REM ========================================================================

REM *SYS* (calling SWI routines).

SYS "OS_CLI","Podules"       : REM A simple SWI call

SYS "OS_ReadMonotonicTime" TO time%
PRINT time%

SYS "XOS_CLI","Run Wibble" TO r0%,r1%,r2% ;flags%

IF (flags% AND 1) THEN
       REM File 'wibble' doesn't exist
       PRINT "You haven't got a file called wibble on your disc"
       PRINT "The actual error returned was : "
       
       loop%=4
       error$=""
       REPEAT
             char%=r0%?loop%
             IF char%<>0 THEN
                  error$+=CHR$char%
                  loop%+=1
             ENDIF
       UNTIL char%=0
       
       PRINT error$
ENDIF
:
REM ========================================================================

REM *WHILE* *ENDWHILE*

PRINT "Entering the WHILE loop..."
loop%=0
WHILE loop%<10
      loop%+=1
      loop2%=0
      WHILE loop2%<2
            loop2%+=1
            PRINT loop2%   : REM Nested WHILE loop
      ENDWHILE
ENDWHILE
PRINT "Exiting the WHILE loop..."

:
REM ========================================================================

REM *REPEAT* *UNTIL*

loop%=0
string$="Hello"
REPEAT
     loop%+=1
     char$=MID$(string$,loop%,1)
UNTIL char$="o"

:
REM ========================================================================
:
REM *IF* *THEN* *ELSE* *ENDIF*. All IF constructs must be in the form IF,
REM THEN, [ELSE], ENDIF.

number1%=100
number2%=200

IF number1%=100 THEN
        PRINT "The first number is 100"
ENDIF

IF number1%>number2% THEN
        PRINT "The first number is greater than the second"
        ELSE
        PRINT "The second number is greater than or equal to the first"
ENDIF

IF number1%<=number2% AND number1%=100 AND (number2%*3)=600 THEN
        PRINT "Yep - that's all true"
        ELSE
        PRINT "What a load of rubbish"
ENDIF

IF number1%=100 THEN
        IF number2%=200 THEN
               PRINT "Both numbers are correct"
               ELSE
               IF number2%=400 THEN
                     PRINT "This isn't right"
               ENDIF
        ENDIF
ENDIF

IF FNmultiply_two_numbers(number1%,number2%)=20000 THEN
       PRINT "That worked"
ENDIF

REM End of *IF* *THEN* *ELSE* *ENDIF*
:
REM ========================================================================

REM *OPENOUT* *OPENIN* *OPENUP* *CLOSE* *PTR#* *EXT#* *EOF#* *PRINT#*
REM *INPUT#* *BGET#* *BPUT#* (ie. file handling).

string$="This is the second line of the file"
string2$="The ASCII code for 'A' is "

fhandle%=OPENOUT("TestFile")
BPUT#fhandle%,"This is the first line of the file"
BPUT#fhandle%,string$
BPUT#fhandle%,string2$;
BPUT#fhandle%,STR$ASC("A")
CLOSE#fhandle%

line$=""
fhandle%=OPENIN("TestFile")
WHILE NOT EOF#fhandle%
      byte%=BGET#fhandle%
      IF byte%=10 THEN
            PRINT line$
            line$=""
            ELSE
            line$+=CHR$byte%
      ENDIF
ENDWHILE
CLOSE#fhandle%

pathname$="TestFile"
fhandle%=OPENUP(pathname$)
PRINT"The file is "+STR$EXT#fhandle%+" bytes long"
PTR#fhandle%=10
PRINT"The byte at offset 10 is "+STR$BGET#fhandle%
CLOSE#fhandle%

fhandle%=OPENOUT(pathname$)
FOR loop%=1 TO 10
      PRINT#fhandle%,loop%,"Number "+STR$loop%
NEXT
CLOSE#fhandle%

fhandle%=OPENIN(pathname$)
WHILE NOT EOF#fhandle%
      INPUT#fhandle%,number%,string$
      PRINT number%
      PRINT string$
ENDWHILE
CLOSE#fhandle%

REM End of file handling
:
REM =========================================================================

REM *TIME* *TIME$*

PRINT TIME
PRINT TIME$

time%=TIME
time$=TIME$

PRINT "Today is "+time$
PRINT "The monotonic time is "+STR$time%

REM We could have just done :

PRINT "Today is "+TIME$
PRINT "The monotonic time is "+STR$TIME

:
REM =========================================================================

REM *PROC* *DEFPROC* *ENDPROC* (calling, defining and exiting functions and
REM procedures). *LOCAL* variables are covered also.

DIM array$(5)
DIM array%(5)

string$="Hello !"
number%=100
array$(1)="Goodbye"
array%(5)=200

PROCour_procedure    : REM Calling the procedure (no parameters).
PROCour_new_procedure(string$,10,number%,array$(1),array%(5))

PRINT string$ : REM Just to prove the LOCAL 'string$' has gone out of scope

returned_value%=FNour_function
PRINT "The result of the first function is "+STR$returned_value%
returned_value%=FNmultiply_two_numbers(number%,array%(5))
PRINT "The result of the second function is "+STR$returned_value%

REM Don't forget the END (doesn't have to go at the end of the file).

END

REM ================== EXAMPLE PROCEDURES / FUNCTIONS =======================

DEFPROCour_procedure
PRINT "I am now in the procedure"
ENDPROC

DEFPROCour_new_procedure(a_string$,a_number%,number2%,string2$,number3%)
LOCAL temp_var%,string$
temp_var%=10
string$="This is a local var. The string passed was "+a_string$
PRINT string$
PRINT "Our temporary variable has a value of "+STR$10
PRINT "Our temporary variable has a value of "+STR$temp_var%
PRINT "The other parameters were : "
PRINT a_number%
PRINT number2%
PRINT string2$
PRINT number3%
ENDPROC

DEFFNour_function
LOCAL number1%,number2%
number1%=10
number2%=100
=(number1%*number2%)

DEFFNmultiply_two_numbers(number1%,number2%)
LOCAL result%
result%=(number1%*number2%)
=result%
