Generic

Usefull notes for beginners:
____________________________

How to read the syntax:

Everything is written inside
of [] characters are
optional values.
Everything is written inside
of {} characters means you
must select one of them.
The symbol | means OR.
The symbols ... means you
can repeat the previous
syntax.
The keywords are written
with capital letters.

Examples:
Syntax: TEST {1|2}

Valid calls:
TEST 1
TEST 2

Syntax: TEST [HI]

Valid calls:
TEST
TEST HI

____________________________

Limits:
____________________________

Max. length of 
   code text line: 511 chars
Max. keyword length: 32 char
Max. num. of parameters: 64
Max. arrays dimentions: 4
Numeric value range: 64b FPN
Max. string size: 32KB
Max. number of file handles:
  PalmOS: 16
  Other: 256
INPUT (console only)
  limit: 255B per call.
  up to 16 variables.
Max. number of colors: 16
Max. bytecode size: 64KB
  (by using CHAIN you can
  run progs > 64KB)
Background sound queue
  size: 256 notes

System events are checked
every 50ms

PalmOS:
  Be careful with memory
  there is no too much.
____________________________

Variables:
____________________________

There is no data types. All
user variables (include
arrays) are 'VARIANT'.

SB uses internaly 3 types
1. Integer (32bit)
2. Real    (64bit)
3. String  (<32KB)

Variable names can use any
alphanumeric characters,
and the '$'. The first char
of the name cannot be
a digit.
The symbol '$' is supported
for compatibility. Its use
is meanless.

Example:

a="123"
a$=1
? a<>a$
REM displays 1 (true)
____________________________

System Variables:
____________________________

OSVER  - OS Version
OSNAME - OS Name
SBVER  - SmallBASIC Version
PI     - 3.14..
XMAX,YMAX
       graphics display max.
BPP    - Bits per pixel
CWD    - Current Working
         Directory
HOME   - User's directory
____________________________

Operators (by priority):
____________________________

( )       = parenthesis
-         = unary
^         = power

* / \     = mul, div, idiv
% MOD     = modulus

+ -       = add, sub

=> =<  = 
>= <= <>  = compare

AND & OR  |
NOT ! XOR ~
BAND BOR
          = logical & bitwise

:         = EOL

[,;]       = code array
____________________________

Base convertion:
____________________________

&H|0x hex. ex: 0x1F + &H1F
&o|0o oct. ex: 0o33 = &o33
&b|0b bin. ex: 0b11 = &b11
____________________________

Meta-commands:
____________________________

#!...
  Used by Unix to make
  SB source runs as script
  executable

#sec:section name
  Used internaly to store
  the section name

  DON'T USE IT

#inc:"file"
#inc:file
  Used to include a SB
  source file into current
  BASIC code

Example:
...
#inc:"mylib.bas"
...
MyLibProc "Hi"
____________________________

Matrices
____________________________

Define a 3x2 matrix

A=[11,12; 21,22; 31,32]

That creates the array

    | 11  12 |
A = | 21  22 |
    | 31  32 |

The comma used to separate
column items; the semi-colon
used to separate rows.

Values between columns can
be omitted.

Example:

A=[;;1,2;3,4,5]

This creates the array

    | 0  0  0 |
A = | 1  2  0 |
    | 3  4  5 |

Operators:

Add/sub:

B = [1, 2; 3, 4]
C = [5, 6; 7, 8]

A = B + C
C = A - B

EQ:
bool=(A=B)

Unary:

A2 = -A

Multiply:

A = [1, 2; 3, 4]
B = [5 ; 6]

C = A * B

D = 0.8 * A

Inverse:
A = [1,-1,1;2,-1,2;3,2,-1]
? INVERSE(A)

Gauss-Jordan:

? "Solve this:"
? "  5x - 2y + 3z = -2"
? " -2x + 7y + 5z =  7"
? "  3x + 5y + 6z =  9"
?
A = [5,-2,3; -2,7,5; 3,5,6]
B = [-2;7;9]
C = LinEqGJ(A, B)
? "[x;y;z] ="; C

Note:
There is a problem with 1
dimension arrays.

Because 1-dim arrays does
not specify how SB must
see them.

Example:
DIM A(3)

A = | 1 2 3 |

or
    | 1 |
A = | 2 |
    | 3 |

And because this is not the
same thing. (ex. for
multiplication)

So the default is columns
ex:
DIM A(3) ' or A(1,3)

A = | 1 2 3 |

For vertical arrays you
must declare it as 2-dim
arrays Nx1

DIM A(3,1)

    | 1 |
A = | 2 |
    | 3 |

Nested arrays are allowed

A=[[1,2],[3,4]]

A = | |1 2| |3 4| |
____________________________

Subroutines/Functions:
____________________________

SUB name
  [([BYREF] par1 [,
  ...[BYREF] parN)]]

  [LOCAL var[, var[, ...]]]
  [EXIT SUB]

END

FUNC name
  [([BYREF] par1 [,
  ...[BYREF] parN)]]

  [LOCAL var[, var[, ...]]]
  [EXIT FUNC]

  name=return-value
END

Use function's name
to return the value.

Nested procedures/functions
are allowed (like Pascal).

Example:

FUNC f(x)
  FUNC f11
    FUNC f21
        f21=21
        END
  END
  FUNC f12
  f12=12
  END

? f11
? f21: REM ERROR
f=x+f11+f
END

____________________________

The parameters are 
'by value' by default.
Passing parameters by value
means the executor makes
a copy of the parameter to
stack. The value in caller's
code will not be changed.

Use BYREF keyword for
passing parameters 
'by reference'. 
Passing parameters by
reference means the
executor push the pointer
of variable into the stack.
The value in caller's code
will be the changed.

Example:

' 'by value'
SUB F(x)
x=1
END

x=2
F x
? x:REM displays 2

' 'by reference'
SUB F(BYREF x)
x=1
END

x=2
F x
? x:REM displays 1
____________________________

Use the LOCAL keyword for
local variables.

LOCAL creates variables
(dynamic) at routine's
code.

Example:

SUB MYPROC
LOCAL N:REM LOCAL VAR
N=2
? N:REM displays 2
END

N=1:REM GLOBAL VAR
MYPROC
? N:REM displays 1
____________________________

You can send arrays as
parameters with ().

When using arrays as
parameters its better to use
them as BYREF; otherwise 
their data will be
duplicated.

Example:
SUB FBR(BYREF tbl())
? FRE(0)
...
END

SUB FBV(tbl())
? FRE(0)
...
END

' MAIN
DIM dt(128)
...
? FRE(0)
FBR dt()
? FRE(0)
FBV dt()
? FRE(0)

Avoid to use nested
arrays as BYREF parameters.
SB code is not prepared for
that. Sorry.
____________________________

On a multi-section 
applications sub/funcs needs
declaration on the main
section.

Example:
#sec:Main
declare func f(x)

#sec:another section
func f(x)
...
end
____________________________

Passing & returing arrays,
using local arrays.

Example:

func fill(a())
  local b(), i

  dim b(16)
  for i=0 to 16
    b(i)=16-a(i)
  next
  fill=b()
end

DIM v(4)
v()=fill(v())

____________________________

The USE keyword.

This keyword is used on 
specific commands for user
defined expression.

SPLIT s," ",v USE trim(x)

In that example, every
element of V() will be
'trimmed'.

Use the x variable to
specify the parameter of
the expression.
____________________________

Statements:
____________________________

'|#|REM ...

Remarks.
The # can be used as remarks
only in the first pos. of
the text line.
____________________________

[LET] var = expr

Assign 'expr' to variable
'var'.

Example:
z=1
z="Change to string"

DIM v(4)
v2()=v()
z=v():REM make z copy of v()
____________________________

CONST var = expr

Assign 'expr' to variable
'var' and make it READ-ONLY.
____________________________

DIM var( [lower TO] 
             upper [, ...])

Creates an array.
____________________________

[LABEL] label

Defines a label. There are
two kinds of labels. Numeric
and alphanumeric.

Numeric labels does not 
needed the keyword LABEL,
but alphanumeric does.

Example:
1000 ? "Hello"

LABEL AlphaLabel
? "Hello"
...

GOTO 1000
GOTO AlphaLabel
____________________________

GOTO label

Branches to a specified
label.
____________________________

GOSUB label - RETURN

Branches to an old-style
subroutine. The subroutine
returns to GOSUB's next
instruction with RETURN.
____________________________

ON expr GOTO label-list
ON expr GOSUB label-list

Branches to one of the 
several locations, depending
of the value of the 'expr'.
____________________________

FOR var = expr TO expr
         [STEP expr] - NEXT

Repeats a code block for
a specified number of times.
____________________________

FOR var IN expr - NEXT

The expr must be an array
For each element of 'expr'
repeats the block. 'var'
is the current element.
____________________________

WHILE expr - WEND

WHILE/WEND code block, loops
while 'expr' is true.
____________________________

REPEAT - UNTIL expr

REPEAT/UNTIL code block, 
loops while 'expr' is false.
____________________________

IF expr  [THEN] -
         [ELSE|ELIF|ELSEIF]
         - ENDIF|FI

Executes a code block
depending on specified
conditions.
____________________________

IF expr THEN
          [num-label]|[...]
   [ELSE [num-label]|[...]]

Old-style inline-IFs.
____________________________

STOP|END

Stops the program execution.
____________________________

RESTORE label
READ var[, var ...]
DATA n[,n ...]

DATA specifies values to
be read by READ.

RESTORE specifies the
position of the next
data to be read.

READ reads values from
current data position.

Example:

RESTORE MyDataBlock
FOR I=1 TO 3
        READ v
        PRINT v
NEXT
END

LABEL MyDataBlock
DATA 1,2,3
____________________________

ERASE var1[, var2[,
  ... varN]]

Frees the memory used by the
specified arrays or 
variables. 
After that these variables
turned to simple integer
with value 0

Example:
DIM x(100)
...
? fre(0)
ERASE x
? fre(0)
? x(1):REM ERROR
____________________________

EXIT [FOR|LOOP|SUB|FUNC]

By itself exits from last
command block (loop, 
for-loop or routine)

FOR - Exit from the last
  FOR-NEXT loop

LOOP - Exit from the last
  WHILE/REPEAT loop

SUB - Return from the
  current routine

FUNC - Return from the
  current function
____________________________

LEN(x)

if x is a string
  returns the length
  of the string
if x is an array
  returns the number of
  the elements
if x is an number
  returns the len of
  the STR(n)
____________________________

EMPTY(x)

if x is a string
  returns true if the 
  len(x) is 0;
if x is an integer or real
  returns true if the x = 0
if x is an array
  returns true if all the
  elements of array are
  empty


