
Blunt_Axe_Basic Project

Copyright:(c) sarbayo, 2001-2012
Bxbasm Alpha Version.1.6.3

Bxbasic (aka:Blunt Axe Basic)

Welcome to Bxbasm:


How to use Bxbasm:
The Bxbasm components are: (in this version):


Bxbasm.exe may be used in the following manner:

        Bxbasic MyProg.bas
or
        Bxbasic MyProg

where the program script name is assumed to have the extension ".bas". 

As shown above, the extension may be omitted from the command line. If the 
script name extension is not ".bas", an error message will be generated. 
Otherwise, the script will be compiled in memory and an assembly language
file will be generated.


Below, are several examples of the Bxbasic dialect usable with Bxbasm.

What functions does Bxbasic support?
Since Bxbasic is a work in progress, as of this date it consists of a subset
of the Basic language. New commands and functions are being added at regular
intervals.

At present the KEYWORD list is as follows:
==========================================
        Keyword:                Description:
      ============      =================================
        ASM             embeds assembly language statements.
        BEEP            beep sound on pc speaker.
        BOX             draws a filled box, using the current GDI brush.
        BREAK           interupts and terminates a conditional loop.
        CALL            call a SUB function/routine.
        CASE            switch/case.
        CDBL()          converts a number to double precision.
        CHDIR           changes the current directory path.
        CHDRIVE         changes the current disk drive.
        CINT()          converts a floating point number to an integer.
        CLEAR           erase variables.
        CLNG()          converts a floating point number to a long integer.
        CLOSE           terminate disk file access.
        CLS             clear screen.
        COLOR           sets fore-ground and back-ground colors.
        CSNG()          converts number to single precision.
        DECLARE         create a SUB function/routine.
        DEFAULT         switch/case.
        DIM             dimension a variable or an array.
        DO              conditional loop.
        DRIVE()         returns the current drive number; ie: 1=A, 2=B, 3=C.
        ELSE            default action.
        ELSEIF          alternate condition.
        END             terminate program.
        ENDIF           condition terminator.
        ENDLOOP         ends a conditional loop.
        ENDSUB          declares the end of a SUB function.
        ENDSWITCH       switch/case.
        ERASE           erase an array.
        FIELD           fields i/o buffer.
        FILES           lists all the files, sizes and dates in the current
                        working directory.
        FOR             loop construct (includes: [TO][STEP]).
        FREE            erase an array.
        GET             device input.
        GOSUB           branch to subroutine.
        GOTO            absolute jump to line label.
        IF              conditional expression.
        INPUT           device input.
        INSTR()         search for first occurrance of string2 in string1.
        KILL            deletes file.
        LABS()          computes the absolute value of a long integer.
        LET             assignment to variable.
        LINE            draws a line, using the current GDI pen.
        LINE INPUT      device input (extended).
        LOCATE          position cursor on console screen.
        LOOP            sets up a conditional loop.
        LPRINT          line printer output.
        LSET            moves data to i/o buffer.
        MESSAGEBOX      displays a Windows Message Box.
        MKDIR           creates the directory specified.
        MOD()           calculates the integer remainder of a divided.
        NAME            renames old filename to new filename.
        NEXT            jump to start of loop.
        OPEN            open disk file for access.
        PAUSE           stops program execution or termination until the
                        [Enter] key is pressed.
        PRINT           display text.
        PUT             device output.
        RAND()          generate random number.
        RANDOM          seeds random number generator.
        READ            file input.
        REDIM           re-dimension array.
        REDRAW          is used to repaint the double-buffer onto the front
                        screen after calling certain line-draw or pixel GDI
                        functions.
        REM             comments. may substitute with: '
        RENAME          renames old filename to new filename.
        RETURN          return from subroutine.
        RMDIR           removes the directory specified.
        RSET            moves data to i/o buffer.
        SGN()           determines number's sign.
        SHELL           executes a DOS command.
        SHOW            displays a gui window (client area) created by the
                        WINDOW statement.
        SLEEP           cause program to pause n(milli-seconds).
        STOP            terminate program.
        SUB             declares start of a SUB function.
        SWITCH          switch/case.
        SYSTEM          terminate program.
        TIMER           a high resolution performance timer.
        WEND            end WHILE loop.
        WHILE           conditional loop.
        WINDOW          creates a GUI window referenced by "ID". 
        WRITE           device output.

===================================





**Note:
Bxbasic is case sensitive. 
All statement keywords must appear in either all upper-case, or, may be in
lower-case, beginning with an upper-case letter. 
Such as: Declare, Let, Color, Dim, etc.


All function names must appear in upper-case.
Additionally, there are several string, algebraic and device functions.

Strings:
========
        Function:                Description:
      ===========       =====================================
        DATE$           retrieves the current date.
        CHR$()          ascii character assignment.
        INSTR()         search for first occurrance of string2 in string1.
        LCASE$()        convert upper-case string to lower-case.
        LEFT$()         left string slicing.
        MID$()          middle string slicing.
        MKD$()          convert double precision to string.
        MKI$()          convert integer to string.
        MKS$()          convert single precision to string.
        RIGHT$()        right string slicing.
        SPACE$()        blank space(s) assignment.
        STR$()          numeric to string assignment.
        STRING$()       ascii character string assignment.
        TIME$           retrieves the current time.
        UCASE$()        convert lower-case string to upper-case.




Numeric:
========
        Function:                Description:
      ============      =================================
        ASC(str$)       numeric value of ascii character.
        CLOCK()         number of clock_ticks since program start.
        CINT()          converts a floating point number to an integer.
        CDBL()          converts a number to double precision.
        CLNG()          converts a floating point number to a long integer.
        CSNG()          converts number to single precision.
        CVD(str$)	convert string to double precision.
        CVI(str$)	convert string to integer.
        CVS(str$)	convert string to single precision.
        LEN(str$)	length of string$.
        RAND()          generate random number.
        SECONDS()       number of seconds since: 0:0:0 GMT.
        SGN()           determines number's sign.
        TIMER           a high resolution performance timer.
        VAL(str$)       number value of a numeric string.



Algebraic:
==========
        Function:                Description:
      ============      =================================
        ABS(exp)	absolute value of expression.
        ACOS(num)       calculates the arc cosine of number.
        ASIN(num)       calculates the arc sine of number.
        ATN(exp)	arctangent of expression.
        ATAN2(n1,n2)    calculates the arc tangent of n1/n2.
        CEIL(nun)       calculates the smallest whole number
                        that is not less than number.
        COS(exp)	returns cosine of expression.
        COSH(num)       return hyperbolic cosine of number.
        EXP(num)        returns the natural exponent of number.
        FABS(num)       returns the absolute value of a floating
                        point number.
        FLOOR(num)      returns a double precision, largest whole
                        number, less than number.
        FMOD(n1,n2)     calculates the floating point remainder of
                        a n1 divided by n2.
        FREXP(n1,n2)    returns the mantissa of a floating point
                        number (n1), as a normalized fraction.
                        the power of 2 exponent of n1 is stored in n2.
        HYPOT(n1,n2)    calculates the length of the hypotenuse of
                        a right triangle, with sides n1 and n2.
        INT(exp)	integer value of expression.
        LABS(n1)        computes the absolute value of a long integer.
        LDEXP(n1,n2)    calculates n1 times 2, raised to the power
                        of n2.
        LOG(exp)        LOG of a numeric value.
        LOG10(exp)      LOG10 of a numeric value.
        MOD(n1,n2)      calculates the integer remainder of a n1 
                        divided by n2.
        MODF(n1,n2)     returns the fractional part of n1,
                        the whole part is stored in n2.
        POW(n1,n2)      calculates n1 raised to the n2 power.
        POW10(num)      calculates 10 raised to the power of num.
        SIN(exp)	sine of expression.
        SINH(num)       calculates the hyperbolic sine of num.
        SQRT(exp)	square root of expression.
        TAN(exp)	tangent of expression.
        TANH(num)       calculates the hyperbolic tangent of num.



Console:
========
        Function:                Description:
      ===========       =====================================
        CLS             clear screen.
        COLOR           sets fore-ground and back-ground colors.
        FILES           lists all the files, sizes and dates in the current
                        working directory.
        INPUT           device input.
        INPUT$()	a string of keyboard characters.
        LOCATE          position cursor on console screen.
        PRINT           display text.
        SHELL           executes a DOS command.



Device:
=======
        Function:                Description:
      ===========       ===============================
        CHDIR           changes the current directory path.
        DRIVE()         returns the current drive number;
                        ie: 1=A, 2=B, 3=C, etc.
        EOF()		end of file indicator.
        FILES           lists all the files, sizes and dates
                        in the current working directory.
        INKEY$		a single keyboard character.
        INPUT$()	a string of keyboard characters.
        LOC()		file position pointer.
        LOF()		length of file.
        MKDIR           creates the directory specified.
        NAME            renames old filename to new filename.
        RMDIR           removes the directory specified.




Usage examples:
===============
Here are some 'cut-n-paste' examples that you can try. Merely 'cut-n-paste' 
them to Notepad or any other text editor and save them as Test.bas. 
Then assemble them using JWasm or Masm.

** NOTE:
These examples are from Bxbasic, but, will produce assembly language output.

________________________________________________________
________________________________________________________

Line Numbers, REM, CLS, PRINT, BEEP, END:
=========================================
In it's most basic form, the program statement looks like this:


'-----cut-n-paste------'
1 REM  test.bas version 1
2 PRINT "hello world!"
3 BEEP
4 END
'-----cut-n-paste------'


Line Numbers:
=============
Program lines may or may not be numbered. Line numbers have a minimal 
practical use and their usage is not recommended, but, their usage is 
included for compatibility. If line numbers are used, the must appear in 
column #1, the far left side, only. Line numbers will appear here for 
illustrative purposes only.

In the above example:
REM:		in line 1: is a comment,
PRINT:	in line 2: prints a message on the display screen
BEEP:		in line 3: sounds a beep on the pc speaker
END:		in line 4: terminates the program


PRINT:	The PRINT command takes the form:
                PRINT:	(generates a newline)
        or      PRINT "text"
        or      PRINT variable
        or      PRINT (expression)

END:            Every program must have an END command. 
                However, it need not be at the end of the program.

________________________________________________________
________________________________________________________

GOTO:
=====
In the example below, using the GOTO command:
         line 4:        performs an absolute jump to line #8
        line 10:        an absolute jump to line #5
         line 7:        terminates the program


'-----cut-n-paste------'
1 REM  test.bas version 2
2 PRINT "hello world!"
3 BEEP
4 GOTO 8
5 PRINT "Back at line #6"
6 PRINT "The End."
7 END
8 PRINT "Now at line #9"
9 BEEP
10 GOTO 5
'-----cut-n-paste------'

________________________________________________________
________________________________________________________

LET:
====
The LET command has the form:
                LET variable = value
        or      LET variable = variable
        or      LET variable = "text string"


**NOTE:  DIM:
=======  ====
In this version of Bxb, the DIM command should precede all variable 
declarations. 
This is not STANDARD BASIC, but, it serves a greater purpose.

The DIM command has the form:
                DIM variable = value
        or      DIM myInt = 0, myLong% = 10, myFloat! = 9.1
        or      DIM string$ = "text string"


In this example, 
        line 2: keyword DIM creates the memory space for variable 'abc' and
                assigns it a value of zero.
        line 5:	keyword LET assigns a numeric value to integer variable: 
                "abc". 


'-----cut-n-paste------'
1 REM  test.bas version 3
2 DIM abc = 0
3 CLS
4 PRINT "hello world!"
5 BEEP
6 LET abc = 100
7 PRINT "abc = 100"
8 END
'-----cut-n-paste------'


Variable names are limited to 32 alpha-numeric characters only. No 
punctuation characters are permitted (at this time). Variables are 
distinguished into five types:

        Symbol:	Type:
          $             character string
          #             double precision floating point
          !             single precision float
          %             long integer
         none           integer (assumed)

If a variable name has no type specifier, it is assumed to be of type 
integer.

Here, in:
line 12 thru 14:        three integer assignments are made.
        line 15:        variable 'abc' is re-assigned a new value:


'-----cut-n-paste------'
1 REM  test.bas version 4
2 DIM abc = 0, xyz = 0, qwerty = 0
3 CLS
4 PRINT "hello world!"
5 BEEP
' ...
12 LET abc = 100
13 LET xyz = 999
14 LET qwerty = 12345
15 LET abc = 32123
16 END
'-----cut-n-paste------'


In this next example, variables: abc, xyz and qwerty are assigned values. 
Then PRINT command is used to display each variable's contents.


'-----cut-n-paste------'
1 REM  test.bas version 5
  DIM abc = 0, xyz = 0, qwerty = 0
2 CLS
3 PRINT "hello world!"
4 LET abc = 100
5 PRINT abc,
6 LET xyz = 999
7 LET qwerty = 12345
8 LET abc = 32123
9 PRINT xyz,
10 PRINT qwerty,
11 PRINT abc
12 PRINT "The End."
13 END
'-----cut-n-paste------'

________________________________________________________
________________________________________________________

LOCATE:
=======
The LOCATE command has the form:

        LOCATE row, column

In lines 4 and 5, variables: row and column are each given a value.
Then on line 6, the LOCATE command it used to position the cursor,
 at:
            Row: 2
         Column: 10

and again in line 10:


'-----cut-n-paste------'
1  REM  test.bas version 6
   DIM Row = 0, Column = 0
2  CLS
3  PRINT "hello world!"
4  LET Row = 2
5  LET Column = 10
6  LOCATE Row, Column
7  PRINT "hello world!"
8  LET Row = 4
9  LET Column = 20
10 LOCATE Row, Column
11 PRINT "hello world!"
12 END
'-----cut-n-paste------'

The console mode screen is character based and has the dimensions of 25x80.
The upper left corner is row 0, column 0.

________________________________________________________
________________________________________________________

Math Expression Assignments:
============================
A variable assignment can be in the form of a mathematical expressions.
As shown in line 4:


'-----cut-n-paste------'
1 REM  test.bas version 7
  DIM abc = 0
2 CLS
3 PRINT "hello world!"
4 LET abc = 2 + 2
5 PRINT abc
6 END
'-----cut-n-paste------'


Complex algebraic expressions can be used in an assignment:


'-----cut-n-paste------'
1  REM  test.bas version 8
   DIM xylophone = 0, yazoo = 0, quasar = 0, zapp = 0
   DIM abc = 0, xyz = 0
2  CLS
3  PRINT "hello world!"
4  LET xylophone = 50
5  LET yazoo = 100
6  LET abc = yazoo/xylophone
7  LET xyz = yazoo/10
8  LOCATE abc , xyz
9  PRINT "hello world!"
10 LET quasar = 2
11 LET zapp = 4
12 LET abc = (quasar * quasar * zapp + zapp)/5
13 LET xyz = ((quasar*quasar)*zapp)+zapp
14 LOCATE abc, xyz
15 PRINT "hello world!"
50 END
'-----cut-n-paste------'

________________________________________________________
________________________________________________________

Optional: Line Numbers, REM, LET:
=================================
As stated previously, line numbers are entirely optional and in most cases 
un-needed. The only time they may actually be needed is as line labels. 
Here, even the REM is optional, as well. The REM keyword may be replaced 
with the apostrophy (') character. Blank or empty lines are ignored by the
compiler and often times help to  make the source code more readable. Also,
the LET keyword is optional.


'-----cut-n-paste------'
'  test.bas version 9

  DIM xylophone = 0, yazoo = 0, abc = 0, xyz = 0
  DIM quasar = 0, zapp = 0
'
  CLS
  PRINT "hello world!"
  LET xylophone = 50
  LET yazoo = 100
  LET abc = yazoo/xylophone
  xyz = yazoo/10

  LOCATE abc , xyz
  PRINT "hello world!"
' ------------------------------------------
  quasar = 2
  zapp = 4
  abc = (quasar * quasar * zapp + zapp)/5
  xyz = ((quasar * quasar) * zapp) + zapp

  LOCATE abc, xyz
  PRINT "hello world!"
' ------------------------------------------

  PRINT:
  PRINT " 2*(3+4)*5/10 = ";
  abc = 2*(3+4)*5/10
  PRINT abc

TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


In the above code, examine the PRINT statements. 
PRINT has several forms:
        PRINT abc               prints variable followed by newline
        PRINT:	                generates a newline
        PRINT ""                also a newline
        PRINT a;                semi-colon does not send a newline
        PRINT a,                comma sends a tab, no newline

________________________________________________________
________________________________________________________

BLOCK LABELS:
=============
"Block Labels" are preferred over line numbers and give symbolic meaning 
to a routine or block of code. 


'-----cut-n-paste------'
'  test.bas version 10
  CLS
'               now jump to a block label
  GOTO OverThere
'
TheBeginning:
  PRINT "We"; CHR$(39); "re at The Beginning!"
  GOTO TheEnd
'
There:
  PRINT "We"; CHR$(39); "re There!"
  GOTO TheBeginning
'
JumpBack1:
  PRINT "We Jumped Back 1!"
  GOTO There
'
OverThere:
  PRINT "We"; CHR$(39); "re Over There!"
  GOTO JumpBack1
'
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


Where used, line Labels or "Block Labels" must start at the far left column,
as shown above. 

A Label name:
=============
*        may contain up to 32 alpha-numeric characters,
*        must contain no punctuation characters,
*        must be terminated by a colon (:),
*        is case sensitive, so:	label:

         Label:
and      LABEL:

are each unique.

When used with a GOTO statement, the label name is not terminated by the
colon. i.e.:
        GOTO Label1


'-----cut-n-paste------'
'  test.bas version 11

   DIM xylophone = 0, yazoo = 0, abc = 0, xyz = 0
   DIM quasar = 0, zapp = 0

Start1:
  CLS
  GOTO Jump
Return:
  GOTO TheEnd
Jump:
  PRINT "hello world!"
' ------------
  LET xylophone = 50
  LET yazoo = 100
  LET abc = yazoo/xylophone
  xyz = yazoo/10
  LOCATE abc , xyz
  PRINT "hello world!"
' ------------------------------------------
  quasar = 2
  zapp = 4
  abc = (quasar * quasar * zapp + zapp)/5
  xyz = ((quasar * quasar) * zapp) + zapp
  LOCATE abc, xyz
  PRINT "hello world!"
' ------------------------------------------
  PRINT:
  PRINT " 2*(3+4)*5/10 = ";
  abc = 2*(3+4)*5/10
  PRINT abc
  GOTO Return
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

CLEAR:
======
The CLEAR command has the form:

        CLEAR


'-----cut-n-paste------'
'  test.bas version 12
'
  DIM xylophone# = 0, yazoo# = 0, abc = 0, xyz = 0, quasar = 0, zapp = 0
'
Start1:
  CLS
  PRINT "hello world!"
' ------------
  LET xylophone# = 50.3
  LET yazoo# = 101.25
  LET abc = yazoo#/xylophone#
  xyz = yazoo#/10
  quasar = 2
  zapp = 4
  abc = (quasar * quasar * zapp + zapp)/5
  xyz = ((quasar * quasar) * zapp) + zapp
  abc = 2*(3+4)*5/10
'
  CLEAR
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


A CLEAR statement will erase all 'global' variables. If a variable no longer
exists, or has previously been erased, the CLEAR command will ignore that 
fact. It will not cause an error. The CLEAR command has no effect on 'local'
variables.



'-----cut-n-paste------'
'  test.bas version 13
'
  DIM abc = 0, xyz = 0, abcl% = 0, xyzl% = 0
  DIM abcf! = 0, xyzf! = 0, abcd# = 0, xyzd# = 0
  DIM test1$ = ""
'
Start1:
  CLS
  PRINT "hello world!"
' ------------------------------------------
  abc = 11100
  xyz = 32000
  abcl% = 33000
  xyzl% = 99000
  abcf! = 33000.33
  xyzf! = 99000.47
  abcd# = 333000.33
  xyzd# = 999000.47
  test1$ = "test"
'
  CLEAR
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

NUMERICAL DATA TYPES:
=====================
**Note: all variable names must be unique, regardless of type.
**Hungarian notation: the term refers to prefixing a variable name with a 
  letter signifier as to the variables type. ie: intiger, long, float, 
  double, string. In cases where two or more variables of different types,
  share the same name, Hungarian notation can be used.
**reverse-Hungarian notation: where the data type signifier is added to the
  end of the variable name.

Simple integers have a limited range and can not handle fractional or "real"
numbers. As shown here, an expression may contain mixed data types. The 
result will be the destination variable's type.


'-----cut-n-paste------'
'  test.bas version 14
'
  DIM xylophone# = 0, yazoo# = 0, abc = 0
  DIM xyz = 0, quasar = 0, zapp = 0
'
Start1:
  CLS
  PRINT "hello world!"
' ------------
  LET xylophone# = 50.3
  LET yazoo# = 101.25
  LET abc = yazoo#/xylophone#
  xyz = yazoo#/10
  LOCATE abc , xyz
  PRINT "hello world!"
' ------------------------------------------
  quasar = 2
  zapp = 4
  abc = (quasar * quasar * zapp + zapp)/5
  xyz = ((quasar * quasar) * zapp) + zapp
  LOCATE abc, xyz
  PRINT "hello world!"
' ------------------------------------------
  PRINT:
  PRINT " 2*(3+4)*5/10 = ";
  abc = 2*(3+4)*5/10
  PRINT abc
' ------------------------------------------
  PRINT:
  PRINT "xylophone# = ";
  PRINT xylophone#
  PRINT "yazoo# = ";
  PRINT yazoo#
TheEnd:
  CLEAR
  END
' ------------------------------------------
'-----cut-n-paste------'


Here are some examples of expressions using different data types.


'-----cut-n-paste------'
'  test.bas version 15
'
  DIM abc = 0, xyz = 0, yazoo# = 0, xylophone# = 0
  DIM quasar% = 0, zapp% = 0, abcl% = 0, xyzl% = 0
'
'
Start1:
  CLS
  PRINT "hello world!"
' ------------------------------------------double float
  LET xylophone# = 50.3
  LET yazoo# = 101.25
  LET abc = yazoo# / xylophone#
  xyz = yazoo# / 10
  LOCATE abc , xyz
  PRINT "hello world!"
' ------------------------------------------long integers
  quasar% = 2
  zapp% = 4
  abcl% = (quasar% * quasar% * zapp% + zapp%)/5
  xyzl% = ((quasar% * quasar%) * zapp%) + zapp%
  LOCATE abcl%, xyzl%
  PRINT "hello world!"
' ------------------------------------------
  PRINT:
  PRINT " 2*(3+4)*5/10 = ";
  abc = 2*(3+4)*5/10
  PRINT abc
' ------------------------------------------
  PRINT:
  PRINT "xylophone# = ";
  PRINT xylophone#
  PRINT "yazoo# = ";
  PRINT yazoo#
  PRINT:
  PRINT "abcl%=";
  PRINT abcl%
  PRINT "xyzl%=";
  PRINT xyzl%
' ------------------------------------------
TheEnd:
  CLEAR
  END
' ------------------------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 16
'
Start1:
  CLS
' ------------------------------------------
  DIM  abc = 11100, xyz = 32000
  DIM  abcl% = 33000, xyzl% = 99000
  DIM  abcf! = 33000.33, xyzf! = 99000.47
  DIM  abcd# = 333000.33, xyzd# = 999000.47
'
'                   integer
  PRINT:
  PRINT "abc=";
  PRINT abc
  PRINT "xyz=";
  PRINT xyz
'                   long
  PRINT "abcl%=";
  PRINT abcl%
  PRINT "xyzl%=";
  PRINT xyzl%
'                   float
  PRINT "abcf!=";
  PRINT abcf!
  PRINT "xyzf!=";
  PRINT xyzf!
'                   double
  PRINT "abcd#=";
  PRINT abcd#
  PRINT "xyzd#=";
  PRINT xyzd#
' ------------------------------------------
TheEnd:
  CLEAR
  END
' ------------------------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 17
'
  DIM xylophone# = 0, yazoo# = 0, abc = 0, xyz = 0
  DIM quasar% = 0, zapp% = 0, abcl% = 0, xyzl% = 0
  DIM abcf! = 0, xyzf! = 0, abcd# = 0, xyzd# = 0
'
Start1:
  CLS
  PRINT "hello world!"
' ------------------------------------------double float
  LET xylophone# = 50.3
  LET yazoo# = 101.25
  LET abc = yazoo# / xylophone#
  xyz = yazoo# / 10
  LOCATE abc , xyz
  PRINT "hello world!"
' ------------------------------------------long integers
  quasar% = 2
  zapp% = 4
  abcl% = (quasar% * quasar% * zapp% + zapp%)/5
  xyzl% = ((quasar% * quasar%) * zapp%) + zapp%
  LOCATE abcl%, xyzl%
  PRINT "hello world!"
' ------------------------------------------
  PRINT:
  PRINT " 2*(3+4)*5/10 = ";
  abc = 2*(3+4)*5/10
  PRINT abc
' ------------------------------------------
  abc = 11100
  xyz = 32000
  abcl% = 33000
  xyzl% = 99000
  abcf! = 33000.33
  xyzf! = 99000.47
  abcd# = 333000.33
  xyzd# = 999000.47
'                   integers
  PRINT:
  PRINT "abc=";
  PRINT abc
  PRINT "xyz=";
  PRINT xyz
'                   long integers
  PRINT "abcl%=";
  PRINT abcl%
  PRINT "xyzl%=";
  PRINT xyzl%
'                   float
  PRINT "abcf!=";
  PRINT abcf!
  PRINT "xyzf!=";
  PRINT xyzf!
'                   double
  PRINT "abcd#=";
  PRINT abcd#
  PRINT "xyzd#=";
  PRINT xyzd#
' ------------------------------------------
TheEnd:
  CLEAR
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

STRING VARIABLES:
=================
String variable assignments may be expressed in several ways. To begin with,
a string variable is terminated by the '$' symbol. A string variable may be
a single character, no character, or a number of characters, with a maximum
of 255 characters.


'-----cut-n-paste------'
'  test.bas version 18
'
  DIM abc$ = "", xyz$ = ""
'
Start1:
  CLS
  PRINT "hello world!"
  abc$ = "test"
  xyz$ = ""
'   ^---------------here, xyz is null, empty!
  END
'-------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 19
'
  DIM abc$ = "", xyz$ = ""

  CLS
  abc$ = "testing"
  xyz$ = abc$
  PRINT abc$
  PRINT xyz$
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

COMPLEX PRINTING:
=================
The PRINT statement can be used in complex ways to create the desired 
display.


'-----cut-n-paste------'
'  test.bas version 20
'
  DIM abc = 0, xyz = 0, abcl% = 0, xyzl% = 0
  DIM abcf! = 0, xyzf! = 0, abcd# = 0, xyzd# = 0
'
Start1:
  CLS
  PRINT "hello world!"
' ------------------------------------------
  abc = 2*(3+4)*5/10
  PRINT "": " 2*(3+4)*5/10 ="; abc
' ------------------------------------------
  abc = 11100
  xyz = 32000
  abcl% = 33000
  xyzl% = 99000
  abcf! = 33000.33
  xyzf! = 99000.47
  abcd# = 333000.33
  xyzd# = 999000.47
'                                               integers
  PRINT "": "abc="; abc: "xyz="; xyz
'                                               long integers
  PRINT "abcl%="; abcl%: "xyzl%="; xyzl%
'                                               float
  PRINT "abcf!="; abcf!: "xyzf!="; xyzf!
'                                               double
  PRINT "abcd#="; abcd#: "xyzd#="; xyzd#
' ------------------------------------------
TheEnd:
  CLEAR
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

GOSUB RETURN:
=============
Subroutines are the preferred method of program branching. Subroutines 
allow for a more structured style of programming over the absolute jump of 
a GOTO statement. Subroutines are identified by a block label and called 
with the GOSUB command. Each GOSUB command has a matching RETURN command. 
If you GOSUB, you must RETURN from the subroutine.


'-----cut-n-paste------'
'  test.bas version 21
'
  DIM Hello$ = "", test$ = "test"
  DIM abc = 0, xyz = 0, yazoo# = 0, xylophone# = 0
  DIM quasar% = 0, zapp% = 0, abcl% = 0, xyzl% = 0
  DIM abcf! = 0, xyzf! = 0, abcd# = 0, xyzd# = 0
'
  GOSUB Start1
  GOSUB DoubleFloat
  GOSUB LongIntegers
  GOSUB RDParser
  GOSUB PrintVars
  GOSUB ClearVars
  GOTO TheEnd
' ------------------------------------------
Start1:
  CLS
  Hello$ = "hello world!"
  PRINT Hello$
  RETURN
' ------------------------------------------double float
DoubleFloat:
  LET xylophone# = 50.3
  LET yazoo# = 101.25
  LET abc = yazoo# / xylophone#
  xyz = yazoo# / 10
  LOCATE abc , xyz
  PRINT Hello$
  RETURN
' ------------------------------------------long integers
LongIntegers:
  quasar% = 2
  zapp% = 4
  abcl% = (quasar% * quasar% * zapp% + zapp%)/5
  xyzl% = ((quasar% * quasar%) * zapp%) + zapp%
  LOCATE abcl%, xyzl%
  PRINT Hello$
  RETURN
' ------------------------------------------
RDParser:
  abc = 2*(3+4)*5/10
  PRINT "": " 2*(3+4)*5/10 ="; abc
  RETURN
' ------------------------------------------
PrintVars:
  abc = 11100
  xyz = 32000
  abcl% = 33000
  xyzl% = 99000
  abcf! = 33000.33
  xyzf! = 99000.47
  abcd# = 333000.33
  xyzd# = 999000.47
'                                          integers
  PRINT "": "abc="; abc: "xyz="; xyz
'                                          long integers
  PRINT "abcl%="; abcl%: "xyzl%="; xyzl%
'                                          float
  PRINT "abcf!="; abcf!: "xyzf!="; xyzf!
'                                          double
  PRINT "abcd#="; abcd#: "xyzd#="; xyzd#
  RETURN
' ------------------------------------------
ClearVars:
  PRINT test$
  CLEAR
  RETURN
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


GOSUB's may be nested. That means that a second GOSUB may be called even
before RETURNing from the first subroutine. The second subroutine may even
call a third subroutine, etc. As long as there are an equal number of 
RETURNs as GOSUBs.


'-----cut-n-paste------'
'  test.bas version 22
'
  DIM Hello$ = "", test1$ = "test"
  DIM xylophone# = 0, yazoo# = 0, abc = 0, xyz = 0
  DIM quasar% = 0, zapp% = 0, abcl% = 0, xyzl% = 0
  DIM abcf! = 0, xyzf! = 0, abcd# = 0, xyzd# = 0
'
'
  GOSUB Start1
  GOTO TheEnd
' ------------------------------------------
Start1:
  CLS
  Hello$ = "hello world!"
  PRINT Hello$
  GOSUB DoubleFloat
  RETURN
' ------------------------------------------double float
DoubleFloat:
  LET xylophone# = 50.3
  LET yazoo# = 101.25
  LET abc = yazoo# / xylophone#
  xyz = yazoo# / 10
  LOCATE abc , xyz
  PRINT Hello$
  GOSUB LongIntegers
  RETURN
' ------------------------------------------long integers
LongIntegers:
  quasar% = 2
  zapp% = 4
  abcl% = (quasar% * quasar% * zapp% + zapp%)/5
  xyzl% = ((quasar% * quasar%) * zapp%) + zapp%
  LOCATE abcl%, xyzl%
  PRINT Hello$
  GOSUB RDParser
  RETURN
' ------------------------------------------
RDParser:
  abc = 2*(3+4)*5/10
  PRINT "": " 2*(3+4)*5/10 ="; abc
  GOSUB PrintVars
  RETURN
' ------------------------------------------
PrintVars:
  abc = 11100
  xyz = 32000
  abcl% = 33000
  xyzl% = 99000
  abcf! = 33000.33
  xyzf! = 99000.47
  abcd# = 333000.33
  xyzd# = 999000.47
'                   			integers
  PRINT "": "abc="; abc: "xyz="; xyz
'                   			long integers
  PRINT "abcl%="; abcl%: "xyzl%="; xyzl%
'                   			float
  PRINT "abcf!="; abcf!: "xyzf!="; xyzf!
'                   			double
  PRINT "abcd#="; abcd#: "xyzd#="; xyzd#
  GOSUB ClearVars
  RETURN
' ------------------------------------------
ClearVars:
  PRINT test1$
  CLEAR
  RETURN
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

FOR NEXT:
=========
The FOR/NEXT commands allow for the creation of complex loop structures.
The basic syntax is:

        FOR (condition, increment)
                program...
        NEXT (increment loop)

The 'conditional expression' and 'increment' take the form of:

        variable% = start TO end, STEP increment

      variable:  is the object of the condition
         start:  is the starting value for 'variable'
           end:  is the destination for 'variable'
     increment:  is the amount by which to increment 'variable'

Where:	FOR x = 1 TO 100 STEP 1

    x = 1:   Assigns the starting value of 1 to variable 'x'.
             Variable 'x' must be of type: INTEGER.
   TO 100:   Sets a desired value of: 100 for 'x'.
   STEP 1:   The amount by which to increment.
             If the STEP value were: 3
             'x' would be incremented by 3 after each loop cycle.
             If no STEP value is stated, the default is: 1.

NEXT is little more than a block label, or block delimiter, but, it also
keeps track of which variable we need to increment for the next cycle.

FOR/NEXTs may be nested. 
i.e.:
        FOR (cond-1)            [outer loop]
            FOR (cond-2)        [inner loop]
                program...
            NEXT (inc)          [inner loop]
        NEXT (inc)              [outer loop]

However, you may not exit an outer loop before exiting an inner loop. An 
inner loop may be terminated, however. To terminate an inner loop, an 
IF/ELSE expression can be used to test for a condition and based on the 
result, object variable can be forced to the destination value. 
Example:

        FOR x = 1 TO 10
            FOR y = 1 TO 100    ......[inner loop]
                IF y = 50 THEN
                    y = 100           [force: y = 100]
                ENDIF
                PRINT CHR$(32);
            NEXT y              ......[inner loop]
        NEXT x

This will have the desired effect of satisfying the condition:
        FOR y = 1 TO 100


'-----cut-n-paste------'
'  test.bas version 23
'
  DIM x = 0, y = 0
'
  CLS
  GOSUB TOP
  GOSUB Center
  GOSUB Bottom
  GOTO TheEnd
'----------------------
Center:
  FOR x = 1 TO 5
      PRINT "*";
      FOR y = 1 TO 28
          PRINT " ";
      NEXT y
      PRINT "*":
  NEXT x
  RETURN
'----------------------
TOP:
Bottom:
  FOR x = 1 TO 30
      PRINT "*";
  NEXT x
  PRINT "":
  RETURN
'----------------------
TheEnd:
  END
'----------------------
'-----cut-n-paste------'


This example will generate a box made of stars in the upper left corner of
the display, like this:

******************************
*                            *
*                            *
*                            *
*                            *
*                            *
******************************


________________________________________________________
________________________________________________________

POWER, MODULUS:
===============
Besides the numerical operators: +,-,/ and *, Bxbasic also uses the Power
symbol: ^ and the Modulo symbol: %. 

Power:
======
The symbol ^ represents the Power function. The effect is to raise a number
to the Power of a second number. 

Example:
        result = 10 ^ 2	"result" equals: 10 raised to the power of 2.

The product, (100) is assigned to "result"


Modulo:
=======
The symbol % represents the Modulus function. The effect is to capture the
remainder of a division operation. 

Example:
        mod = 10 % 3	"mod" equals the remainder of 10/3.

The product, (1) is assigned to variable "mod"


'-----cut-n-paste------'
'  test.bas version 24
'
  DIM power = 0, ten = 10, three = 3, imod = 0
'
  GOSUB Start1
  END
' ------------------------------------------
Start1:
  CLS
  power = 10 ^ 2
  PRINT "power="; power
'
'                we can use the modulus operator: %
  imod = ten % three
  PRINT "imod="; imod
'                or we can use the keyword: MOD 
  imod = 30 MOD 9
  imod = ten MOD imod
  PRINT "imod="; imod
  RETURN
' ------------------------------------------
'-----cut-n-paste------'


The word MOD may be used in place of the % symbol.
One word of caution: when used with numeric variables, the % symbol has to
have a blank space on either side of it, or the variable may be confused as
a LONG integer. 

i.e.:   var1 % var2     correct.
         var1%var2      incorrect!


________________________________________________________
________________________________________________________

IF/ELSE:
========
The IF/ELSE conditional expression uses the form:
        IF (condition) THEN             first condition
                [program...]
        ELSEIF (condition) THEN         second condition
                [program...]
        ELSE                            default action
                [program...]
        ENDIF                           terminator

In the above, there are two conditional expressions:
Condition #1:
        if condition #1 is TRUE, then:
                [the following action is taken]
                [program resumes at point beyond the ENDIF]
        if condition #1 is FALSE, then:
                [evaluate expression #2]
	--------------------------------------
Condition #2:
        elseif condition #2 is TRUE, then:
                [the following action is taken]
                [program resumes at point beyond the ENDIF]
        elseif condition #2 is FALSE, then:
                [take default action]
	--------------------------------------
Default:
        else
            [the following action is taken]
            [program resumes at point beyond the ENDIF]
        endif

The simplest conditional expression might be:
        IF (condition) THEN        conditional expression
            [program...]
        ENDIF                terminator

where only one condition is evaluated.
Conditional expressions may also use the Boolean AND/OR operators.

Example:
        IF a = b AND x = y THEN
            ...etc.
or:
        IF a = b OR x = y THEN
            ...etc.

These condition operators may be used:

     operator    description
     ========    ===========    
        =        is equal to
        <>       is not equal to
        <        is less than
        >        is greater than
        <=       is less or equal to
        >=       is greater or equal to


'-----cut-n-paste------'
'  test.bas version 25
'
  CLS
  DIM abc = 99, xyz = 33
  DIM abcs$ = "test", xyzs$ = "testing"
'
'
  IF xyzs$ = "testing" AND abc >= xyz THEN 
     PRINT "if:expression = true"
  ELSEIF abc <= 100 OR abcs$ <= "hello" THEN
     PRINT "elseif:expression = true"
  ELSE
     PRINT "else:expressions = false"
  ENDIF
  PRINT "done"
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

STRING FUNCTIONS:
=================
       Function:  Usage:
       =========  =================================================
        CHR$()    a$ = CHR$(n)
                           where: (n) is an ascii value.

        LEFT$()   a$ = LEFT$(s$,n)
                           where: s$ is a string variable name,
                           'n' is the number of characters to copy
                           from the left.

        RIGHT$()  a$ = RIGHT$(s$,n)
                           where: s$ is a string variable name,
                           'n' is the number of characters to copy
                           from the right.

        MID$()    a$ = MID$(s$,x,n)
                           where: s$ is a string variable name,
                           'x' is the character starting position
                           from the left,
                           'n' is the number of characters to copy.

        SPACE$()  a$ = SPACE$(n)
                           where: 'n' is the number of blank spaces

        STR$()    a$ = STR$(n)
                           where: 'n' is a numeric value to be 
                           converted to a character string.

        STRING$() a$ = STRING$(n,x)
                           where: 'n' is the number of characters,
                           'x' is an ascii value.



Try this new example:


'-----cut-n-paste------'
'  test.bas version 26
'
  DIM xyzi = 0
  DIM abcs$ = "", xyzs$ = ""
'
'
  CLS
  xyzi = 42
  abcs$ = CHR$(xyzi)
  PRINT "abcs$ = ";abcs$
'
  xyzs$ = "testing"
  abcs$ = LEFT$(xyzs$, 4)
  PRINT abcs$
'
  abcs$ = RIGHT$(xyzs$, 5)
  PRINT abcs$
'
  abcs$ = MID$(xyzs$, 3, 3)
  PRINT abcs$
'
  abcs$ = SPACE$(3)
  PRINT ">";abcs$;"<"
'
  abcs$ = STR$(199)
  PRINT abcs$
'
  abcs$ = STRING$(10, xyzi)
  PRINT ">";abcs$;"<"
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 27
'
  DIM ixyz = 0
  DIM sxyz$ = "", sabc$ = ""
'
'
  CLS
  ixyz = 42
  sxyz$ = "testing"
'
  sabc$ = LEFT$(sxyz$, 4) + CHR$(ixyz) + RIGHT$(sxyz$, 5) + SPACE$(3)
  sabc$ = sabc$ + MID$(sxyz$, 3, 3) + STR$(-199) + STRING$(10, ixyz)

  PRINT sabc$
'
  sabc$ = CHR$(34) + "Hello" + CHR$(32) + "world!" + CHR$(34)
  PRINT sabc$
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 28
'
  DIM abc$ = ""
'
  CLS
  abc$ = "This is a test of the Emergency Broadcast System"
  PRINT "Test: >"; CHR$(251); "< End Test"
  PRINT ">"; LEFT$(abc$, 14); "<"
  PRINT ">"; RIGHT$(abc$, 26); "<"
  PRINT ">"; MID$(abc$, 23, 19); "<"
  PRINT ">"; SPACE$(10); "<"
  PRINT ">"; STR$(1000); "<"
  PRINT ">"; STRING$(10, 251); "<"
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 29
'
  DIM abc = 0, xyz = 0
'
  CLS
  PRINT ">"; STR$(1000); "<"
  PRINT ">"; STRING$(10, 251); "<"
  PRINT CHR$(247)
  abc = 10
  xyz = 3
  PRINT abc * xyz
  PRINT 1 + (abc * xyz)
  PRINT (abc / xyz) * 2
  PRINT 1+(2*5)/3
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

INKEY$:
=======
The INKEY$ function captures the character currently entered in the 
keyboard buffer. INKEY$ has a unique quality that makes it quite different
from other types of keyboard input. When INKEY$ is called, it does not 
wait for the user to strike a key. Instead, after collecting the character,
even if there is no character in the buffer, it continues on to the next 
instruction. 

You may be wondering "what good is that?"
"I doesn't wait for you to type a character?"

The short answer is no, it doesn't wait.
On the other hand the user doesn't have to strike the return key, either.
What does this mean?

INKEY$ is especially well suited for a loop construct or a subroutine call
that polls the keyboard buffer.

Here is an example of how to use INKEY$:


'-----cut-n-paste------'
'  test.bas version 30
'
  DIM abc$ = ""
'
  CLS
Start:
  abc$ = INKEY$
  IF abc$ = "" THEN
    GOTO Start
  ENDIF
  PRINT abc$
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


In the above example, INKEY$ is used in a continuous loop, that tests the
keyboard buffer for a character. If there is no character, then abc$ will 
be null, or empty. In that event, program control jumps back up to START: 
and repeats the loop.

Does this look familiar?

        Press any key to continue._


'-----cut-n-paste------'
'  test.bas version 31
'
  DIM abc$ = ""
'
  CLS
  PRINT "Press any key: ";
Start:
  abc$ = INKEY$
  IF abc$ = "" THEN
    GOTO Start
  ENDIF
  PRINT abc$
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

INPUT:
======
The INPUT command accepts standard input from the keyboard. The INPUT 
command requires a return or newline character to terminate input.

Example:
        INPUT a$        accepts a character string
        INPUT val       accepts a numeric value

In this example:
        INPUT ;"First: "; first$; " Last: "; last$:

the display shows:
        First: _

while the cursor waits for the contents of first$ to be entered.
Which then displays:
        First: Bill Last:_

on the same line, waiting for the contents of last$ to be entered.
INPUT, in this example, acts as both an INPUT and a PRINT command. Since 
the return key is required to end input, by placing a semi-colon after the
INPUT command, tells Bxbasic not to echo the newline character.

Example:
        INPUT ; "Enter your Name: "; name$

This will have the effect of keeping the cursor on the same line.


'-----cut-n-paste------'
'  test.bas version 32
'
  DIM abc$ = "", first$ = "", init$ = "", last$ = ""
  DIM age = 0, mo = 0, day = 0, year% = 0
'
  CLS
  PRINT "Press any key to begin: ";
Start:
  abc$ = INKEY$
  IF abc$ = "" THEN
    GOTO Start
  ENDIF
'
  PRINT
'
  PRINT "Enter your name:"
  INPUT ;"First: "; first$; " Initial: "; init$; " Last: "; last$
  PRINT
  PRINT "Enter your age and birth date:"
  INPUT ;"Age: "; age; " Month: "; mo; "/Day: "; day; "/Year: "; year%
  PRINT
'
  PRINT first$, init$, last$
  PRINT age, mo, day, year%
  PRINT "Press any key: ";
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

INPUT$:
=======
The INPUT$ function differs from the INPUT command in the way in which it 
is used. The INPUT$ function is a character string function and is used to
input string data, as opposed to numeric data. The characters entered are 
assigned to a string variable. The INPUT$ function accepts a parameter, in 
the form of an integer value. That value is the number of characters that
INPUT$ will accept. 

Example:
        a$ = INPUT$(n)	where 'n' is an integer

Once the total number of characters have been entered, the program moves on
to the next instruction. Hitting the return key is not required, but, 
entering the total number of characters is. An example of where this might 
be used is in accepting data entry of a known fixed length.


'-----cut-n-paste------'
'  test.bas version 33
'
  DIM abc$ = ""
'
  CLS
  PRINT "Enter 10 digits"
  abc$ = INPUT$(10)
  PRINT "": abc$
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

LINE INPUT:
===========
The LINE INPUT command is very similar to the plain INPUT command, except
that all the data entered is assigned to a single string variable. Also,
LINE INPUT will accept an entire line of text, up to 255 characters and is
terminated by a newline character. LINE INPUT can be used much the same way
as the INPUT command, with or without a prompt string:

Example:
        LINE INPUT "Enter your: Address, City and State: "; a$
or      LINE INPUT a$

The return key terminates input.


'-----cut-n-paste------'
'  test.bas version 34
  DIM abc$ = ""
'
  CLS
  PRINT "1: ";
  LINE INPUT abc$
'           ^-----notice no prompt
  PRINT
  PRINT abc$
  LINE INPUT "2:enter a string: "; abc$
  PRINT
  PRINT abc$
  LINE INPUT ;"3:enter a string: "; abc$
'            ^------no echo:return
  PRINT
  PRINT abc$
  LINE INPUT ;"4:enter a string: "; abc$,
'  no echo---^         insert tab-------^
  PRINT
  PRINT abc$
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



________________________________________________________
________________________________________________________

ALGEBRAIC FUNCTIONS:
====================
        Function:     Usage:
       ==========  =============================================
        ABS(n)	    num% = ABS(number)
                        returns the absolute value of a number.

        ASC(c$)	num  = ASC(char$)
                        returns the value of an ascii character.

        ATN(n)	num# = ATN(num)
                        returns the arctangent of a number.

        COS(n)	num# = COS(num)
                        returns the cosine of a number.

        SIN(n)	num# = SIN(num)
                        returns the sine of a number.

        TAN(n)	num# = TAN(num)
                        returns the tangent of a number.

        SQRT(n)	num# = SQRT(num)
                        returns the square root of a number.

        INT(n)	num% = INT(num#)
                        returns the integer value of a floating point
                        number.

        LEN(c$) num  = LEN(char$)
                        returns the length of a character string.

        LOF(n)  num  = LOF(file)
                        returns the length-of-file of file number.

        LOC(n)  num  = LOC(file)
                        returns the record pointer location of file.

        CVD(c$) num# = CVD(char$)
                        converts a string to double precision value.

        CVI(c$) num# = CVI(char$)
                        converts a string to integer value.

        CVS(c$) num# = CVS(char$)
                        converts a string to single precision value.

        ATN2(n,n) num# = ATN2(num,num)
                        returns the arctangent of 2 numbers.

        COSH(n) num# = COSH(num)
                        returns the hyperbolic cosine of a number.

        SINH(n) num# = SINH(num)
                        returns the hyperbolic sine of a number.

        TANH(n) num# = TANH(num)
                        returns the hyperbolic tangent of a number.

        ACOS(n) num# = ACOS(num)
                        returns the arc cosine of a number.

        ASIN(n) num# = ASIN(num)
                        returns the arc sine of a number.

        CEIL(n) num  = CEIL(num)
                        returns the ceiling of a number.

        FLOOR(n) num = FLOOR(num)
                        returns the floor of a number.

        HYPOT(n,n) num# = HYPOT(n,n)
                        returns the hypotenuse of 2 numbers.

        LOG(n)  num  = LOG(n)
                        returns the natural logarithm of number.

        LOG10(n) num = LOG10(n)
                        returns the logarithm base 10 of number.

        RAND()  num  = RAND()
                        returns a random number.

        CLOCK() num  = CLOCK()
                        returns clock ticks since start of program.

        VAL(s$) num  = VAL(str$)
                num  = VAL("100")
                         returns the value of a numeric string
                         in a variable or quoted string.

        EOF(n)  num  = EOF(file)
                         returns a boolean value (true/false).




Try this new example:


'-----cut-n-paste------'
'  test.bas version 35
'
  DIM ixyz = 0, iabc = 0, labc! = 0
'
  CLS
  ixyz = 99
  iabc = ABS(ixyz - 1.75)
  PRINT iabc
  iabc = ASC("A")
  PRINT iabc
  labc! = ATN(ixyz / 3)
  PRINT labc!
  labc! = COS(5.8 * .0174533)
  PRINT labc!
  labc! = SIN(ixyz / 11)
  PRINT labc!
  labc! = TAN(ixyz / 10)
  PRINT labc!
  labc! = SQRT(ixyz)
  PRINT labc!
  iabc = INT(ixyz / 3.1)
  PRINT iabc
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 36
'
  DIM abc = 10, xyz = 99
'
  CLS
'
  PRINT ABS(xyz - 1.75)
  PRINT ASC("A")
  PRINT ATN(xyz / 3)
  PRINT COS(5.8 * .0174533)
  PRINT SIN(xyz / 11)
  PRINT TAN(xyz / 10)
  PRINT SQRT(xyz)
  PRINT INT(xyz / 3.1)
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



________________________________________________________
________________________________________________________

DISK FILE I/O:
==============
OPEN, CLOSE:
============
File I/O is dependant on the abiliy to OPEN and CLOSE disk files. The OPEN
command requires a specific format using three parameters.

i.e.:
        1) I/O Mode
        2) File Handle
        3) Filename/Path

Example:
            OPEN "I", #1, "data.fil"
    I/O Mode------^    ^      ^-------Filename
                       ^-----File Handle

The I/O Modes are:

        I = Input        read a file
        O = Output       create/write to file
        A = Append       write to existing file

File Handle numbers can range from 1 to 99.
The CLOSE command can be used in two ways:

        CLOSE                close all open files
        CLOSE 1,2,3          close files #1, #2 and #3


Before we can run this next program, you will need to create a file named
Test.txt. Using Notepad, create an empty file,  just hit the return key 
about three or four times, then save the file to your working directory, 
naming it "Test.txt", and close it.

Now copy this to Test.bas, and run it:



'-----cut-n-paste------'
'  test.bas version 37
  CLS
'
  PRINT "Opening Test File"
  OPEN "I", #1, "test.txt"
  CLOSE 1
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


Okay, maybe that wasn't all that impressive, but, it did OPEN Test.txt for
Input and then CLOSE it.

In this next example, a character string, filename$, is assigned the 
file-name information. Either a quoted string, as used in the above, or a
string variable may be used for this purpose.


'-----cut-n-paste------'
'  test.bas version 38
'
  DIM filename$ = "test.txt"
'
  CLS
'
  PRINT "Opening Test File"
  OPEN "I", #1, filename$
  CLOSE 1
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



For the next example, copy this line of data to our data file, Test.txt:

"hello world","next string",32000,650000,1.123,3000000.123


Make sure this is at the very top line. Also, delete any blank lines that
may come after it, so that this is the only thing in Test.txt.

Now, run this Test.bas:


'-----cut-n-paste------'
'  test.bas version 39
'
  DIM input$ = "", next$ = ""
  DIM valuea = 0, valueb% = 0, valuec! = 0, valued# = 0
'
  CLS
'
  PRINT "Opening Test File"
  OPEN "I", #1, "test.txt"
  INPUT#1, input$, next$, valuea, valueb%, valuec!, valued#
  CLOSE 1
  PRINT input$, next$, valuea, valueb%, valuec!, valued#
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


When executed, Bxbasic OPENs Test.txt for Input, using Handle #1 and INPUTs
two string variables and four numeric variables. It then CLOSEs Handle #1 
and prints out the information.

Now, let's try something a little more challenging. Copy the following into
the data file: Test.txt

"hello world","next string",32000,650000,1.123,3000000.123
"hello ","world",2000,50000,0.123,5000000.123


Now run this Test.bas:


'-----cut-n-paste------'
'  test.bas version 40
'
  DIM input$ = "", next$ = ""
  DIM valuea = 0, valueb% = 0, valuec! = 0, valued# = 0
'
  CLS
'
  PRINT "Opening Test File"
  OPEN "I", #1, "test.txt"
  INPUT#1, input$, next$, valuea, valueb%, valuec!, valued#
  PRINT input$, next$, valuea, valueb%, valuec!, valued#
'
  INPUT#1, input$, next$, valuea, valueb%, valuec!, valued#
  PRINT input$, next$, valuea, valueb%, valuec!, valued#
  CLOSE 1
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


In this example, Bxbasic read-in two seperate lines of data and processed 
it as before. This is okay, if you only have one or two lines of data to 
input. In practice though, it's not very practical.


________________________________________________________
________________________________________________________

EOF():
======
If you have a data file that contains twenty lines of data to input, you 
don't want to code twenty identical lines of INPUT instructions. Instead, 
a more practical application would be to read the data in, in some form of
loop. 
For example:

  OPEN "I", #1, "test.txt"
'
Start:
  INPUT#1, input$, next$, valuea, valueb%, valuec!, valued#
  PRINT input$, next$, valuea, valueb%, valuec!, valued#
  GOTO Start
  ...

Here, the program loops through the data file, inputing each line of data.
There is one major problem with this though. The code above forms a 
continuous loop that would end in an error or program crash.
Why ?

It has to do with the fact that when the program gets to the end of the 
file, it just tries to keep on reading. This is not a good thing. The 
solution is to have a means of detecting when we have reached the end of 
the file and terminate the process before it does any harm. That is where 
EOF comes in.

EOF is a file or device function. The sole purpose is to detect the 
End-Of-File. Using the sample code from above, all we need to do is to add 
a condition test to the loop, that will test for End-Of-File. 
Like this:

  OPEN "I", #1, "test.txt"
'
Start:
  IF EOF(1) THEN
     GOTO Finish
  ENDIF
  INPUT#1, input$, next$, valuea, valueb%, valuec!, valued#
  PRINT input$, next$, valuea, valueb%, valuec!, valued#
  GOTO Start
Finish:
  CLOSE 1

In this example, we keep looping, reading-in data, until we detect an 
End-Of-File condition. Then we stop trying to read.

Here is a Test.bas that we can try it on.
Before we can test this out, we need to modify Test.txt. Copy the following
into Test.txt:

"hello world","next string",32000,650000,1.123,3000000.123
"hello ","world",2000,50000,0.123,5000000.123
"hello world","next string",32000,650000,1.123,3000000.123

Save and close it. Now execute it.


'-----cut-n-paste------'
'  test.bas version 41
'
  DIM input$ = "", next$ = ""
  DIM valuea = 0, valueb% = 0, valuec! = 0, valued# = 0
'
  CLS
  PRINT "Opening Test File"
  OPEN "I", #1, "test.txt"
'
Start:
  IF EOF(1) THEN
     GOTO Finish
  ENDIF
'
  INPUT#1, input$, next$, valuea, valueb%, valuec!, valued#
'
  IF input$="" THEN
     GOTO Start
  ENDIF
'
  PRINT input$, next$, valuea, valueb%, valuec!, valued#
  GOTO Start
'
Finish:
  CLOSE 1
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


In line 11, is another status test. There, it is testing for the 
possibility of a mis-read, where a read attempt was made but for some 
reason it was unable to. In this case, it loops back up to see if it has 
reached the End-Of-File.


________________________________________________________
________________________________________________________

WRITE:
======
Inputing data is only half of file I/O. The other half is WRITEing data to 
a disk file. The WRITE command looks identical to the INPUT command. In 
fact, the WRITE command is the mirror image of the INPUT command. Except 
that the data flows in the opposite direction.

Here is an example where we open a second file for OUTPUT and WRITE to it 
the data we have INPUT from the first file. Notice that the data written 
out need not be in the same order as was read-in.



'-----cut-n-paste------'
'  test.bas version 42
'
  DIM input$ = "", next$ = ""
  DIM valuea = 0, valueb% = 0, valuec! = 0, valued# = 0
'
  CLS
  PRINT "Opening Test File"
'
  OPEN "I", #1, "test.txt"
  OPEN "O", #2, "test2.txt"
'
Start:
  IF EOF(1) THEN
     GOTO Finish
  ENDIF
'
  INPUT#1, input$, next$, valuea, valueb%, valuec!, valued#
'
  IF input$="" THEN
     GOTO Start
  ENDIF
'
  PRINT input$, next$, valuea, valueb%, valuec!, valued#
  WRITE#2, valued#, valuec!, valueb%, valuea, next$, input$
' ..................write data in reversed order!
  GOTO Start
'
Finish:
  CLOSE 1, 2
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


Compile and execute the above Test.bas and then examine the contents of 
Test2.txt.

Now try this next one:


'-----cut-n-paste------'
'  test.bas version 43
'
  DIM input$ = "", next$ = ""
  DIM valuea = 0, valueb% = 0, valuec! = 0, valued# = 0
'
  CLS
  PRINT "Opening Test File"
'
  OPEN "I", #1, "test.txt"
  OPEN "A", #2, "test2.txt"
'
Start:
  IF EOF(1) THEN
     GOTO Finish
  ENDIF
'
  INPUT#1, input$, next$, valuea, valueb%, valuec!, valued#
'
  IF input$="" THEN
     GOTO Start
  ENDIF
'
  PRINT input$, next$, valuea, valueb%, valuec!, valued#
  WRITE#2, input$, next$, valuea, valueb%, valuec!, valued#
'
  GOTO Start
'
Finish:
  CLOSE 1, 2
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


Is there going to be anything different in the result ?
After executing it, examine Test2.txt.


________________________________________________________
________________________________________________________

LINE INPUT#:
============
Just as we can use the LINE INPUT command to enter an entire line of text
from the keyboard, we can also us it to INPUT an entire line of data from 
a disk file. An entire line of data, up to 255 characters, terminated by a
newline character, can be read in to a single string variable.

Before we try this, delete everything currently in Test.txt and copy this
new informaion into Test.txt:

hello world, next string, 32000, 650000, 1.123, 3000000.123
hello , world, 2000, 50000, 0.123, 5000000.123
hello world, next string, 32000, 650000, 1.123, 3000000.123


Notice that there are no "quotes" surrounding either of the lines of text.
Now try this Test.bas:


'-----cut-n-paste------'
'  test.bas version 44
'
  DIM input$= ""
'
  CLS
  PRINT "Opening Test File"
  OPEN "I", #1, "test.txt"
'
Start:
  IF EOF(1) THEN
     GOTO Finish
  ENDIF
'
  LINE INPUT#1, input$
'
  IF input$="" THEN
     GOTO Start
  ENDIF
'
  PRINT input$;
  input$= ""
  GOTO Start
'
Finish:
  CLOSE
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



________________________________________________________
________________________________________________________

PRINT#:
=======
The function that mirrors LINE INPUT, oddly enough is not LINE WRITE, but,
PRINT#. We are using the PRINT command and the hash-mark (#) indicates that
we are PRINTing to a device.

Try this Test.bas and then examine Test2.txt:


'-----cut-n-paste------'
'  test.bas version 45
'
  DIM input$ = ""
'
  CLS
  PRINT "Opening Test File"
'
  OPEN "I", #1, "test.txt"
  OPEN "O", #2, "test2.txt"
'
Start:
  IF EOF(1) THEN
     GOTO Finish
  ENDIF
'
  LINE INPUT#1, input$
'
  IF input$="" THEN
     GOTO Start
  ENDIF
'
  PRINT input$
  PRINT#2, input$
  input$= ""
  GOTO Start
'
Finish:
  CLOSE 1, 2
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



________________________________________________________
________________________________________________________

RANDOM I/O:
===========
An additional method of disk I/O is called Random Access. Unlike sequential
file access, which requires that disk file data be accessed sequentially,
from beginning to end, Random access allows individual records to be 
written or read from a disk file in any desired order. Generally, in a 
random access file, records have a fixed length, with a predetermined 
number of characters or bytes. There by allowing records to be stored with
each record having a known distance from the beginning of the file. 

For instance, assume for a moment that a database will contain an unknown
number of records, but, that each record will have a fixed length of one 
hundred ascii characters. 

Example:

      first name:[               ] = 15 characters
       last name:[               ] = 15 characters
         address:[                              ] = 30 characters
     information:[                    ] = 20 characters
     information:[                    ] = 20 characters

The record consists of the clients: name, address and information, for a 
total of 100 characters.

If this record were to be stored as record number one, then record number
two would be stored beginning one hundred bytes away from the beginning of
the file. You would say that record number two has an offset of one hundred
bytes. Record number three would begin two hundred bytes from the start of
the file and therefore have an offset of two hundred bytes.

A disk file of this description, opened for random access, would have the
ability to read-in or write-out data using a disk buffer one hundred bytes
in length. Reading in or writing out information one hundred bytes at a 
time, beginning at a calculated offset for a particular record.

Since a random access file has the ability to read or write individual 
records without disturbing the surrounding records, it need not be opened 
strictly for INPUT or for OUTPUT. Once a random access file is opened, it
may be both read from and written to, at the same time.

Opening a random access file is no different from opening a sequential 
access file, with the exception that an "R" is used for the mode specifier
and the filename/path is followed by the record length. 
i.e.:
    OPEN "R", #1, "test.txt", 50

The record length indicates the number of bytes the buffer will read or 
write for each record and will be used to calculate the offsets for each 
record.

There are five commands that are used when dealing with random access files;
 FIELD, LSET, RSET, PUT and GET.

FIELD: divides the I/O buffer into it's individual parts or strings of 
information that will comprise the record. Using the above example data:

      first name: = 15 characters
       last name: = 15 characters
         address: = 30 characters
     information: = 20 characters
     information: = 20 characters

the I/O buffer will be divided up like this:

                   I/O BUFFER
                  ------------
  [first$    ][last$     ][address$  ][info1$    ][info2$    ]
  ( 15 chars )( 15 chars )( 30 chars )( 20 chars )( 20 chars )


The usage for the FIELD command is:

        FIELD #1, 15 AS F$, 15 AS L$, 30 AS A$, 20 AS I1$, (etc...)


LSET/RSET: are abbreviations for Left-Set and Right-Set. 
In the event that the data contained in a particular string is too short,
for instance if first$ only contains five characters and not all fifteen,
LSET or RSET may be used to add padding, (blank spaces) to fill in the 
required length. 

The difference between LSET and RSET is that:
LSET pushes the existing string information to the far left of the string
and adds any required padding to the right of the data. 

RSET pushes the existing string information to the far right of the string
and adds any required padding to the left of the data.

Example:
        First$ = "Fred"
        LSET [Fred...........]
        RSET [...........Fred]

LSET and RSET guarantee that each data string is the proper length when put
into the buffer before writing it to the file.

Usage for LSET and RSET are:

        LSET F$ = first$
        LSET L$ = last$
        LSET A$ = address$
        RSET I1$ = info1$
        RSET I2$ = info2$

As a result of the LSET or RSET commands, the data is set to the proper
lengths and placed into the I/O buffer.

PUT: is the command to write the buffer to the file.
The usage is:

        PUT 1,(record #)
        PUT 1, 99
        PUT 1, rec%   (where rec% is a long integer variable)

GET: is the command to read-in a file record into the buffer.
Usage is:

        GET 1,(record #)
        GET 1, 99
        GET 1, rec%   (where rec% is a long integer variable)


Here is an example of using the above random access commands:
(*** First, delete test.txt.***)


'-----cut-n-paste------'
'  test.bas version 46
'
   DIM q$ = "This", x$ = "is", y$ = "a", z$ = "test", w$ = "record"
   DIM A$ = "", B$ = "", C1$ = "", D$ = "", E$ = ""
'
   CLS
'
   OPEN "R", #1, "test.txt", 50
   FIELD #1, 10 AS A$, 10 AS B$, 10 AS C1$, 10 AS D$, 10 AS E$
   LSET A$ = q$
   LSET B$ = x$
   LSET C1$ = y$
   LSET D$ = z$
   RSET E$ = w$
'
   PUT 1, 1
   CLOSE 1
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



Cut-n-paste Test.bas #46 and try it, then examine file: "test.txt".
Now change the record number in the PUT statement to read:

	PUT 1, 2

execute Test.bas and again, examine "test.txt".

Now try this Test.bas:


'-----cut-n-paste------'
'  test.bas version 47
'
    DIM q$ = "This", x$ = "is", y$ = "a", z$ = "test", w$ = "record"
    DIM A$ = "", B$ = "", C1$ = "", D$ = "", E$ = ""
    DIM rec% = 1, xx = 0
'
    CLS
'
    OPEN "R", #1, "test.txt", 50
    FIELD #1, 10 AS A$, 10 AS B$, 10 AS C1$, 10 AS D$, 10 AS E$
    FOR xx = 1 TO 5 STEP 1
        LSET A$ = q$
        LSET B$ = x$
        LSET C1$ = y$
        LSET D$ = z$
        RSET E$ = w$
        '
        PUT 1, rec%
        rec% = rec% + 1
    NEXT xx
'
    CLOSE 1
    CLEAR
'
    OPEN "R", #1, "test.txt", 50
    FIELD  1, 10 AS A$, 10 AS B$, 10 AS C1$, 10 AS D$, 10 AS E$
    GET 1, 2
'
    PRINT A$
    PRINT B$
    PRINT C1$
    PRINT D$
    PRINT E$
'
    CLOSE 1
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



________________________________________________________
________________________________________________________

I/O STRING FUNCTIONS:
=====================
As you've seen in the above, when reading from or writing to a random I/O
file, the buffer is made up of fixed length strings. You may be wondering
how then do we read or write numeric information, such as floating point
numbers or the results of a calculation. This is accomplished with the 
"make" and "convert" functions.

The make functions are:

        MKD$() = make a double float into a string
        MKS$() = make a single float into a string
        MKI$() = make an integer into a string

and are used for writing data to a file.
The usage would be:
        A$ = MKD$(double#)
        B$ = MKS$(single!)
        C$ = MKI$(integer%) or (integer)


The convert functions are:
        CVD() = convert a string into a double float
        CVS() = convert a string into a single float
        CVI() = convert a string into an integer

The usage would be:
        double#  = CVD(A$)
        single!  = CVS(B$)
        integer% = CVI(C$)


Here is a new Test.bas, using these new functions to try:


'-----cut-n-paste------'
'  test.bas version 48
    DIM az#=1.012345, bz!=123.456
    DIM cz%=123456, dz = 12345, rec = 1, ix = 0
    DIM A$ = "", B$ = "", C1$ = "", D$ = "", E$ = ""
    DIM w$ = "end"
    CLS
'
    OPEN "R", #1, "test.txt", 34
    FIELD #1, 4 AS A$, 4 AS B$, 8 AS C1$, 8 AS D$, 10 AS E$
    FOR ix = 1 TO 5 STEP 1
        LSET A$ = MKI$(dz)
        LSET B$ = MKI$(cz%)
        LSET C1$ = MKS$(bz!)
        LSET D$ = MKD$(az#)
        RSET E$ = w$
        PUT 1, rec
        rec = rec + 1
    NEXT ix
    CLOSE 1
    CLEAR
'
    OPEN "R", #1, "test.txt", 34
    FIELD #1, 4 AS A$, 4 AS B$, 8 AS C1$, 8 AS D$, 10 AS E$
    GET 1, 1
'
    az# = CVD(D$)
    bz! = CVS(C1$)
    cz% = CVI(B$)
    dz =  CVI(A$)
    PRINT "az#="; az#
    PRINT "bz!="; bz!
    PRINT "cz%="; cz%
    PRINT "dz ="; dz
    CLOSE 1
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'


Some other useful functions are:
        LOC() = returns the offset pointer within the current file
        LOF() = returns the length, in bytes, of the current file
        LEN() = returns the length of a string variable

Usages would be:
        pointer% = LOC(buffer)
            len% = LOF(buffer)
             len = LEN(mystring$)


Here is a Test.bas showing them in use:


'-----cut-n-paste------'
'  test.bas version 49
'
    DIM az# = 0, bz! =0
    DIM cz% = 0, dz = 0, pointer = 0, len = 0
    DIM A$ = "", B$ = "", C1$ = "", D$ = "", E$ = ""
    DIM string$ = ""
    CLS
'
    OPEN "R", #1, "test.txt", 34
    FIELD #1, 4 AS A$, 4 AS B$, 8 AS C1$, 8 AS D$, 10 AS E$
    GET 1, 2
'
    pointer = LOC(1)
    PRINT "file offset = "; pointer
'
    len = LOF(1)
    PRINT "file length = "; len
'
    string$ = E$
    len = LEN(string$)
    PRINT "len string$ = "; len, ">"; string$; "<"
'
    az# = CVD(D$)
    bz! = CVS(C1$)
    cz% = CVI(B$)
    dz =  CVI(A$)
    PRINT "az# = "; az#
    PRINT "bz! = "; bz!
    PRINT "cz% = "; cz%
    PRINT "dz = "; dz
    CLOSE 1
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'




________________________________________________________
________________________________________________________

ARRAYS:
=======
Multi-dimensional arrays can be created, resized and destroyed with the
following commands:

          DIM:        dimension an array
        REDIM:        redimension (resize) an array
        ERASE:        erase an array

The syntax for DIM is as follows:

        DIM MyLong%(10,10)       : creates a two dimensional array of 
                                   long-integers
        DIM MyFloat!(10,10)      : creates a two dimensional array of 
                                   single precision
        DIM MyDouble#(10,10)     : creates a two dimensional array of 
                                   double precision

The syntax for REDIM is as follows:

        DIM MyValue%(1)           : creates a single dimension integer array

        REDIM MyValue%(2,2)       : redimensions array to a two dimension
                                    array

The syntax for ERASE is as follows:

        ERASE MyValue%            : removes array space from memory


*Note: Arrays have global scope.


Try these test programs:


'-----cut-n-paste------'
'  test.bas version 50
'  create single dimension array
  DIM MyArray%(5)
'
  CLS
'
  MyArray%(1) = 10
  MyArray%(2) = 20
  MyArray%(3) = 30
  MyArray%(4) = 40
  MyArray%(5) = 50
'
  PRINT MyArray%(1)
  PRINT MyArray%(2)
  PRINT MyArray%(3)
  PRINT MyArray%(4)
  PRINT MyArray%(5)
'
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 51
'  create single dimension array
  DIM MyArray%(5)
  DIM xvalue = 0
'
  CLS
'
  MyArray%(1) = 10
  MyArray%(2) = 20
  MyArray%(3) = 30
  MyArray%(4) = 40
  MyArray%(5) = 50
'
  PRINT MyArray%(1)
  PRINT MyArray%(2)
  PRINT MyArray%(3)
  PRINT MyArray%(4)
  PRINT MyArray%(5)
'
  xvalue = MyArray%(1) + MyArray%(2)
'
  PRINT
  PRINT xvalue
'
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



'-----cut-n-paste------'
'  test.bas version 52
'  create single dimension array
  DIM MyArray%(1)
  DIM xvalue = 0
'
  CLS
  MyArray%(1) = 99
'
  PRINT MyArray%(1)
  PRINT
'
'                 redimension single dimension array
  REDIM MyArray%(5)
'
  MyArray%(1) = 10
  MyArray%(2) = 20
  MyArray%(3) = 30
  MyArray%(4) = 40
  MyArray%(5) = 50
'
  PRINT MyArray%(1)
  PRINT MyArray%(2)
  PRINT MyArray%(3)
  PRINT MyArray%(4)
  PRINT MyArray%(5)
'
  xvalue = MyArray%(1) + MyArray%(2)
'
  PRINT
  PRINT xvalue
'
  ERASE MyArray%()
'
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



When using ERASE, how do you know the memory space is freed?
Try this next example:


'-----cut-n-paste------'
'  test.bas version 53
'
  DIM MyArray%(1)
'
  CLS
  MyArray%(1) = 99
'
  PRINT MyArray%(1)
  PRINT
'
  ERASE MyArray%()
'
'
  MyArray%(1) = 100
  PRINT MyArray%(1)
'
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'



Now try these multi-dimensional examples:


'-----cut-n-paste------'
'  test.bas version 54
'
'                 create single dimension array
  DIM MyArray%(1)
'
'                 redimension to multi-dimensional array
  REDIM MyArray%(2,2)
'
  MyArray%(1,1) = 10
  MyArray%(1,2) = 20
  MyArray%(2,1) = 30
  MyArray%(2,2) = 40
'
  CLS
  PRINT MyArray%(1,1)
  PRINT MyArray%(1,2)
  PRINT MyArray%(2,1)
  PRINT MyArray%(2,2)
'
  ERASE MyArray%()
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'




'-----cut-n-paste------'
'  test.bas version 55
'
'                 create single dimension array
  DIM MyStrArry$(1)
'
'                 redimension to multi-dimensional array
  REDIM MyStrArry$(2,2)
'
  MyStrArry$(1,1) = "ten"
  MyStrArry$(1,2) = "twenty"
  MyStrArry$(2,1) = "thirty"
  MyStrArry$(2,2) = "forty"
'
  CLS
  PRINT MyStrArry$(1,1)
  PRINT MyStrArry$(1,2)
  PRINT MyStrArry$(2,1)
  PRINT MyStrArry$(2,2)
'
  ERASE MyStrArry$()
' ------------------------------------------
TheEnd:
  END
' ------------------------------------------
'-----cut-n-paste------'




________________________________________________________
________________________________________________________

CONDITIONAL LOOPS:
==================
Besides IF/ELSEIF and FOR/NEXT statements Bxbasic also supports these 
conditional loops:

        WHILE/WEND

        WHILE   :       begins and tests a conditional loop 
        WEND    :       end a conditional WHILE loop

and
        DO/WHILE

        DO      :       begins an unconditional loop
        WHILE   :       tests a conditional loop


________________________________________________________
________________________________________________________

WHILE/WEND:
===========
The basic WHILE/WEND loop begins with a test condition. If the condition 
tests TRUE then the loop is executed, up to the WEND and then re-tests the
condition at the top of the loop. 

Example:
        WHILE x < 10
             { do stuff... 
               x = x + 1
             }
        WEND

In the above example, provided that variable "x" has a start value of less
than 10, the loop will be executed. Variable "x" will be incremented during
each pass through the loop. The loop will continue to execute as long as 
"x" is less than 10.

Let's replace the FOR/NEXT loops used in Example 23 with WHILE/WEND's in 
this example:


'-----cut-n-paste------'
'  test.bas version 56
'
  DIM x = 0, y = 0
'
  CLS
  GOSUB Top
  GOSUB Center
  GOSUB Bottom
  GOTO TheEnd
'----------------------
Center:
  x = 1
  WHILE x <= 5
      PRINT "*";
      y = 1
      WHILE y <= 28
          PRINT " ";
          y = y + 1
      WEND
      PRINT "*":
      x = x + 1
  WEND
  RETURN
'----------------------
Top:
Bottom:
  x = 1
  WHILE x <= 30
      PRINT "*";
      x = x + 1
  WEND
  PRINT "":
  RETURN
'----------------------
TheEnd:
  END
'----------------------
'-----cut-n-paste------'




________________________________________________________
________________________________________________________

DO/WHILE:
=========
The DO/WHILE loop enters a loop or block of code prior to testing any 
conditions, therefore the loop/block is executed at least once everytime.

Example:
        DO
             { do stuff... 
               x = x + 1
             }
        WHILE x < 10

In this case, "stuff" will be done, at least once, prior to WHILE testing 
for a TRUE condition.

DO/WHILE has not been thoroughly debugged and tested yet. It does work as 
a stand-alone loop. However, it does not work when used in a nested loop or
 with WHILE/WEND in a nested loop.

Here is a simple example to try:


'-----cut-n-paste------'
'  test.bas version 57
'
  DIM x = 1
  DIM MyStr$(20)
'
  CLS
  MyStr$(1) = "At"
  MyStr$(2) = " present,"
  MyStr$(3) = " DO/WHILE"
  MyStr$(4) = " may"
  MyStr$(5) = " not"
  MyStr$(6) = " be"
  MyStr$(7) = " nested"
  MyStr$(8) = " or"
  MyStr$(9) = " used"
  MyStr$(10) = " in"
  MyStr$(11) = " conjunction"
  MyStr$(12) = " with"
  MyStr$(13) = " WHILE"
  MyStr$(14) = "/"
  MyStr$(15) = "WEND"
  MyStr$(16) = " loops."
'
  DO
    PRINT MyStr$(x);
    x = x + 1
  WHILE x <= 16
'
  PRINT
'
  ERASE MyStr$()
'
'----------------------
TheEnd:
  END
'----------------------
'-----cut-n-paste------'


________________________________________________________
________________________________________________________

SWITCH/CASE:
============
The SWITCH/CASE pair, which is very similar to an IF/ELSEIF construct, 
allows for conditional program branching, based on a single integer value,
tested by the SWITCH statement.

Example:

        SWITCH value
            CASE 1
                {do something...}
            CASE 2
                {do something else...}
            CASE 3
                {do something different...}
            DEFAULT
                {test failed, error handler...}
        ENDSWITCH


A similar IF statement would look like this:

        IF value = 1
            {do something...}
        ELSEIF value = 2
            {do something else...}
        ELSEIF value = 3
            {do something different...}
        ELSE
            {test failed, error handler...}
        ENDIF

In theory, the SWITCH/CASE block may be a little faster to execute, since 
it is designed to test if two integer values are equal.

Try this example:


'-----cut-n-paste------'
'  test.bas version 58
'
  DIM IntVal = 0
  DIM a$ = ""
'
  CLS
  PRINT "Press a number key,(from 1 to 5):"
  WHILE a$ = ""
      a$ = INKEY$
  WEND
'
  IntVal = VAL(a$)
  PRINT "The number you pressed was:";
'
  SWITCH IntVal
    CASE 1
      PRINT " One"
    CASE 2
      PRINT " Two"
    CASE 3
      PRINT " Three"
    CASE 4
      PRINT " Four"
    CASE 5
      PRINT " Five"
    DEFAULT
      PRINT " Oops!"
  ENDSWITCH
'
'----------------------
TheEnd:
  END
'----------------------
'-----cut-n-paste------'



________________________________________________________
________________________________________________________
________________________________________________________

**ADDED FUNCTIONS:
========================
________________________________________________________
========================================================

RANDOM:         seeds random number generator
=======
       usage:  
               seed% = SECONDS
               RANDOM seed%

________________________________________________________
========================================================

RAND:           generate random number
=====
       usage:
               randNumber = RAND()
________________________________________________________
========================================================

COLOR:          sets fore-ground and back-ground colors.
======
        usage:
               COLOR fore-ground, back-ground
               COLOR 7, 0
               COLOR var1, var2

Colors:
  0 = black     8 = dark gray
  1 = blue      9 = light blue
  2 = green    10 = light green 
  3 = cyan     11 = light cyan
  4 = red      12 = light red
  5 = magenta  13 = light magenta
  6 = brown    14 = yellow
  7 = gray     15 = white

________________________________________________________
========================================================

KILL:            deletes file.
        usage:
               KILL "MyFile.txt"
               KILL file$

________________________________________________________
========================================================

SHELL:           executes a DOS command.
======
        usage:
               SHELL "dir"
               SHELL "type myfile.txt"
               SHELL command$

________________________________________________________
========================================================

CHDIR:          changes the current directory path
======
       usage:
               CHDIR dum$
               CHDIR ".."

________________________________________________________
========================================================

MKDIR:           creates the directory specified
======
       usage:
               MKDIR "dummy"
               MKDIR dum$

________________________________________________________
========================================================

RMDIR:           removes the directory specified
======
       usage:
               RMDIR dum$

________________________________________________________
========================================================

NAME:           renames old filename to new filename
=====
       usage:
               NAME old$, new$

________________________________________________________
========================================================

FILES:          lists all the files, sizes and dates
=====
       usage:
               FILES
               Files

________________________________________________________
========================================================

DATE$:          retrieves the current date
======
       usage:
               Mydate$ = DATE$
               Print Mydate$

________________________________________________________
========================================================

TIME$:          retrieves the current time
======
       usage:
               Mytime$ = TIME$
               Print Mytime$

________________________________________________________
========================================================

SLEEP:          cause program to pause n(milli-seconds)
======
       usage:
               SLEEP 100

________________________________________________________
========================================================

CLOCK:          number of clock_ticks since program start
======
       usage:
               number = CLOCK()

________________________________________________________
========================================================


SECONDS:        calculates number of seconds elapsed since 00:00:00 GMT.
========        can be used as a random number seed.
                *note: (not part of Standard Basic)
       usage:
               number% = SECONDS

________________________________________________________
========================================================

PAUSE:          stops program execution or termination until the
======          [Enter] key is pressed.
       usage:
               PAUSE

________________________________________________________
========================================================

UCASE$():        convert lower-case text to upper-case.
=========
        usage:
               a$ = UCASE$(str$)
               a$ = UCASE$("lowercase test")

________________________________________________________
========================================================

LCASE$():        convert upper-case text to lower-case.
=========
        usage:
               a$ = LCASE$(str$)
               a$ = LCASE$("UPPERCASE TEXT")

________________________________________________________
========================================================

VAL():           returns the value of a numeric string
======           in a variable or quoted string.
        usage:
              number  = VAL(str$)
              number  = VAL("100")

________________________________________________________
========================================================

LOG():           returns the natural logarithm of number.
========
        usage:
              number = LOG(variable)
              number = LOG(3.14)

LOG10():         returns the logarithm base 10 of number.
========
        usage:
              number = LOG10(variable)
              number = LOG10(99)

________________________________________________________
========================================================

DRIVE():        returns the current drive number;
========        ie: 1=A, 2=B, 3=C, etc.
       usage:
               aa = DRIVE()
               Print "drive = "; aa

________________________________________________________
========================================================

MESSAGEBOX:     displays a Windows Message Box
MSGBOX:
===========
       usage:
               MESSAGEBOX "Test", "HelloWorld!", MB_ICONQUESTION
               Messagebox text$, caption$, uType
        -or-:
                   Msgbox text$, caption$, uType

Message Box Constants:
======================
    MB_OK                  equ    0
    MB_OKCANCEL            equ    1
    MB_ABORTRETRYIGNORE    equ    2
    MB_YESNOCANCEL         equ    3
    MB_YESNO               equ    4
    MB_RETRYCANCEL         equ    5
    MB_ICONSTOP            equ    16
    MB_ICONERROR           equ    16
    MB_ICONQUESTION        equ    32
    MB_ICONEXCLAMATION     equ    48
    MB_ICONWARNING         equ    48
    MB_ICONINFORMATION     equ    64
    MB_ICONASTERISK        equ    64
________________________________________________________
========================================================

EXP(num):       returns the natural exponent of number
=========
       usage:
               MyDouble# = EXP(double#)
               Print "exponent="; MyDouble#
________________________________________________________
========================================================

ACOS(num):      calculates the arc cosine of number
==========
       usage:
               MyDouble# = ACOS(double#)
               Print "ACOS("; double#; ")="; MyDouble#
________________________________________________________
========================================================

ASIN(num):      calculates the arc sine of number
==========
       usage:
               MyDouble# = ASIN(double#)
               Print "ASIN("; double#; ")="; MyDouble#
________________________________________________________
========================================================

CEIL(nun):      calculates the smallest whole number that is not
==========      less than number
       usage:
               MyDouble# = CEIL(double#)
               Print "CEIL("; double#; ")="; MyDouble#
________________________________________________________
========================================================

COSH(num):      return hyperbolic cosine of number
==========
       usage:
               MyDouble# = COSH(double#)
               Print "COSH("; double#; ")="; MyDouble#
________________________________________________________
========================================================

FLOOR(num):     returns a double precision, largest whole number, 
===========     less than number
       usage:
               MyDouble# = FLOOR(double#)
               Print "FLOOR("; double#; ")="; MyDouble#
________________________________________________________
========================================================

HYPOT(n1,n2):   calculates the length of the hypotenuse of a right triangle, 
=============   with sides n1 and n2
       usage:
               MyDouble# = HYPOT(aDouble#, bDouble#)
               Print "HYPOT("; aDouble#; ","; bDouble#; ")="; MyDouble#
________________________________________________________
========================================================

SINH(num):      calculates the hyperbolic sine of num
==========
       usage:
               MyDouble# = SINH(aDouble#)
               Print "SINH("; aDouble#; ")="; MyDouble#
________________________________________________________
========================================================

TANH(num):      calculates the hyperbolic tangent of num
==========
       usage:
               MyDouble# = TANH(aDouble#)
               Print "TANH("; aDouble#; ")="; MyDouble#
________________________________________________________
========================================================

ATAN2(n1,n2):   calculates the arc tangent of n1/n2
=============
       usage:
               MyDouble# = ATAN2(aDouble#, bDouble#)
               Print "ATAN2("; aDouble#; ","; bDouble#; ")="; MyDouble#
________________________________________________________
========================================================

FABS(num):      returns the absolute value of a floating point number
==========
       usage:
               MyDouble# = FABS(double#)
               Print "FABS("; double#; ")="; MyDouble#
________________________________________________________
========================================================

FMOD(n1,n2):    calculates the floating point remainder of n1 divided 
============    by n2
       usage:
               MyDouble# = FMOD(aDouble#, bDouble#)
               Print "FMOD("; aDouble#; ","; bDouble#; ")="; MyDouble#
________________________________________________________
========================================================

LDEXP(n1,n2):   calculates n1 times 2, raised to the power of n2
=============
       usage:
               MyDouble# = LDEXP(aDouble#, Myint)
               Print "LDEXP("; aDouble#; ","; Myint; ")="; MyDouble#
________________________________________________________
========================================================

MODF(n1,n2):    returns the fractional part of n1, the whole part is 
============    stored in n2
       usage:
               MyDouble# = MODF(aDouble#, bDouble#)
               Print "MODF("; aDouble#; ","; bDouble#; ")="; MyDouble#
               Print "bDouble# ="; bDouble#
________________________________________________________
========================================================

POW(n1,n2):     calculates n1 raised to the n2 power
===========
       usage:
               MyDouble# = POW(aDouble#, bDouble#)
               Print "POW("; aDouble#; ","; bDouble#; ")="; MyDouble#
________________________________________________________
========================================================

POW10(num):     calculates 10 raised to the power of num
===========
       usage:
               MyDouble# = POW10(aDouble#)
               Print "POW10("; aDouble#; ")="; MyDouble#
________________________________________________________
========================================================

FREXP(n1,n2):   returns the mantissa of a floating point number (n1), 
=============   as a normalized fraction. the power of 2 exponent of 
                n1 is stored in n2.
       usage:
               MyDouble# = FREXP(aDouble#, Myint)
               Print "FREXP("; aDouble#; ","; Myint; ")="; MyDouble#
               Print "Myint="; Myint
________________________________________________________
========================================================

SUB_FUNCTIONS:
==============
The most significant addition to this version of Bxb is the addition of 
Sub-Functions, LOCAL variables and the ability to pass local variables to
a SUB. This required an modest rewrite of the variable name parser.

In previous releases of Bxb, all variables were literally global in scope. 
With this latest release, variables can be global or local in scope, 
depending on where they are (DIM'd) created. 

First, variables are strongly typed. That means that a variable name must 
be declared (or DIM'd, rather) and associated with a specific data type. 
Example: 
an integer, long, single, double or string. 

So called "Variant" data types are not allowed. 

Secondly, variable names may not be shared across data types. That means 
that if integer variable MyVar is DIM'd, you cannot also DIM MyVar$. 
This has to do with the "object handler" and how it keeps variable data 
types straight.

Thirdly, global variables are DIM'd at the beginning of the program, prior
to entering any Sub-Functions. All variables declared within a Sub-Function
are local to that Sub-Function and are destroyed upon exiting that Sub-
Function. All parameter variables passed from one Sub-Function to another 
are "passed by value". Global variables should not be passed as parameters
between Sub-Functions, since they are already global in nature.

The elements of a Sub-Function are:

        DECLARE  :       create a Sub Function's memory space
        CALL     :       call a Sub Function and creates parameter data 
                         space
        SUB      :       start of a Sub Funtion and transfers local data 
                         values
        ENDSUB   :       the end of a Sub Function and destroys local 
                         variables


Here is an example of how SUB's are declared, (in the public program area):


'========== Declare Sub Prototypes ==========
'
'========== Main Subs ==========
    DECLARE SUB xMain()
    DECLARE SUB getToken()
    DECLARE SUB pgmParser()
    DECLARE SUB parser()
    DECLARE SUB numLabel()


'========== Error Subs ==========
    DECLARE SUB Abort(code, xx)
    DECLARE SUB errHndlr(a, b, c, d, e)


Declaring a Sub is done in the above manner. The keywords DECLARE SUB are
followed by the Sub NAME, including parenthesis. If there are parameters 
passed to a Sub, then the parameter types must be included within the 
parenthesis. Otherwise, the parenthesis will be left empty.

After the Sub is declared, it may be called using the CALL keyword, as 
shown here:

    CALL xMain()

In this case, since Main() is being called from the public area of the 
program, there are no parameters to be passed to it, since all variables 
thus far would be global. Once inside sub function Main(), local variables
can be created at any point.

Here is an example of what sub Main() might look like:

'-------------------------------------------
'============ MAIN: Sub Routines ==========
'==========================================
SUB xMain()
'
    CALL LineCnt()
'
    CALL Header()
'
    CALL pgmParser()
'
    CALL Epilog()
'
    CALL clrArrays()
'
    CLOSE
'
ENDSUB
'================================SUB xMain()
'

Here is an example where parameters are passed from subroutine "xMain()" 
to subroutine "inStrChr()":


'==========================================
SUB xMain()
'
    DIM ch$ = "", str$ = ""
    DIM strch = 0
'
    str$ = "$%!#@&"
    ch$ = MID$(pstring$, pi, 1)
'
'                          call Sub "inStrChr()", with 2 string parameters
    CALL inStrChr(str$, ch$)
'
    strch = return
'
ENDSUB
'================================SUB Main()
'

'
'==========================================
SUB inStrChr(s$, c$)
    DIM xpi = 1, xlen = 0
    DIM xch$ = ""
'                       similar to BASIC's INSTR($,$)
'                       but, more like C's strchr()
    return = FALSE
    xlen = LEN(s$)
'
    WHILE return = FALSE AND xpi <= xlen
        xch$ = MID$(s$, xpi, 1)
'
        IF xch$ = c$ THEN
            return = xpi
        ELSE
            xpi = xpi + 1
        ENDIF
    WEND
'
ENDSUB
'============================SUB inStrChr()
'

Needless to say, with the advent of Sub Functions, complex code can be 
better controlled by building containers for reusable code.

Try this new example:


'-----cut-n-paste------'
'  test.bas version 59
'
  DECLARE SUB SMain()
  DECLARE SUB Switch(val)
'
'
  CALL SMain()
'
'----------------------
TheEnd:
  END
'----------------------
'


'=========================================
SUB SMain()
'
  DIM IntVal = 0
  DIM aa$ = ""
'
  CLS
  PRINT "Press a number key,(from 1 to 5):"
  WHILE aa$ = ""
      aa$ = INKEY$
  WEND
'
  IntVal = VAL(aa$)
'
  CALL Switch(IntVal)
'
ENDSUB
'================================SUB Main()
'

'==========================================
SUB Switch(val)
'
  PRINT "The number you pressed was:";
'
  SWITCH val
    CASE 1
      PRINT " One"
    CASE 2
      PRINT " Two"
    CASE 3
      PRINT " Three"
    CASE 4
      PRINT " Four"
    CASE 5
      PRINT " Five"
    DEFAULT
      PRINT " Oops!"
  ENDSWITCH
'
ENDSUB
'================================SUB Switch()
'
'-----cut-n-paste------'
'


*NOTE:
Variables and Arrays:

1) While regular variables can have either global or local scope, depending 
on where they are created, arrays are only global in scope, regardless of 
where they are created.

2) Additionally, do not use overly simple names for variables or SUB names.
Neither variable names nor SUB names are decorated, in any way, by Bxbasm. 

i.e.: the C language generally adds an underscore to a name, turning "var"
into "_var" or "Main" into "_Main". Bxbasic does not.

A name given to a SUB, (in the bxbasic script), is the same name that will 
be used by the assembler at compile time. Special care should be taken to 
name SUBs with unique names that do not conflict with Masm/Jwasm reserved 
words and syntax. Assuming a syntactically correct source script, the most 
likely source of compiler errors will be due to conflicts in names and 
reserved words.



This new version of Bxb lends itself to a more modular style of programming.

There is one more point to address and that has to do with return values. 
The main difference between Functions and Sub-Functions is that true 
Functions have the ability to return a value to the calling procedure. 
There is a very simple work-around to that problem. That is, by creating a
set of global (public) variables that are used expressly for return values.
When a Sub-Function generates a result that needs to be used by the caller 
routine, that data is placed in a special global variable, where it is 
easily accessed by the calling routine upon return from the Sub-Function
that generated the result.

Example:

'========== Declare Global Returns ==========
    DIM return=0
    DIM lreturn% = 0
    DIM dreturn# = 0
    DIM sreturn$ = "", rvarName$ = ""
'
'----------------------------------


Since Functions (generally) only return a single value, we only need a 
single variable for each data type, as shown here. Of course, additional
variables can be created, if needed.
________________________________________________________
________________________________________________________
________________________________________________________
========================================================

LABS():         computes the absolute value of a long integer.
======
       usage:
               llong! = LABS(long1!)
       example:
               DIM llong! = 0, long1! = -1
               llong! = LABS(long1!)
               PRINT "llong="; llong!

________________________________________________________
========================================================

TIMER:          a high resolution performance timer.
======
       usage:
               float# = TIMER
       example:
               TimerStart# = TIMER

               (... do stuff...)

               TimerEnd# = TIMER
               HiRezTime# = TimerEnd# - TimerStart#

Produces a floating point value. Resolution measured to the micro-second.

________________________________________________________
========================================================

SGN:            determines number's sign. If number is negative, SGN 
====            returns 0. If number is positive, SGN returns 1. 
       usage:
               sign = SGN(num)
       example:
               num = -99
               sign = SGN(a)

               IF sign = 0 THEN
                   PRINT "sign is negative"
               ELSEIF sign = 1 THEN
                   PRINT "sign is positive"
               ENDIF

________________________________________________________
========================================================

MOD():          calculates the integer remainder of a n1 divided by n2.
======
       usage:
               integer = MOD(int1, int2)
       example:
               DIM ten = 10, three = 3, imod = 0
               imod = MOD(ten, three)
               PRINT "imod="; imod

________________________________________________________
========================================================

CINT:           converts a floating point number to an integer by rounding
=====           up the fractional portion of the number. 
       usage:
               result = CINT(float)
       example:
               Dim float# = 14.9999
               Dim intVal = 0
               intVal = CINT(float#)

The value of intVal is: 15

________________________________________________________
========================================================

CDBL:           converts a number to double precision.
=====
       usage:
               double# = CDBL(Integer)
       example:
               Dim intVal = 10
               Dim dblVal# = 0
               dblVal# = CDBL(intVal)
               Print "Double="; dblVal#

________________________________________________________
========================================================

CSNG:           converts number to single precision, rounding the number
=====           when converting it to single precision.
       usage:
               single! = CSNG(Float#)
       example:
               Dim snglVal! = 0
               Dim dblVal# = .1453885509
               snglVal! = CSNG(dblVal#)
               Print "Single="; snglVal!

________________________________________________________
========================================================

CLNG:           converts a floating point number to a long integer by 
=====           rounding up the fractional portion of the number. 
       usage:
               long% = CLNG(float#)
       example:
               Dim lngVal% = 0
               Dim dblVal# = 32767.55
               lngVal% = CLNG(dblVal#)
               Print "long="; lngVal%

________________________________________________________
========================================================

INSTR:          searches for the first occurrance of string2 in string1
======          and returns the position at which the match is found.
       usage:
               INSTR(string1$, string2$)
       example:
               Dim result = 0
               Dim string1$ = "this is a test"
               Dim string2$ = "test"
               result = INSTR(string1$, string2$)
               Print "result="; result

Output: result= 11

________________________________________________________
========================================================

________________________________________________________

**FUNCTIONS ADDED 03/12:
========================
________________________________________________________

________________________________________________________
========================================================

WINDOW:         creates a GUI window referenced by "ID". 
=======         Must be used prior to using the SHOW statement.
       usage:
                WINDOW ID
       example:
                WINDOW "MyWindow"

________________________________________________________
========================================================

SHOW:           displays a gui window (client area) created by the WINDOW 
=====           statement at the top-left starting co-ordinates specified 
                by x/y and with a width and height specified by w/h.
       usage:
               SHOW "ID","Name",x,y,w,h
       example:
               SHOW "MyWindow", "MyWindow1", 0, 0, 600, 500

Displays a client window beginning at screen co-ordinates 0/0 to 600/500.

________________________________________________________
========================================================

LINE:           draws a line, using the current GDI pen width and color,
=====           beginning at pixel co-ordinates x/y and ending at end-x, 
                end-y.
       usage:
               LINE "Name", x, y, end-x, end-y 
       example:
               LINE "MyWindow1", 50, 50, 150, 50 
               REDRAW "MyWindow1"

Draws a GDI line, on client window "MyWindow1", beginning at 50/50 to 
150/50. LINE requires REDRAW to repaint the graphics screen.

________________________________________________________
========================================================

REDRAW:         is used to repaint the double-buffer onto the front screen
=======         after calling certain line-draw or pixel GDI functions.
       usage:
               REDRAW "name"
       example:
               PSET "MyWin1", x, y
               REDRAW "MyWin1"

________________________________________________________
========================================================

BOX:            draws a filled box, using the current GDI brush, beginning
====            at pixel co-ordinates x/y and ending at end-x and end-y.
                The fill color is specified by values RGB.
       usage:
               BOX "Name", x, y, end-x, end-y, R,G,B
       example:
               BOX "MyWindow1", 51, 51, 150, 150, 255, 0, 255
               REDRAW "MyWindow1"

Draws a GDI box, on client window "MyWindow1", beginning at 51/51 to 
150/150. Fill color is specified as mixed Red and Blue. RGB values range 
from 0 to 255. BOX requires REDRAW to repaint the graphics screen.

________________________________________________________
========================================================

TEXT:           draws text string onto a GUI window, using the current GDI
=====           text foreground and background colors and font, at pixel
                co-ordinates x/y.
       usage:
               TEXT "Name", string, x, y
       example:
               TEXT "MyWindow1", "Hello World!", 50, 30

Draws text string: "Hello World!" at 50/30.

________________________________________________________
========================================================

FONT:           changes the current GDI Stock-Object Font.
=====
       usage:
               FONT "Name", stock-font
       example:
               FONT "MyWindow1", ANSI_FIXED_FONT

Available stock fonts:
======================
ANSI_FIXED_FONT    ANSI_VAR_FONT    DEVICE_DEFAULT_FONT
DEFAULT_GUI_FONT   OEM_FIXED_FONT   SYSTEM_FONT
SYSTEM_FIXED_FONT

________________________________________________________
========================================================

OLDFONT:        restore original font that was current prior to the FONT
========        statement.
       usage:
               FONT "MyWindow1", ANSI_FIXED_FONT
               OLDFONT

________________________________________________________
========================================================

RECTANGLE:      draws a GDI rectangle on the client window, using the 
==========      current pen color, at the pixel co-ordinates x/y with a 
                width and height of w/h.
       usage:
               RECTANGLE "Name", x, y, w, h
       example:
               RECTANGLE "MyWindow1", 50, 160, 125, 225

Draws a rectangle at 50/160 to 125/225.

________________________________________________________
========================================================

RNDRECT:        draws a rounded rectangle on the client window, using the
========        current pen color, at the pixel co-ordinates x/y with a 
                width and height of w/h and and ellipse size of ew/eh.
       usage:
               RNDRECT "name", x, y, w, h, ew, eh
       example:
               RNDRECT "MyWindow1", 50, 235, 125, 305, 30, 30

Draws a rounded rectangle at 50/235 to 125/305 with an ellipse width and 
height of 30/30.

________________________________________________________
========================================================

SQUARE:         draws a square on the client window, using the current pen
=======         color, at the pixel co-ordinates x/y with a width and height
                specified by z.
       usage:
               SQUARE "name", x, y, z
       example:
               SQUARE "MyWindow1", 50, 315, 75

Draws a square on the client area, starting at co-ordinates 50/315 with a
width and height of 75 pixels.

________________________________________________________
========================================================

ELLIPSE:        draws an ellipse on the client window, using the current pen
========        color, at the pixel co-ordinates x/y with a width and height
                specified by w/h.
       usage:
               ELLIPSE "name", x, y, w, h
       example:
               ELLIPSE "MyWindow1", 160, 70, 260, 130

Draws an ellipse on the client area, starting at co-ordinates 160/70 to 
260/130.

________________________________________________________
========================================================

CIRCLE:         draws a circle on the client window, using the current pen
=======         color, with the center of the radius at the pixel 
                co-ordinates cx/cy with a radius specified by R.
       usage:
               CIRCLE "name", cx, cy, R
       example:
               CIRCLE "MyWindow1", 200, 180, 40

Draws a circle on the client area, centered at co-ordinates 200/180 with a
radius of 40 pixels.

________________________________________________________
========================================================

PIE:            draws a pie chart on the client window, using the current
=======         pen color, based on an ellipse, specified by x/y to w/h.
                The pie section is specified by co-ordinates xS/yS to xE/yE.
       usage:
               PIE "name", x, y, w, h, xS, yS, xE, yE
       example:
               PIE "MyWindow1", 160, 235, 260, 305, 190, 235, 160, 270

Draws an (invisible) ellipse on the client area, starting at the pixel 
coordinates x/y with a width and height specified by w/h. The pie section 
is drawn (counter clockwise) starting from about the 11:o'clock position to
the 9:o'clock position.

________________________________________________________
========================================================

CHORD:          draws a semi-circle or semi-ellipse with a line (chord) 
======          drawn through, connecting the open ends. The semi-ellipse 
                is specified by x/y to w/h. The connecting chord is 
                specified by co-ordinates xS/yS to xE/yE.
       usage:
               CHORD "name", x, y, w, h, xS, yS, xE, yE
       example:
               CHORD "MyWindow1", 160, 315, 285, 385, 230, 340, 160, 370

Draws an semi-ellipse on the client area, starting at the pixel co-ordinates
x/y with a width and height specified by w/h. With the values shown above, 
the semi-ellipse is drawn counter-clockwise from about the 2:o'clock 
position to about the 8:o'clock position. The chord, is a straight line 
drawn starting from about the 2:o'clock position to the 8:o'clock position,
connecting the two open ends.

________________________________________________________
========================================================

ARC:            draws an arc on the client window, using the current pen
====            color, based on an ellipse, specified by x/y to w/h.
                The arc section is specified by co-ordinates xS/yS to xE/yE.
       usage:
               ARC "name", x, y, w, h, xS, yS, xE, yE
       example:
               ARC "MyWindow1", 290, 70, 390, 130, 350, 50, 300, 150

Draws an (invisible) ellipse on the client area, starting at the pixel 
co-ordinates x/y with a width and height specified by w/h. Using the values
above, the arc section is drawn (counter clockwise) starting from about the
1:o'clock position to the 7:o'clock position.

________________________________________________________
========================================================

NEWPEN:         creates a new pen with a width specified by w and pen color
=======         specified by values R,G,B.
       usage:
               NEWPEN w, R,G,B
       example:
               NEWPEN 1, 0,255,0

Creates a new pen, one (1) pixel wide and green in color. The value of the
original pen is saved. RGB values range from 0 to 255.

________________________________________________________
========================================================

OLDPEN:         restores the pen width and color to what it was prior to the
=======         call to NEWPEN. 
       usage:
               OLDPEN
       example:
               NEWPEN 1, 0, 255, 0
               (... draw stuff...)
               OLDPEN

RGB values range from 0 to 255. The OLDPEN statement is REQUIRED whenever a
new pen is no longer needed. This not only restores the original pen, but,
it also destroys that pen's "Device Context".

________________________________________________________
========================================================

PENCOLOR:       changes the pen color to values specified by RGB.
=========
       usage:
               PENCOLOR R,G,B
       example:
               PENCOLOR 255, 0, 0

RGB values range from 0 to 255.

________________________________________________________
========================================================

PSET:           sets a pixel specified by x/y to the current pen color.
=====
       usage:
               PSET "name", x, y
       example:
               PSET "MyWindow1", 200, 180
               REDRAW "MyWindow1"

PSET requires REDRAW to repaint the graphics screen.

________________________________________________________
========================================================

BGCOLOR:     1) changes the client-area background color to that 
========        specified by the values R,G,B.
             2) returns the current background color.
1)     usage:
               BGCOLOR R,G,B
       example:
               BGCOLOR 0,0,0        'sets background color to black
               BGCOLOR 255,255,255  'sets background color to white

                RGB values range from 0 to 255.
2)     usage:
               BGCOLOR
       example:
               color% = BGCOLOR

Returns a long integer value of the current background color.

________________________________________________________
========================================================

CLRWIN:         clears the client-area window to the current background
=======         color.
       usage:
               CLRWIN "name"
       example:
               BGCOLOR 0,0,0        'sets background color to black
               CLRWIN "MyWindow1"

________________________________________________________
========================================================

BKMODE:      1) changes the background mode.
=======      2) determines the current background mode.
1)     usage:
               BKMODE mode
       example:
               BKMODE TRANSPARENT

The two modes are available:
============================
 TRANSPARENT and OPAQUE


2)     usage:
               integer = BKMODE
       example:
               mode = BKMODE

Returns an integer value indicating the mode:
                1 = TRANSPARENT
                2 = OPAQUE

________________________________________________________
========================================================

POINT:          determines the color of a pixel point specified by x/y.
======
       usage:
               color = POINT x, y
       example:
               color% = POINT 50, 50

Returns a long integer value of the pixel's color, specified by window 
co-ordinates x/y.

________________________________________________________
========================================================

VIEW:           repositions and resizes the named window.
=====
       usage:
               VIEW "name", x, y, w, h
       example:
               VIEW "MyWin",100,50,900,700

Repositions client window to screen co-ordinates: 100/50 and 900/700.

________________________________________________________
========================================================

PEN:            is a wrapper for the GDI CreatePen() function.
====
       usage:
               PEN style, width, R,G,B
       example:
               PEN DASH, 1, 255,0,0
               LINE "MyWin1", 294, 150, 294, 200
               OLDPEN

Creates a red, dashed pen, one pixel wide. OLDPEN function must be used when
drawing with the current pen is finished. OLDPEN restores the original pen
and deletes the new pen. PEN differs from NEWPEN only in that PEN allows
specifing a pen style.

Available pen styles are:
-------------------------
  SOLID
           The pen is solid. 
  DASH
           The pen is dashed. This style is valid only when the pen width
           is one or less in device units. 
  DOT
           The pen is dotted. This style is valid only when the pen width
           is one or less in device units. 
  DASHDOT
           The pen has alternating dashes and dots. This style is valid
           only when the pen width is one or less in device units. 
  DASHDOTDOT
           The pen has alternating dashes and double dots. This style is
           valid only when the pen width is one or less in device units. 
  NULL
           The pen is invisible. 
  INSIDEFRAME
           The pen is solid. When this pen is used in any GDI drawing
           function that takes a bounding rectangle, the dimensions of the
           figure are shrunk so that it fits entirely in the bounding
           rectangle, taking into account the width of the pen.

________________________________________________________
========================================================

LOGBRUSH:       is used in conjunction with and sets the parameters for
=========       function BRUSHIND.
       usage:
               LOGBRUSH style, pattern, R,G,B
       example:
               LOGBRUSH SOLID, CROSS, 0,255,0

Creates a solid brush, with a cross pattern and an RGB color of green. 
Actually, when a solid brush is selected, no pattern is displayed, so, any
pattern may be used.

       example:
               LOGBRUSH HATCHED, DIAGCROSS, 255,255,0

Creates a hatch brush, with a diagonal-cross pattern and an RGB color of
yellow. 

Available brush styles are:
---------------------------
  DIBPATTERN
           A pattern brush defined by a device-independent bitmap (DIB) 
           specification.
  DIBPATTERN8X8
           A pattern brush defined by a device-independent bitmap (DIB) 
           specification.
  DIBPATTERNPT
           A pattern brush defined by a device-independent bitmap (DIB) 
           specification. 
  HATCHED
           Hatched brush.
  HOLLOW
           Hollow brush.
  PATTERN
           Pattern brush defined by a memory bitmap.
  PATTERN8X8
           Same as PATTERN.
  SOLID
           Solid brush.


Available brush patterns are:
-----------------------------
  BDIAGONAL
           A 45-degree upward, left-to-right hatch.
  CROSS
           Horizontal and vertical cross-hatch.
  DIAGCROSS
           45-degree crosshatch.
  FDIAGONAL
           A 45-degree downward, left-to-right hatch.
  HORIZONTAL
           Horizontal hatch.
  VERTICAL
           Vertical hatch.
  BITMAP
           Used with PATTERN style indicates a BMP is used for the hatch.

________________________________________________________
========================================================

BRUSHIND:       is a wrapper for the GDI CreateBrushIndirect() function.
=========
       usage:
               BRUSHIND
       example:
               LOGBRUSH SOLID, CROSS, 0, 255, 0
               BRUSHIND
               ELLIPSE "MyWin1", 160, 70, 260, 130

                Creates a solid brush, with a cross pattern and an RGB color
                of green. Actually, when a solid brush is selected, no 
                pattern is displayed, so, any pattern may be used.
       example:
               LOGBRUSH HATCHED, DIAGCROSS, 255, 255, 0
               BRUSHIND
               RECTANGLE "MyWin1", 50, 160, 125, 225

Creates a hatch brush, with a diagonal-cross pattern and an RGB color of
yellow. 

________________________________________________________
========================================================

OLDBRUSH:       restores the original brush's style and pattern that was 
=========       in effect prior to calling the BRUSH command.
       usage:
               OLDBRUSH
       example:
               LOGBRUSH SOLID, CROSS, 0, 255, 0
               BRUSHIND
               ELLIPSE "MyWin1", 160, 70, 260, 130

               OLDBRUSH
               SQUARE "MyWin1", 50, 315, 75

The OLDBRUSH statement is REQUIRED whenever a new brush is no longer needed.
This not only restores the original brush, but, it also destroys that 
brush's "Device Context".

________________________________________________________
========================================================
________________________________________________________
========================================================
________________________________________________________
========================================================
________________________________________________________
========================================================
========================================================

**More to come:
________________________________________________________
========================================================


If you have any suggestions or functions you'd like to see added, your 
feedback will be welcome. If you do find any errors or typos you'd like to
report, you can contact me through the QDepartment Group at:  

        http://tech.groups.yahoo.com/group/QDepartment/ .
or:
      <blunt_axe_basic@yahoo.com>

The Author,
Steve A.
-----------------------------------------------------
Blunt_Axe_Basic Project
Copyright:(c) sarbayo, 2001-2012
-----------------------------------------------------




