Basic V Guide
~~~~~~~~~~~~~
Contents
~~~~~~~~
Introduction
History
Features
Constants
Variables
Keywords
Line Numbers
Operators
Assignment Operators
Indirection Operators
Array Operations
Built-in Functions
Pseudo Variables
Procedures and Functions
Error Handling
Issuing Commands to the Underlying Operating System
Statement Types
Statements
Commands
The Program Environment
Screen Output
VDU Commands
PLOT Codes
Basic Keywords, Commands and Functions
Introduction
~~~~~~~~~~~~
The following notes give a brief introduction to Basic V and to
the environment that the interpreter emulates. They describe the
entire language but not in any great detail; more attention is
given to features specific to this version of Basic. Useful
information can be found on the web site 'The BBC Lives!' where
scanned version of manuals such as the 'BBC Microcomputer User
Guide' can be found. The information in these manuals is not 100%
relevant to Basic V but they are good for background information
and many details of Basic II, the predecessor of (and to all
intents and purposes, a strict subset of) Basic V.
These notes describe the Basic language. The file 'use' contains
information on how to use the interpreter and on the features
and limitations of the different versions of the program.
History
~~~~~~~
At the start of the 1980s the British Broadcasting Corporation was
looking for a microcomputer to be used for their series 'The
Computer Programme'. The machine chosen became known as the 'BBC
Micro' and it was made by Acorn Computers. It was an extremely
potent and flexible little computer that some people still use to
this day. The dialect of Basic on it was called 'BBC Basic'. This
was an extended Basic that added such features as procedures and
multi-line functions. It was also one of the fastest Basic
interpreters available on an eight-bit computer. The interpreter
was well integrated with the rest of the machine: it was possible
to directly call operating system functions from Basic programs
and there was also a built-in assembler. If something could not be
done in Basic or was too slow it was possible to write the code in
assembler. Many programs were written that used a combination of
Basic and assembler. Compilers and interpreters for languages such
as BCPL, C and Pascal were written for the BBC Micro, but by far
the most popular language was Basic.
In 1987 Acorn brought out the Archimedes. This included a new
version of the BBC Basic interpreter that had many additional
features such as 'CASE' statements and multi-line 'IF' statements.
It kept its reputation for speed. This version of Basic was called
'Basic V' and it is the dialect of the language implemented by
this interpreter.
The operating system that ran on the Archimedes and the machines
that have succeeded it over the years is called 'RISC OS'. This
was designed and written by Acorn Computers.
Features
~~~~~~~~
The main features of Basic V are:
1) It is a structured Basic with a full range of statement
types such as WHILE and REPEAT loops, a block IF statement
and a CASE statement.
2) It has procedures and multi-line functions which can have
local variables and arrays.
3) It has 'indirection operators' which allow data structures to
be constructed and manipulated. Memory can be allocated from
the Basic heap that can be referenced using these operators.
(This is not to say that the dialect includes data structures
per se but they can be set up and used in a way that appears
to be reminiscent of BCPL.)
4) The Acorn-written interpreters include an assembler.
Programs can be written using a mix of Basic and assembler.
All the features of the Basic interpreter are available to
the assembler, so that, for example, functions written in
Basic are used as macros.
5) Speed: the interpreter is very fast.
Notation
~~~~~~~~
A few words on the notation used in these notes might be in
order.
In describing the syntax of statements, parts of the statement
are often put in angle brackets . The purpose of
this is to say what goes at that part of the statement, for
example:
GOSUB
This says that the keyword GOSUB is to be followed by a line
number if a GOSUB statement is used in the program. Another
example:
ON ERROR
This one says that in an 'ON ERROR' statement, the keywords
'ON ERROR' are followed by one or more Basic statements.
In some cases, parts of a statement are in square brackets,
for example:
IF THEN
[ ELSE ]
This means that that part of the statement is optional. In
the example, the '[ ELSE ]' part of the
statement can be omitted.
Constants
~~~~~~~~~
The interpreter supports five types of variable:
- Decimal integer
- Hexadecimal integer
- Binary integer
- Floating point
- String
Hexadecimal constants begin with a '&' and binary ones with a '%'.
Strings are enclosed in '"'. It is possible to embed a '"' is a
string by preceding it with another '"'. Examples:
&FFFF
&123456
%1001101
%1
"abcdefghij"
"klmnop""qrst"
Variables
~~~~~~~~~
The interpreter supports three main types:
Integer e.g. abc%
Floating point e.g. def
String e.g. ghi$
Integer variables are 32 bits wide. A variable is denoted as being
an integer by having a '%' at the end of the name.
Floating point variables are 64 bits wide. If a variable does
not have either a '%' or a '$' suffix then it is a floating
point variable.
String variables have a '$' suffix at the end of their name. They
can refer to strings that have a maximum length of 65,536
characters.
Note that it is possible for variables of different types to have
the same name, for example, 'abc%', 'abc' and 'abc$' can all exist
at the same time. The '%' and '$' are considered to be part of the
name. Similarly, it is possible to have arrays and simple
variables of the same name, for example:
abcd$ <-- String variable
abcd$() <-- String array
What happens is that the '(' is considered to be part of the name
of the array.
Variable names are case sensitive, so that 'abcd' and 'AbCd' are
different variables.
Basic V has two classes of variables, the normal dynamic variables
that are created when the program runs and a set of what are
called 'static' variables which comprises of the integer variables
A% to Z%. These variables are independent of any program in that
their valaues are not reset or changed when a program is loaded or
modified. They can, for example, be used to pass values from
one program to another.
Keywords
~~~~~~~~
Keywords are Basic's reserved words. They are split into two types
in this interpreter, Basic keywords and Basic commands. Examples
of the former are 'IF', 'ENDPROC' and 'WHILE'. Examples of
commands are 'LOAD', 'LIST' and 'NEW'. A complete list of keywords
is given at the end of these notes.
Basic keywords have to be in upper case. On the other hand,
commands can be given in either lower or upper case to make it
more convenient to type them in.
The interpreter tries to be clever with keywords. In general
keywords cannot be used as variable names but there are cases
where if a keyword is followed by a letter it is not identified as
a keyword, for example, 'COUNT' on its own is a keyword but
'COUNTER' can be used as a variable without any problems. The
keywords taht can are treated in this way are marked with a '*'
in the keyword list at the end of the notes.
Line Numbers
~~~~~~~~~~~~
Each line in a Basic program has a line number. This is used when
editing a program at the command line and in the program by such
statements as 'GOTO', 'GOSUB', 'ON GOTO', and 'RESTORE'. Basic V
is a structured Basic and line numbers are largely superfluous if
statement types such as these are not used. They are still needed
to identify the line on which an error was detected when a program
runs. Programs and libraries can be written without line numbers
using a text editor such as 'vi'. Line numbers will automatically
be added when the program is loaded. Similarly, programs can be
saved without line numbers, although the default is to include
them.
Line numbers are in the range 0 to 65279.
Operators
~~~~~~~~~
Basic V supports the usual range of operators. The following list
details what is available. The operators are given in priority
order, with operators of the same priority grouped together. From
highest to lowest priority they are:
^ Exponentiation
------------------
* Multiplication
/ Division
DIV Integer division
MOD Integer modulus
------------------
+ Addition and string concatenation
- Subtraction
------------------
= Equals
<> Not equals
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
<< Left shift
>> Arithmetic right shift
>>> Logical right shift
------------------
AND Logical AND
------------------
OR Logical OR
EOR Exclusive OR
There is a point to watch out for when using the comparison and
shift operators. It is not possible to chain these together in an
expression, for example:
abc% >> 2 <= 10
will give an error. The solution is to put brackets around the
first part of the expression thus:
(abc% >> 2) <= 10
This is a feature of Basic V.
Assignment Operators
~~~~~~~~~~~~~~~~~~~~
As well as using '=' for assignments in the normal way, Basic V
has two other assignment operators:
+=
-=
'+=' adds to the variable and '-='
subtracts it.
Examples:
abc% += 1
ghi(N%) -= count
xyz$ += "abcd"
table%!offset% -= X%
$(table%+name%) += "xyz"
Indirection Operators
~~~~~~~~~~~~~~~~~~~~~
These are equivalent to 'peek' and 'poke' in other versions of
Basic except that they are far more flexible and powerful.
Strictly speaking these are not proper operators but language
constructs.
There are two types of operator, unary and dyadic. The unary ones
are:
? Reference to a one byte integer
! Reference to a four byte integer
| Reference to a floating point value
$ Reference to a string
The dyadic operators are:
? Reference to a one byte integer
! Reference to a four byte integer
Note that there are not dyadic versions of '$' and '|'.
Unary operators can be followed by a variable, array reference or
an expression in parentheses. For dyadic operators, the item
before the operator must be a variable or array reference. A
variable, array reference or expression in parentheses follows the
operator.
Examples of unary operators:
$pointer%
!abc%
?(abc%+10)
$text%
$text% = "abc"
Examples of dyadic operators:
pointer%!offset%
abc%?next%
array%(N%)!field%
The operators all work in the same way. The value of the
expression after the operator (unary version) or of the variable
before the operator (dyadic version) is interpreted as an address.
The value after the operator in the dyadic version is a byte
offset from that address.
Indirection operators cannot be chained together, that is, they
cannot be used in an expression such as:
pointer%!offset%!field%
In general, indirection operators can be used in the same way and
places as normal variables and the two forms of reference can be
freely mixed.
Examples:
IF $text%="quit" THEN STOP
table%!offset% = table%!offset2
!(table%+offset%) = !(table%+offset2)
abc = |address+1.0
PROCabcd(!table%, table%!4)
FOR table%!8=1 TO 10: NEXT
The interpreter limits the range of addresses that can be read
from or written to using indirection operators to the Basic
workspace. It is not possible to access any location outside this
block of memory.
Indirection operators can be used to built up and manipulate data
structures. However they are not true data structures in the sense
of structs in a C program and there are no checks on the legality
of references (beyond ensuring that the addresses are in range).
It is possible for a program to allocate memory from the Basic
heap to be used used for data structures and accessed via the
indirection operators. A special form of the DIM statement is
used for this:
DIM table% 100
Strictly speaking this allocates a byte array with indexes 0 to
100. From a more practical point of view, it allocates a 101 byte
block of memory and puts its address in table%. This block can
then be manipulated using the indirection operators as desired,
for example:
$table%="an error message"
table%!0 = 0: table%!4 = 99
In fact, blocks of memory allocated this way can only be
referenced via indirection operators.
Array Operations
~~~~~~~~~~~~~~~~
The interpreter supports some arithmetic operations on entire
arrays. There are some restrictions: the arrays have to be the
same size (number of dimensions and size of each dimension) and of
exactly the same type. Also, general expressions involving arrays
are not allowed, nor is it possible to return an array as the
result from a function. What is allowed is as follows:
Assignment
----------
=
The contents of are copied to
=
All elements of array are set to
= , , ... ,
Each expression is evaluated and then assigned
to the x'th element of the array . There can be fewer
expressions than there are elements in the array, in which case
the remaining array elements are left unchanged.
+= , -=
Each element of is added to .
+= , -=
The expression is evaluated and the result added
to .
Examples:
abc%() = def%()
ghi$() = "test"
jkl() = 0.0, 1.1, 2.2, 3.3, FNxyz(4.4)
abc%() += def%()
jhl() -= PI
Addition and Subtraction
------------------------
= +
Add the corresponding elements of and and
store the result in the same element in .
= -
Subtract the elements in from the corresponding element
in array <2> and store the result in .
= +
= +
Add to each element of , storing the result
of each addition in the corresponding element of .
= -
= -
Subtract from each element of , storing the
result of each subtraction in the corresponding element of
.
Examples:
abc%() = def%() + ghi%()
jkl() = mno() - pqr()
aaa$() = bbb$() + "ccc" + FNddd(eee$)
abc%() = 1 - def%()
Multiplication and Division
---------------------------
= *
Multiply each element of by the corresponding element
in and store the result in .
= /
Divide each element of by the corresponding element
in and store the result in .
= DIV
Carry out an integer division of each element of by the
corresponding element in and store the result in
.
= MOD
Carry out an integer division of each element of by the
corresponding element in and store the remainder in
.
= *
= *
Multiply each element of by the value and
store the result in the corresponding element in .
= /
Divide each element of by the value and
store the result in the corresponding element in .
= /
Divide by each element of and store the
result in the corresponding element in .
= DIV
Carry out an integer division of each element of by the
value and store the result in the corresponding
element in .
= DIV
Carry out an integer division of by each element of
and store the result in the corresponding element in
.
= MOD
Carry out an integer division of each element of by the
value and store the remainder in the corresponding
element in .
= MOD
Carry out an integer division of by each element of
and store the remainder in the corresponding element in
.
Examples:
abc() = def() * ghi()
abc() = 10.0 * ghi()
jkl%() = mno%() MOD 100
abc() = 1 / abc()
Matrix Multiplication
---------------------
= .
Perform a matrix multiplication of and and
store the result in .
Note that '.' is used as the matrix multiplication operator.
Built-in Functions
~~~~~~~~~~~~~~~~~~
The interpreter has a fairly standard set of functions. One
feature of this dialect of Basic is that many of the functions
look like monadic operators, for example, a call to the 'LEN'
function can be written as 'LEN abc$' as well as 'LEN(abc$)'.
Function names can often be abbreviated when typing them at the
command line. The abbreviated version of the name is the first
few characters of the name followed by a dot, for example, the
'LE' is the abbreviated form of 'LEFT$('. The names are given
in full when the program is listed.
Following is a list of functions implemented and a summary of
their actions. More detailed information on the vast majority of
them can be found in the manuals on the 'The BBC Lives!' web site.
Entries marked with a '*' after the name are functions added in
this interpreter.
represents a simple expression that consists of just a
variable name, array reference or constant or a complete
expression in parentheses.
is a full expression. Sometimes this is written as
or to qualify the type
of expression, or abbreviated to to reduce clutter.
is a reference to a whole array.
ABS
Use: ABS
Returns the absolute value of the numeric value
ACS
Use: ACS
Returns the arccosine of the numeric value
ADVAL
Use: ADVAL
This is an unsupported function. Either use of it is
flagged as an error or it returns zero, depending on the
options used to start the interpreter.
ARGC *
Use: ARGC
Returns the number of parameters on the command line.
This will be zero if there are no parameters.
ARGV$ *
Use: ARGV$
Returns parameter number on the command line
as a string. ARGV$ 0 returns the name of the program.
ARGV$ 1 is the first parameter, ARGV$ 2 the second and
so forth. ARGV$ ARGC is the last parameter.
ASN
Use: ASN
Returns the arcsine of the numeric value
ATN
Use: ATN
Returns the arctan of the numeric value
BEAT
Use: BEAT
Returns information from the RISC OS sound system.
This function returns zero.
BGET
Use: BGET#
Returns the next byte from the file with handle
CHR$
Use: CHR$
Returns a string consisting of a single character with
ASCII code
COLOUR
Use: COLOUR(, ,
)
This takes the colour with the specified colour
components and returns a number that represents the
closest match to that colour in the current screen
mode. This value is for use with the 'COLOUR OF' and
'GCOL OF' statements. It has no meaning otherwise.
Example:
red = COLOUR(255, 0, 0): COLOUR OF red
COS
Use: COS
Returns the cosine of the numeric value
COUNT
Use: COUNT
Returns the number of characters printed on the current
line by PRINT.
DEG
Use: DEG
Converts the angle from radians to degrees.
DIM
Use: a) DIM()
b) DIM(, )
a) returns the number of dimensions in array .
b) returns the highest index of dimemsion of
array .
END
Use: END
Returns the address of the top of the Basic heap.
EOF
Use: EOF#
Returns TRUE if the file with handle is at end of
file.
ERL
Use: ERL
Returns the number of the line that contained the last error
encountered by the interpreter or zero if no error has been
seen.
ERR
Use: ERR
Returns the error number of the last error encountered by
the interpreter or zero.
EVAL
Use: EVAL
Evaluates the string as if it were an expression in
a statement in the program and returns the result.
EXP
Use: EXP
Returns the exponentional of the numeric value .
FALSE
Use: FALSE
The function returns the value corresponding to 'false' in
the interpreter (zero).
GET
Use: GET
Returns the next character pressed on the keyboard as a
number, waiting if there is not one available.
GET$
Use: a) GET$
b) GET$#
a) Returns the next character pressed on the keyboard as a
one character string, waiting if there is not one
available.
b) Returns the next line from the open file with handle
as a character string.
INKEY
Use: INKEY
If numeric value is greater than or equal to zero,
return the next character pressed on the keyboard as a number
but only wait for centiseconds. Return -1 if no key
pressed in that time.
If numeric value is -256, return a number that
identifies the operating system under which the program is
running. (See the 'use' guide for the values returned.)
If numeric factor is less than zero and greater
than -256, return TRUE if the key with RISC OS internal
key number is being pressed otherwise return FALSE.
INKEY$
Use: INKEY$
This is the same as INKEY but returns its result as a single
character string. In the case of a keyboard read with
timeout, an empty string is returned if the time limit
expires instead of -1.
INSTR(
Use: INSTR( , [, ])
Search string for the string returning the
index (starting from 1) of the start of in
if the string is found otherwise return zero. is
an option expression that gives a starting point in
at which to start looking for .
INT
Use: INT
Returns the integer part of number , rounding down
(towards minus infinity).
LEN
Use: LEN
Returns the length of string .
LISTO *
Use: LISTO
Returns the current LISTO setting.
LN
Use: LN
Return the natural log of number .
LOG
Use: LOG
Returns the base 10 log of number .
MOD Use: MOD
Returns the modulus (square root of the sum of the
squares) of numeric array .
MODE Use: MODE
Returns the number of the current RISC OS screen mode.
NOT
Use: NOT
Returns the logical negation (ones complement) of numeric
value .
OPENIN
Use: OPENIN
Opens the file named by the string for input and
returns its numeric handle or zero if it cannot be opened.
OPENOUT
Use: OPENOUT
Opens the file named by the string for output and
returns its numeric handle. If the file exists already its
length is reset to zero.
OPENUP
Use: OPENUP
Opens the file named by the string for both input
and output and returns its numeric handle.
PI
Use: PI
Returns the value PI.
POINT(
Use: POINT(,)
Returns the colour number of the point on the graphics
screen with graphics coordinates (, ).
POS
Use: POS
Returns the offset (from 0) of the text cursor from
the left-hand side of the screen.
QUIT
Use: QUIT
Returns TRUE if the interpreter was started with the
option '-quit', that is, the interpreter will be exited
from when the Basic program finishes running.
RAD
Use: RAD
Convert the angle given in degrees to radians.
REPORT$
Use: REPORT$
Returns the message for the last error encountered.
RND
Use: a) RND
b) RND()
c) RND(0)
d) RND(1)
e) RND()
a) Return a pseudo-random number in the range -2147483648
to 2147483647
b) Initialises the random number generator with seed value
.
c) Returns the last number generated by RND(1).
d) Returns a floating point number in the range 0 to 1.
e) Returns an integer number in the range 1 to .
SGN
Use: SGN
Returns -1 if the numeric value is less than
zero, zero if it is zero or 1 if it is greater than zero.
SIN
Use: SIN
Returns the sine of numeric value .
SQR
Use: SQR
Returns the square root of numeric value .
STR
Use: a) STR
b) STR~
a) Converts the numeric value to a decimal
string.
b) Converts the numeric value to a hexadecimal
string.
STRING$(
Use: STRING$( , )
Returns a string made from the string repeated
times.
SUM
Use: SUM
If is a numeric array it returns the sum of all of
the elements of the array. If is a string array it
returns a string made from all of the elements of
concatenated.
SUM LEN
Use: SUM LEN
Returns the total length of all of the strings in string
array .
TAN
Use: TAN
Returns the tangent of numeric value
TEMPO
Use: TEMPO
Unsupported RISC OS feature. The function returns zero or
generates an error depending on intepreter command line
options.
TINT
Use: TINT(,)
Returns the TINT value of the position with x and y
graphics coordinates and