p - charme interpreter An interpreter for structured BASIC by Frans van Hoesel
|
| |
Naar mijn mening wellicht de meest welkome aanvulling van de Atom Basic. Frans van Hoesel heeft zich hiermee en met zijn real-time-clock Big-Benny voor de Atom een vaste plaats verworven in de Atom-kronieken. Zoekend naar teksten en onderwerpen voor de Atom kwam ik
Frans naam opnieuw tegen nu in een wel heel andere verband en niet minder spraakmakend. (H)
Inleiding
De nieuwe P-Charme interpreter is een zeer veelzijdige uitbreiding
van de normale ATOM interpreter en bevat een opvallend nuttige statements.
De P-Charme interpreter moet in een EPROM worden gezet die in de
plaats komt van IC24 in de ATOM.
De P-Charme interpreter is bijzonder geschikt voor het schrijven van
gestructureerde BASIC programma's en is zo opgezet dat de programma's haast
vanzelf beter leesbaar worden. Bovendien is P-Charme zo geschreven dat
uitbreidingen op alle nivo's mogelijk zijn. Zo kunnen er bv. hele lijsten
van extra "statements" in BASIC worden geprogrammeerd.
De in P-Charme opgenomen statements zijn onder andere geselecteerd op een
grote mate van systeem onafhankelijkheid. Wel moet in de ATOM een
floating-point ROM aanwezig zijn.
De handleiding bevat een alfabetische behandeling van de statements en
commando's. De procedures, functies, multi-dimensionale array's
staan in aparte hoofdstukken.
© F.v. Hoesel, Groningen.1984
Hieronder een verkorte Engelse versie van de handleiding. De volledige Nederlandse versie is conform de oorspronkelijke uitgave als scan beschikbaar.
Statements and functions
AUTO |
Automatic
line-numbering and indentation |
A. |
|
Examples:
AUTO - first line 10, each next one 10 higher.
AUTO 40 - first line 40, each next one 10 higher.
AUTO ,20 - first line 10, each next one 20 higher.
AUTO 100,100 - first line 100, each next one 100 higher.
|
|
BEEP |
Generate
sound |
BE. |
|
Emits a tone of a specific pitch and
duration. The syntax is:
BEEP <expr>,<expr>
|
|
BSAVE |
Basic
save |
BS. |
|
The command is the same as the normal
SAVE statement. The program, however, gets another
execution address (#AFAF inside the P-Charme). This
effectively makes it possible to *RUN basic programs,
that require stack, free space pointer etc. to be
initialized.
On the Atom Emulator, however, it only works if P-Charme
is selected. |
|
CASE |
Case
... Of |
CA. |
|
Examples:
10 CASE J-48 OF
20 2 PRINT "THIS IS EVEN"'
30 3 PRINT "THIS IS "
40 PRINT "ODD"'
50 1 PRINT "J = 49"'
60 CEND
10 CASE $A OF
20"SWEET" PRINT "NICE"'
30"BORING" PRINT "DULL"'
40$A PRINT "NO IDEA"'
50 CEND
If a case expression does not equal a case label,
program execution is resumed right behind CEND. In the
second example, the case label at line 40 always
satisfies, and is therefore executed if the others do
not. CASE statements may not be nested.
|
|
CAT |
Catalog |
|
|
This statement shows a list with all the
programs that are resident in the memory area #1000 to
#9FFFF, starting with <space>PROGRAM. |
|
CONT |
Continue |
|
|
May be used to resume program execution
after a STOP. |
|
COPY |
Copy
memory areas |
|
|
The syntax is as follows:
COPY expr, expr, expr
The first expression is the start address, the second
is the end address of the area that is to be copied. The
last expression is the destination memory address. If
this one is within the boundaries of the source area, the
COPY statement effectively is a FILL command. For example
COPY #2000,#3000,#2004
The result of this command is the the area between
32000 and 33004 repeatedly contains the same four bytes.
|
|
COS |
Casette
operation system |
|
|
Example:
COS 0 - 300 baud
COS 1 - 1200 baud
|
|
DATA |
|
|
|
See READ and RESTORE. |
|
DEL |
Delete
line |
|
|
Examples:
DEL 200,300 - Delete lines 200 to 300.
DEL /REM/,300L - Lines 0 to 300, containing the text 'REM'.
DEL /STOP/V - All lines that contain the text 'STOP'.
DEL - Delete all lines (be careful!).
If the Veto option (V) is selected, a line is printed
on screen first and a query will be made Y/N? There are
several possible answers:
Y - YES proceed with the operation,
N - NO do not execute the operation,
C - CONTINUE proceed with the operation and disable the veto option,
L - LIST execute the operation and go on without the veto
option, however, do list all the lines that are changed,
S - SKIP do not execute the operation and go on to the next line,
ESC do not proceed with the operation and go back to direct mode.
|
|
ELSE |
|
|
|
This is the alternative for the XIF
statement.
The line behind ELSE is executed only if the expression
behind XIF is false. |
|
EVEN |
|
EV. |
|
This function has the value TRUE (1) if
the argument is even. Syntax is:
EVEN (factor)
|
|
FALSE |
|
FA. |
|
Always results in the value 0. 'A=0' and
'A=FALSE' are completely equal. |
|
FEND |
Function
end |
|
|
This statement delimits the end of a
FUNCTION block. |
|
FUNCTION |
Function
declaration |
FUNC. |
|
Function can be used to calculate one
value, which on its turn is to be used in an expression.
Functions begin with the FUNCTION statement and end with
the FEND statement. Example:
10 PROGRAM FTEST
20
30 FUNCTION ADD(A,B)
40 ADD=A+B
50 FEND
60
70 PRINT 2*ADD(5,6)
80 END
Recursive functions are allowed as well:
FUNCTION GCD(M,N)
XIF N=0 THEN GCD=M
ELSE GCD=GCD(N,M%N)
FEND
It is NOT allowed to used DIM inside functions and
procedures.
|
|
HEX |
Hexadecimal
/ ASCII dump |
|
|
Hexdump is started from the specified
address. The syntax is:
HEX <expr>
|
|
HTAB |
Horizontal
tabulation |
HT. |
|
This statement is especially useful when
creating tables. Example:
HTAB 16
|
|
ICOPY |
Intelligent
copy |
IC. |
|
This is almost the same as the COPY
statement. However, the fill effect cannot occur with
this statement. |
|
INKEY |
Input
key |
INK. |
|
The INKEY statement waits until a key is
pressed, and then assigns an ASCII value to the specified
variable. Example:
DO
INKEY A
PRINT $A
UNTIL A=CH"."
|
|
INSTR |
In
string |
I. |
|
With this integer function a string can
be saught in another string. The syntax is:
INSTR (string var,string right)
The brackets ( and ) are obligatory. The functions
starts seaching in the first string for the second
string. If found, INSTR is assigned the value of the
position, otherwise it's zero.
INSTR may also be used in a logical expression. Examples:
P=INSTR($A,"HALLO")
R=INSTR($B+6,$C); REM search from 6th position in $B onwards.
IF INSTR($D,$E) THEN PRINT "FOUND"'
|
|
KEY |
Single
keyboard scanner |
K. |
|
The keyboard is scanned through once and
an ASCII value is assigned to the specified variable. |
|
NOT |
|
N. |
|
This function equals a logical negation.
The values of NOT are exclusively FALSE or TRUE (0 or 1). |
|
ODD |
|
O. |
|
This function has the value TRUE (1) if
the argument is odd. Syntaxis:ODD (factor)
|
|
ON
ERROR |
|
O. |
|
For trapping BASIC errors. |
|
ON
... GOSUB |
Gosub
selector. |
|
|
This statement is used to choose from a
number of possibilities. Example:
10 INPUT S
20 ON S GOSUB 100,110,50,a,70
30 PRINT"*"'
40 GOTO 10
50 PRINT "THREE";RETURN
70 PRINT "FIVE";RETURN
80aPRINT "FOUR";RETURN
100 PRINT "ONE";RETURN
110 PRINT "TWO";RETURN
|
|
ON
... GOTO |
|
|
|
This statement is the same as ON ...
GOSUB, except for the fact that GOSUB is replaced by
GOTO. |
|
PAUSE |
Delay
program execution |
PA. |
|
PAUSE is followed by an expression. PAUSE
60 waits for one second. |
|
PEND |
Procedure
end |
|
|
This statement delimits the end of a PROC
block. |
|
POP |
|
|
|
This statement gets one return address
from the GOSUB stack. It cannot cause an error. |
|
PROC |
Procedure
declaration |
|
|
Within a procedure there are three types
of variables:
-Local variables
-Value parameters
-Output variablesExamples:
10 PROGRAM EXAMPLE
20
30 PROC FIX-PRINT (%A),Z,@
40 Z=%(%A*1000+5)/10;PRINT Z/100
50 @=0;Z=Z%100
60 PRINT "."Z/10,Z%10
70 PEND
80
90 @=11
100 FOR I=1 TO 5
110 READ %F
120 FPRINT %F;FIX-PRINT(%F)
130 PRINT'
140 NEXT I
150 END
160
170 DATA 10,1/3,2/3,10.9999,0
Herein %A is a value parameter. Z and @ are local
variables.
10 PROGRAM EXTREME
20
30 PROC MINMAX (A,B:G,S)
40 XIF A>B THEN G=A
50 ELSE G=B
60 XIF A <B THEN S=A
70 ELSE S=B
80 PEND
90
100 MINMAX(3,7,X,Y);PRINT X,Y'
110 A=1;B=2;G=3;K=4
120 MINMAX(G,12,X,Y);PRINT X,Y'
130 PRINT A,B,G,K'
140 END
Herein A and B are value parameters. G and S are ouput
variables.
The output of the program is:
7 3
12 3
1 2 3 4
Recursion is allowed as well. Example:
PROC STAR(N)
IF N>1 PRINT "*";STAR(N-1)
IF N=1 PRINT "*"
PEND
It is NOT allowed to used DIM inside functions and
procedures.
|
|
PROGRAM |
Program
heading |
|
|
Behind this statement there is room for a
name. The rest of the line is regarded as comment.
Besides giving a name to a program, the following
features are supported:
- Automatical RESTORE at the start of the program,
- Initialization of procedures and functions,
- Initialization of built-in functions (INSTR, EVEN
etc),
- Initialization of error pointer routines,
- Initialization of multi-dimensional arrays,
- Initialization of WHILE loops,
- Recognition for the CAT statement.
Item 2 effectively fills the area #28DD-#28FF with
#00. This area is NOT used by the floating point ROM. For
Item 3, 4 and 5 the BRKVEC is changed for the duration of
the program. A correct program name begins with two
different characters. Here are some examples:
10 PROGRAM TEST VERSIE IV - the name here is 'TEST'
10 PROGRAM CRC-TEST - the name here is 'CRC-TEST'
10 PROGRAM QS(QUICK START) - the name here is 'QS'
10 PROGRAM -A Anemometer - the name here is '-A'
If the program is resident in the memory area
#1000-#9FFF and if there's one space between the NOT
abreviated statement PROGRAM and the line number the
program name is automatically promoted to a statement.
Typing a program name results in searching the memory
for that program, initializing the labels, clearing the
FOR-NEXT, DO-UNTIL and GOSUB-stacks, setting the value of
TOP and starting the program.
|
|
READ |
Read
data |
|
|
With the READ statement integer, floating
point variables, arrays and multi-dimensional arrays, and
string variables can be read. Example:
READ A,B,%A,%B,$T,DD(12),%FF(3,4)
|
|
RENUM |
Renumber
program |
REN. |
|
This command renumbers the program
according to the specified expressions. |
|
RESTORE |
Restore
data |
RES. |
|
With this statement the data-pointer can
be set to a specific line. Examples:
RESTORE
RESTORE 160
RESTORE a
|
|
STOP |
Stop
execution |
|
|
This statement is ment for trapping
errors.
If a program is stopped, the text 'STOPPED AT LINE ...'
is printed.
Execution can be resumed by typing CONT. |
|
TRUE |
|
TR. |
|
Always results in the value 1. 'A=1' and
'A=TRUE' are completely equal. |
|
VAR |
Variable
dump |
|
|
This statement shows the values of the
variables A to Z. |
|
VTAB |
Vertical
tabulation |
V. |
|
The syntax for this stament is:
VTAB <expr>
|
|
WEND |
End
of WHILE loop |
|
|
This statement delimits the end of the
WHILE loop. |
|
WHILE |
WHILE
loop |
|
|
A WHILE block is executed until the
expression behind WHILE is FALSE.
The WHILE statement can be nested up to 10 levels deep. |
|
XIF |
Expanded
IF |
|
|
The XIF statement must be used together
with ELSE.
If the expression behind XIF is TRUE, the block behind it
is executed and the line behind ELSE not. And vice versa,
if the expression behind XIF is FALSE.
The ELSE statement may not be abreviated and must be at
the beginning of a line.XIF...THEN...ELSE
constructions may be nested unlimited. Example:
10 XIF A+9=B-2 THEN I=1
20 Z=S?I
30 S?I=S?J
40 XIF %X=PI THEN PRINT '"PI="
60 PRINT "3.1415"'
70 ELSE PRINT'"NO PI"'
80 ELSE I=2
90 PRINT I'
Note that the THEN part may be spread over more than
one line,
and the ELSE part can take no more than one line.
|
|
ZERO |
Clear
variables |
Z. |
|
Fills the BASIC variables A to Z with the
value 0. |
|
/ |
Find
text |
|
|
With the FIND command a certain text can
be sought in a program.
Line numbers are not a part of the text. Examples:
/REM/ - searches for the text 'REM' in the entire program,
/STOP/200, - searches 'STOP' from line 200 onwards,
/$A/,1000 - searches '$A' until line 1000.
/ Change text
With this command text can be sought and replaced.
Examples:
/A$/$A/ - replace 'A$' by '$A',
/STEP -1/STEP 1/V - replace 'STEP -1' by 'STEP 1' with veto,
/ //L - remove all spaces with the list option
/DIM/FDIM/,100V - replace 'DIM' by 'FDIM' in the lines 0 to 100 with
the veto option.
|
|
Multi-dimensional arrays
With P-Charme it is possible to use multi-dimensional arrays.
Example:
10 PROGRAM ARRAY
20
30 DIM TT(5,4,2)
40 A=0
50 FOR I=0 TO 5
60 FOR J=0 TO 4
70 FOR K=0 TO 2
80 TT(I,J,K)=A
90 A=A+1
100 NEXT K
110 NEXT J
120 NEXT I
130 PRINT TT(1,1,2)'
140 END
All indices are checked. If, for example, line 130 is changed
into
130 PRINT TT(1,5,2)'
error 134 (Array subscript out of range) is generated.
Multi-dimensional arrays can only be used in programs, and only
if it begins with the PROGRAM header. If you would like to know
the value of TT(5,3,1) in direct mode, the following must be
entered:
PRINT TT((5*(4+1)+3)*(2+1)+1)
Herein (4+1) is one more than the second dimension and (2+1)
is one more than the third dimension of the array TT. A statement
like DIM SS(7) has (7+1) elements also.
Multi-dimensional floating point arrays are possible as well.
Note that brackets ( and ) are obligatory. The maximum number
of dimensions is 9.
String functions
With exception of INSTR, no new string-handling functions have
been added.
The following examples, however, show that it is very easy to
implement them yourself:
FUNCTION LEFT(S,L)
IF L<1 OR LEN(S)>64 THEN ERROR
$#140=$S;L?#141=13
LEFT=#140
FEND
FUNCTION RIGHT(S,L)
IF L<1 OR LEN(S)>64 THEN ERROR
$#140=$S;IF L<LEN(S) $#140="$S+LEN*(S)-L" RIGHT="#140"
FEND
FUNCTION MID(S,L,M) IF L<="1" OR M<="1" OR LEN(S)>64 THEN ERROR
?#140=13;IF L<=LEN(S) $#140="$S+L-1;M?#140=13" MID="#140"
FEND
Since the word ERROR is not a statement, the interpreter will
produce error 94 on an attempt to interpret ERROR. Note that,
although functions (and procedures) don't "know" string
variables it is very well possible to handle strings by passing
the string's address. If the strings are no longer than 64
characters, the string buffer at #140 can safely be used. For
longer strings, a buffer must be dimensioned first outside the
functions. Example: $S="THIS IS A STRING" PRINT
$LEFT(S,6) THIS IS PRINT $RIGHT(S,10) S A STRING PRINT
$MID(S,2,6) HIS IS
Expanding the P-Charme interpreter
There arethree ways to expand the interpreter. The first one is the
easiest and most obvious way: Just writing it in BASIC. See the
PROGRAM statement. Example:
10 PROGRAM HELP 20
30 DIM S64 40 $S="$#100"
50 K="INSTR(S,"HELP")"
60 IF K="0" THEN PRINT '"SORRY, NO HELP."';GOTO e
70 E="VAL(#100+K+3)"
80 CASE E OF 90<2> PRINT "TOO MANY GOSUBS"
100<6> PRINT "CHECKSUM ERROR"
110<18> PRINT "TOO MANY DO STATEMENTS"
120<29> PRINT "UNKNOWN OR MISSING FUNCTION"
130 REM etc.
140 CEND
150 PRINT '
160e?18=#29
170 END
Try typing
HELP 29
The second way offers a lot more possibilities, but require
more skill. It must be written in machine code and is preceded by
a table. A table must always start on a new page (low byte #00).
The P-Charme interpreter will check the table if the second byte
on the page equals #E3 and the third byte equals #C6. It is wise
to put #FF in the first byte. The rest of the table is followed
by subsequently the name of a statement and its address. The high
byte of the address comes first, and the MSB is always set. This
results is address which are always higher than or equal to
#8000.
If, however, the table is in the memory area lower than #8000,
the P-Charme interpreter substracts #8000 from the address.
The table must be ended with a byte equal to #80. The table
may not be larger than 256 bytes. Example:
3B00 FF (page extension byte)
3B01 E3
3B02 C6
3B03 43 C
3B04 4C L
3B05 53 S
3B06 BB (=3B+80)
3B07 10
3B08 53 S
3B09 54 T
3B0A 41 A
3B0B 52 R
3B0C BB (=3B+80)
3B0D 19
3B0E 80 (end of table)
CLS 3B10 JSR C4E4
3B13 JSR FD6D
3B16 JMP C55B
STAR 3B19 JSR C4E1
3B1C LDX 04
3B1E DEX
3B1F STX 04
3B21 LDA 16,X
3B23 TAY
3B24 LDA @2A
3B26 JSR FFF4
3B29 DEY
3B2A BNE 3B26
3B2C JMP C55B
To tell the interpreter where the table is, the page number
must be POKEd into memory address #3FE (here it is #3B). It is
possible to use more than one table. The first byte in a table
(the page extension byte) must point to the following page. The
page extenstion byte of the last table should be #FF.
Please note the following:
- Almost all the statements end with JMP #C55B
- Statements without parameters always begin with JSR #C4E4
to test whether or not the statement is followed by ';'
or CR.
- Statements with one expression as parameter, begin with
JSR #C4E1.
The expression is read, and then the routine at #C4E4 is
done.
The third way to expand the P-Charme is somewhat difficult.
During program execution, the P-Charme interpreter uses the
BRK-vector. If during program execution an error occurs and
memory address #3FB contains the value #B3 and memory address
#3EE is zero, the instruction
JMP (#03EE)
is executed. This test is done before the built-in functions
and multi-dimensional arrays are handled.
This last method is for experienced programmers only.
Error messages
22 |
Out of data. A read is being commited
when there are no more DATA lines. |
38 |
Stack error in PROC or FUNCTION block.
The control byte, stored during the call of the procedure
or function in the free space, has changed on executing
PEND or FEND. This could have been caused by a DIM
statement within a procedure or function. |
84 |
Illegal function |
120 |
'(' expected |
129 |
Division by zero; Missing CEND;
Protected RAM |
132 |
WEND without WHILE |
133 |
Variable expected after KEY or INKEY |
135 |
Out of memory; SYNtax error
Not enough memory to execute a function or procedure.
SYNtax error in the COS statement. |
137 |
Error in parameterlist; paremeter
expression too complicated. |
163 |
Illegal or too many names |
166 |
Missing PEND or FEND |
182 |
Line not found in RESTORE |
200 |
Malformed string. An odd number of
quotes was used, or a '/' is missing. |
210 |
Missing CEND |
222 |
Variable expected |
237 |
Can't continue; Illegal STOP in direct
mode |
242 |
Too many WHILE statements |
249 |
Missing WEND, missing ELSE |
Memory usage
The P-Charme interpreter only uses zero page addresses
#90-#99.
The memory area #28BD-#28FF is used to keep the addresses of
functions and procedures.
|