EOF# is only true if PTR# is set beyond the last byte written to the file. It will NOT be true if an attempt has been made to read from an empty block of a sparse random access file. Because of this, it is difficult to tell which records of a random access file have had data written to them. These files need to be initialised and the unused records marked as empty.
Writing to a byte beyond the current end of file updates the file length immediately, whether the record is physically written to the disk at that time or not. However, the file must be closed in order to ensure that all the data written to it is physically written to the disk.
<n-var>=EOF#(<numeric>)
OPENIN, OPENUP, OPENOUT, CLOSE#, PRINT#, INPUT#, BPUT#, EXT#, PTR#
You can use EOR as a logical operator or as a 'bit-by-bit' (bitwise) operator. The operands can be boolean (logical) or numeric.X=B EOR 4 IF A=2 EOR B=3 THEN 110
Unfortunately, BBC BASIC does not have true boolean variables; it uses numeric variables and assigns the value 0 for FALSE and -1 for TRUE. This can lead to confusion at times. (See NOT for more details.)
In the example below, the operands are boolean (logical) and the result of the tests (IF) A=2 and (IF) B=3 is either TRUE or FALSE.
The result of this example will be FALSE if A=2 and B=3 or A<>2 and B<>3. In other words, the answer will only be TRUE if the results of the two tests are different.
The brackets are not necessary, they have been included to make the example easier to follow.answer=(A=2 EOR B=3)
The last example uses EOR in a similar fashion to the numeric operators (+, -, etc).
Suppose X was -20, the EOR operation would be:A=X EOR 11
11111111 11111111 11111111 11101100 00000000 00000000 00000000 00001011 11111111 11111111 11111111 11100111 = -25
<n-var>=<numeric> EOR <numeric>
NOT, AND, OR
If there was an error in a procedure call, the line number of the calling line would be returned, not the line number of the definition.X=ERL
The number returned by ERL is the line number printed out when BBC BASIC (Z80) reports an error.
See the Error Handling sub-section for more information on error handling and correction.
<n-var>=ERL
ON ERROR GOTO, ON ERROR OFF, REPORT, ERR
Once you have assumed responsibility for error handling using the ON ERROR statement, you can use this function to discover which error occurred.X=ERR
See the Error Handling sub-section for more information on error handling and correction.
<n-var>=ERR
ON ERROR GOTO, ON ERROR OFF, ERL, REPORT
A statement which can 'force' an error to occur. This can be useful for testing or for adding 'user-defined' errors. ERROR is followed by the error number and the error string:
Unless errors are trapped using ON ERROR this will result in the message:200 ERROR 100,"Fault"
and ERR will be set to 100. User-defined errors should normally be given error numbers in the range 100 to 179 so that they don't conflict with the built-in error codes. However, if you specify an error number of zero BBC BASIC will treat it as a fatal error, i.e. it will not be trapped by the ON ERROR statement and will cause the program to end immediately.Fault at line 200
Note that the error string is held in a temporary buffer, which will be overwritten if an INPUT, CALL or READ statement is executed, or if BBC BASIC returns to immediate mode. This means you should be careful when accessing the error string using REPORT or REPORT$; if necessary copy it into a conventional string variable first.
ERROR is also used in the ON ERROR, ON ERROR LOCAL and RESTORE ERROR statements.
ERROR <numeric>,<string> ON ERROR <stmt>{:<stmt>} ON ERROR LOCAL <stmt>{:<stmt>} ON ERROR OFF RESTORE ERROR
ON ERROR, ON ERROR LOCAL, ERL, ERR, REPORT, RESTORE
EVAL |
EV. |
In effect, you pass the string to BBC BASIC (Z80)'s evaluation program and say 'work this out'.X=EVAL("X^Q+Y^P") X=EVAL"A$+B$" X$=EVAL(A$)
You can use this function to accept and evaluate an expression, such as a mathematical equation, whilst the program is running. You could, for instance, use it in a 'calculator' program to accept and evaluate the calculation you wished to perform. Another use would be in a graph plotting program to accept the mathematical equation you wished to plot.
The example below is a 'bare bones' calculator program which evaluates the expression typed in by the user.
You can only use EVAL to work out functions (like SIN, COS, etc). It won't execute statements like MODE 0, PRINT, etc.10 PRINT "This program evaluates the expression" 20 PRINT "you type in and prints the answer" 30 REPEAT 40 INPUT "Enter an expression" exp$ 50 IF exp$<>"END" PRINT EVAL exp$ 60 UNTIL exp$="END" 70 END
<n-var>=EVAL(<str>) <s-var>=EVAL(<str>)
STR$, VAL
EXIT |
EX. |
A statement which causes a premature exit from a FOR...NEXT, REPEAT...UNTIL or WHILE...ENDWHILE loop.
EXIT FOR causes execution to continue after the matching NEXT statement, EXIT REPEAT causes execution to continue after the matching UNTIL statement and EXIT WHILE causes execution to continue after the matching ENDWHILE statement. Typically you would use EXIT when a situation occurs which necessitates leaving the loop 'part way through':
In the case of EXIT FOR an optional loop variable can be specified, causing execution to continue after the NEXT statement which matches that variable:FOR I% = start% TO finish% ... IF bool% THEN EXIT FOR ... NEXT I% REPEAT ... IF bool% THEN EXIT REPEAT ... UNTIL condition% WHILE condition% ... IF bool% THEN EXIT WHILE ... ENDWHILE
You can EXIT from a loop even when inside a nested loop of a different kind:FOR I% = start% TO finish% FOR J% = first% TO last% ... IF bool% THEN EXIT FOR I% ... NEXT NEXT REM Execution continues here
EXIT is not compatible with the use of non-standard FOR...NEXT constructs such as 'popping' an inner loop or listing multiple loop variables after NEXT. When EXIT is used, every FOR must have a matching NEXT.REPEAT FOR J% = first% TO last% ... IF bool% THEN EXIT REPEAT ... NEXT UNTIL FALSE REM Execution continues here
EXIT FOR [<n-var>] EXIT REPEAT EXIT WHILE
FOR, REPEAT, WHILE
This function can be used as the 'anti-log' of a natural logarithm. Logarithms are 'traditionally' used for multiplication (by adding the logarithms) and division (by subtracting the logarithms). For example,Y=EXP(Z)
will calculate 2.5*2 by adding their natural logarithms and print the answer.10 log1=LN(2.5) 20 log2=LN(2) 30 log3=log1+log2 40 answer=EXP(log3) 50 PRINT answer
<n-var>=EXP(<numeric>)
LN, LOG
In the case of a sparse random-access file, the value returned is the complete file length from byte zero to the last byte written. This may well be greater than the actual amount of data on the disk, but it is the amount of disk space allocated to the file by CP/M-80.length=EXT#f_num
The file must have been opened before EXT# can be used to find its length.
<n-var>=EXT#(<numeric>)
OPENIN, OPENUP, OPENOUT, CLOSE#, PRINT#, INPUT#, BPUT#, BGET#, GET$#, PTR#, EOF#
FALSE |
FA. |
BBC BASIC (Z80) does not have true Boolean variables. Instead, numeric variables are used and their value is interpreted in a 'logical' manner.10 flag=FALSE 20 ... 150 IF flag ...
A value of zero is interpreted as FALSE and NOT FALSE (in other words, NOT 0) is interpreted as TRUE. In practice, any value other than zero is considered TRUE.
You can use FALSE in a REPEAT....UNTIL loop to make the loop repeat for ever. Consider the following example.
Since 'terminator' will never be zero, the result of the test 'terminator=0' will always be FALSE. Thus, the following example has the same effect as the previous one.10 terminator=10 20 REPEAT 30 PRINT "An endless loop" 40 UNTIL terminator=0
Similarly, since FALSE=0, the following example will also have the same effect, but its meaning is less clear.10 REPEAT 20 PRINT "An endless loop" 30 UNTIL FALSE
See the keyword AND for logical tests and their results.10 REPEAT 20 PRINT "An endless loop" 30 UNTIL 0
<n-var>=FALSE
TRUE, EOR, OR, AND, NOT
The operation may appear to fail if the graphics background colour is not available as a 'solid' colour, with the current display settings, and has therefore been approximated by 'dithering'.
FILL x,y is equivalent to PLOT 133,x,y
FILL BY x,y is equivalent to PLOT 129,x,y
FILL is also used with the CIRCLE, ELLIPSE and RECTANGLE statements to indicate that a filled (solid) shape should be drawn, or that a block move rather than a block copy is required.
FILL 400,400
FILL <numeric>,<numeric> FILL BY <numeric>,<numeric> CIRCLE FILL <numeric>,<numeric>,<numeric> ELLIPSE FILL <numeric>,<numeric>,<numeric>,<numeric> RECTANGLE FILL <numeric>,<numeric>,<numeric>,<numeric> [TO <numeric>,<numeric>]
BY, CIRCLE, ELLIPSE, GCOL, RECTANGLE
If there are spaces between the function name and the opening bracket of the parameter list (if any) they must be present both in the definition and the call. It's safer not to have spaces between the function name and the opening bracket.
A function may be defined with any number of parameters of any type, and may return (using =) a string or numeric result. It does not have to be defined before it is used.
A function definition is terminated by '=' used in the statement position.
The following examples show the '=' as part of a program line and at the start of a line. The first two examples are single line function definitions.
Functions are re-entrant and the parameters (arguments) are passed by value.DEF FN_mean(Q1,Q2,Q3,Q4)=(Q1+Q2+Q3+Q4)/4 DEF FN_fact(N) IF N<2 =1 ELSE =N*FN_fact(N-1) DEF FN_reverse(A$) LOCAL B$,Z% FOR Z%=1 TO LEN(A$) B$=MID$(A$,Z%,1)+B$ NEXT =B$
You can write single line, multi statement functions so long as you have a colon after the definition statement.
The following function sets the print control variable to the parameter passed and returns a null string. It may be used in a PRINT command to change the print control variable (@%) within a print list.
Functions have to return an answer, but the value returned by this function is a null string. Consequently, its only effect is to change the print control variable. Thus the PRINT statementDEF FN_pformat(N):@%=N:=""
will print X in G9z10 format and Y in F2z10 format. See the keyword PRINT for print format details.PRINT FN_pformat(&90A) X FN_pformat(&2020A) Y
<n-var>|<s-var>=FN<name>[(<exp>{,<exp>})] DEF FN<name>[([RETURN]<n-var>|<s-var>{,[RETURN]<n-var>|<s-var>})]
ENDPROC, DEF, LOCAL
FOR |
F. |
The FOR...NEXT loop is a way of repeating a section of program a set number of times. For example, the two programs below perform identically, but the second is easier to understand.FOR temperature%=0 TO 9 FOR A(2,3,1)=9 TO 1 STEP -0.3
You can GOTO anywhere within one FOR...NEXT loop, but not outside it. This means you can't exit the loop with a GOTO. You can force a premature end to the loop by setting the control variable to a value equal to or greater than the end value (assuming a positive STEP).10 start=4: end=20: step=2 20 counter=start 30 PRINT counter," ",counter^2 40 counter=counter+step 50 IF counter<=end THEN 30 60 ... 10 start=4: end=20: step=2 20 FOR counter=start TO end STEP step 30 PRINT counter," ",counter^2 40 NEXT 50 ...
It is not necessary to declare the loop variable as an integer type in order to take advantage of fast integer arithmetic. If it is an integer, then fast integer arithmetic is used automatically. See Annex E for an explanation of how BBC BASIC (Z80) recognises an integer value of a real variable.110 FOR I=1 TO 20 120 X=A^I 130 IF X>1000 THEN I=20: GOTO 150 140 PRINT I,X 150 NEXT
Any numeric assignable item may be used as the control variable. In particular, a byte variable (?X) may act as the control variable and only one byte of memory will be used. See the Indirection sub-section for details of the indirection operators.
Because a single stack is used, you cannot use a FOR...NEXT loop to set array elements to LOCAL in a procedure or function.FOR ?X=0 TO 16: PRINT ~?X: NEXT FOR !X=0 TO 16 STEP 4: PRINT ~!X: NEXT
FOR <n-var>=<numeric> TO <numeric> [STEP <numeric>]
TO, STEP, NEXT
GCOL |
GC. |
Not implemented in the generic CP/M version of BBC BASIC (Z80)
GCOL <numeric>,<numeric>
CLS, CLG, MODE, COLOUR, PLOT
GET and GET$ wait for a 'key' (character) to be present in the keyboard buffer and then return the ASCII number of the key (see Annex A) or a string containing the character of the key. If there are any characters in the keyboard buffer when a GET is issued, then a character will be returned immediately. See the keyword INKEY for a way of emptying the keyboard buffer before issuing a GET.N=GET N$=GET$
GET and GET$ do not echo the pressed key to the screen. If you want to display the character for the pressed key, you must PRINT it.
You can use GET and GET$ whenever you want your program to wait for a reply before continuing. For example, you may wish to display several screens of instructions and allow the user to decide when he has read each screen.
REM First screen of instructions CLS PRINT ....... PRINT ....... PRINT "Press any key to continue "; temp=GET REM Second screen of instructions CLS PRINT ....... etc
N=GET(X) :REM input from port X
GET$ may optionally be used with the qualifier BY (to specify how many bytes to read from the file, maximum 255) or TO (to specify the terminator character). These override the normal CR, LF or NUL terminators:A$=GET$#file_channel
The terminator character is specified as its ASCII code, for example to specify a comma terminator use TO 44, TO &2C or TO ASC(","). If you add &100 to the value (e.g. TO &12C) the specified terminator will be recognised in addition to (rather than instead of) the normal CR and LF terminators.dest$=GET$#file_channel BY bytecount% dest$=GET$#file_channel TO termchar%
If you add &8000 to the value (e.g. TO &802C) CR (carriage return) will be recognised as a terminator in addition to the specified character (in this example a comma). However LF will not be recognised as a terminator.
<n-var> = GET <s-var> = GET$ <n-var> = GET(<numeric>,<numeric>) <s-var> = GET$(<numeric>,<numeric>) <s-var> = GET$#<numeric> <s-var> = GET$#<numeric> BY <numeric> <s-var> = GET$#<numeric> TO <numeric>
INKEY, INKEY$, INPUT#, READ#, OPENIN, OPENOUT, OPENUP
The only limit placed on the depth of nesting is the room available for the stack.GOSUB 400 GOSUB (4*answer+6)
You may calculate the line number. However, if you do, the program should not be RENUMBERed. A calculated value must be placed in brackets.
Very often you need to use the same group of program instructions at several different places within your program. It is tedious and wasteful to repeat this group of instructions every time you wish to use them. You can separate this group of instructions into a small sub-program. This sub-program is called a subroutine. The subroutine can be 'called' by the main program every time it is needed by using the GOSUB statement. At the end of the subroutine, the RETURN statement causes the program to return to the statement after the GOSUB statement.
Subroutines are similar to PROCedures, but they are called by line number not by name. This can make the program difficult to read because you have no idea what the subroutine does until you have followed it through. You will probably find that PROCedures offer you all the facilities of subroutines and, by choosing their names carefully, you can make your programs much more readable.
GOSUB <l-num> GOSUB (<numeric>)
RETURN, ON, PROC
GOTO |
G. |
You may not GOTO a line which is outside the current FOR...NEXT, REPEAT...UNTIL or GOSUB loop.GOTO 100 GOTO (X*10)
If a calculated value is used, the program should not be RENUMBERed. A calculated value must be placed in brackets.
The GOTO statement makes BBC BASIC (Z80) jump to a specified line number rather than continuing with the next statement in the program.
You should use GOTO with care. Uninhibited use will make your programs almost impossible to understand (and hence, debug). If you use REPEAT....UNTIL and FOR....NEXT loops you will not need to use many GOTO statements.
GOTO <l-num> GOTO (<numeric>)
GOSUB, ON
HIMEM must not be changed within a subroutine, procedure, function, FOR...NEXT, REPEAT...UNTIL or GOSUB loop.
BBC BASIC (Z80) uses the computer's memory to store your program and the variables that your program uses. When BBC BASIC is first loaded and run it checks to find the highest memory address it can use. If this is in excess of &10000 bytes, HIMEM is set to &10000. Otherwise, HIMEM is set to the maximum available address.HIMEM=HIMEM-40
If you want to use a machine code subroutine or store some data for use by a CHAINed program, you can move HIMEM down. This protects the area above HIMEM from being overwritten by BBC BASIC (Z80). See the Assembler section and the keyword CHAIN for details.
If you want to change HIMEM, you should do so early in your program. Once it has been changed it will stay at its new value until set to another value. Thus, if you wish to load a machine code subroutine for use by several programs, you only have to change HIMEM and load the subroutine once.
USE WITH CARE.
HIMEM=<numeric> <n-var>=HIMEM
LOMEM, PAGE, TOP
The IF statement is the primary decision making statement. The testable condition (A<C, etc) is evaluated, and converted to an integer if necessary. If the value is non-zero the rest of the line (up to the ELSE clause if there is one) is executed. If the value is zero, the rest of the line is ignored, unless there is an ELSE clause in which case execution continues after the ELSE.IF length=5 THEN 110 IF A<C OR A>D GOTO 110 IF A>C AND C>=D THEN GOTO 110 ELSE PRINT "BBC" IF A>Q PRINT"IT IS GREATER":A=1:GOTO 120
The above examples will print "Under 21" if the value of 'age' is less than 21, and do nothing otherwise.IF age<21 THEN PRINT "Under 21" flag=age<21 IF flag THEN PRINT "Under 21"
The above examples will print "Under 21" if the value of 'age' is less than 21, and "21 or over" otherwise.IF age<21 THEN PRINT "Under 21" ELSE PRINT "21 or over" flag=age<21 IF flag THEN PRINT "Under 21" ELSE PRINT "21 or over"
The keyword THEN is optional in most examples of the single-line IF statement. The exceptions are when THEN is followed immediately by a destination line number, by a pseudo-variable (e.g. TIME) or by an end-of-function (=). However, THEN is mandatory for the multi-line IF statement.
A multi-line IF clause is begun by an IF statement which has the keyword THEN as the very last thing on the line (it cannot even be followed by a REMark). It is ended by an ENDIF statement, which must be the first thing on the line. If the integer numeric expression after IF is non-zero, the statements up to the ENDIF (or ELSE clause if present) are executed. If the expression evaluates to zero the statements after ELSE are executed, or if there is no ELSE clause execution continues after the ENDIF statement.IF length=5 THEN PRINT "length is 5" ELSE PRINT "length is not 5" ENDIF
There may be any number of lines between the IF ... THEN statement and the ENDIF statement. Multi-line IF ... ENDIF clauses may be nested.
You can cascade multiple IF ... ENDIF clauses to test a number of different alternatives:
but in this situation a CASE statement would be a better choice.IF x=3 THEN PRINT "x is 3" ELSE IF x=4 THEN PRINT "x is 4" ELSE IF x=5 THEN PRINT "x is 5" ELSE PRINT "x is not 3 or 4 or 5" ENDIF ENDIF ENDIF
IF <t-cond> [THEN <stmt>{:<stmt>}] [ELSE <stmt>{:<stmt>}] IF <t-cond> GOTO <l-num> [ELSE <l-num>] IF <t-cond> THEN <l-num> [ELSE <l-num>] IF <t-cond> THEN
THEN, ELSE, ENDIF
Since INKEY and INKEY$ remove characters from the keyboard buffer, one character will be returned every time an INKEY is issued. A single INKEY will return the first character and leave the rest in the keyboard buffer.key=INKEY(num) N=INKEY(0) N$=INKEY$(100)
You can use this function to wait for a specified time for a key to be pressed. A key can be pressed at any time before INKEY is used.
Pressed keys are stored in an input buffer. Since INKEY and INKEY$ get a character from the normal input stream, you may need to empty the input buffer before you use them. You can do this with the following program line.
The number in brackets is the number of 'ticks' (one hundredths of a second) which BBC BASIC (Z80) will wait for a key to be pressed. After this time, BBC BASIC (Z80) will give up and return -1 or a null string. The number of 'ticks' may have any value between 0 and 32767.REPEAT UNTIL INKEY(0)=-1
<n-var>=INKEY(<numeric>) <s-var>=INKEY$(<numeric>)
GET, GET$
If items are not immediately preceded by a printable prompt string (even if null) then a '?' will be printed as a prompt. If the variable is not separated from the prompt string by a comma, the '?' is not printed. In other words: no comma - no question mark.INPUT A,B,C,D$,"WHO ARE YOU",W$,"NAME"R$
Items A, B, C, D$ in the above example can have their answers returned on one to four lines, separate items being separated by commas. Extra items will be ignored.
Then WHO ARE YOU? is printed (the question mark comes from the comma) and W$ is input, then NAME is printed and R$ is input (no comma - no '? ').
When the <Enter> key is pressed to complete an entry, a new-line is generated. BBC BASIC has no facility for suppressing this new-line, but the TAB function can be used to reposition the cursor. For example,
will position the cursor at column 0 of line 5 and print the prompt Name ?. After the name has been entered the cursor will be positioned at column 20 on the same line and Age ? will be printed. When the age has been entered the cursor will move to the next line.INPUT TAB(0,5) "Name ? " N$,TAB(20,5) "Age ? " A
The statement
is exactly equivalent toINPUT A
Leading spaces will be removed from the input line, but not trailing spaces. If the input string is not completely numeric, it will make the best it can of what it is given. If the first character is not numeric, 0 will be returned. Neither of these two cases will produce an error indication. Consequently, your program will not abort back to the command mode if a bad number is input. You may use the EVAL function to convert a string input to a numeric and report an error if the string is not a proper number or you can include your own validation checks.INPUT A$: A=VAL(A$)
Strings in quoted form are taken as they are, with a possible error occurring for a missing closing quote.INPUT A$ A=EVAL(A$)
A semicolon following a prompt string is an acceptable alternative to a comma.
INPUT [TAB(X[,Y])][SPC(<numeric>)]['][<s-const>[,|;]] <n-var>|<s-var>{,<n-var>|<s-var>}
INPUT LINE, INPUT#, GET, INKEY
INPUT LINE A$
INPUT LINE[TAB(X[,Y])][SPC(<numeric>)]['][<s-const>[,|;]] <s-var>{,<s-var>}
INPUT
It is possible to read past the end-of-file without an error being reported. You should always include some form of check for the end of the file.INPUT #E,A,B,C,D$,E$,F$ INPUT #3,aux$
READ# can be used as an alternative to INPUT#.
See the Disk Files section for more details and numerous examples of the use of INPUT#.
INPUT #<numeric>,<n-var>|<s-var>{,<n-var>|<s-var>}
INPUT, OPENIN, OPENUP, OPENOUT, CLOSE#, PRINT#, BPUT#, BGET#, GET$#, EXT#, PTR#, EOF#
The first string is searched for any occurrence of the second string.
There must not be any spaces between INSTR and the opening bracket.
You can use this function for validation purposes. If you wished to test A$ to see if was one of the set 'FRED BERT JIM JOHN', you could use the following:X=INSTR(A$,B$) position=INSTR(word$,guess$) Y=INSTR(A$,B$,Z%) :REM START AT POSITION Z%
The character used to separate the items in the set must be excluded from the characters possible in A$. One way to do this is to make the separator an unusual character, say CHR$(127).set$="FRED BERT JIM JOHN" IF INSTR(set$,A$) PROC_valid ELSE PROC_invalid
z$=CHR$(127) set$="FRED"+z$+"BERT"+z$+"JIM"+z$+"JOHN"
<n-var>=INSTR(<str>,<str>[,<numeric>])
LEFT$, MID$, RIGHT$, LEN
This function converts a real number (one with a decimal part) to the nearest integer (whole number) less than the number supplied. Thus,X=INT(Y) INT(99.8) =99 INT(-12) =-12 INT(-12.1) =-13
gives 14, whereasINT(14.56)
gives -15.INT(-14.5)
<n-var>=INT<numeric>
None
(BBC BASIC version 5 or later only)
LEFT$ may also be used to the left of an equals sign to
change the leftmost part of a string whilst leaving the rest alone.
There must not be any spaces between LEFT$ and the opening bracket.
For example,newstring$=LEFT$(A$,num) A$=LEFT$(A$,2) A$=LEFT$(RIGHT$(A$,3),2) LEFT$(A$,3) = B$
would printname$="BBC BASIC" FOR i=3 TO 9 PRINT LEFT$(name$,i) NEXT END
LEFT$(A$,0) returns an empty string; LEFT$(A$,-1) returns the original string unmodified.BBC BBC BBC B BBC BA BBC BAS BBC BASI BBC BASIC
When using LEFT$ on the left of an equals sign, and the expression to the right of the equals sign evaluates to a string with fewer characters than the specified sub-string length, only that number of characters is changed. For example:
will set A$ equal to "ZZC BASIC". Although the sub-string length is set to three, only two characters are actually modified since that is the length of the string "ZZ".A$ = "BBC BASIC" LEFT$(A$,3) = "ZZ"
(BBC BASIC version 5 or later only)
LEFT$(A$) is shorthand for LEFT$(A$,LENA$-1),
in other words it returns or sets all but the last character of A$.
<s-var>=LEFT$(<string>[,<numeric>]) LEFT$(<s-var>[,<numeric>])=<string>
RIGHT$, MID$, LEN, INSTR
This function 'counts' the number of characters in a string. For example,X=LEN"fred" X=LENA$ X=LEN(A$+B$)
would set 'length' to 15 since the string consists of the 12 characters of BBC BASIC (Z80) followed by three spaces.length=LEN("BBC BASIC (Z80) ")
LEN is often used with a FOR....NEXT loop to 'work down' a string doing something with each letter in the string. For example, the following program looks at each character in a string and checks that it is a valid hexadecimal numeric character.
10 valid$="0123456789ABCDEF" 20 REPEAT 30 INPUT "Type in a HEX number" hex$ 40 flag=TRUE 50 FOR i=1 TO LEN(hex$) 60 IF INSTR(valid$,MID$(hex$,i,1))=0 flag=FALSE 80 NEXT 90 IF NOT flag THEN PRINT "Bad HEX" 100 UNTIL flag
<n-var>=LEN(<str>)
LEFT$, MID$, RIGHT$, INSTR
LET is not permitted in the assignment of the pseudo-variables LOMEM, HIMEM, PAGE, PTR# and TIME.
LET was mandatory in early versions of BASIC. Its use emphasised that when we write
we don't mean to state that X equals X+4 - it can't be, but rather 'let X become equal to what it was plus 4':X=X+4
Most modern versions of BASIC allow you to drop the 'LET' statement. However, if you are writing a program for a novice, the use of LET makes it more understandable.LET X=X+4
[LET] <var>=<exp>
None
A statement which draws a straight line between two points in the current graphics foreground colour. LINE is followed by the X and Y coordinates of the ends of the line.
This will draw a straight line from the point 100,200 to the point 300,400.LINE 100,200,300,400
LINE x1,y1,x2,y2 is equivalent to MOVE x1,y1 : DRAW x2,y2
The keyword LINE is also used in the INPUT LINE statement. LINE INPUT is synonymous with INPUT LINE.
LINE <numeric>,<numeric>,<numeric>,<numeric> LINE INPUT [TAB(X[,Y])][SPC(<numeric>)]['][<s-const>[,|;]] <s-var>{,<s-var>}
DRAW, INPUT, MOVE, PLOT
LIST |
L. |
A hyphen is an acceptable alternative to a comma.
LIST lists the entire program LIST ,111 lists up to line 111 LIST 111, lists from line 111 to the end LIST 111,222 lists lines 111 to 222 inclusive LIST 100 lists line 100 only
When using the normal screen output (*OPT 0), the listing may be paused by pressing the <Ctrl> and <Shift> keys together. You can also set the output to paged mode by typing ^N (VDU 14). In this mode, the screen output will halt at the end of each page until the <Shift> key is pressed. Paged mode may be turned off by typing ^O (VDU 15).
Escape will abort the listing.
You can cause the listing to be printed by pressing ^P. Printing can be stopped by pushing ^P a second time (it's a 'toggle' action).
LIST may be included within a program, but it will exit to the command mode on completion of the listing.
LIST LIST <n-const> LIST <n-const>, LIST ,<n-const> LIST <n-const>,<n-const>
LIST IF, LISTO, OLD, NEW
You can specify the range of line numbers to be listed in a similar manner to LIST. For example,LIST IF *FX LIST IF Please press <ENTER> to continue
Will list all the lines between 100 and 2500 which contain the keyword 'DEF'LIST 100,2500 IF DEF
Keywords are tokenised before the search begins. Consequently, you can use LIST IF to find lines with particular commands in them.
LIST IF is very useful for locating the lines in a program which define or use functions or procedures.LIST IF PROC LIST IF DEF
You cannot search for the 'left' form of those pseudo-variables which have two forms ( PTR#=, PAGE=, TIME=, TIME$=, LOMEM=, HIMEM=) because the 'right' form is assumed when the name is tokenised. Consequently,LIST IF *LOAD LIST IF DO YOU WANT TO PRINT THE RESULTS?
will find line 20 but not line 10 in the following program segmentLIST IF TIME
You cannot search for 'keywords' which are not tokenised in the context of the program. For example,10 TIME=20 20 now=TIME
will not list lines containingLIST IF LOAD
because LOAD is not tokenised in any of these lines.ZLOAD=1 PROCLOAD FNLOAD "LOAD" REM LOAD etc
The internal format of line numbers (GOTO 1000, for example) may spuriously match a search string of three characters or less.
LIST IF <string> LIST <n-const> IF <string> LIST <n-const>, IF <string> LIST ,<n-const> IF <string> LIST <n-const>,<n-const> IF <string>
LIST, OLD, NEW
The default setting of LISTO is 7. This will give a properly formatted listing. The indentation of the FOR..NEXT and REPEAT..UNTIL lines is done in the correct manner, in that the NEXT is aligned with the FOR and the REPEAT with the UNTIL.
will giveLISTO 7
at the other extreme10 A=20 20 TEST$="FRED" 30 FOR I=1 TO A 40 Z=2^I 50 PRINT I,Z 60 REPEAT 70 PRINT TEST$ 80 TEST$=LEFT$(TEST$,LEN(TEST$)-1) 90 UNTIL LEN(TEST$)=0 100 NEXT 110 END
will giveLISTO 0
and10A=20 20TEST$="FRED" 30FOR I=1 TO A 40Z=2^I 50PRINT I,Z 60REPEAT 70PRINT TEST$ 80TEST$=LEFT$(TEST$,LEN(TEST$)-1) 90UNTIL LEN(TEST$)=0 100NEXT 110END
will giveLISTO 2
10A=20 20TEST$="FRED" 30FOR I=1 TO A 40 Z=2^Z 50 PRINT I,Z 60 REPEAT 70 PRINT TEST$ 80 TEST$=LEFT$(TEST$,LEN(TEST$)-1) 90 UNTIL LEN(TEST$)=0 100NEXT 110END
LISTO <n-const>
LIST
This function gives the logarithm to the base 'e' of its argument. The 'natural' number, 'e', is approximately 2.71828183.X=LN(Y)
Logarithms are 'traditionally' used for multiplication (by adding the logarithms) and division (by subtracting the logarithms). For example,
will calculate 2.5*2 by adding their natural logarithms and print the answer.10 log1=LN(2.5) 20 log2=LN(2) 30 log3=log1+log2 40 answer=EXP(log3) 50 PRINT answer
<n-var>=LN<numeric>
LOG, EXP
LOAD |
LO. |
File names must conform to the standard CP/M-80 format. However, if no extension is given, .BBC is assumed. If no disk and/or path are given, the current disk and/or path are assumed. See the Operating System Interface section for a more detailed description of valid file names.LOAD "PROG1" LOAD A$
You use LOAD to bring a program in a disk file into memory. The keyword LOAD should be followed by the name of the program file. If the program file is in the current directory, only the file name needs to be given. If the program is not in the current directory, its full drive, path and file name must be specified. For example:
would load the program 'demo.bbc' from the directory 'bbcprogs' on drive a:.LOAD "a:\bbcprogs\demo"
LOAD <str>
SAVE, CHAIN
LOCAL saves the value(s) of the specified variable(s) on the stack, and initialises the variables to zero (in the case of numeric variables) or null (in the case of string variables). The original values are restored from the stack on exit from the function or procedure (i.e. at '=' or ENDPROC). The variables need not have been previously declared.
(BBC BASIC version 5 or later only)
An entire array may be made LOCAL, following which it is in an undimensioned
state. Before the local array can be used within the function or procedure it must be
dimensioned using a DIM statement. The new
dimensions can be the same as or different from those of a global array with the same name. LOCAL
arrays are allocated on the stack, and are freed when the function/procedure is exited.
If a function or a procedure is used recursively, the LOCAL variables will be preserved at each level of recursion.LOCAL A$,X,Y%,items()
LOCAL DATA saves the current DATA pointer on the stack (but leaves its value unchanged). When used inside a FOR...NEXT, REPEAT...UNTIL or WHILE...ENDWHILE loop, or inside a user-defined function, procedure or subroutine, the data pointer is automatically restored to its original value on exit. Otherwise it can be restored using the RESTORE DATA statement.
LOCAL DATA RESTORE +1 DATA "Here", "is", "some", "local", "data" READ A$, B$, C$, D$, E$ RESTORE DATA
LOCAL is also used in the ON ERROR LOCAL and DIM LOCAL statements.
LOCAL <n-var>|<s-var>|<array()>{,<n-var>|<s-var>|<array()>} LOCAL DATA
DEF, DIM, ENDPROC, FN, ON, PROC
This function calculates the common (base 10) logarithm of its argument. Inverse logarithms (anti-logs) can be calculated by raising 10 to the power of the logarithm. For example, if x=LOG(y) then y=10^x.X = LOG(Y)
Logarithms are 'traditionally' used for multiplication (by adding the logarithms) and division (by subtracting the logarithms). For example,
10 log1=LOG(2.5) 20 log2=LOG(2) 30 log3=log1+log2 40 answer=10^log3 50 PRINT answer
<n-var>=LOG<numeric>
LN, EXP
Normally, dynamic variables are stored in memory immediately after your program. (See the Annex entitled Format of Program and Variables in Memory.) You can change the address where BBC BASIC (Z80) starts to store these variables by changing LOMEM.LOMEM=LOMEM+100 PRINT ~LOMEM :REM The ~ makes it print in HEX.
USE WITH CARE. Changing LOMEM in the middle of a program causes BBC BASIC (Z80) to lose track of all the variables you are using.
LOMEM=<numeric> <n-var>=LOMEM
HIMEM, TOP, PAGE
CONTENTS |
CONTINUE |