SPL

The next step in developing the complete compiler is to define the language that it will compile. The language designed for this purpose is called SPL - Simple Programming Language. In some respects it is a subset of the popular languages Pascal and Algol, but with the restriction that numbers are limited to the range 0 to 255, and that the language includes only the essential types of statement.

Syntax of SPL

Programs in SPL are written as lines of text; the line numbers have no significance, except when editing. Spaces must be used to separate words, and must not occur within words, but otherwise they are ignored and can be added to make the structure of programs clearer.

Symbols

All variable names, array names, procedure names, and labqls, can consist of up to six letters, all of which are significant. None of the language words may be used as symbols. On the BBC Computer all symbols and language words are in lower case; however, on the Atom, and in the following examples, upper case is used.

Comments

Any text between brackets '{' and '}' is ignored by the compiler, and can be inserted, to comment SPL programs, anywhere spaces are permitted.

Programs

Programs normally consist of a procedure such as the following:

PROC MAIN();
BEGIN
   stmt;
   stmt;
   ...
   stmt
END

where 'stmt' represents any of the statements described below. The statements in the body of the procedure between BEGIN and END are separated by semi-colons.

SPL Statements

SPL contains the following statements:

Array Declaration

Arrays are declared with the ARRAY statement. For example:

ARRAY MAX[3],B[2]

reserves space for arrays with elements:

MAX[0], MAX[1], MAX[2], MAX[3], and B[0], B[1], and B[2].

These array elements can then be used is tha same way as simple variables. Arrays can have up to 255 elements, and there is no checking that arrays are within bounds.

Procedure Declaration

Any number of procedures, with one parameter, can be declared. For example:

PROC ADD(X); statement

and the procedure is called by:

ADD(expression)

The parameter is a local parameter; i.e. the use of X in the procedure ADD above does not affect the value of X outside the procedure. Thus, in the following example:

PROC INC(X); X=X+1
ENTER: WRHEX(X); INC(X); WRHEX(X)

the two calls to WRHEX, which print the value of X, both print the same value.

The single parameter is optional; thus a procedure can be defined:

PROC INC(); J=J+1

which alters the value of J outside the procedure. Note that a procedure cannot be declared inside another procedure which has a parameter.

Function Declaration

A function is identical to a procedure, except that its last statement is a RETURN statement specifying the result to be returned. For example:

PROC ADDONE(N); RETURN N+1

defines a function ADDONE whose value is one greater than its argument. Thus:

WRHEX(2+ADDONE(3))

would print '06'.

Assignment

The assignment statement is of the form:

variable = expression

where the variable is an identifier or an array element. For example:

TIME=TIME+1
SYMBOL[RDCH()]=A-3

Operators

Expressions can use any of the following operations, which work on 8 bit numbers:

+  : add             -  : subtract
&  : logical AND     |  : logical OR
>> : right shift     << : left shift

All these operators have the same priority, and brackets can be used to alter the order of evaluation. The shift operators shift the left-hand operand the number of places specified by the right-hand operand, which must be a constant as in:

A=B>>3     (equivalent to A=B/8)
A=B<<4     (equivalent to A=B*16)

GOTO Statement

Any statement can be prefixed by a label:

LOOP: A=A+1

A jump can be made to the labelled statement by means of the GOTO statement, as in:

GOTO LOOP

IF Statements

The IF statement has the form:

IF condition THEN statement

in which the statement is only executed if the condition is true. There may also be an ELSE clause:

IF condition THEN statement ELSE statement

in which case the second statement will only be executed if the condition is false.
Note that if one of the statements is itself an IF...THEN...ELSE statement the ELSE statement associates with the nearest IF condition.
For example:

IF A=1 THEN
IF A>0 THEN WRHEX(1)
ELSE WRHEX(2)

will, if A=2, write nothing.

Conditions

The condition in an IF statement is of the form:

expression comparison expression

where the comparison is one of:

> : greater than    <= : less than or equal
< : less than       >= : greater than or equal
= : equal           <> : not equal

BEGIN...END Block

Any number of statements can be grouped together within a BEGIN...END block, which has the format:

BEGIN
   statement;
   statement;
   ...
   statement
END

The entire block then has the same status as a single statement. Note that the semi-colons are used as statement separators, not as statement terminators, and so there is no need for a semi-colon before the END statement.

Pre-defined Symbols

The following symbols are defined in both versions of the compiler:

Symbol   Operation                        Example
RDCH     Function to read a character     A=RDCH()-48 
WRCH     Procedure to write a character   WRCH(32)
SCREEN   Array of 256 screen locations    SCREEN[0]=0

In addition, in the Atom version, the following symbols are defined:

Symbol   Operation                        Example 
WRHEX    Procedure to print in hex        WRHEX(255) 
PORT     Array of I/0 ports               PORT[2)=4

SPL Syntax Diagrams

A more formal definition of the syntax of a language like SPL can be given using 'bead' diagrams as shown below. The diagrams can be used to work out whether a given program is legal in terms of the language. Each construct, such as 'expr:', is defined by travelling along the line to its right, following the arrows. Constructs in square brackets, such as [stmt], are defined by referring to another diagram. Constructs in round brackets, such as (ARRAY) or (:), refer to keywords or symbols in the language. The language is defined recursively, so certain constructs, such as 'stmt:', contain references to themselves.