1
-
-
-
-
-
-
-                       The BCPL Programming Manual
0                                  by
0                             M. Richards
-
-
-
-
-
-
-
-
0 The Computer Laboratory,
  University of Cambridge,
  Corn Exchange Street,
  Cambridge   CB2 3QG                              November 1974
1                        TABLE OF CONTENTS
-
 1.      INTRODUCTION
-2.      LANGUAGE DEFINITION
0        2.1     Program
0        2.2     Elements
0        2.3     Expressions
0                2.3.1   Addressing operators
                 2.3.2   Arithmetic operators
                 2.3.3   Relations
                 2.3.4   Shift operators
                 2.3.5   Logical operators
                 2.3.6   Conditional operator
                 2.3.7   Table
                 2.3.8   Constant expression
0        2.4     Section brackets
0        2.5     Commands
0                2.5.1   Assignment
                 2.5.2   Conditional commands
                 2.5.3   For command
                 2.5.4   Other repetitive commands
                 2.5.5   Resultis command and valof expression
                 2.5.6   Switchon command
                 2.5.7   Transfer of control
                 2.5.8   Compound command
                 2.5.9   Block
0        2.6     Declarations
0                2.6.1   Global
                 2.6.2   Manifest
                 2.6.3   Static
                 2.6.4   Dynamic
                 2.6.5   Vector
                 2.6.6   Function and routine
                 2.6.7   Label
                 2.6.8   Simultaneous declaration
0        2.7     Miscellaneous features
0                2.7.1   GET
                 2.7.2   Comments and spaces
                 2.7.3   Optional symbols and synonyms
-        2.8     The run-time library
0                2.8.1   Input-Output routines
                 2.8.2   Other useful subroutines
                 2.8.3   Library variables
-3.      USING BCPL ON THE 370
0        3.1     Compilation
0                3.1.1   Library declarations
                 3.1.2   Diagnostics
                 3.1.3   Compilation options
0        3.2     Execution
0                3.2.1   Loading
                 3.2.2   Execution faults
                 3.2.3   A complete job
0Appendix A      Basic symbols and synonyms
0Appendix B      The BCPL syntax
0Appendix C      The EBCDIC character code
0Appendix D      Common extensions
1                    1.    INTRODUCTION
-        BCPL is a programming language designed primarily for non-
 numerical applications such as compiler-writing and general systems
 programming.   It has been used successfully to implement compilers,
 interpreters, text editors, game playing programs and operating systems.
 The BCPL compiler is written in BCPL and runs on several machines
 including the IBM 370/165 at Cambridge.
0        Some of the distinguishing features of BCPL are:
0            The syntax is rich, allowing a variety of ways to write
             conditional branches, loops, and subroutine definitions.
             This allows one to write quite readable programs.
0            The basic data object is a word (32 bits on the 370) with no
             particular disposition as to type.   A word may be treated
             as a bit-pattern, a number, a subroutine entry or a label.
             Neither the compiler nor the run-time system makes any
             attempt to enforce type restrictions.   In this respect BCPL
             has both the flexibility and pitfalls of machine language.
0            Manipulation of pointers and vectors is simple and
             straightforward.
0            All subroutines may be called recursively.
0        This manual is not intended as a primer; the constructs of the
 language are presented with scant motivation and few examples.   To use
 BCPL effectively on the 370 one must have a good understanding of how
 the machine works and be familiar with its operating system.   To the
 experienced and disciplined programmer it is a powerful and useful
 language but there are few provisions for the protection of naive users.
0        The main body of this manual describes the official standard
 subset of BCPL which will be supported at most BCPL installations. Many
 of the larger installations provide extensions to the language and a
 summary of the extensions available on the 370 implementation can be
 found in Appendix D.   Users are strongly recommended to remain within
 the standard subset unless there are exceptionally strong reasons for
 not doing so.
1Acknowledgments
+_______________
0        The overall layout and organisation of this manual is based on a
 manual written by J.H. Morris of the University of California, Berkeley,
 which itself was based on a well-written memorandum by R.H. Canaday and
 D.M. Richie of Bell Telephone Laboratories.
0        The initial design and implementation of BCPL was done on CTSS
 at Project MAC in 1967 and since then the language has developed and
 been transferred to many machines around the world.
0        The machine code library was implemented for the 370 by J.K.M.
 Moody and many of the language extensions for the 370 were implemented
 with the assistance of H.C.M. Meekings.   Many of the extensions were
 first designed and implemented by J.L. Dawson.
0        The language design was strongly influenced by the author's
 experience with CPL.   This language is described by D.W. Barron et al
 in  "The Main Features of CPL",  The Computer Journal, Vol. 6, p.134.
1                    2.    LANGUAGE DEFINITION
-
 2.1     Program
+_______________
0        At the outermost level, a BCPL program consists of a sequence of
 declarations.   To understand the meaning of a program, it is necessary
 to understand the meaning of the more basic constructs of the language
 from which it is made.   We, therefore, choose to describe the language
 from the inside out starting with one of the most basic constructs,
 namely the 'element'.
-2.2     Elements
+________________
0        <element>  ::=  <identifier> | <number> |
                         TRUE | FALSE | ? |
                         <string constant> | <character constant>
0        An <identifier> consists of a sequence of letters, digits and
 underlines, the first character of which must be a letter.
0        A <number> is either an integer consisting of a sequence of
 decimal digits,  or an octal constant consisting of the symbol '#'
 followed by octal digits,  or a hexadecimal constant consisting of the
 character pair #X followed by hexadecimal digits.   The reserved words
 TRUE and FALSE denote -1 and 0 respectively (on a 2's complement
 machine) and are used to represent the two truth values.   The symbol
 '?' may be used anywhere in an expression when no specific value is
 required,  as in:
0               LET OP, A = ?, ?
-        A <string constant> consists of up to 255 characters enclosed in
 string quotes (").   The internal character set is EBCDIC (on the 370).
 The character " may be represented only by the pair *" and the character
 * can only be represented by the pair **.   Other characters may be
 represented as follows:
0        *N     is newline
         *C     is carriage return
         *T     is horizontal tab
         *S     is space
         *B     is backspace
         *P     is newpage
0       In a string the sequence
0        * <newline> [ <space> | <tab> ] *
0is skipped.   Thus, the string
0                "THIS STRING *
                 *CONTAINS NEWLINES*
                 * AND SPACES"
0is equivalent to
0                "THIS STRING CONTAINS NEWLINES AND SPACES"
0        The machine representation of a string is the address of the
 region of store where the length and characters of the string are
 packed.   The packing and unpacking of strings may be done using the
 machine dependent library routines PACKSTRING and UNPACKSTRING, and
 individual characters in a string can be accessed and updated using the
 library routines GETBYTE and PUTBYTE, see section 2.8.2.
0        A <character constant> consists of a single character enclosed
 in character quotes (').   The character ' can be represented in a
 character constant only by the pair *'.   Other escape conventions are
 the same as for a string constant.   A character constant is right
 justified in a word.   Thus 'A' = 193 (on the 370).
-2.3     Expressions
+___________________
0        Because an identifier has no type information associated with
 it, the type of an element (and hence an expression) is assumed to match
 the type required by its context.
0        All expressions are listed below.   E1, E2 and E3 represent
 arbitrary expressions except as noted in the descriptions which follow
 the list, and K0, K1 and K2 represent constant expressions (whose values
 can be determined at compile time, see section 2.3.8).
0Primary                 element
                         (E1)
0function call           E1()
                         E1(E2,E3,...)
0addressing              E1!E2             subscripting
                         @E1               address generaton
                         !E1               indirection
0arithmetic              E1 * E2
                         E1 / E2
                         E1 REM E2         integer remainder
                         E1 + E2
                         + E1
                         E1 - E2
                         - E1
0relational              E1 = E2
                         E1 ~= E2          not equal
                         E1 < E2
                         E1 <= E2
                         E1 > E2
                         E1 >= E2
0shift                   E1 << E2          left shift by E2(>=0) bits
                         E1 >> E2          right shift by E2(>=0) bits
0logical                 ~ E1              not (complement)
                         E1 & E2           and
                         E1 | E2           inclusive or
                         E1 EQV E2         bitwise equivalence
                         E1 NEQV E2        bitwise not-equivalence
                                              (exclusive or)
 conditional             E1 -> E2, E3
0table                   TABLE K0,K1,K2,...
0valof                   VALOF command
0        The relative binding power of the operators is as follows:
0 (highest, most binding)        function call
                                 !  (subscripting)
                                 @ !
                                 * / REM
                                 + -
                                 relationals
                                 shifts (see section 2.3.4)
                                 ~
                                 &
                                 |
                                 EQV  NEQV
                                 ->
                                 TABLE
  (lowest, least binding)        VALOF
0        Operators of equal binding power associate to the left.  For
 example,
                 X + Y - Z
 is equivalent to
                 (X + Y) - Z
0        In order that the rule allowing the omission of most semicolons
 should work properly, a diadic operator may not be the first symbol on a
 line.
0        The function call will be described with the function definition
 in section 2.6.6, and the valof expression will be described with the
 resultis command in section 2.5.5.
-2.3.1   Addressing operators
+        ____________________
0        A powerful pair of operators in BCPL are those which allow one
 to generate and use addresses.   An address may be manipulated using
 integer arithmetic and is indistinguishable from an integer until it is
 used in a context which requires an address.   If the value of a
 variable X is the address of a word in storage, then X+1 is the address
 of the next word.
0        If V is a variable, then associated with V is a single word of
 memory, which is called a cell.   The contents of the cell is called the
 value of V and the address of the cell is called the address of V.
0        An address may be used by applying the indirection operator (!).
 The expression
                 !E1
 has, as value, the contents of the cell whose address is the value of
 the expression E1.   Only the low-order 22 bits of E1 are used (on the
 370).
0        An address may be generated by means of the operator @.   The
 expression
                  @E1
 is only valid if E1 is one of the following:
0        (1)  An identifier (not declared by a manifest declaration),
              in which case @V is the address of V.
0        (2)  A subscripted expression, in which case the value of
              @E1!E2 is E1+E2.
0        (3)  An indirection expression, in which case the value of
              @!E1 is E1.
0Case (1) is self-explanatory.   Case (2) is a consequence of the way
 vectors are defined in BCPL.   A vector of size n is a set of n + 1
 contiguous words in memory, numbered 0, 1, 2, ..., n.   The vector is
 identified by the address of word 0.   If V is an identifier associated
 with a vector, then the value of V is the address of word 0 of the
 vector.
0                  -------              -------
               V  |   *---|----------> |       |  0
                   -------             |-------|
                                       |       |  1
                                       |-------|
                                       |       | ...
                                       |-------|
                                       |       |  n
                                        -------
0        The value of the expression
                 V!E1
 is the contents of cell number E1 of vector V, as one would expect. The
 address of this cell is the value of
                 V + E1
 hence
                 @(V!E1)  =  V + E1
 This relation is true whether or not the expression
                 V!E1
 happens to be valid, and whether or not V is an identifier.
0Case (3) is a consequence of the fact that the operators @ and ! are
 inverse.
0        The interpretation of
                 !E1
 depends on context as follows:
0        (1)  If it appears as the left-hand side of an assignment
              statement, e.g.
                 !E1 := E2
              E1 is evaluated to produce the address of a cell
              and E2 is stored in it
0        (2)  @(!E1) = E1  as noted above.
0        (3)  In any other context E1 is evaluated and the contents
              of that value, treated as an address, is taken.
0Thus, ! forces one more contents-taking than is normally demanded by the
 context.
0        As a summarising example, consider the four variables A, B, C
 and D with initial values @C, @D, 5 and 7, respectively.   Then, after
 the assignment
                 A := B
 their values will be @D, @D, 5, 7.
0If, instead, the assignment
                 A := !B
 had been executed, then the values would have been 7, @D, 5, 7.
0And if the assignment
                 !A := B
 had been executed, then the values would have been @C, @D, @D, 7.
0Note that
                 @A := B
 is not meaningful, since it would call for changing the address
 associated with A, and that association is permanent.
-2.3.2   Arithmetic operators
+        ____________________
0        The arithmetic operators *, /, REM, + and - act on 32 bit
 quantities (on the 370) interpreted as integers.
0        The operators * and / denote integer multiplication and
 division.   The operator REM yields the integer remainder after dividing
 the left hand operand by the right hand one.   If both operands are
 positive the result will be positive, it is otherwise implementation
 dependent.
0        The operators + and - may be used in either a monadic or diadic
 context and perform the appropriate integer arithmetic operations.
0        The treatment of arithmetic overflow is undefined.
-2.3.3   Relations
+        _________
0        A relational operator compares the integer values of its two
 operands and yields a truth-value (TRUE or FALSE) as result.   The
 operators are as follows:
0                =       equal
                 ~=      not equal
                 <       less than
                 <=      less than or equal
                 >       greater than
                 >=      greater than or equal
0        The operators = and ~= make bitwise comparisons of their
 operands and so may be used to determine the equality of values
 regardless of the kind of objects they represent.
0        An extended relational expression such as
                 'A' <= CH <= 'Z'
 is equivalent to
                 'A' <= CH  &  CH <= 'Z'
-2.3.4   Shift operators
+        _______________
0        In the expression E1 << E2 (E1 >> E2), E2 must evaluate to yield
 a non-negative integer.   The value is E1, taken as a bit-pattern,
 shifted left (or right) by E2 places.   Vacated positions are filled
 with 0 bits.
0        Syntactically, the shift operators have lower precedence on the
 left than relational operators but greater precedence on the right.
0Thus, for example,
                A << 10 = 14
 is equivalent to
                (A<<10) = 14
 but
                14 = A << 10
 is equivalent to
                (14=A) << 10
-2.3.5   Logical operators
+        _________________
0        The effect of a logical operator depends on context.   There are
 two logical contexts: 'truth-value' and 'bit'.   The truth-value context
 exists whenever the result of the expression will be interpreted
 immediately as true or false.   In this case each subexpression is
 interpreted, from left to right, in truth-value context until the truth
 or falsehood of the expression is determined.   Then evaluation stops.
 Thus, in a truth-value context, the evaluation of
                 E1 | E2 & ~E3
 is as follows.
0           E1 is evaluated, and if true  the whole expression is true,
 otherwise  E2 is evaluated, and if false the whole expression is false,
 otherwise  E3 is evaluated, and if false the whole expression is true,
 otherwise  the whole expression is false.
0        In a 'bit' context, the operator ~ causes bit-by-bit
 complementation of its operand.   The other operators combine their
 operands bit-by-bit according to the following table:
0                -------------------------------------
                |            |        Operator        |
                |  Operands  |                        |
                |            |   &     |   NEQV   EQV |
                |------------|------------------------|
                |            |                        |
                |   0    0   |   0     0     0     1  |
                |            |                        |
                |   0    1   |   0     1     1     0  |
                |            |                        |
                |   1    0   |   0     1     1     0  |
                |            |                        |
                |   1    1   |   1     1     0     1  |
                |            |                        |
                 -------------------------------------
12.3.6   Conditional operator
+        ____________________
0        The expression
                 E1 -> E2, E3
 is evaluated by evaluating E1 in truth-value context.   If it yields
 true, then the expression has value E2, otherwise E3.   E2 and E3 are
 never both evaluated.
-2.3.7   Table
+        _____
0        The value of the table expression
                 TABLE  K0, K1, K2, ...
 is the address of a static vector of cells initialised to the values of
 K0, K1, K2, ... which must be constant expressions.
-2.3.8   Constant expression
+        ___________________
0        A constant expression is any expression involving only numbers,
 character constants, names declared by manifest declaration, TRUE, FALSE
 and the operators *, /, REM, + and - .
-2.4     Section brackets
+________________________
0        Blocks, compound commands and some other syntactic constructions
 use the symbols $( and $) which are called opening and closing section
 brackets.
0        A section bracket may be tagged with a sequence of letters,
 digits and underlines (the same characters as are used in identifiers).
 A section bracket immediately followed by a space or newline is, in
 effect, tagged with null.
0        An opening section bracket can be matched only by an identically
 tagged closing bracket.   When the compiler finds a closing section
 bracket with a non-null tag, if the nearest opening bracket (smallest
 currently open section) does not match, that section is closed and the
 process repeats until a matching opening section bracket is found.
0        Thus it is impossible to write sections which are overlapping
 (not nested).
-2.5     Commands
+________________
0        The complete set of commands is shown here, with E, E1, E2 and K
 denoting expressions, C, C1 and C2 denoting commands, and D1 and D2
 denoting declarations.
0        routine call       E(E1, E2, ...)
                            E()
0        assignment         <left hand side list> := <expression list>
0        conditional        IF E THEN C
                            UNLESS E THEN C
                            TEST E THEN C1 OR C2
0        repetitive         WHILE E DO C
                            UNTIL E DO C
                            C REPEAT
                            C REPEATWHILE E
                            C REPEATUNTIL E
                            FOR N = E1 TO E2 BY K DO C
                            FOR N = E1 TO E2 DO C
0        resultis           RESULTIS E
0        switchon           SWITCHON E INTO <compound command>
0        transfer           GOTO E
                            FINISH
                            RETURN
                            BREAK
                            LOOP
                            ENDCASE
0        compound           $( C1; C2; ... $)
0        block              $( D1; D2; ...; C1; C2; ... $)
0Discussion of the routine call is deferred until section 2.6.6 where
 function and routine declarations are described.
-2.5.1   Assignment
+        __________
0        The command
                 E1 := E2
 causes the value of E2 to be stored into the cell specified by E1. E1
 must have one of the following forms:
0        (1)  The identifier of a variable       <identifier>
         (2)  A subscripted expression           E3!E4
         (3)  An indirection expression          !E3
0In case (1) the cell belonging to the identifier is updated.   Cases (2)
 and (3) have been described in section 2.3.1.
0        A list of assignments may be written thus:
                 E1, E2, ..., En := F1, F2, ..., Fn
 where Ei and Fi are expressions.   This is equivalent to
                 E1 := F1
                 E2 := F2
                    ...
                 En := Fn
-2.5.2   Conditional commands
+        ____________________
0                IF  E  THEN  C1
                 UNLESS  E  THEN  C2
                 TEST  E  THEN  C1  OR  C2
0Expression E is evaluated in truth-value context.   Command C1 is
 executed if E is true, otherwise the command C2 is executed.
-2.5.3   For command
+        ___________
0                FOR  N = E1  TO  E2  BY  K  DO  C
0N must be an identifier and K must be a constant expression.   This
 command will be described by showing an equivalent block.
0                $( LET  N, t = E1, E2
                    UNTIL N > t DO $(  C
                                       N := N + K  $)
                 $)
0If the value of K is negative the relation N > t is replaced by N < t.
 The declaration
                 LET  N, t = E1, E2
 declares two new cells with identifiers N and t; t being a new
 identifier that does not occur in C.   Note that the control variable N
 is not available outside the scope of the command.
0        The command
                 FOR  N = E1  TO  E2  DO  C
 is equivalent to
                 FOR  N = E1  TO  E2  BY  1  DO  C
-2.5.4   Other repetitive commands
+        _________________________
0                WHILE  E  DO  C
                 UNTIL  E  DO  C
                 C  REPEAT
                 C  REPEATWHILE  E
                 C  REPEATUNTIL  E
0Command C is executed repeatedly until condition E becomes true or false
 as implied by the command.   If the condition precedes the command
 (WHILE, UNTIL) the test will be made before each execution of C.   If it
 follows the command (REPEATWHILE, REPEATUNTIL), the test will be made
 after each execution of C,  and so C is executed at least once.   In the
 case of
                 C  REPEAT
 there is no condition and termination must be by a transfer or resultis
 command in C.   C will usually be a compound command or block.
0        Within REPEAT, REPEATWHILE and REPEATUNTIL C is taken as short
 as possible.   Thus, for example
                 IF E THEN C REPEAT
 is the same as
                 IF E THEN $( C REPEAT $)
 and
                 E := VALOF C REPEAT
 is the same as
                 E := VALOF $( C REPEAT $)
-2.5.5   Resultis command and valof expression
+        _____________________________________
0        The expression
                 VALOF  C
 where C is a command (usually a compound command or block) is called a
 valof expression.   It is evaluated by executing the commands (and
 declarations) in C until a resultis command
                 RESULTIS  E
 is encountered.   The expression E is evaluated, its value becomes the
 value of the valof expression and execution of the commands within C
 ceases.
0        A valof expression must contain one or more resultis commands
 and one must be executed.
0        In the case of nested valof expressions, the resultis command
 terminates only the innermost valof expression containing it.
-2.5.6   Switchon command
+        ________________
0                SWITCHON  E  INTO  <compound command>
0where the compound command contains labels of the form
0                CASE  <constant expression>:
             or  DEFAULT:
0The expression E is first evaluated and, if a case exists which has a
 constant with the same value, then execution is resumed at that label;
 otherwise, if there is a default label, then execution is continued from
 there, and if there is not, execution is resumed just after the end of
 the switchon command.
0        The switch is implemented as a direct switch, a sequential
 search or a binary search depending on the number and range of case
 constants.
-2.5.7   Transfer of control
+        ___________________
0                GOTO  E
                 FINISH
                 RETURN
                 BREAK
                 LOOP
                 ENDCASE
0The command GOTO E interprets the value of E as an address, and
 transfers control to that address, see section 2.6.7.   The command
 FINISH causes an implementation dependent termination of the entire
 program.   RETURN causes control to return to the caller of a routine.
 BREAK causes execution to be resumed at the point just after the
 smallest textually enclosing repetitive command.   The repetitive
 commands are those with the following key words:
0        UNTIL, WHILE, REPEAT, REPEATWHILE, REPEATUNTIL and FOR
0LOOP causes execution to be resumed at the point just before the end of
 the body of a repetitive command.   For a for command it is the point
 where the control variable is incremented, and for the other repetitive
 commands it is where the condition (if any) is tested.  ENDCASE causes
 execution to be resumed at the point just after the smallest enclosing
 switchon command.
-2.5.8   Compound command
+        ________________
0        A compound command is a sequence of commands enclosed in section
 brackets.
                 $(  C1; C2; ... $)
 The commands C1, C2, ... are executed in sequence.
-2.5.9   Block
+        _____
0        A block is a sequence of declarations followed by a sequence of
 commands enclosed together in section brackets.
                 $(  D1; D2; ... ; C1; C2; ... $)
 The declarations D1, D2, ...   and the commands C1, C2, ...   are
 executed in sequence.   The scope of an identifier (i.e.   the region of
 program where the identifier is known) declared in a declaration is the
 declaration itself (to allow recursive definition), the subsequent
 declarations and the commands of the block.   Notice that the scope does
 not include earlier declarations or extend outside the block.
-2.6     Declarations
+____________________
0        Every identifier used in a program must be declared explicitly.
 There are 10 distinct declarations in BCPL:
0        global, manifest, static, dynamic, vector, function, routine,
         formal parameter, label and for-loop control variable.
0        The declaration of formal parameters is covered in sections
 2.6.6 and 2.6.7, and the for-loop is described in section 2.5.3.
0        The scope of identifiers declared at the head of a block is
 described in the previous section.
-2.6.1   Global
+        ______
0        A BCPL program need not be compiled in one piece.   The sole
 means of communication between separately compiled segments of program
 is the global vector.   The declaration
                 GLOBAL $( Name : constant-expression $)
 associates the identifier Name with the specified location in the global
 vector.   Thus Name identifies a static cell which may be accessed by
 Name or by any other identifier associated with the same global vector
 location.
0        Global declarations may be combined.
                 GLOBAL $( N1:K1; N2:K2; ...; Nn:Kn  $)
 is equivalent to
                 GLOBAL  $( N1:K1  $)
                 GLOBAL  $( N2:K2  $)
                 ...
                 GLOBAL  $( Nn:Kn  $)
-2.6.2   Manifest
+        ________
0        An identifier may be associated with a constant by the
 declaration
                 MANIFEST  $(  Name = constant-expression  $)
0An identifier declared by a manifest declaration may only be used in
 contexts where a constant would be allowable.   It may not, for
 instance, appear on the left hand side of an assignment.   Like global
 declarations, manifest declarations may be combined.
                 MANIFEST  $(  N1=K1; N2=K2; ...; Nn=Kn  $)
 is equivalent to
                 MANIFEST  $(  N1=K1  $)
                 MANIFEST  $(  N2=K2  $)
                 ...
                 MANIFEST  $(  Nn=Kn  $)
-2.6.3   Static
+        ______
0        A variable may be declared and given an initial value by the
 declaration
                 STATIC  $(  Name = constant-expression  $)
0The variable that is declared is static, that is it has a cell
 permanently allocated to it throughout the execution of the program
 (even when control is not dynamically within the scope of the
 declaration).   Like global declarations, static declarations may be
 combined.
                 STATIC  $(  N1=K1; N2=K2; ...; Nn=Kn  $)
 is equivalent to
                 STATIC  $(  N1=K1  $)
                 STATIC  $(  N2=K2  $)
                 ...
                 STATIC  $(  Nn=Kn  $)
-2.6.4   Dynamic
+        _______
0        The declaration
                 LET  N1, N2, ..., Nn = E1, E2, ..., En
 creates dynamic cells and associates with them the identifiers N1, N2,
 ..., Nn.   These cells are initialised to the values of E1, E2, ..., En.
 The space reserved for these cells is released when the block in which
 the declaration appears is left.
-2.6.5   Vector
+        ______
0        The declaration
                 LET  N = VEC  K
 where K is a constant expression, creates a dynamic vector by reserving
 K + 1 cells of contiguous storage in the stack, plus one cell which is
 associated with the identifier N.   Execution of the declaration causes
 the value of N to become the address of the K + 1 cells.   The storage
 allocated is released when the block is left.
-2.6.6   Function and routine
+        ____________________
0        The declaration
                 LET  N(P1, P2, ..., Pm) = E
 declares a function named N with m parameters.   The parentheses are
 required even if m = 0.   A parameter name has the same syntax as an
 identifier, and its scope is the expression E.   A routine declaration
 is similar to a function declaration except that its body is a command.
                 LET N(P1, P2, ..., Pm) BE C
0        If the declaration is within the scope of a global declaration
 for N, then the global cell will be initialised to the entry address of
 the function (or routine) before execution of the program.   Thus the
 function may be accessed from anywhere.   Otherwise, a static cell is
 created, is associated with the identifier N, and is initialised to the
 entry address.
0        The function or routine is invoked by the call
                 E0(E1, E2, ..., Em)
 where expression E0 evaluates to the entry address.   In particular,
 within the scope of the identifier N, the function or routine may be
 invoked by the call
                 N(E1, E2, ..., Em)
 provided the value of N has not been changed during the execution of the
 program.
0        Each value passed as a parameter is copied into a newly created
 cell which is then associated with the corresponding parameter name. The
 cells are consecutive in store and so the argument list behaves like an
 initialised dynamic vector.   The space allocated for the argument list
 is released when evaluation of the call is complete.   Notice that
 arguments are always passed by value; however, the value passed may, of
 course, be an address.
0        A function call is a call in the context of an expression. If a
 function is being called, the result is the value of E, and if a routine
 is being called, the result is undefined.   A routine call is a call
 in the context of a command and may be used to call either a function or
 a routine.   A routine call has no result.
0        No dynamic (or vector or formal) variable that is declared
 outside the function may be referred to from within E.
-2.6.7   Label
+        _____
0        A label may be declared by
                 Name:
0A label declaration may precede any command or label declaration, but
 may not precede any other form of declaration.   Exactly as in the case
 of a function or routine, a label declaration creates a static cell if
 it is not within the scope of a global declaration of the same
 identifier.   The local or global cell is initialised before execution
 with the address of the point in the program labelled, so that the
 command
                 GOTO Name
 has the expected effect.
0        The scope of a label depends on its context.   It is the
 smallest of the following regions of program:
         (1)   the command sequence of the smallest textually
               enclosing block,
         (2)   the body of the smallest textually enclosing valof
               expression or routine,
         (3)   the body of the smallest enclosing for command.
0        Labels may be assigned to variables and passed as parameters. It
 is, in general, not useful for them to be declared global, but they can
 be assigned to global variables.
0        Using a goto command to transfer to a label which is outside the
 current function or routine will produce undefined (chaotic) results.
 Such transfers can only be performed using the library functions LEVEL
 and LONGJUMP which are described in section 2.8.2.
-2.6.8   Simultaneous declaration
+        ________________________
0        Any declaration of the form
                 LET ...
 may be followed by one or more declarations of the form
                 AND ...
 where any construct which may follow LET may follow AND.   As far as
 scope is concerned, such a collection of declarations is treated like a
 single declaration.   This makes is possible, for example, for two
 routines to know each other without recourse to the global vector.
-
02.7     Miscellaneous features
+______________________________
-2.7.1   GET
+        ___
0        It is possible to include a file in the source text of a program
 using a get directive of the form:
0                GET  "string"
0On the 370, text of the get directive is replaced by the text of the
 file whose DDNAME is string.   A get directive should appear on a line
 by itself.
-2.7.2   Comments and spaces
+        ___________________
0        The character pair // introduces a comment.   All characters
 from (and including) // up to but not including the character 'newline'
 will be ignored by the compiler.   The character pair /* introduce a
 comment which is terminated by the pair */,  such a comment may extend
 over several lines.
0        Blank lines are also ignored.
0        Space and tab characters may be inserted freely except inside a
 basic symbol,  but Space or tab characters are required to separate
 identifiers or system words from adjoining identifiers or system words.
-2.7.3   Optional symbols and synonyms
+        _____________________________
0        The reserved words DO and THEN are synonyms in BCPL.   Most
 implementations of BCPL also allow other synonyms and a list of the
 synonyms for the 370 implementation can be found in Appendix A.
0        In order to make BCPL programs easier to read and to write, the
 compiler allows the syntax rules to be relaxed in certain cases.   The
 word DO (or THEN) may be omitted whenever it is immediately followed by
 the keyword of a command (e.g.  RESULTIS).   Any semicolon occurring as
 the last symbol of a line may be omitted.   As an example, the following
 two programs are equivalent:
0        IF A = 0  DO GOTO X;        |        IF  A = 0  GOTO X
         A := A - 1;                 |        A := A - 1
-2.8     The run-time library
+____________________________
0        This section summarises the library functions and routines that
 are available on the 370 implementation of BCPL.
-2.8.1   Input-Output routines
+        _____________________
0        The input/output facilities of BCPL are quite primitive and
 simple, and are always invoked by means of function or routine calls.
0FINDINPUT(ddname) is a function taking a string for the ddname of a
 data-set as argument and returning a stream-pointer to be used by the
 input routines.   If the data-set is not already open for reading it is
 opened.   If the data-set does not exist, the result is zero.
0SELECTINPUT(stream) is a routine which selects the specified input
 stream for future reading.
0RDCH() is a function whose result is the next character from the
 currently selected input stream.   If the stream is exhausted, it yields
 ENDSTREAMCH(=-1).
0UNRDCH() is a routine that will cause the next call of RDCH to yield the
 same character that it returned on its last call for the currently
 selected input stream.
0REWIND() repositions the currently selected input stream to point to the
 first record.
0ENDREAD() closes the currently selected input stream.
0FINDOUTPUT(ddname) is a function taking a string for the ddname of a
 data-set as argument and returning a stream-pointer to be used by the
 output routines.   If the data-set is not already opened for writing it
 is opened.   If the data-set does not exist, the result is zero.
0SELECTOUTPUT(stream) is a routine which selects the specified output
 stream for future writing.
0WRCH(CH) will write the character CH to the currently selected output
 stream.
0ENDWRITE() closes the currently selected output stream.
0ENDTOINPUT() closes the currently selected output stream and reopens it
 for reading.
0INPUT() is a function that will return with the currently selected input
 stream.
0OUTPUT() is a function that will return with the currently selected
 output stream.
0TRIMINPUT(SW) sets the control that specifies the treatment of trailing
 blanks in records read from the current input stream.   If SW is true
 trailing blanks will be skipped, if SW is false they will not.
0READREC(V) is a function that will read a record from the current input
 stream into the vector V packing four characters per word.   The result
 is the number of characters read, or -1 if the stream is exhausted.
0WRITEREC(V,N) will write N characters from the vector V to the current
 output stream followed by a newline.   The characters in V are packed
 four per word.
0WRITESEG(V,N) will write N characters from the vector V to the current
 output stream.   The characters in V are packed four per word.
-2.8.2   Other useful subroutines
+        ________________________
0PACKSTRING(V,S) is a function which packs the characters V!1 to V!N into
 S, where N = V!0 & 255.   The result is the subscript of the highest
 element of S used (i.e. N/4 on the 370).
0UNPACKSTRING(S,V) is a routine to unpack characters from the string S
 into V!1 to V!N when N is the length of the string, and set V!0 = N.
0GETBYTE(S, I) is a function whose result is the Ith character of the
 string S.   By convention the zeroth character of a string is its
 length.
0PUTBYTE(S, I, CH) is a routine which will update the Ith character of
 the string S with CH.
0WRITES(S) writes the string S to the current output stream.
0NEWLINE() writes a newline to the current output stream.
0WRITED(N,D) writes the integer N to the current output stream right
 justified in a field of width D places.   If D is too small the number
 is written correctly using as many characters as necessary.
0WRITEN(N) is equivalent to WRITED(N,0).
0WRITEOCT(N,D) writes the D least significant octal digits of N to the
 current output stream.
0WRITEHEX(N,D) writes the D least significant hexadecimal digits of N to
 the current output stream.
0WRITEF(FORMAT,A,B, ...)   is a routine to output A,B, ...   to the
 current output stream according to FORMAT.   The FORMAT string is copied
 to the stream until the end is reached or the warning character '%' is
 encountered.   The character following the '%' defines the format of the
 next value to be printed as follows:
0        %%      print '%'
         %S      print as a string
         %C      print as a character
         %N      print as a integer (minimum width)
         %In     print as a integer width n
         %On     print as an octal number width n
         %Xn     print as a hexadecimal number width n
0In the last three cases the width n is represented by a single
 hexadecimal digit.   The routine takes the format and a maximum of 11
 additional arguments.
0MAPSTORE() prints a map of the program area including function and
 routine names, and the values of all global variables used.
0BACKTRACE() prints a summary of the dynamic stack giving the names of
 all functions and routines currently active and the values of the first
 few local variables of each.
0ABORT(CODE,ADDR) is called automatically by the system after most
 faults.   It calls BACKTRACE and MAPSTORE in order to provide the user
 with some postmortem information.
0STOP(N) will terminate the job step, returning a completion code N.
0LEVEL() is a function whose result is the current value of the run-time
 stack pointer for use with LONGJUMP.   The stack pointer changes only
 when a function or routine is entered or left.
0LONGJUMP(P,L) will cause a non-local jump to the label L at the
 activation level given by the stack pointer P.
0TIME() is a function whose result is the computation time used in units
 of 26 micro-seconds.
0APTOVEC(F,N) is a function which will apply F to two arguments V and N
 where V is a vector of size N.   APTOVEC could (illegally) be defined in
 BCPL as follows:
0                LET APTOVEC(F,N) = VALOF
                        $(  LET V = VEC N
                            RESULTIS F(V,N) $)
02.8.3   Library variables
+        _________________
0STACKBASE points to the base of the runtime stack.
0STACKEND points to the end of the runtime stack.
0PARMS holds a string representing the PARM field for the current job
 step.
0TERMINATOR holds the character following the last digit of the most
 recent number read in by READN.
0ENDSTREAMCH is a manifest constant (=-1) which is produced by RDCH when
 the input stream is exhausted.
1              3.    USING BCPL ON THE 370
-
         Files relating to the BCPL system are catalogued in the file
 directory BCPLIB.   These include the compiler itself BCPLIB.SYS2, the
 library modules which are held in a partitioned data set BCPLIB.LIB and
 the standard header file BCPLIB.LIBHDR which contains global
 declarations for all the library routines.   There is, also, an
 information document BCPLIB.INFO which contains recent news about the
 BCPL system.
0        There are four catalogued procedures BCPLCLG, BCPLCL, BCPLC and
 BCPLLG to simplify the use of the compiler.
-3.1     Compilation
+___________________
0        The BCPL compiler is usually invoked by means of one of the
 catalogued procedures.   The following complete job illustrates the use
 of BCPLCLG.   It will compile and run the routine START.
0                JOB ...
                 LIMSTORE 150K
                 // EXEC BCPLCLG
                 //BCPL.SYSIN DD DATA
0                GET "LIBHDR"
0                LET START(PARM) BE $(1
                 ...
                 ...
                 $)1
                 /*
0        The compiler runs as one job step and currently requires a
 region size of 150K, hence the need for LIMSTORE 150K.   The example
 given above will cause the program to be compiled, link-edited and run
 with the standard library.   The catalogued procedure BCPLCLG is as
 follows:
1 //BCPLCLG PROC TRKS='5,5',PRINTC='SYSOUT=C',REGC=150K,
  //             MINC=,SECC=20,CONDC=,PARMC='L12000/K',
  //             LIBC='BCPLIB.SYS2',LIBHDR='BCPLIB.LIBHDR',
  //             SYSLIBL='BCPLIB.LIB',IOSPACE=54K,
  //             PRINTL='SYSOUT=C',REGL=98K,MINL=,SECL=20,
  //             CONDL='4,LT,BCPL',
  //             LISTL=LIST,MAPL=NOMAP,XREFL=NOXREF,LETL=LET,
  //             ATTL=,CAL=CALL,DCBL=DCBS,BLKL=4096,
  //             SIZEL='(999999,8K)',NAMEL='&GOSET(BCPLGO)',
  //             DISPL='(NEW,PASS),SPACE=(TRK,(8,3,1),RLSE)',
  //             PARMG=,PRINTG='SYSOUT=A',REGG=120K,MING=1439,
  //             SECG=,CONDG='(4,LT,BCPL),(4,LT,LKED)'
  //*
  //BCPL    EXEC PGM=BCPL,REGION=&REGC,PARM='$&IOSPACE.$&PARMC',
  //             TIME=(&MINC,&SECC),COND=(&CONDC)
  //STEPLIB DD   DISP=SHR,DSN=&LIBC
  //SYSPRINT DD  &PRINTC
  //LIBHDR   DD  DISP=SHR,DSN=&LIBHDR
  //SYSGO    DD  DSN=&LOADSET,DISP=(MOD,PASS),UNIT=DISC,
  //             SPACE=(TRK,(&TRKS),RLSE),
  //             DCB=(RECFM=FB,LRECL=80,BLKSIZE=2480)
  //LKED    EXEC PGM=IEWL,REGION=&REGL,
  // PARM='SIZE=&SIZEL,&LISTL,&MAPL,&XREFL,&LETL,&ATTL,&CAL,&DCBL',
  //             COND=(&CONDL),TIME=(&MINL,&SECL)
  //SYSLIB   DD  DSN=&SYSLIBL,DISP=SHR
  //SYSLMOD  DD  DSN=&NAMEL,DISP=&DISPL,DCB=BLKSIZE=&BLKL,UNIT=DISC
  //SYSPRINT DD  &PRINTL
  //SYSUT1   DD  UNIT=DISC,SPACE=(TRK,(&TRKS)),SEP=SYSLMOD,
  //             DSN=&SYSUT1
  //SYSLIN   DD  DSN=&LOADSET,DISP=(OLD,DELETE)
  //         DD  DDNAME=SYSIN
  //GO      EXEC PGM=*.LKED.SYSLMOD,COND=(&CONDG),REGION=&REGG,
  //             PARM='&PARMG',TIME=(&MING,&SECG)
  //SYSPRINT DD  &PRINTG
03.1.1   Library declarations
+        ____________________
0The directive
0        GET "LIBHDR"
0will insert the standard library declarations from the data-set whose
 DDNAME is LIBHDR.   The default setting of this data-set is
 BCPLIB.LIBHDR.   The items declared in this file are shown below.   By
 convention library variables are given global numbers in the range 1 to
 99 and so users should avoid allocating globals in this region for their
 own purposes.
1        GLOBAL
         $(  START:1             // The main routine
             ABORT:3             // Calls BACKTRACE and MAPSTORE
             BACKTRACE:4         // Summarise the run-time stack
             SELECTINPUT:11      // Select input stream
             SELECTOUTPUT:12     // Select output stream
             RDCH:13             // Read a character
             WRCH:14             // Write a character
             UNRDCH:15           // 'Unread' a character
             INPUT:16            // Find current input
             OUTPUT:17           // Find current output
             TRIMINPUT:20        // Set trailing blank control
             READREC:23          // Read a record
             WRITEREC:24         // Write record
             WRITESEG:25         // Write part-record
             TIME:28             // Find computation time
             STOP:30             // Terminate job step
             LEVEL:31            // Find activation pointer
             LONGJUMP:32         // Make non-local jump
             REWIND:35           // Rewind input stream
             APTOVEC:40          // Apply function to dynamic vector
             FINDOUTPUT:41       // Find specified output stream
             FINDINPUT:42        // Find specified input stream
             ENDREAD:46          // Close input stream
             ENDWRITE:47         // Close output stream
             ENDTOINPUT;51       // Close and reposition output stream
             STACKBASE:54        // Base of stack pointer
             STACKEND:55         // End of stack pointer
             WRITES:60           // Write a string
             WRITEN:62           // Write a number (minimum width)
             NEWLINE:63          // Write a newline
             PACKSTRING:66       // Pack characters
             UNPACKSTRING:67     // Unpack characters
             WRITED:68           // Write a number
             READN:70            // Read a number
             TERMINATOR:71       // Terminator character of READN
             WRITEHEX:75         // Write a hexadecimal number
             WRITEF:76           // Write with format
             WRITEOCT:77         // Write an octal number
             MAPSTORE:78         // Map the store
             GETBYTE:85          // Obtain a character from a string
             PUTBYTE:86          // Update a character in a string
         $)
0        MANIFEST
         $(  ENDSTREAMCH= -1     // End of stream character
         $)
13.1.2   Diagnostics
+        ___________
0        The BCPL compiler has three passes: parse, translate and
 code-generate.   There are correspondingly three kinds of error
 diagnostic.
0        A parse diagnostic occurs when a relatively simple syntactic
 error is detected during the first pass of compilation.   The message
 includes a portion of the source program to give the context and a brief
 description of the probable error.   The compiler usually skips to the
 end of the line before continuing the parse.   Later error messages
 should be viewed with suspicion since the automatic recovery is often
 not very successful.
0        Translation phase diagnostics occur in the second pass of
 compilation and report errors such as the use of an undeclared
 identifier.   Each error is briefly described and a representation of
 the relevant portion of the parse tree is printed.
0        Code-generation diagnostics are rare and usually result from
 table overflows or compiler errors.
-3.1.3   Compilation options
+        ___________________
0        The compilation of a program can be controlled by various
 compilation options passed to the compiler by the PARM field of the EXEC
 card that invoked the compiler.   The options for the code-generator are
 separated from those for the first phase of the compiler by a slash.
 Most options are specified by single letters and some are primarily
 debugging aids for the implementer of the compiler.
0        The first phase options are as follows:
0Ln      Set the size of work-space area used during compilation.
         The best value of n is usually between 6000 and 12000.
0Dn      Set the size of the work-space area used to hold declared
         names.  The default setting is D1800 which allows for 600 names
         to be declared at any one time.
0N       Disable the GET directive.
0S       List the source program with line numbers.
0T       Print the parse tree of the source program.
0O       Print the intermediate object code form of the program.
0        The code generator options are as follows:
0K       Compile instructions with each function and routine to count
         the number of times they are executed.   The counts can be
         printed using MAPSTORE.
0P       Compile instructions after labels and conditional jumps to
         accumulate execution counts.   These counts can be printed
         using MAPSTORE and allow one to make a detailed analysis of
         the execution of the program.
0G       Execute the compiled program as a subroutine of the compiler
         and thus save the overhead of the 'link-edit' and 'go' steps.
         This option is particularly useful when running BCPL under the
         BATCH monitor,  but one is  limited to the region size and
         library used by the compiler.
0H       Construct a symbol table that gives the identifiers of local
         variables.  The extended post-mortem will then print the
         values of such variables together with source names (specify
         NEEDS "PM" to obtain the special post-mortem).
0L       Output an assembly listing of the compiled program.
0N       Do not generate an object module for the program.
0        The default setting of the PARM field when using BCPLCLG is
 'L12000/K'.
-3.2     Execution
+_________________
-3.2.1   Loading
+        _______
0        Each compiled segment of a BCPL program has an external
 reference to BCPLMAIN which is the entry point of the standard machine
 code library and this, in turn, has a reference to BLIB which is the
 portion of the standard library written in BCPL.   Thus, when the
 compiled segments are link-edited together, the library modules are
 automatically incorporated.   The standard library modules are held in
 BCPLIB.LIB.
0        When the complete program is executed, the machine code library
 initialises the run-time system and obtains space for the global vector
 and stack.   The globals are initialised to their appropriate values and
 then control is passed to the BCPL program by calling the routine START
 (global 1) which must have been defined by the programmer.   START is
 passed a string representing the PARM field of the job control card that
 caused the program to be executed.
0        The size of the global vector is the smallest multiple of 100
 words large enough to accommodate the highest global number actually
 used in any segment of the loaded program.   The size of the run-time
 stack depends on the space available in the region in which the program
 is run.   Some space is returned for input/output buffers and system
 use.   The limits of the stack are held in STACKBASE and STACKEND.
0        If the PARM string starts with a sequence of the form:
0        $kKgGiItTD$
0then the standard initialisation is modified as follows:
0        kK specifies the size of the I/O space.
         gG specifies that the global vector will be initialised in
 blocks of g (default 100).
         iI specifies that the first iK bytes (default 250K) of the stack
 will be initialised to '* STCK *'.
         tT specifies the amount of time in centi-seconds to be made
 available for post mortem routines (default 0.75 seconds).
         D  disable the standard trapping of faults (so that a SYSUDUMP
 can be generated).
0   All these directives are optional and may be omitted.  The remainder
 of the string following the second '$' is passed to the program (as the
 argument of START).
0        When START is called, the initial output selection is to
 SYSPRINT, if it exists; and the initial input selection is from SYSIN,
 if it exists.
-3.2.2   Execution faults
+        ________________
0        In the event of an execution fault such as division by zero or a
 protection exception the routine ABORT is called.   This will print the
 fault number and the program address when the fault was detected,
 followed by a summary of the runtime stack (printed out by BACKTRACE)
 and a map of the program store and globals (printed out by MAPSTORE).
 This information is output to SYSPRINT which should therefore always be
 provided.
03.2.3   A complete job
+        ______________
0        The following is an example of a complete BCPL job to compile
 and execute a BCPL program using the catalogued procedure BCPLCLG.
-  JOB ...
   LIMSTORE 150K
   // EXEC BCPLCLG
   //BCPL.SYSIN DD DATA
0  // THIS IS A DEMOSTRATION BCPL PROGRAM
0  GET "LIBHDR"
       // THIS INSERTS THE STANDARD GLOBAL DECLARATION
-  LET START(PARM) BE $(1  // START(GLOBAL 1) IS THE MAIN ROUTINE
0  GLOBAL $( TREE:100; TREEP:101; CH:102  $)
0  STATIC $( COUNT=0; MIN=0; MAX=0  $)
0  MANIFEST $(  // THE FOLLOWING NAMES WILL
                // BE USED AS SELECTORS
   VAL=0; LEFT=1; RIGHT=2
   $)
0  // THE FUNCTIONS PUT, LIST AND SUM(DEFINED BELOW)
   // OPERATE ON A TREE STRUCTURE WHOSE ROOT IS HELD
   // IN TREE.  IF T IS A BRANCH IN THIS TREE THEN
   // EITHER T=0
   // OR  T POINTS TO A TREE NODE AND VAL!T IS AN
   //     INTEGER(K SAY), LEFT!T IS A BRANCH CONTAINING
   //     NUMBERS <K AND RIGHT!T IS A BRANCH CONTAINING
   //     NUMBERS >=K.
-  LET PUT(K, P) BE  // THE ROUTINE PUT WILL ADD A NODE TO THE
                     // TREE WHOSE ROOT IS POINTED TO BY P.
0     $(P UNTIL !P=0 DO
            $( LET T = !P
               P := K<VAL!T -> @LEFT!T, @RIGHT!T  $)
0         VAL!TREEP, LEFT!TREEP, RIGHT!TREEP := K, 0, 0
          !P := TREEP
          TREEP := TREEP + 3  $)P
0  AND LIST(T) BE  // LIST THE NUMBERS HELD IN THE TREE T
        UNLESS T=0 DO $( LIST(LEFT!T)
                         IF COUNT REM 10 = 0 DO NEWLINE()
                         COUNT := COUNT + 1
                         WRITEF(" %I6", VAL!T)
                         LIST(RIGHT!T)  $)
-  AND SUM(T) = T=0 -> 0,
                VAL!T<MIN -> SUM(RIGHT!T),
                VAL!T>MAX -> SUM(LEFT!T),
                VAL!T+SUM(LEFT!T)+SUM(RIGHT!T)
0  LET V = VEC 600
0  TREE, TREEP := 0, V
0  NXT: CH := RDCH()  // THIS IS A CONVENIENT WAY
                      // TO ORGANISE A TEST PROGRAM
   SW: SWITCHON CH INTO
0  $(S CASE 'Q': CASE ENDSTREAMCH:
                 WRITES("*NEND OF TEST*N")
                 FINISH
0      CASE 'P':  PUT(READN(), @TREE)  // PUT A NUMBER
                  CH := TERMINATOR     // IN THE TREE
                  GOTO SW
0      CASE 'L': NEWLINE()  // LIST THE NUMBERS IN THE TREE
                 COUNT := 0
                 LIST(TREE)
                 NEWLINE()
                 GOTO NXT
0      CASE 'S': MIN := READN()
                 MAX := READN()
                 WRITEF("*NSUM OF NUMBERS BETWEEN %N AND %N IS %N*N",
                        MIN, MAX, SUM(TREE))
                 CH := TERMINATOR
                 GOTO NXT
0      CASE 'M':  MAPSTORE(); GOTO NXT  // PRINT A STORE MAP
0      CASE 'Z': TREE := 0; WRITES("*NTREE CLEARED*N"); GOTO NXT
0      CASE '*S': CASE '*N': GOTO NXT  // IGNORE SPACE AND NEWLINE
0      DEFAULT: WRITEF("*NBAD CH '%C'*N", CH); GOTO NXT  $)S
0  $)1   // END OF PROGRAM
   /*
   //GO.SYSIN DD *
   P24 P13 P96 P46 P-12 P0 P45
   L S10 50
   Q
   /*
0When this job is run, its GO step will output the following:
0    -12      0     13     24     45     46     96
0SUM OF NUMBERS BETWEEN 10 AND 50 IS 128
0END OF TEST
1              Appendix A:  Basic symbols and synonyms
+              _______________________________________
-        The following list of words and symbols are treated as atoms by
 the syntax analyser.   The name of the symbol or its standard
 representation on the 370 is given in the first column, and examples or
 synonyms are given in the second.
-        Basic symbol         Examples and synonyms
+        ____________         _____________________
0        identifier           A  H1  PQRST  TAX_RATE
         number               126  7249  #3771
         string constant      "A"  "*NTEST"
         character constant   'X'  ')'  '*N'  '"'
         TRUE
         FALSE
         (
         )
         @                    LV
         !                    RV
         *
         /
         REM
         +
         -
         =                    EQ
         ~=                   NE
         <=                   LE
         >=                   GE
         <                    LS
         >                    GR
         <<                   LSHIFT
         >>                   RSHIFT
         ~                    NOT
         &                    /\  LOGAND
         |                    \/  LOGOR
         EQV
         NEQV
         ->
         ,
         TABLE
         VALOF
         ;
         :
         $(                   $(AB  $(1
         $)                   $)AB  $)1
         VEC
         BE
         LET
         AND
         :=
         BREAK
         LOOP
         ENDCASE
-        RETURN
         FINISH
         GOTO
         RESULTIS
         SWITCHON
         INTO
         REPEAT
         REPEATUNTIL
         REPEATWHILE
         DO                   THEN
         UNTIL
         WHILE
         FOR
         TO
         BY
         TEST
         THEN                 DO
         OR                   ELSE
         IF
         UNLESS
         CASE
         DEFAULT
1              Appendix B:   BNF of BCPL
+              _________________________
-        This appendix presents the Backus Naur Form of the syntax of
 BCPL.   The whole syntax is given, with the following exceptions:
01.      Comments are not included, and the space character is not
         represented even where required.
02.      The section bracket tagging rule is not included, since it
         is impossible to represent in BNF.
03.      The graphic escape sequences allowable in string and
         character constants are not represented.
04.      No account is made of the rules which allow dropping of
         semicolon and DO in most cases.   It seemed that these
         rules unnecessarily complicate the BNF syntax yet are easy
         to understand by other means.
05.      BCPL has several synonymous system words and operators:
         for example, DO and THEN.   Only a  standard  form of these
         symbols is shown in the syntax;  a list of synonyms can
         be found in Appendix A.
06.      Certain constructions can be used only in specific contexts.
         Not all these restrictions are included:  for example,
         CASE and DEFAULT can only be used in switches, and RESULTIS
         only in VALOF expressions.   Finally, there is the necessity
         of declaring all identifiers that are used in a program.
07.      There is a syntactic ambiguity relating to <repeated command>
         which is resolved in section 2.5.4.
0The brackets [ ] imply arbitrary repetition of the categories enclosed.
-1.      Identifiers, Strings, Numbers
+        _____________________________
0<letter>  ::=  A | B | ... | Z
0<octal digit>  ::=  0 | 1 | ... | 7
0<hex digit>  ::=  0 | 1 | ... | F
0<digit>  ::=  0 | 1 | ... | 9
0<string constant>  ::=   "<255 or fewer characters>"
0<character constant>  ::=  '<one character>'
0<octal number>  ::=  # <octal digit> [ <octal digit> ]
0<hex number>  ::=  #X <hex digit> [ <hex digit> ]
0<number>  ::=  <octal number> | <hex number> | <digit> [ <digit> ]
0<identifier>  ::=  <letter> [ <letter> | <digit> | _ ]
-2.      Operators
+        _________
0<address op>  ::=  @ | !
0<mult op>  ::=  * | / | REM
0<add op>  ::=  + | -
0<rel op>  ::=  = | ~= | <= | >= | < | >
0<shift op>  ::=  << | >>
0<and op>  ::=  &
0<or op>  ::=  |
0<eqv op>  ::=  EQV | NEQV
-3.      Expressions
+        ___________
0<element>  ::=  <character constant> | <string constant> |
                 <number> | <identifier> | TRUE | FALSE
0<primary E>  ::=  <primary E> (<expression list>) |
                   <primary E> ( ) |
                   (<expression>) | <element>
0<vector E>  ::=  <vector E> ! <primary E> | <primary E>
0<address E>  ::=  <address op> <address E> | <vector E>
0<mult E>  ::=  <mult E> <mult op> <address E> | <address E>
0<add E>  ::=  <add E> <add op> <mult E> |
               <add op> <mult E> |
               <mult E>
0<rel E>  ::=  <add E> [ <rel op> <add E> ]
0<shift E>  ::=  <shift E> <shift op> <add E> | <rel E>
0<not E>  ::=  ~ <shift E> | <shift E>
0<and E>  ::=  <not E> [ <and op> <not E> ]
0<or E>  ::=  <and E> [ <or op> <and E> ]
0<eqv E>  ::=  <or E> [ <eqv op> <or E> ]
0<conditional E>  ::= <eqv E> -> <conditional E> , <conditional E> |
                      <eqv E>
0<expression>  ::=  <conditional E> |
                    TABLE <constant expression>
                      [ , <constant expression> ] |
                    VALOF <command>
-4.      Constant Expressions
+        ____________________
0<C element>  ::=  <character constant> | <number> | <identifier> |
                   TRUE | FALSE | (<const expression>)
0<C mult E>  ::=  <C mult E> <mult op> <C element> | <C element>
0<constant expression>  ::=  <constant expression> <add op> <C mult E> |
                             <add op> <C mult E> | <C mult E>
-5.      Lists of Expressions and Identifiers
+        ____________________________________
0<expression list>  ::=  <expression> [ , <expression> ]
0<name list>  ::=  <name> [ , <name> ]
-6.      Declarations
+        ____________
0<manifest item>  ::=  <identifier> = <constant expression>
0<manifest list>  ::=  <manifest item> [ ; <manifest item> ]
0<manifest declaration>  ::=  MANIFEST $( <manifest list> $)
0<static declaration>  ::=  STATIC $( <manifest list> $)
0<global item>  ::=  <identifier> : <constant expression>
0<global list>  ::=  <global item> [ ; <global item> ]
0<global declaration>  ::=  GLOBAL $( <global list> $)
0<simple definition>  ::=  <name list> = <expression list>
0<vector definition>  ::=  <identifier> = VEC <constant expression>
0<function definition>  ::=  <identifier> (<name list>) = <expression> |
                             <identifier> ( ) = <expression>
0<routine definition>  ::=  <identifier> (<name list>) BE <command> |
                            <identifier> ( ) BE <command>
0<definition>  ::=  <simple definition> | <vector definition> |
                    <function definition> | <routine definition>
0<simultaneous declaration>  ::=  LET <definition> [ AND <definition> ]
0<declaration>  ::=  <simultaneous declaration> |
                     <manifest declaration> |
                     <static declaration> |
                     <global declaration>
-7.      Left hand side Expressions
+        _________________________
0<LHSE>  ::=  <identifier> | <vector E> ! <primary E> |
              ! <primary E>
0<left hand side list>  ::=  <LHSE> [ , <LHSE> ]
-8.      Unlabelled Commands
+        ___________________
0<assignment>  ::=  <left hand side list> := <expression list>
0<simple command>  ::=  BREAK | LOOP | ENDCASE | RETURN | FINISH
0<goto command>  ::=  GOTO <expression>
0<routine command>  ::=  <primary E> (<expression list>) |
                         <primary E> ( )
0<resultis command>  ::=  RESULTIS <expression>
0<switchon command>  ::=  SWITCHON <expression> INTO <compound command>
0<repeatable command>  ::=  <assignment> | <simple command> |
                            <goto command> | <routine command> |
                            <resultis command> | <repeated command> |
                            <switchon command> | <compound command> |
                            <block>
0<repeated command>  ::=  <repeatable command> REPEAT |
                          <repeatable command> REPEATUNTIL <expression> |
                          <repeatable command> REPEATWHILE <expression>
0<until command>  ::=  UNTIL <expression> DO <command>
0<while command>  ::=  WHILE <expression> DO <command>
0<for command>  ::=  FOR <identifier> = <expression> TO <expression>
                         BY <constant expression> DO <command> |
                     FOR <identifier> = <expression> TO <expression>
                         DO <command>
0<repetitive command>  ::=  <repeated command> | <until command> |
                            <while command> | <for command>
0<test command>  ::=  TEST <expression> THEN <command> OR <command>
0<if command>  ::=  IF <expression> THEN <command>
0<unless command>  ::=  UNLESS <expression> THEN <command>
0<unlabelled command>  ::=  <repeatable command> | <repetitive command>
                            <test command> | <if command> |
                            <unless command>
09.      Labelled Commands
+        _________________
0<label prefix>  ::=  <identifier> :
0<case prefix>  ::=  CASE <constant expression> :
0<default prefix>  ::=  DEFAULT :
0<prefix>  ::=  <label prefix> | <case prefix> | <default prefix>
0<command>  ::=  <unlabelled command> |
                 <prefix> <command> |
                 <prefix>
-10.     Blocks and Compound Commands
+        ____________________________
0<command list>  ::=  <command> [ ; <command> ]
0<declaration part>  ::=  <declaration> [ ; <declaration> ]
0<block>  ::=  $( <declaration part> ; <command list> $)
0<compound command>  ::=  $( <command list> $)
0<program>  ::=  <declaration part>
1         Appendix C:   The EBCDIC character set
+         ______________________________________
0        The following table gives the decimal values and graphics of the
 characters available on the 370 implementation of BCPL.
-    0       1       2       3       4       5 HT    6       7
     8       9      10      11      12 NP   13 CR   14      15
    16      17      18      19      20      21 NL   22 BS   23
    24      25      26      27      28      29      30      31
    32      33      34      35      36      37 LF   38      39
    40      41      42      43      44      45      46      47
    48      49      50      51      52      53      54      55
    56      57      58      59      60      61      62      63
    64 SP   65      66 [    67 ]    68      69      70      71
    72      73      74      75 .    76 <    77 (    78 +    79 |
    80 &    81      82      83      84      85      86      87
    88      89      90 !    91 $    92 *    93 )    94 ;    95 ~
    96 -    97 /    98 \    99    100    101 ^   102 _   103
   104     105     106     107 ,   108 %   109 _   110 >   111 ?
   112     113     114     115     116     117     118     119
   120     121     122 :   123 #   124 @   125 '   126 =   127 "
   128     129 a   130 b   131 c   132 d   133 e   134 f   135 g
   136 h   137 i   138     139     140     141     142     143
   144     145 j   146 k   147 l   148 m   149 n   150 o   151 p
   152 q   153 r   154     155     156     157     158     159
   160     161     162 s   163 t   164 u   165 v   166 w   167 x
   168 y   169 z   170     171     172     173     174     175
   176     177     178     179     180     181     182     183
   184     185     186     187     188     189     190     191
   192     193 A   194 B   195 C   196 D   197 E   198 F   199 G
   200 H   201 I   202     203     204     205     206     207
   208     209 J   210 K   211 L   212 M   213 N   214 O   215 P
   216 Q   217 R   218     219     220     221     222     223
   224     225     226 S   227 T   228 U   229 V   230 W   231 X
   232 Y   233 Z   234     235     236     237     238     239
   240 0   241 1   242 2   243 3   244 4   245 5   246 6   247 7
   248 8   249 9   250     251     252     253     254     255
0Where   HT  is  horizontal tab
         NL  is  newline
         CR  is  carriage return
         LF  is  line feed
         NP  is  newpage
         BS  is  backspace
         SP  is  space
0and the end-of-stream character ENDSTREAMCH is minus one.
1                Appendix D:  Common extensions
+                ______________________________
-        The extensions given here are available on the 370 version of
 BCPL and, although they are not in the standard language, they should be
 considered by other implementers of BCPL planning to extend the
 language.   This appendix is provided in the hope that it will reduce
 needless incompatibilities between different implementations.
0        It must be stressed that these extensions should only be used
 where absolutely necessary, and then as sparingly as possible.   They
 tend to decrease the efficiency and the understandability of the program
 and often indicate bad programming style.
0        On machines with suitable wordlengths, floating-point arithmetic
 and field selection are appropriate extensions.   These are described in
 the next two sections The last section describes other miscellaneous
 extensions[
0Floating-point arithmetic
+_________________________
-        A floating-point constant may have one of the following forms:
                 i.jEk
                 i.j
                 iEk
0where i and j are unsigned integers and k is a (possibly signed)
 integer.   The value is represented on the 370 as a 32 bit floating-
 point number.
0        The arithmetic and relational operators for floating-point
 quantities are as follows:
0                #*  #/
                 #+  #-
                 #=  #~=  #<=  #>=  #<  #>
0They have the same precedence as the corresponding integer operators.
 There are, also, two monadic operators FIX and FLOAT for conversions
 between integers and floating-point numbers.   They have the same
 precedence as @.
-Field selectors
+_______________
0        Field selectors allow quantities smaller than a whole word to be
 accessed with reasonable convenience and efficiency.   A selector is
 applied to a pointer using the operator OF(or ::).   It has three
 components: the size, the shift and the offset.   The size is the number
 of bits in the field, the shift is the number of bits between the
 right-most bit of the field and the right hand end of the word
 containing it, and the offset is the position of the word containing the
 field relative to the pointer.
0        The precedence of OF is the same as that of the subscription
 operator(!), but its left operand (the selector) must be a constant
 expression.   A convenient way to specify a selector is to use the
 operator SLCT whose syntax is as follows:
0        <constant expression>  ::=  SLCT <size>:<shift>:<offset> |
                                     SLCT <size>:<shift> |
                                     SLCT <size>
0where <size>, <shift> and <offset> are constant expressions.   Unless
 explicitly specified the shift and offset are assumed to be zero by
 default.   A size of zero indicates that the field extends to the left
 hand end of the word.
0        Selectors are best defined using manifest declarations.
0        A selector application may be used on the left hand side of an
 assignment and in any other context where an expression may be used,
 except as the operand of @.   In the assignment
0                F OF P := E
0the appropriate number of bits from the right hand end of E are assigned
 to the specified field.   When
0                F OF P
0is evaluated in any other context, the specified field is extracted and
 shifted so as to appear at the right hand end of the result.
0        On the 370, fields corresponding to half-words and bytes are
 treated efficiently.
-Miscellaneous extensions
+________________________
0a)      Identifiers
0        Capital and small letters, dots and underlines may be used in
 identifiers and section bracket tags.   System words must still be spelt
 in capitals.
0b)      Constants
0        Binary, octal and hexadecimal constants may be written using the
 warning sequences #B, #O(or just #) and #X.   They denote right
 justified values.
0c)      Comments
0The sequence || (like //) introduces a comment which extends to the end
 of the line.   The sequence |* ...   *| (like /* ...   */) is a
 bracketed comment (possibly containing newlines).
0d)      Operators
0        The monadic operators ABS and #ABS obtain the absolute value of
 an integer or floating-point number.   They have the same precedence as
 @.
0        The operator <> has a similar meaning to semicolon but is
 syntactically more binding than DO, OR, REPEAT etc.   For example
0                IF E DO C1 <> C2
0is equivalent to
0                IF E DO $( C1 ; C2 $)
0        The operator _ is a synonym for the assignment operator :=, and
 both may be preceded by one of the following diadic operators:
0                *  /  REM  #*   #/
                 +  -  #+  #-
                 &
                 |
                 EQV  NEQV
0The meaning of
0                E1 <op>:= E2
0is the same as
0                E1 := E1 <op> E2
0e)      Segment headings
0        A segment of BCPL program may start with a directive of the
 following form:
0                SECTION "name"
0where name is a module name acceptable to the linkage-editor.   It
 defines the section name given to the object module corresponding to the
 segment of program.
0        This directive may be followed by one or more directives of the
 form:
0                NEEDS "name"
0where name is a module name acceptable to the linkage-editor.   It
 causes an external reference to be set up in the object module, with the
 result that the specified object will be retrieved automatically by the
 linkage-editor.
1
