PLASYD NOTES

The set of PLASYD Notes, initially PL1900 Notes until the name was changed, show the development of the language. PLN 14, PLASYD - A Programmer's Guide, is effectively the manual used by ICL staff and was the main basis for the Atlas Computer Laboratory's PLASYD Manual..

ReferenceTitleAuthorDate
PLN 1Introduction to PL1900JKB13.08.68
PLN 2PLASYD - Syntax and NotesJKB04.09.68
PLN 3On PL1900: Note 1AW17.07.68
PLN 4On PL1900: Note 2AW17.07.68
PLN 5Example of the use of PL1900 to Define Basic List Processing ProceduresDMF22.07.68
PLN 6PL1900: Note 3JKB26.07.68
PLN 7Notes on the Trusted Program Controlling PL1900PHD24.07.68
PLN 8PL1900: Note 4JKB29.07.68
PLN 9PL1900: Note 5JKB02.08.68
PLN 10PLASYD Linkage with Functional LanguageVDW05.08.68
PLN 11Amendments to PLN 2 Version 2JKB15.08.68
PLN 12POLGEN and relationsJKB28.08.68
PLN 13Monitoring and Trace Facilities in PLASYDPHD15.10.68
PLN 14PLASYD - A Programmer's GuideJKB, PHD1969
PGEN 1Some Notes on the PLASYD Programming SystemJKB1969

Note: PLASYD was originally called PL1900.


PLN 1

INTRODUCTION

TO

PLASYD

A language for software production for the 1900 series computers

Version: 3 August 1968

Note: PLASYD was originally called PL1900.

1. General

The language is designed to allow any machine code facilities to be exploited. However, some aspects of the order code are made easier to use, sometimes at a slight cost in efficiency, sometimes with no penalty. In general more effort is made to simplify flow of control that data manipulation, over which the user has more direct control.

Within the limits imposed by the first design aim the second aim is readability. The syntax of the language is Algol-like though much simpler and no run time stack is required. In addition the 'fixed word symbols' of Algol are replaced by reserved words so that spaces become significant. In certain cases the need. for readability requires that certain non-significant characters be written and punched (to the annoyance of programmers and punch girls). As a compromise, during transfer to disc, full and reduced forms of certain fixed symbols are allowed (e.g. INT for INTEGER) but the full form is always listed. Comments may appear anywhere between symbols and identifiers and will be ignored. (In fact if a symbol input routine is used, which seems sensible, comments could even appear within identifiers).

The compiling system must have the ability to separately compile segments which are procedures and to later consolidate such segments to make a program which can possibly be overlaid. Decisions on overlaying and the incorporation of common store areas into overlays are delayed until consolidate time.

2. The Compiling Svstem

The PLASYD compiler must produce normal semi-compiled output (possibly with minor modifications) and this must be capable of being consolidated and possibly overlaid in the normal way. Compilation is to be one segment at a time and, if possible the whole segment should be held in store at one time, minicompiler fashion. This will greatly simplify the processing of FOR loops and forward jumps but is not essential. Input to the compiler should be from slow peripheral or disc. The compiling system must be capable of reading a complete set of segments from one disc file and producing a corresponding semi-compiled file. The compiler must be interfaced with a consolidator and an editor program in such a way that the following sequence of operations is provided automatically on receipt of some parameters:-

  1. The source segments held on a disc file are selectively replaced or amended or added to, according to slow peripheral parameters, from a slow peripheral or source segments in other files.
  2. The changed or added segments are compiled and the output (optionally) replaces segments of, or is added to, the semi-compiled file. A listing of recompiled segments is produced.
  3. The semi-compiled file is selectively or totally consolidated according to overlay information stored in a standard steering segment or according to new information from slow peripherals which can optionally replace the stored information. Consolidation details are listed.
  4. The newly consolidated program is optionally run with trial data. In order to provide complete flexibility it is probably advantageous to produce a simple minded compiler and to have the edit/compile/consolidate/run sequence master-minded by a trusted program (R.C.T.P. so it can run on the 1903).

3. Code Generated

The compiler itself must be written in 15AM, DBM using the basic instruction set (1903 type) and may assume a 32K store for itself and the trusted program. The object program produced must be in one of four modes, set by switches or parameters as under:-

  1. Either 15am or 22am, DBM and basic instruction set
  2. Either 15am or 22am, DBM and simulated extended set
  3. 22am, DBM and extended instruction set
  4. 22am, EBM and extended instruction set.

Mode 2 is to be used only for testing programs to be finally produced in mode 3. The extra instructions available (MVCH, SMO etc) are simulated. by macros. Mode 4 is not necessary for the initial version. Mode 1 should be implemented first and the others bootstrapped. This will provide a test of the facilities available.

The form of the language is such that the code may be as optimised as the programmer wishes e.g.

            X1 ← X1 + F  is compiled as  ADX   1   F
while       X1 ← F  + X1 is compiled as  LDX   1   F
                                         ADX   1   1

and means something quite different.

In cases where more control is needed over the instructions generated, facilities are available for the insertion into program or data of all machine orders in a pseudo functional form.

4. Pros and Cons

The advantages of PLASYD over PLAN are:-

  1. It is more easily readable and therefore easier to document and maintain.
  2. Many of the chores associated with flow of control are removed from the programmer.
  3. With no customer pressures we can build an editing/compiling/operating system more suitable to our needs than the PLAN systems.
  4. We can from inception incorporate the EMA functional language (see 6).

The disadvantages compared with PLAN are:-

  1. PLAN exists, PLASYD doesn't.
  2. Many people are already familiar with PLAN.

The first of these is slightly offset by the fact that even with PLAN we might have to design an operating system of our own for use with large projects.

The advantages of PLASYD over a higher level language are:-

  1. Being machine dependent it produces efficient code with little bother.
  2. Its syntax is designed for ease of implementation i.e. much of the grammar is context free and is restrictive enough to allow in most cases only one way of doing something.
  3. It can be implemented much faster than a new high level language and no existing h.l.l. is suitable.

The disadvantage compared with a h.l.l. is:-

  1. Being machine dependent it is not transferable to another machine.

5. General form of the language

A unit for compilation consists of a program or a segment. A segment takes the form of a procedure which can be called from other segments without previous declaration {FORTRAN style). Procedures have no parameters but specify their link accumulator and common information may be left in accumulators, common (global) areas, or in the case of procedures which are not separate segments, in variable space.

A segment begins with

             PROCEDURE <identifier> (<link>); BEGIN

or just plain BEGIN for a non-procedure segment.

Segments consist of: a block, that is a BEGIN followed by declarations followed by statements followed by END, and blocks may be nested. This enables the compiler to share storage between variables in different blocks where possible. Recursion is not explicitly permitted and must be provided for by the programmer.

Declarations serve to give names to storage cells which may be 24 bits, 48 bits or 96 bits long and to assign synonyms to accumulators. A special set of declarations are available to ensure that certain named cells are in LOWER store or in GLOBAL blocks. Global blocks are storage which may be common to the routines of one overlay unit {OVERCOMMON) or to the whole program (COMMON PERMANENT) the distinction being defined at consolidate time.

A convention for upper store addressing has been adopted which attempts to minimise the amount of lower store used for literals. This allows upper storage cells to be grouped together into "domains" the address of the first cell being stored in LOWER storage and forming the "base" of the domain. The address @A of any cell A in upper storage is given by the sum of its base £A and its displacement from the base $A. Domains are limited to 4096 words so that $A can always be expressed in 12 bits. For quantities in lower £A is zero and $A is the word address. To address characters whether in upper or lower a modifier (or SMO) must always be used.

Arithmetic and logical operations with real and integer operands are expressed by assignment statements

    X1 ← A + B/C + D*3 

which are executed in strict left to right order. Beside the normal arithmetic operations shift operators etc. are available. Parts of the data may be declared as arrays and references may be made to array elements:-

    X2 ← A(X1+3) 

The complexity of the index allowed depends on whether or not SMO is available in the current output mode. In the case of arrays in upper storage the array name implies $A and it is assumed that the programmer has placed £A in the modifier register already. An attempt to address A directly without the use of a modifier or supplementary modifier will be flagged.

Flow of control is handled by

    GO TO statements - unconditional jumps 
    OBEY statements  - Execute one statement out of line 
    CASE statements  - Execute one of several out of line statements
    FOR statements   - incremental loops 
    WHILE statements - conditional loops 
    Procedure calls. 

Variables may be given initial values which they will have on initial loading and any subsequent reloading caused by the overlay system. Variables not so assigned have undefined values on loading or reloading. Only GLOBAL store which is placed by the consolidator in permanent can be relied upon to retain information from one overlay call to another.

6. The EMA functional language

This is the system used for tree analysis and code generation in the 1900 and ORION E.M.A. compilers. For this particular purpose it is a very powerful tool though it is not so useful in the remainder of the compiler or in non-compiler programs (e.g. run time routines) which could be produced in PLASYD. It therefore seems convenient to incorporate the functional language into the PLASYD compiler in some sense. More details are given in Appendix to PLASYD Syntax and Notes.

J.K. Buckle

680621

Modified
680729
680813


PLN 2

PLASYD - Syntax and Notes

J. K. Buckle

Version: 3

1969

Contents

Appendices

Introduction

This document is a fairly rigorous description of the syntax of the PLASYD language together with informal descriptions of the semantics, programmer's viewpoint and implementation notes. Each section is therefore divided into up to four subsections.

  1. Syntax in modified B.N.F.
  2. Examples where applicable
  3. Semantics and programming notes
  4. Implementation notes where applicable.

Loosely speaking the syntax metalanguage is as follows :-

  1. ::= means "is defined as".
  2. | means "or".
  3. A quantity in angle brackets < > to the left of ::= is a class whose members take one of the forms on the right of ::=.
  4. Appearance of an item in angle brackets to the right of ::= indicates that this may be replaced by any of the members of that class.
  5. An item in angle brackets with associated limits <item>nm means that there may be m, m+1, .... , n consecutive occurences of that item. An upper limit of * means infinity.
    Thus <Asymbol> ::= A
         <name>    ::=<A symbol>41
    
    would allow <name> to take one of the forms A, AA, AAA or AAAA while
         <name>    ::=<A symbol>*0
    
    would allow a null name or A or AA or AAA or .... etc.
  6. A subsidiary backwards definition appearing in parenthesis after a main definition e.g.
         <I assignment> ::= <I Register> ← <I address> (I =:: INTEGER | LONG INTEGER) 
    
    means that the subsidiary definee should be replaced consistently by one of its definitions throughout the main definition. Thus the example above is equivalent to
         <INTEGER assignment> ::= <INTEGER Register> ← <INTEGER address>
    and
         <LONG INTEGER assignment> ::= <LONG INTEGER Register> ← <LONG INTEGER address>
    
    We can think of =:: as "stands for".
  7. The backwards definition of section 5 is valid throughout the description.

Within PLASYD spaces and new lines or end of card (72 characters) are significant and are used, together with other non-alphanumeric symbols, to terminate identifiers, numbers and reserved words. New lines do not however terminate statements. Lines from whatever medium must not be greater than 72 characters, or character positions. Tabs are considered to be at 6 character intervals.

1. Modes

  1. K =:: INTEGER | REAL | LONG INTEGER | LONG REAL
    
  2. If K appears more than once in a syntactic rule it must be replaced consistently or possibly according to further rules in the accompanying text. Thus, for example
         <K register> ::= <K register identifier> 
    means 
         INTEGER register ::= INTEGER register identifier 
         REAL register    ::= REAL register identifier etc. 
    
         INTEGER         corresponds to the 1900 24 bit signed integer
         REAL            corresponds to the 1900 48 bit floating point number
         LONG INTEGER    corresponds to the 1900 48 bit double length integer
         LONG REAL       corresponds to the 1900 96 bit double length floating point number
    
  3. LONG REAL and LONG INTEGER can be omitted from the first version of the compiler.

2. Basic Symbols

  1. <character> ::=
         A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|
         0|1|2|3|4|5|6|7|8|9|
         +|-|*|/|<|=|>|#|←|,|.|;|:|@|%|"|&|(|)|[|]|£|$|?|'|!
    <basic symbol> ::= <character>|
        AND|OR|ER|NOT|NEG|SLL|SRL|SLA|SRA|SRAV|SLC|SRC|IF|THEN|ELSE|CASE|OF|
        CASEND|WHILE|DO|FOR|STEP|UNTIL|BEGIN|END|GOTO|OBEY|GO|TO|FIX|FLOAT|
        REAL|LOGICAL|INTEGER|CHAR|FUNCTION|PROCEDURE|GLOBAL|LOWER|LONG|EX|
        SYN|ACC|LOWEND|GLOBEND|MINUS|UNDER|FROM|CARRY|CNT|CH|INTERPRET|INCLUDE|
        BASE|OVERFLOW|FOVERFLOW|EXTERNAL|ENTRY|GLABEL|DEFINE|DATA|NULL|SA|LA|
        PURE|PUREND|RETURN|BRINGOVERLAY|NONPLASYD
    
  2. All characters within the symbols [ and ] are ignored as comment, except within strings and character sequences where [ ] are normal characters. Fixed word symbols are terminated by any non alpha-numeric character, including space.

    The symbols := are allowed as an alternative to . The full form of all reserved words must be presented to the compiler.

    There is a facility in the language for conditional compilation. The sequence ?<n> (other than in a string or character sequence, where <n> is a positive integer less than 11, will cause the following PLASYD statements up to sequence )?<n> outside a string or character sequence, to be compiled if system switch <n> is on.

    This can be used for optionally compiled calls to a TRACE package if required.

  3. A full listing of all compiler input should be produced on request. A possible error should be signalled if following a [ another [ is found before a ]. Comment should be made when a section of program is omitted by the ? facility. PURE and PUREND are reserved for future use when writing PURE programs.

3. Identifiers

  1. <letter> ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|%
    <identifier> ::= <letter>|<identifier><letter>|<identifier><digit>
    <K accumulator identifier> ::= <identifier>
    <K cell identifier> ::= <identifier>
    <procedure identifier> ::= <identifier>
    <block identifier> ::= <identifier>
    <lower K cell identifier> ::= <identifier>
    <upper K cell identifier> ::= <identifier>
    <label identifier> ::= <identifier>
    <instruction identifier> ::= <procedure identifier>|<label identifier>
    
  2. A KAREN CATCH22 A1B2 %ASPACE
  3. Identifiers are associated with a K accumulator, a K cell, a procedure or function by an appropriate declaration. They may also be associated with a disc subfile in which case they must also conform to other conventions. Identifiers are restricted to 32 characters in any case.

    The fixed words of section 2 may not be used as identifiers, nor may the fixed accumulator identifiers of section 5.

    Identifiers may only be re-used for quantities with absolutely disjoint scopes. Temporary redefinition of identifiers as in Algol is not permitted.

  4. Since recursion is not specifically catered for there is no need for a run time stack. However, variables in disjoint blocks should be made to share space by the compiler. This can be achieved by keeping current pointers for upper and lower storage and incrementing (decrementing) them at the beginning (end) of a block.

4. Values

  1. <digit> ::= 0|1|2|3|4|5|6|7|8|9
    <unsigned integer number> ::= <digit>*1
    <unsigned long integer number> ::= <unsigned integer number>D
    <fractional number> ::= <unsigned integer number>.<digit>|
                                       <fractional number><digit>
    <exponent> ::= <integer number>
    <unsigned real number> ::= <fractional number>|
                               <fractional number>&<exponent>|
                               <unsigned integer number>&<exponent>
    
    <unsigned long real number> ::= <unsigned integer number>L|
                               <unsigned real number>L
    <K number> ::= <unsigned K number>|MINUS <unsigned K number>
    <octal digit> ::= 0|1|2|3|4|5|6|7
    <octal value> ::=#<octal digit>*1
    <truncated number> ::= <integer number>T<unsigned integer number>
    <count> ::= <integer number> CNT
    <string> ::= "<character>*1"
    <character sequence> ::= '<character>41'
    <integer value> ::= <integer number>|<octal value>|<truncated number>|
                       <count>|<character sequence>
    <long integer value> ::= <integer number> D|<octal value> D
    <real value> ::= <real number>|<octal value> R
    <long real value> ::= <real number> L|<octal value> L
    <unsigned integer> ::= <unsigned integer number>
    
    
  2. #270 45CNT "STRING" MINUS 31T15 '%'
    37 13725.21&24 MINUS 1D 3.14159L
    
  3. Exponents denote an integral power of ten.

    MINUS indicates that the quantity following is to be stored as a negative number. CNT followed by a number means "Store in the top nine bits". This is different to the operator CNT (See Section 8 below).

    Numbers must lie within the limits imposed by hardware.

    A string is a sequence of six bit characters which is stored starting at character position zero of a 1900 word. Strings are space filled to the right to a multiple of four characters. Character sequences normally contain one character only although they may contain up to four. They are a type of integer value and can be considered as a sequence of 6 bit characters zero filled to the left to produce 24 bits.

    " within a string, and ' within a character sequence are represented by "" and '' respectively.

    A truncated number is formed by producing the binary equivalent of the integer number (which may be signed) and truncating the most significant end to leave only the number of bits indicated by the unsigned integer number.

  4. MINUS, T and the trailing CNT are all compile time operators and are an integral part of the number they are associated with. By contrast NEG and - are run time operators and serve to initiate the particular instruction which should be compiled. See also section 8 below. Truncated numbers may be omitted from the first version.

5. Accumulator Declarations

  1. <INTEGER accumulator> ::= X0|X1|X2|X3|X4|X5|X6|X7
    <modifier> ::= X1|X2|X3
    <LONG INTEGER accumulator> ::= X01|X12|X23|X34|X45|X56|X67|X70
    <REAL accumulator> ::= A1
    <LONG REAL accumulator> ::= A12
    
  2. The integer accumulators correspond to the fixed point accumulators of the 1900 in an obvious way. Similarly for the other types. The LONG REAL accumulator is available only on machines with that hardware.

    The accumulators may be assigned other names by the SYN declaration (see 12 below)

  3. There is no need to implement LONG REAL or LONG INTEGER in the first version of the compiler but "space" should be left for them.

6. Cell declarations

  1. <integer type> ::= INTEGER|LOGICAL
    <long integer type> ::= LONG INTEGER|LONG LOGICAL
    <real type> ::= REAL
    <long real type> ::= LONG REAL
    <K cell declaration> ::= <K type><item>|<K cell declaration>,<item>
    <simple item> ::= <identifier>|<identifier> = <initial value>
    <array item> ::= <identifier>(<array length>)|
                    <identifier>(<array length>) = (<initial value list>)>
    <item> ::= <simple item>|<array item>
    <array length> ::= <unsigned integer number>
    <inital value list> ::= <initial value>|
                           <initial value>=<array length>|
                           <initial value list>,<initial value list>
    <initial value> ::= <K value>|<string>|<fixed address>|<function statement>|
                       <count> + <fixed address>|<count> + <integer number>|
                       <count> + <truncated number>|<count> + <octal value>
    <declaration list> ::= <K cell declaration>|<base declaration>|
                              <declaration list>;<declaration list>
    <base declaration> ::= BASE
    <block declaration>::= <block identifier>:<declaration list>
    <global tail> ::= <block declaration>GLOBEND|<block declaration>;<global tail>
    <global declaration> ::= GLOBAL <global tail>
    <lower block> ::= <declaration list>|<global declaration>|
                     <lower block>;<lower block>
    <lower declaration> ::= LOWER <lower block> LOWEND
    
  2. REAL X, Y, Z; INTEGER I, J = 13,K; LONG REAL P(L);
    REAL XAR(20), NEXT, YAR(10)=(4.3,2.4,0.0,* 6, 1.0); BASE;
    INTEGER Z(20) = (@I,257CNT + @J, 131CNT + 7, MINUS 4,!LDX(1,0);
    LOWER REAL VW, MGB; GLOBAL BUFF:INTEGER B(32) GLOBEND LOWEND ;
    
  3. A cell declaration introduces identifiers and associates them with calls of the specified type. The validity is throughout the block in the head of which the declaration occurs. Moreover the declaration may specify an initial value to be stored in the cell. This is permanent in the sense that it will be reset by any overlay. Initial values may only be assigned to quantities in an outer block or a segment. A string is stored in successive character positions beginning at character 0 and is space filled to a multiple of four characters.

    Initial values must be of the same type as the cell and for this purpose addresses, strings, function statements and values with <count> as a component are considered to be integer.

    If a cell identifier is followed by an integer or an absolute quantity (see section 24) in parenthesis, that number of storage cells will be allocated to make a one dimensional array. The number of 1900 words assigned to each cell is as follows :-

    INTEGER, LOGICAL    -  1 word
    REAL, LONG INTEGER  -  2 words
    LONG REAL           -  4 words
    

    An initial list of m entries specifies initial values for the first m elements of the array. If an initial value is followed by *n it is equivalent to n identical initial values. Each initial value will correspond to one element of the array, unless the initial value is a string, in which case it will fill as many words as necessary.

    All identifiers (except label or procedure identifiers) must be declared before they are used. Thus in the examples I had to be declared before @I was used as an initial value. <fixed address> is the location (to 22 bits) of the K cell or label or procedure concerned, and may possibly also involve a character address. For details see 7, 8 below. The L in the LONG REAL declaration is assumed to have been set by a define statement - see 24 below.

    A global declaration makes COMMON blocks of all the block declarations it contains. The block identifier is the common block name and the decision on whether the block is permanent or overcommon is delayed until consolidate time. Block declarations with the same identifier are added sequentially.

    A block identifier and a cell identifier must not have the same name e.g. GLOBAL JACK: JACK is not allowed.

    All items within a LOWER declaration are forced into the first 4096 words.

    Upper (i.e. non LOWER) non-GLOBAL locations are dealt with in the following way :- the address of the first upper storage location mentioned is stored in lower and this becomes the base of a "domain" of up to 4096 words. All subsequent cells are stored in consecutive locations and are addressed by their "displacement" from this base. If a base declaration appears a new base is stored and subsequent addresses are relative to that. If 4096 words are declared without a base statement appearing a new base is inserted by default and a comment listed.

    Each non-lower block declaration has a new base associated with its first word and this base is stored in a location which is associated with the block identifier. Additional bases may be introduced by base declarations.

    All lower quantities have a base of zero and a displacement which is their address, regardless of whether they are global or not.

    Upper non-global items will be stored in successive words in the order of declaration. So will items within a global block.

    Either the initial values given to the variables in global block should be identical in all segments or they must be assigned in one segment only.

  4. The compiler must deal with what are effectively a number of compile time stacks. These are:

    • The lower stack - begins at some lower word and contains all lower quantities. Note that other segments will also use lower storage and that lower blocks cannot have bases.
    • The upper stack - all non global upper quantities.
    • The global stacks - one for each block declaration.

    For each stack there must be a stack pointer to the last used (or first unused) word of the stack. This will be incremented as declarations are encountered. and decremented as blocks are left. The pointer for the lower stack is a simple (relative) address. For the upper stack and for each global stack is the current base address (which is stored in lower and will be a relative address) plus an absolute displacement. Exit from block may well cause alteration of the current base as well as the displacement. Obviously the maximum reached by any stack at any point must also be recorded. The cell symbol table entries must contain the following information.

    1. The type of cell
    2. Its base address and the location of its base in lower
    3. Its displacement
    4. The block number of its declaration

    On exit from a block, corresponding symbol table entries will be destroyed. Both the items under 2 are needed, the first for compile time calculated, the second for run time use.

    The blocks within a procedure declaration may share storage with each other but the maximum amount of storage declared throughout the definition of the procedure must be reserved throughout the life of the block in which the procedure is declared. (As a first shot, which would probably not waste much in practice, all declarations at any depth would constitute declarations at the level of the block in which the procedure is declared). Character arrays must begin in the first character of a word. Once an array has been declared there is no reason to distinguish between arrays and simple variables.

    All non-global variables go into upper or lower preset. However, global blocks should go into preset if any initial values are set, variable otherwise.

7. Cell designators

  1. <K cell designator> ::= <simple K cell designator>|(<free SMO index>)|
                           <K cell identifier>(<SMO index>)
    <simple K cell designator> ::= <lower K cell identifier>|(<free index>)|
                                  <lower K cell identifier>(<fixed index>)|
                                  <K cell identifier>(<variable index>)
    <variable index> ::= <modifier>|<modifier>+<unsigned integer>|
                        <modifier>-<unsigned integer>
    <free index> ::= <unsigned integer>|<modifier>|<modifier>+<unsigned integer>
    <fixed index> ::= <unsigned integer>|-<unsigned integer>
    <simple SMO index> ::= <simple integer cell designator>|
                          £<K cell identifier>|<block identifier>
    <free SMO index> ::= <simple SMO index>|<simple SMO index>+<free index>
    <SMO index> ::= <free SMO index>|<simple SMO index>-<unsigned integer>|
                   <simple SMO index>+<modifier>-<unsigned integer>
    
  2. A (X1)  (X1 +5) (30)  A(8) A(-8) A(X1) 
    
    A(X1-10) U(X2) U(X3+5) B((6)) A(B) A(B+X1-1) 
    
    U(B+X3-1) (B) U(B(X1-5)+X2-1) U(£U) (BLOCK+3) 
    
    ((X3)) U(£U+X1-70) U(V(X1)) 
    
  3. Cells are denoted by cell designators. In the case of cells of simple lower type (i.e. declared within a LOWER declaration) the designator can consist simply of the identifier associated with that cell. In the case of lower arrays the array name is followed by an index which designates an element of the array. The index value is divided by the number of memory units (words) occupied by each cell and this is used as the element number of the array to be addressed. The first element of an array has number zero. The result of the division must be positive and the remainder zero. Indices can also be applied to simple variables. The simple variable is then treated as an array with an indefinite number of elements whose first element is the simple variable itself. Similarly references can be made to array elements outside the declared size of the array. In the case of upper variables and arrays a special course is adopted to overcome the 12-bit address field of the 1900. This works in the following way :-

    The address of an element A in upper is known as @A and consists of two parts. The first is the base of the domain in which A exists and will be in general a 22 bit address. This is referred to as £A. The displacement of the element from this base in storage units (words) is referred to as $A. This must always be ≤ 4095. If an upper quantity is to be referenced it must have an index following the identifier and this must contain the £A part of the address either as an explicit quantity e. g. U(£U), or by reference to a store location which contains this quantity e.g. U(B+3) where B contains £U possibly as a constituent of its value, or by reference to a modifier e.g. U(X1) where the contents of X1 are similar to B. Thus the reference to an upper quantity outside the index is really only a reference to its $ part. The user is required to set up the store location or the modifier with the correct value himself. Attempts to refer to upper quantities without subscripts or with constant subscripts will be faulted.

    Indices with no preceding address are taken as a reference to an element of the untyped array which begins at word zero of the store and runs to the end of the store. Thus(30) indicates word 30 of tbe store and ((X3)) indicates the word whose address is held in the word whose address is held in the modifier X3. Integer accumulators may be treated as store locations by this means e.g. (1)

    Note that all use of SMO indices will produce a SMO instruction in the object code. The appropriate method of compilation should therefore be in use.

    The constant parts of indices when added into or subtracted from the displacement must produce a result between 0 and 4095 inclusive.

  4. Assuming that A is a lower quantity, B is a lower integer, U and V are upper quantities and V is an integer, and BLOCK is a block identifier the examples of part b are equivalent PLAN addresses in non literal instructions as follows :-

         
        PLASYD                       PLAN                    NOTES   
        ------                       ----                    -----
           A                           A     
      1.   (X1)                      0(1)     
      2.   (X1+5)                    5(1)     
      3.   (30)                      30     
      4.   A(8)                      A+8                       1   
      5.   A(-8)                     A-8                       2   
      6.   A(X1)                     A(1)     
      1.   A(X1-10)                  A-10(1)     
      8.   U(X2)                     $U(2)     
      9.   U(X3+5)                   $U+5(3)     
      10.  B((6))            SMO     6                         3   
                                     B     
      
      11.  A(B)              SMO     B     
                                     A     
      
      12.  A(B+X1-1)         SMO     B     
                                     A-1(1)     
      
      13.  U(B+X3+1)         SMO     B
                                     $U+1(3)                   1   
      
      14.  (B)               SMO     B     
                                     0     
      
      15.  U(B(X1-5)+X2-1)   SMO     B-5(1)     
                                     $U-1(2)                   2   
      
      16.  U(£U)             SMO     £U     
                                     $U                        4   
      
      17.  (BLOCK +3)        SMO     BLOCK A     
                                     3                         5   
      
      18.  ((X3))            SMO     (3)      
                                     0     
      
      19.  U(£U+X1-70)       SMO     £U
                                     $U-70(1)     
      
      20.  U(V(X1))          SMO     $V(X1)     
                                     $U
    

Notes

  1. A+8 and $U+1 must not be ≥ 4K.
  2. A-8 and. $U-5 must be positive or zero.
  3. SMO could be replaced by an SMO macro - see below.
  4. £U is a lower location which contains the address of the domain in which U appears. It can always be treated thus except in an initial value when the domain address itself must be used.
  5. BLOCK A is the address of the initial base of the common block BLOCK.

The pseudo SMO macros for

SMO      N1(N1)
XXX  X   N2(N2)

where SMO has not been produced by !SMO are as follows :-

  1. If the second address is not modified (e.g. 11,14,16,17,18,20) i.e. No M2
          STO     M    WS    [some workspace] 
          LDX     M    N1(M1)  
          XXX     X    N2(M) 
          LDX     M    WS 
    
    Where M is an modifier other than X
  2. If M2 is present but is not the same as X (e.g. possibly 12, 13, 15, 19)
      
          STO    M2    WS   
          ADX    M2    N1(M1)   
          BVSR         * + 1   [in the case of overflow]   
          XXX    X     N2(M2)   
          LDX    M2    WS   
          
  3. M2 ≡ X (e.g. as ii). Let M3 be any modifier other than M2 (Note that a simple macro could be used for the LD or NGX, NGN instructions but is probably not worth it).
          STO   M3   WS   
          LDX   M3   N1(M1)   
          ADX   M3   M2   
          BVSR       * + 1   
          XXX   M2   N2(M3)   
          LDX   M3   WS
    

Note that any previous overflow will be lost in cases (ii) and (iii) and that carry will be cleared by the pseudo SMO which is different from the actual SMO and if carry is set the accumulator M is corrupted by the addition of 1.

8. Accumulator assignments

  1. <K primary> ::= <I accumulator>|<K value>|<K cell designator>
                          (I=::INTEGER|LONG INTEGER)
    <simple K accumulator assignment> ::= <A accumulator>+<K primary>|
             <A accumulator>←NEG<K primary>|<R accumulator>←<R accumulator>|
             <integer accumulator>←<monadic operator><integer primary>|
             <integer accumulator>←CNT<C operand>|<address assignment>
                          (A=::K|LONG K; R=::REAL|LONG REAL)
    <address assignment> ::= <integer accumulator>←<address>|
             <integer accumulator>←<integer accumulator>+<address>
             <integer accumulator>←<integer accumulator>-<K word address>
    <K word address> ::= @<K cell designator>|$<K cell designator>|
                        £<K cell identifier>|@<K cell identifier>(<fixed index>)|
                        $<K cell identifier>(<fixed index>)
    <address> ::= <K word address>|CHAR <unsigned integer>|
                                CHAR <unsigned integer> OF <K word address>|
                                         @ <instruction identifier>
    <fixed K word address> ::=  @<fixed K cell designator>|
                                   $<fixed K cell designator>|£<K cell identifier>|
    <fixed address> ::= <fixed K word address>|CHAR <unsigned integer>|
                       CHAR <unsigned integer> OF <fixed K word address>|
                       @<instruction identifier>
    <monadic operator> ::= CARRY|EX|CH|NEG CARRY
    <K accumulator asssignment> ::= <simple K accumulator assignment>|
        <long integer accumulator assignment>/<integer cell designator>|
        <A accumulator assignment><arithmetic operator><K primary>|
        <real accumulator assignment><reverse operator><real primary>|
        <integer accumulator assignment><logical operator><integer primary>|
        <I accumulator assignment><shift operator><C operand>
        <real accumulator>←FLOAT<I cell designator>
          (I=::integer|long integer;A=::INTEGER|REAL|LONG REAL)
    <arithmetic operator> ::= <add operator>|*|/
    <add operator> ::= +|-|++|--
    <reverse operator> ::= FROM|UNDER
    <LOGICAL OPERATOR ::=  AND|OR|ER
    <shift operator> ::= SLL|SRL|SRA|SRAV|SLA|SLC|SRC
    <c operand> ::= <unsigned integer number>|<octal value>|<modifier>|
                       <simple integer cell designator>
    
  2. X1 ← 3          X1  ← X2              X1  ← A(B+X1-3)   
    A1 ← 3.14159    X12 ← 1D              X2  ← NEG 1   
    X6 ← CNT 12     X0  ← CARRY V(£V)     X70 ← U(X3)   
    X7 ← CH B(X1)   X6  ← '%'             X1  ← CNT X1   
    
    X1 ← @A(3)      X3  ← CHAR 1 OF £C    X6  ← X6+$U   
    
    X6 ← A/B-213    A1  ← A1 UNDER PI     X0  ← B AND #6617   
    X4 ← X1 SLL 6   A1  ← FLOAT B         X1  ← X1*X6   
    X12← X12/B      X4  ← CNT (6)         X7  ← X7 SRA B(X1+3)  
    
  3. An assignment statement allows the values designated on the right of the ← symbol to be assigned to the accumulator on the left. Operators in general parallel closely available machine functions.

    In this document the syntax given in (a) may not bo completely rigorous in that certain operations may not be (im)possible although (not) specified above. Attempts will be made to clear this up in later editions. As a general rule combinations which produce one 1900 machine instruction per operand, possibly with a preceding SMO order, are allowed. The syntax also fails to define certain limitations imposed by the operation of the 1900 e.g. the value following the shift operator should be less than 10 bits. More details of the meanings of operators are given below and in (d).

    Assignments are carried strictly from left to right including the initial assignment. Thus

    X1  ←  X1+X2    is quite different from
    X1  ←  X2+X1    which is however, the same as the sequence
    X1  ←  X2       and
    X1  ←  X1+X1 
    

    Unnecessary load instructions will not be compiled and the two similar sequences will produce identical machine code.

    Operators have their obvious or PLAN meanings where these exist. Possibly unfamiliar operators are as follows :-

    NEG      Negate the following operand
    CNT      Place the following operand in the top 9 bits
    CARRY    Use a load-setting-carry instruction 
    EX       Consider only the bottom 9 bits of the operand
    ++ )     Use a carry setting instruction with integers
    -- )     undefined for other types at present
    FROM     Reverse subtraction - reals only 
    UNDER    Reverse division - reals only
    
    CH       The following operand designates a 6-bit character. 
    FLOAT    Convert the integer in the first word and the fraction in the 
             second to real. 
    

    Address assignments place, subtract or add an address into or from an accumulator. i.e. the same accumulator must be specified. on both sides of . The @ $ and £ symbols are explained in section 7. CHAR <integer number> indicates a 1900 character modifier for that number of characters and the integer number must be in the range 0 to 3. The only way of designating a particular character storage cell is by use of a character address set up in this fashion as an initial value or by assignment as an index.

    For some instructions, multiplication and division of integers in particular, the 1900 order code places some nasty restrictions on operands and introduces messy side effects. If N and X are lower integers the following holds:

       A1←FLOAT N   expects N (1) to be cleared (or set to a fraction) 
       X1←N*X       produces an integer result in X1 but destroys X2 (sets it to zero) 
                    and involves a shift instruction. To obtain a long integer result 
                    more conveniently a function (see 10) should be used. 
       X1←N/X       produce an unrounded integer result in X1 and a remainder in X0 
    or X01←X01/X    (DVS or DVD) 
    

    Assignment of a character sequence to an integer accumulator puts it in the least significant bits with zeros elsewhere.

    Note that FLOAT accesses either an integer and the next word or a non-standard long integer. K cells whose type is not obvious e.g. (3),(X1) are assumed to be of the correct type for the L.H.S.

  4. The primary aim in defining the syntax is to allow only operations which are easily reduced to machine orders without redundancies. Only where the 1900 order code shows pathological deficiencies is this aim dropped.

    General rules for compilation of assignment statements are :-

    1. X1←X1 should never produce code
    2. Literal operand instructions should be used wherever possible.
    3. The only PLAN type literals generated are for non-zero, non-integer numbers or integers > 4095 modulus and character sequences of more than 2 characters.
    4. The compiler should never make assumptions about the programmer's intentions without at least flagging them.
    5. Checks should be made on 12-bit fields to ensure that they are 12-bits.
    6. Implied use of accumulators e.g. division, should produce a comment.

    The following is the code produced for the examples of (b) assuming the same declarations as in section 6, plus a lower real PI. More detailed notes follow.

            
            PL 1900                          PLAN EQUIVALENT   
    1.  X1  ← 3                        LDN      1        3
    2.  X1  ← X2                       LDX      1        2
    3.  X1  ← A(B+X1-3)                SMO               B
                                       LDX      1        A-3(1)
    4.  A1  ← 3.14159                  LFP               '.3145159E1'
    5.  X12 ← 1D                       LDN      2        1
                                       LDN      1        0
    6.  X2  ← NEG 1                    NGN      2        1
    7.  X6  ← CNT 12                   LDCT     6        12
    8.  X0  ← CARRY V(£V)              SMO               £V
                                       LDXC     0        $V
    9.  X70 ← U(X3)                    LDX      0        $U+1(3)
                                       LDX      7        $U(3)
    
    10. X7  ← CH B(X1)                 LDCH     7        B(1)
    11. X6  ← '%'                      LDN      6        #25
    12. X1  ← CNT X1                   LDCT     1        (1)
    13. X1  ← @A(3)                    LDN      1        A+3
    14. X3  ← CHAR 1 OF £C             LDCT     3        128
                                       ADX      3        £C
    15. X6  ← X6+$U                    ADN      6        $U
    16. X6  ← A/B-213                  LDX      6        A
                                       DVS      5        B
                                       SBN      6        213
    17. A1  ← A1 UNDER PI              FDVD     4        PI
    18. X0  ← B AND #6617              LDX      0        B
                                       ANDN     0        #6617
    
    19. X4  ← X1 SLL 6                 LDX      4        1
                                       SLL      4        6
    20. A1  ← FLOAT B                  FLOAT             B
    21. X1  ← X1*X6                    MPY      1        6
                                       SLA      12       23
    22. X12 ← X12/B                    DVD      1        B
    23. X4  ← CNT X1                   LDCT     4        0(1)
    24. X7  ← X7 SRA B(X1+3)           SMO               B+3(1)
                                       SRA      7        0
    

NOTES

Example 5
This may be difficult to implement and if so the facility should be removed from the language rather than unnecessarily complicating the compiler. Note that the non-carry setting loads are used for the least significant word. In any case LONG will not be in the first implementation.
Example 6
Note that X2 ← -1 is not allowed and X2 ← MINUS 1 is different, translating into LDX 2 '-1'. This is not particularly useful although X2 ← X2*MINUS 1 would be. X2 ← MINUS 32000 is the same as X2 ← NEG 32000.
Example 9
Note that LDX, LDX is used not LDXC, LDX. This allows reals or strings to be placed in a double length accumulator.
Example 10
The character loaded will depend on the contents of X1.
Example 11
A one or two character sequence will always produce a LDN.
Example 12
We recognise this as a modifier. If it had not been, a SMO would have been generated. The same applies to a shift operator (see examples 23 & 24). Note that shifts and CNT have an implied one level bracketting.
Example 13
Were A in upper this would produce 2 instructions LDX 1 £A and ADN 1 $A+3.
Example 14
But + CHARn should be done by n BCHX instructions.
Example 15 & 17
Note no redundant loads.

Long integer operations are similar to the corresponding PLAN macro except that constant loading is more efficient. When the right hand side is an integer the sign bit is removed and propagated through the first word. X12 ← N where N is an integer should produce

LDXC     2        N
NGN      1        0 

If any long integer facility produces problems we should modify the specification rather than introduce inefficiencies into the compiler or object program. Note that CNT can be used as an operator or as part of an integer value. They produce the same results for a simple assignment but by different means e.g.

X1 ← 324CNT    ⇒    LDX   1   '324/0'
X1 ← CNT324    ⇒    LDCT  1   324

The second is obviously better although the other form is essential for

X1 ← X1 + 324CNT    ⇒    ADX   1   '324/0'

EX indicates a LDEX instruction.

9. Cell assignments

  1. <simple K cell assignment> ::=
       <K cell designator>←<K accumulator>|
       <I cell designator>←<0|
       <real cell designator>←0.0|
       <Integer cell designator>←<store operator><integer accumulator>|
       <Integer cell designator>←<part operator><integer accumulator>|
       <I cell designator>←<I cell designator>|
       <simple I cell assignment><add operator><I accumulator>|
       <simple I cell designator><logical operator><I accumulator>|
       <Long integer cell designator>←NEG<long integer accumulator>
             (I=:: Integer|long Integer)
       <store operator> ::= NEG|CARRY|NEG CARRY
       <part operator> ::= EX|SA|LA|CH
       <K cell assignment> ::= <simple K cell assignment>|
                             <long integer cell designator>←FIX<real accumulator>
    
  2. A ← X1         U(B(X2)+1) ← 0         B ← NEG X2
    XX ← LA X3     A(3) ← X3+X2 AND X5    C(X1) ← CH X7
    X ← A1         W(X1) ← FIX A1         B(4) ← B(4) ++ X0
    (3) ← FIX A1   (3) ← A1               (X1) ←SA X6 
    
  3. A cell assignment is used to assign a value to a designated cell. The values must normally be accumulator values. If an I cell designator appears on each side of the ← symbol then these designators must be identical. (Thus the fifth simple K cell assignment form is X ← X and is useful only as part of the two forms which follow). The designators must also appear on the same line.

    The operators NEG, CARRY, EX and CH are similar to those for accumulator assignments except that EX does not disturb the remaining bits of the cell and the bottom six bits of the accumulator are used for CH, the character position of the cell being determined by the modifier if any. SA and LA mean the bottom 12 and 15 bits respectively, again without disturbing the remaining bits. The FIX operator, causes the largest integer less than the real number to be left in the first word of the long integer cell and a fractional part in the second. Note that it is inefficient to use assignments involving several logical or add operators with cells involving SMO indices.

    K cells whose type is not obvious e.g. (3), (X1) are assumed to be of the correct type for the R.H.S.

  4. The implementation is fairly obvious. Plan equivalents of (b) assuming suitable declarations are as follows:-

            
          PLASYD                       PLAN     
          ------                       ----
    A1 ← X1                     STO      1        A
    U(B(X2)+1) ← 0              SMO               B(2)
                                STOZ              $U+1
    B ← NEG X2                  NGS      2        B
    XX ← LA X3                  DLA      3        XX
    A(3) ← X3+X2 AND X5         STO      3        A+3
                                ADS      2        A+3
                                ANDS     5        A+3
    
    C(X1) ← CH X7               DCH      7        C(1)
    X ← A1                      SFP               X
    W(X1) ← FIX A1              FIX               $W(1)
    B(4) ← B(4) ++ X0           ADSC     0        B+4
    (3) ← FIX A1                FIX               3
    (3) ← A1                    SFP               3
    (X1) ← SA X6                DSA      6        (1)
    

10. Function declaration

c) By providing all the 1900 machine functions as standard the need to provide for an alternative method of labelling them is lessened. This section is therefore omitted from this document. The function definition may however, form a convenient way of providing simple local macro facilities which could be incorporated in versions of the compiler other than the first.

All the machine codes are available to the programmer as functions with their PLAN names preceded by the symbol ! with the exceptions that machine codes 111, 113, 115 are the PLAN name followed by the symbol 2, e.g. !SLC2, !NORM2, etc. Additional mnemonics for writing Trusted programs have been introduced namely: !SPP { (set PUC parameter) !ACT (Activate PUC) and !RMS (Request console message).

The method of calling these functions is defined in the next section.

11. Function statements

  1. <function statement> ::= <function identifier>(<X parameter>,<N parameter>)
    <function identifier> ::= !(identifier> 
    <X parameter) ::= <octal digit)|<integer accumulator>|<1ong integer accumulator> 
    <N parameter> ::= <simple K cell designator>|<unsigned integer number>| 
                      <octal value>|<character sequence>|<instruction identifier> 
    
  2. !CDB  (X34,C(X1))  !LDN (X1,4)  !GIVE(0,A(X2+3))  !FAD(3,B) 
    !LFPZ !NULL. 
    
  3. The function statement calls for the execution of one 1900 machine instruction. Note that the use of SMO indices in the cell designator is strictly forbidden. The octal digit and following ',' can be omitted in functions which do not require them (e.g. BVSR). The digit but not the comma may be omitted to imply zero. The N parameter must not exceed 12 bits plus an optional modifier, or must be an instruction identifier.

    Note that !LFPZ and !NUL !SUSAR do not have X or N parameters and !ACT and !SPP have only N parameters as X7 is assumed.

  4. The action is merely to produce a function with the first parameter in the accumulator field and the second in the address field. If a long integer accumulator is specified the first accumulator of the pair is used. No check is made on the use of long accumulators in this way. The effect of the extension of the definition to provide macros is given in Appendix 3.

12. Synonym declarations

  1. <K cell synonym declaration> ::= 
                 <K type> <identifier> <synonymous cell>|
                 <K cell synonym declaration>,<identifier><synonymous cell> 
    
    <synonymous cell> ::= SYN <fixed K cell designator>| SYN(<integer value>)|
                           SYN(<integer value>)=<initial value>
    <K accumulator synonym declaration> ::= 
                              ACC<identifier> SYN <K accumulator>| 
                <K accumulator synonym declaration>,<identifier>SYN <K accumulator> 
    
    <fixed K cell designator> ::= <K cell identifier>|<K cell identifier>(<fixed index>)
    
  2. INTEGER A16 SYN A(16)
    INTEGER MEM SYN(0)
    REAL FP SYN (0)
    INTEGER SWITCHES SYN(30)=#770047
    ACC SUM SYN A1
    INTEGER B1 SYN A(-4)
    REAL X = 1.73E5
    INTEGER XTOP SYN X, XBUTT SYN X(1)
    
  3. Synonym declarations associate extra names with cells or accumulators. The types associated with synonymous cells need not agree. The last examples show a use of this facility.

    The synonymous cell must have been declared before the synonym declaration. When the original is an integer value the synonym is taken as referring to that absolute location of the program. Only with this type of synonymous declaration can an initial value be set. The synonym given to an absolute location can be used wherever a normal K cell identifier could be used. In particular this facility can be used to make the fixed point accumulators act as K cells as in the second and third example above. Thus although X0←(X1) produces LDX 0 (1), X0←(MEM(1)) produces SMO 1, LDX 0 0. A fixed K cell designator using a fixed index should not be such that the cell designated is in a different domain to the cell designated by the identifier alone.

  4. Synonym declarations need to operate as normal declarations except that the storage, base and displacement assigned to the new identifier are the same as the original or are the absolute value stated. The type bits will however not be similar. Note that SYN<integer value> = <initial value> is accepted.

13. If statements

  1. <relation> ::= <|≤|=|≥|>|NOT=
    <character relation> ::= <CH|≤CH|>CH|≥CH
    <condition> ::= <K accumulator><relation><K primary>|
                   <I accumulator><relation><part address>|
                   <I accumulator><character relation><I primary>|
                   OVERFLOW|FOVERFLOW|CARRY|NOT OVERFLOW|NOT FOVERFLOW|
                   NOT CARRY  (I=:: INTEGER| LONG INTEGER)
    <part address> ::= £<K cell identifier>|$<K cell designator>
    <combined condition> ::= <condition>|<combined condition> AND <condition>
    <alternative condition> ::= <condition>|<alternative condition> OR <condition>
    <compound condition> ::= <combined condition>|<alternative condition>
    <if clause> ::= IF <compound condition> THEN
    <true part> ::= <simple statement> ELSE
    <if statement> ::= <if clause> <statement>|
                      <if clause><true part><statement>
    
  2. IF X0≤0 THEN X2←3
    IF A1 > MINUS 3.75 AND X1 < A(4) THEN A(4)←0 ELSE A(X1)←0
    IF X1 NOT = 0 THEN X3←X3 SLL 2 ELSE
       IF NOT OVERFLOW THEN A1←0.0
    IF X7>'%' THEN GO TO BED
    
  3. A condition is either met or not met. If the condition is met the statement following is obeyed, if not the statement following ELSE if present, is obeyed. A combined condition is met only if all its constituent conditions are met. An alternative condition is met if any of its constituent conditions are met. FOVERFLOW indicates floating point overflow and requires the extended or pseudo extended instruction set. Testing OVERFLOW clears it. If CARRY is part of a multiple condition it should be the first item. Character comparisons depend on 1900 internal 6 bit code. CH implies a character or unsigned comparison.
  4. The statement can be implemented by a fairly straightforward sequence of jumps. OVERFLOW should use BVSR. 076 should be used if available in the instruction set in use. If not a macro produced by dumping X1 and X2 say, SPP 1, testing X1, 2 followed by a restore. Conditions involving 0.0 or 0 to the right of a relation should be specially recognised and compiled efficiently. The remainder will involve subtractions of TXU. TXL can be used for character comparisons. Comparisons with zero should be very efficient. See PLN 12 for details.

14. Case statements

  1. <case clause> ::= CASE <modifier> OF
    <case sequence> ::= <statement>|<case sequence>;<statement>
    <case statement> ::= <case clause><case sequence> CASEND
    
  2. CASE I OF
            A1 ← A1 + B;
            A1 ← A1 - B;
            A1 ← A1 * B;
            A1 ← A1 / B;
            A1 ← A1 UNDER B;
    CASEND
    
  3. Statements in case instructions must translate to single machine instructions. The sequence is considered to be numbered starting at zero and the statement whose ordinal number is the value of the modifier is executed. The modifier is destroyed by this instruction.
  4. Case sequences are stored in upper, the address of the first is added into the modifier and this is followed by a modified OBEY.

15. Goto statements

  1. <go to statement> ::= GOTO <instruction identifier>
    
  2. GOTO L3
    
  3. If the goto crosses block boundaries the blocks are effectively closed. GOTO <procedure> means that no return will be made automatically. The effect of the statement is to transfer control to the labelled statement or to the first instruction of the procedure. GOTO may be written as one or two words.

    Procedures and labels need not be declared before use unless they are external (see section 20).

  4. GOTO a local quantity produces a straight BRN, GOTO a non-local (but previously declared) procedure name produces

         BRN <cue>
    

    where the cue is for the quantity <procedure name> @ unless the <procedure name> has been declared in a LOCAL statement. <procedure name> @ is an associated common area explained in section 20. If a reference is made to a label or procedure name which has not been declared it should be treated as an internal quantity. If the procedure has been declared as LOCAL then <cue> is <procedure name>. This enables segments which do not have associated common areas to be incorporated. Outstanding labels at the end of the segment are errors.

16. Obey statements

  1. <obey statement> ::= OBEY<integer cell designator>
    
  2. OBEY U(V(X1)+1)
    
  3. The integer cell designated is assumed to contain an instruction which is obeyed. The instruction must not cause an illegal sequence of SMO's.
  4. Simple obey statement.

17. For statements

  1. <increment> ::= <integer primary>|-<integer primary>| CHAR
    <limit> ::= <integer primary>|<part address>
    <for clause> ::= FOR <integer accumulator assignment>
                     STEP <increment>
                     UNTIL <limit> DO
    <for statement> ::= <for clause><statement>
    
  2. FOR I  ← 1 STEP 2 UNTIL 7 DO A1  ←  A1+X(I)
    FOR X1 ← CHAR 1 OF @ BUFF STEP CHAR UNTIL ENDBUFF DO (X1) ← CH X7
    FOR X3 ← S STEP -1 UNTIL 0 DO BEGIN A(X3) ← 0;B(X3+1) ← 0 END
    FOR X3 ← $FRED STEP 1 UNTIL $JACK DO X1 ← X1+X3;
    
  3. For statements allow a statement to be executed repeatedly while the integer accumulator takes varying values. At each execution except the last, the accumulator is increased by the increment and tested for non-equality with the limit. If this test succeeds the statement is executed, if not the statement is executed once more and control then passes to the next statement. Note that to terminate the loop other than by jumping out the integer variable must reach exactly the value of the limit (if this cannot be guaranteed a WHILE statement should be used). A step of CHAR, means that the accumulator is considered as a modifier and stepped on by one character address. Note that if a complicated expression is to be used as a limit it must be first calculated and then held in an accumulator or stored. A limit of zero will be more efficient than any other.

  4. There are several ways of implementing this and no one seems to stand out. If the limit is zero a straight 05 group can be used as a test. The restriction that the accumulator must "hit" the limit means that for K cells, a large constant or another accumulator a TXU can be used. It could also be used for small constants although this might produce a lower problem with literals. If so a SBN, 05, ADN could do it at the expense of one instruction. Steps of CHAR should use a BCHX instruction.

18. While statements

  1. <while clause> ::= WHILE <compound condition> DO|DO
    <while statement> ::= <while clause><statement>
    
  2. WHILE A1 < MAX (X1) DO A1 ← A1 + STEP
    
    WHILE X1 < ENDBUFF DO BEGIN
                             X7 ←  (X1)
                             IF X7 = END1SEQ THEN GOTO OUT;
                             X1 ← X1 + CHAR 1
                             END
    
  3. A while statement causes the repeated execution of the statement following the while clause as long as the condition is met. A while clause consisting only of DO implies WHILE TRUE DO and can be used for a loop instead of an unconditional GOTO at the end. Conditions involving zero are most efficient.
  4. This can be considered as :-

    label: IF condition THEN BEGIN
                             statement
                             goto label
                             end
    

    with the IF condition omitted for a DO.

19. Blocks

  1. <declaration> ::= <K cell declaration>|<function declaration>|
                       <procedure declaration>|<K cell synonym declaration>|
                       <K accumulator synonym declaration>|<external declaration>|
                       <base declaration>|<global declaration>|
                       <lower declaration>|<define declaration>
    <simple statement> ::= <K accumulator assignment>|<K cell assignment>|
                           <function statement>|<procedure statement>|
                           <case statement>|<block>|<goto statement>|<data statement>|
                           <obey statement>|NULL|<label definition><simple statement>
    <statement> ::= <simple statement>|<if statement>|<include statement>|
                    <interpret statement>|<while statement>|<for statement>|
                    <label definition><statement>
    <label definition> ::= <label identifier>: |GLABEL<label identifier> :|ENTRY <digit>:
    <block head> ::= BEGIN|<block head><declaration>;
    <data statement> ::= DATA <initial value>|DATA(<initial value list>)
    <block body> ::= <statement>|<block body>;<statement>|<block body>;<label definition>
    <block> ::= <block head><block body>END
    <program> ::= <statement>
    <compilable segment> ::= <program>|<procedure declaration>
    
  2. BEGIN REAL X ; INTEGER I; I ← 0; PROCA; DATA(3,5);
        L: X ← A1; I ← I+X2 AND X3; X4 ← X4+1
    ENTRY 3: IF X4=0 THEN GO TO L;IF X4 = 1 THEN GO TO OUT ;
             CASE X1 OF A1 ← Z;
                        A1 ← Z(1);
                        NULL
             CASEND;
    GLABEL OUT: END
    
  3. Blocks, labels and statements are similar to Algol. Identifiers can only be used within the blocks in which they are declared. Semi-colons must be used to terminate statements although extra semi-colons will normally be ignored. NULL is a statement defining no action. Labels define instructions within a block or the end of a block. A GLABEL label is a label which can be referred to in sections of program compiled at different times. Glabels can be "goto"ed. or, if they occur in a procedure, can be called as a procedure. The effect of the latter is as if another similar procedure were declared with the glabel as name and with its first instruction a goto to the glabeled instruction.

    A data statement causes the initial values specified to be stores in successive words at that point. Note that the number of words stored per item is found from the item type so that 0 is not the same as 0.0 and that the programmer must arrange not to obey data statements.

    An ENTRY label specifies an entry point for the program and the digit that follows indicates which entry.

  4. Most of this is dealt with elsewhere. NULL generates a 123 order. Algol-like dummy statements generate nothing. Although the syntax is strict about semi-colons the compiler can afford to be generous. For example an extra semi-colon after NULL or one missing after CASEND (which must end a statement) could be commented on but allowed. Since there is no comment after END facility a great many bogies are removed from that e.g.

                       END
              LABEL1 : END
    

    although having a semi-colon missing could be dealt with properly. The guiding light is: if you expect a terminator and none appears, or if two cell designators or accumulators occur without an operator, insert a semi-colon between the operators and comment. Data can use the initial value mechanism without a type check.

    An ENTRY label merely places the correct jump in one of the words 20-29 and a GLABEL is equivalent to the PLAN #CUE. It should generate a satisfied cue and unlike PLAN, a local label as well. See also section 20 below. There is in general little distinction between labels and procedure names and each can be used interchangeably.

20. Procedure declarations

  1. <procedure heading> ::= PROCEDURE<procedure identifier>(<integer accumulator>);|
                            PROCEDURE<procedure identifier>(<integer accumulator>,
                                                  <unsigned integer number>);
    <procedure declaration> ::= <procedure heading><statement>|
                                GLABEL <procedure heading><statement>
    <external specification> ::= <instruction identifier>|
                                 <instruction identifier>(<integer accumulator>)
    <external declaration> ::= EXTERNAL <external specification>|
                               <external declaration>,<external specification>
    
  2. PROCEDURE SORT (X0);
       FOR X1 ← £A STEP 1 UNTIL ENDA DO
           BEGIN X6 ← A(X1);X3 ← X1;
             FOR X2 ← X1 + 1 STEP 1 UNTIL ENDA DO
             IF X6 ≤ A(X2) THEN BEGIN X6 ← A(X2); X3 ← X2 END;
             X2 ← A(X1); A(X1) ← X6; A(X3) ← X2;
           END
    PROCEDURE SUM (X1,2);
           BEGIN X2 ← (X1); X5 ← (X1+1);X7 ← 0;
           FOR X2  ← 1 STEP 1 UNTIL X5 DO X7 ← X7+(X2);
           RETURN;
           END;
    EXTERNAL FRED (X1), OUT, JOE (X5);
    
  3. A procedure declaration serves to define a sequence of instructions and to associate an identifier with them. This sequence can then be invoked by a procedure statement or a goto <procedure identifier>. For a procedure statement the accumulator specified in the procedure heading is used as a link and when the end of the sequence of instructions is encountered, a return will be made to the next instruction after the procedure statement, unless the unsigned integer is present. In this case the return is to (n+1)th instruction after the procedure statement where n is the unsigned integer and 0 ≤ n ≤ 63. RETURN is described in 25.

    Procedure declarations can appear in the declarations at the beginning of a block or can be a separately compiled section of program. In the first case communication can be via any variables declared in outer blocks or the accumulators. In the second case communication can only be via accumulators or GLOBALly declared variables. If the link accumulator is used in the procedure body for any other purpose it must be dumped and restored before the end of the procedure is encountered.

    If a separately compiled procedure, or a glabel in a separately compiled segment, is used in another segment the calling segment must contain an external declaration, which specifies the link accumulator to be used where necessary. If a goto only is to be made to a procedure it can be specified as a label and glabels within procedures can be specified as procedures if required. External labels and procedure names must be specified before use.

    In general a jump or call to an external procedure or glabel will cause entry to the overlay mechanism. This can be avoided if it is known that particular procedures or glabels will always be in permanent or always called from the same unit, by preceding the segment by a non-PLASYD directive. This takes one of the following forms:

       LOCAL:<label list>;
       LOCAL ALL;
       LOCAL ALL BUT:<label list>;
    where
    <label list> ::= <procedure identifier>|<glabel identifier>|
                      <label list>,<label list>
    

    This will inhibit the call of the overlay mechanism when this segment is entered from another for: the identifiers in the label list; all glabels and the segment name itself, or all labels and the segment name except those in the glabel list, respectively. When exit is made from a procedure the unit from which it was called must be in store. If the label list contains instruction identifiers referred to in the external declaration then CALLs and GOTOs to these identifiers will address the <procedure name> and not <procedure name>@

  4. For a locally compiled procedure only, the identifier can be treated as a label associated with the link accumulator. Goto statements then produce normal jumps and procedure statements call instructions. Glabels (and in fact all labels) within procedures should have the same link accumulator as the procedure associated with them.

    Separately compiled procedures and all glabels produce in addition a common area called <identifier>@ e.g. PROCEDURE JACK produces COMMON JACK@. This is a five word permanent common area containing the following information:

    STO   1   %AAX1            [This is a LOWER COMMON AREA]
    CALL  1   %EROL            [The overlay package]
              Area/unit no.    [Handled by s/c.]
    LDX   1   %AAX1            [cue for the procedure]
    BRN       JACK
    

    This ensures that the program segments can be mixed into (almost) any order of overlays. If no overlay calls are in fact made little extra code is executed but this can be eliminated and storage space saved by the LOCAL directive. This should be checked for before the BEGIN or PROCEDURE which starts a segment and the compiler must be capable of compiling either the sequence described above for glabels and segment names or no common area but a program cue<identifier>@ which is identical to the program cue for the identifier itself. In either mode of operation identifiers in a special list, or marked specially, must be treated in the other mode. No directive or a LOCAL; directive causes the first mode to be entered. LOCAL ALL; and LOCAL ALL BUT: involve the second mode and a label list if present is noted for exception treatment.

    Note that local procedures and labels or glabels must always be jumped to directly.

    All external procedures and glabels must be specified before use. This specification could cause a blank cue to be generated whether or not the specified quantity is later used.

21. Procedure statements

  1. <procedure statement> ::= <instruction identifier>
    
  2. SORT
    
  3. This involves the execution of the appropriate procedure body using the designated link. A label or glabel identifier could be used in place of a procedure identifier providing the link was correctly taken care of. A procedure can only be called in this way if it is

    1. already declared
    2. external and already specified
    3. declared within the current block or within an enclosed block.

    Procedures declared within parallel blocks cannot be called unless no return is expected since crossing block boundaries will cause the loss of corresponding storage.

  4. This produces a

        CALL <link>   <identifier>
    

    for a local procedure or a call to the associated common area <identifer>@ for external quantities. This latter will need revision for EBM (Mode 4 compilation).

    Undefined identifiers are assumed to be local and both the address and the link will need to be filled in when the label or procedure is encountered.

22. Include statements

  1. <include statement> ::= INCLUDE (<identifier>)|INCLUDE(<identifier>,SL)
    
  2. INCLUDE (DATASTATMNTS)
    
  3. Sections of PLASYD program which do not contain include statements may be stored by the PLASYD system and assigned an identifier. These sections can then be included in any segment that requires them by mentioning the identifier in an include statement. The facility is particularly useful for common data declarations and define declarations. The include statement should appear on a line by itself and the identifier must conform with 1900 subfile names.

  4. Action should be to switch off the listing and call in the operating system with the subfile identifier as a parameter. The subfile will then be accessed by the operating system and passed to the compiler as normal source. When the end of the subfile is reached the operating system should cause the listing to be switched on again. Alternatively, possibly at the user's request, listing of the included section should continue without increasing the line number, to aid editing. If SL is present the INCLUDE subfile is short listed.

23. RETURN

  1. <return statement> ::= RETURN | RETURN(<unsigned integer number>)
    
  2. RETURN
    RETURN (3)
    
  3. The first form of RETURN causes the compiled program to exit from the procedure in which the RETURN statement appears and return to the (n+1)th statement after the procedure call. n is specified in the procedure heading (see 20), or is 0 if absent. In the second form of the statement the unsigned integer, m, overrides n and control is returnd to the (m+1)th instruction after the procedure statement. The link must if necessary be restored into the accumulator before the RETURN statement. Note that a RETURN is automatically compiled at the end of a procedure so that an explicit RETURN statement is only needed for exit from the body of the procedure or in order to override the n of the procedure heading.

  4. RETURN is compiled as EXIT X n where X is the link accumulator and n defined in the procedure heading. RETURN (m) is compiled as EXIT Xm.

24. Define

  1. <define declaration> ::= DEFINE<equation>|<define declaration>,<equation>
    <equation> ::= <definee> = <expression>
    <definee> ::= <identifier>
    <term> ::= <integer value>|<definee>
    <expression> ::= <absolute expression>|<term>|
                     <expression><D operator><term>
    <absolute expression> ::= $<upper K cell identifier>|
                              $<upper K cell identifier><fixed index>|
                              @<fixed K cell designator>-@<fixed K cell designator>|
                              £<K cell identifier>-£<K cell identifier>|
                              @<instruction identifier>-@<instruction identifier>
    <D operator> ::= + | - | * | /
    
  2. DEFINE I = 3,A=1
    DEFINE J = I + 5/2
    DEFINE K = @X - @ Y*I
    
  3. The expression is evaluated from left to right over twenty four bits and the resulting value is associated with the definee. All items in the expressions, including labels, must have been previously defined or declared. There is no need for the types of the cell identifiers of an absolute expression to agree but the two cells specified must either both be in the same common block or both in non-common lower storage or both in non-common upper storage. The difference between two addresses is a number of 1900 words. After a define statement the definee can be used wherever an integer value is allowed in the rest of the segment. If the value of the expression is positive it can be used where an unsigned integer is allowed. In particular it can be used as an assignment operand, an array length or an initial value, e.g.

    INTEGER A(I) = (K*I) ; 
    X1←J 
    
  4. The expression is evaluated strictly from left to right and whenever the definee is subsequently met it is replaced by the corresponding integer. The sign of the integer must be tested in cases where unsigned integers are required (e.g. array lengths). DEFINE x =$FRED is not allowed if FRED is declared in LOWER as the displacement of FRED is dependent on the address in lower and is not an absolute quantity when the DEFINEE is declared.

25. NON PLASYD

  1. <nonplasyd identifier> ::= <identifier>
    <nonplasyd specification> ::= <nonplasyd identifier> |
                                  <nonplasyd identifier> (<integer accumulator>)
    <nonplasyd declaration> ::= NONPLASYD <nonplasyd specification>|
                                <nonplasyd declaration>, <nonplasyd specification>                        
    <nonplasyd GOTO statement> ::= GOTO <nonplasyd identifier>|
                                   GOTO <nonplasyd identifier>(<unsigned integer number>)
    <nonplasyd procedure statement> ::= <nonplasyd identifier>|
                                         <nonplasyd identifier>(<unsigned integer number>)
    
  2. NONPLASYD JACK, JOHN (X0), JOE (X1)
    JACK; JOHN; JOE (3);
    GOTO JOE; GOTO JACK (6);
    
  3. Nonplasyd declarations serve to introduce separately compiled procedures or glabels in the same way as an external declaration (see 20), but also specify that these are not in a standard plasyd form (e.g. they may have been compiled in PLAN). Such procedures may have multiple entry points.

    If no integer follows the nonplasyd identifier in a goto or procedure statement the identifier will be branched to or called in the same way as an external procedure. If an integer, n, follows the identifier, however, the branch or call will be made to the nth word following that specified by the identifier.

  4. JACK (3); produces CALL <link><identifier+3>
    GO TO JACK (3); produces BRN <identifier+3>
    

26. MEMBER

  1. <priority> ::= <unsigned integer number>
    <member number> ::= <unsigned integer number>
    <member statement> ::= MEMBER (<member number>,<priority>)
    
  2. MEMBER(2,25)
    
  3. The member statement allows the user when compiling multimember programs to specify the member number and priority of individual members. The statement must appear before the head of a procedure similar to LOCAL. It need only appear once for each member although there may be more than one segment in a member.

27. BRINGOVERLAY

  1. <bringoverlay statement> ::= BRINGOVERLAY <instruction identifier>
    
  2. BRINGOVERLAY JACK
    
  3. The bringoverlay statement allows users to bring into core store an overlay without actually entering the overlay. Any instruction identifier in the required overlay can be specified, provided this identifier has been specified in an overlay list.

  4. The code produced is

    STO   1   %AAX1   [This is a LOWER COMMON area]
    CALL  1   %EROL   [The overlay package]
               Area/Unit no.[Handled by s/c]
    LDX   1   %AAX1
    

A1. --Removed--

A2. Input/Output

I/O has not been discussed in the the main document since it is not immediately obvious what is needed. PERI's are available as functions but one would think that more than that could be provided which would still be useful to more than one program written in PLASYD. A high degree of sophistication is not called for and would be wasted effort. The sort of facilities are:

Input
  1. Fill a buffer with one record from a slow peripheral and place the normal record information which would be obtained from a fast peripheral at the front. Set a pointer to the first word. Optionally double buffer.
  2. Provide a pointer to the next record from a fast peripheral, if necessary reading another block to do it and optionally double buffering.
1 & 2 would look the same to the PLASYD programmer and the system could be extended to provide the next record from a store area.
Output
Take a record in standard format from a designated area (either directly designated or by a pointer), send it to a slow peripheral or put it in a fast peripheral buffer or in an area of store as in input.
Conversion
  1. Convert a character integer of a given number of digits or to a terminator to binary. The integer should be designated by a character modifier which should be stepped on appropriately.
  2. As 1 for a real number with or without exponent.
  3. Convert a binary integer in an accumulator (or two accumulators) to characters in a designated store area.
  4. As for 3 with a real number without exponent.
  5. As for 4 with exponent and designated exponent character.

Comments on alterations to, or additions to these suggestions will be welcomed. One possible alteration would be to provide a character rather than word count at the beginning of the records.

J. K. Buckle

A3. Functional macros

Since functions are not used in the current version of the language the original facility of PL360 could be adopted to provide a simple macro generator, if necessary done by a prepass or as the segment is being read in initially. It could work like this - Basically

    FUNCTION<identifier>(<any sequence of PLASYD statements>);

would be noted and whenever

! <identifier> appeared in the program the segment would be inserted instead. In addition the function definition could use ↑<integer> at any point in the PLASYD sequence. In this case the macro call should take the form

! <identifier>  (param1, param2, ...paramn)

and parami would be substituted for ↑i in the expansion. If this were done as a separate pass there seems no reason why it should not be a recursive routine (written in Algol?) and macros of macros allowed.

J. K. Buckle

A4. --Removed--

A5. Syntactic Definitions

This appendix lists the syntactic entities of PLASYD in alphabetic order and gives for each the PLN2 section number and the number of the relevant definition within the section. The entity OPEN STRING does not actually appear in the text. It would be needed if pure BNF were used and is equivalent to <character>*1.

A

ABSOLUTE EXPRESSION          24     6
ADD OPERATOR                  8    11
ADDRESS                       8     5
ADDRESS ASSIGNMENT            8     3
ALTERNATIVE CONDITION        13     6
ARITHMETIC OPERATOR           8    10
ARRAY ITEM                    6     7
ARRAY LENGTH                  6     9

B

BASE DECLARATION              6    13
BASIC SYMBOL                  2     2
BLOCK                        19     8
BLOCK BODY                   19     7
BLOCK DECLARATION             6    14
BLOCK HEAD                   19     5
BLOCK IDENTIFIER              3     6
BRING-OVERLAY STATEMENT      27     1

C

C OPERAND                     8    15
CASE CLAUSE                  14     1
CASE SEQUENCE                14     2
CASE STATEMENT               14     3
CHARACTER                     2     1
CHARACTER RELATION           13     2
CHARACTER SEQUENCE            4    15 
COMBINED CONDITION           13     5
COMPILABLE SEGMENT           19    10
COMPOUND CONDITION           13     7
CONDITION                    13     3
COUNT                         4    12

D

D OPERATOR                   24     7
DATA STATEMENT               19     6
DECLARATION                  19     1
DECLARATION LIST             6     12
DEFINE DECLARACTION          24     1
DEFINEE                      24     3
DIGIT                         4     1

E

EQUATION                     24     2
EXPONENT                      4     5
EXPRESSION                   24     5
EXTERNAL DECLARATION         20     4
EXTERNAL SPECIFICATION       20     3

F

FIXED ADDRESS                      8    7
FIXED INDEX                        7    5
FIXED K CELL DESIGNATOR           12    4
FIXED K WORD ADDRESS               8    6
FOR CLAUSE                        17    3
FOR STATEMENT                     17    4
FRACTIONAL NUMBER                  4    4
FREE INDEX                         7    4
FREE SMO INDEX                     7    7
FUNCTION IDENTIFIER               11    2
FUNCTION STATEMENT                11    1

G

GLOBAL DECLARATION                 6   16
GLOBAL TAIL                        6   15
GO TO STATEMENT                   15    1

I

IDENTIFIER                         3    2
IF CLAUSE                         13    8
IF STATEMENT                      13   10
INCLUDE STATEMENT                 22    1
INCREMENT                         17    1
INITIAL VALUE                      6   11
INITIAL VALUE LIST                 6   10
INSTRUCTION IDENTIFIER             3   10 
INTEGER ACCUMULATOR                5    1
INTEGER TYPE                       6    1
INTEGER VALUE                      4   16
ITEM                               6    8

K

K ACCUMULATOR ASSIGNMENT           8    9
K ACCUMULATOR IDENTIFIER           3    3
K ACCUMULATOR SYNONYM DECLARATION 12    3
K CELL ASSIGNMENT                  9    4
K CELL DECLARATION                 6    5
K CELL DESIGNATOR                  7    1
K CELL IDENTIFIER                  3    4
K CELL SYNONYM DECLARATION        12    1
K NUMBER                           4    8
K PRIMARY                          8    1
K WORD ADDRESS                     8    4


L

LABEL DEFINITION               19    4
LABEL IDENTIFIER                3    9
LETTER                          3    1
LIMIT                          17    2
LOGICAL OPERATOR                8   13
LONG INTEGER ACCUMULATOR        5    3
LONG INTEGER TYPE               6    2
LONG INTEGER VALUE              4   17
LONG REAL ACCUMULATOR           5    5
LONG REAL TYPE                  6    4
LONG REAL VALUE                 4   19
LOWER BLOCK                     6   17
LOWER DECLARATION               6   10
LOWER K CELL IDENTIFIER         3    7

M

MEMBER NUMBER                  26    2
MEMBER STATEMENT               26    2
MODIFIER                        5    2
MONADIC OPERATOR                8    8

N

N PARAMETER                    11    4
NONPLASYD PROCEDURE STATEMENT  25    5

O

OBEY STATEMENT                 16    1
OCTAL DIGIT                     4    9
OCTAL VALUE                     4   10
OPEN STRING                     4   13

P

PART ADDRESS                   13    4
PART OPERATOR                   9    3
PROCEDURE DECLARATION          20    2
PROCEDURE HEADING              20    1
PROCEDURE IDENTIFIER            3    5
PROCEDURE STATEMENT            21    1
PROGRAM                        19    9
PRIORITY                       26    1

R

REAL ACCUMULATOR                5    4
REAL TYPE                       6    3
REAL VALUE                      4   18
RELATION                       13    1
REVERSE OPERATOR                8   12
RETURN STATEMENT               23    1

S

SHIFT OPERATOR                  8   14
SIMPLE ITEM                     6    6
SIMPLE K ACCUMULATOR ASSIGNMENT 8    2
SIMPLE K CELL ASSIGNMENT        9    1
SIMPLE K CELL DESIGNATOR        7    2
SIMPLE SMO INDEX                7    6
SIMPLE STATEMENT               19    2
SMO INDEX                       7    8
STATEMENT                      19    3
STORE OPERATOR                  9    2
STRING                          4   14
SYNONYMOUS CELL                12    2
T

TERM                         24    4
TRUE PART                    13    9
TRUNCATED NUMBER              4   11

U

UNSIGNED INTEGER NUMBER       4    2
UNSIGNED LONG INTEGER NUMBER  4    3
UNSIGNED LONG REAL NUMBER     4    7
UNSIGNED REAL NUMBER          4    6
UPPER K CELL IDENTIFIER       4    8

V

VARIABLE INDEX                7    3

W

WHILE CLAUSE                 18    1
WHILE STATEMENT              18    2

X

X PARAMETER                  11    3


Should this be added?
INTERPRET STATEMENT               

A6. Definition Numbers

This Appendix lists syntactic elements in alphabetical order and assigns to each a definition number.

A

ABSOLUTE EXPRESSION         128
ADD OPERATOR                 70
ADDRESS                      66
ADDRESS ASSIGNMENT           64
ALTERNATIVE CONDITION        91
ARITHMETIC OPERATOR          69
ARRAY ITEM                   42
ARRAY LENGTH                 44

B

BASE DECLARATION             48
BASIC SYMBOL                  2
BLOCK                       114
BLOCK BODY                  113
BLOCK DECLARATION            49
BLOCK HEAD                  111
BLOCK IDENTIFIER              8


C

C OPERAND                    74
CASE CLAUSE                  96
CASE SEQUENCE                97
CASE STATEMENT               98
CHARACTER                     1
CHARACTER RELATION          133
CHARACTER SEQUENCE           26 
COMBINED CONDITION           90
COMPILABLE SEGMENT          116
COMPOUND CONDITION           92
CONDITION                    88
COUNT                        24

D

D OPERATOR                  129
DATA STATEMENT              112
DECLARATION                 107
DECLARATION LIST             47
DEFINE DECLARACTION         123
DEFINEE                     125
DIGIT                        13

E

EQUATION                    124
EXPONENT                     17
EXPRESSION                  127
EXTERNAL DECLARATION        134
EXTERNAL SPECIFICATION      119

F

FIXED ADDRESS                    132
FIXED INDEX                       58
FIXED K CELL DESIGNATOR           86
FIXED K WORD ADDRESS             131
FOR CLAUSE                       103
FOR STATEMENT                    104
FRACTIONAL NUMBER                 16
FREE INDEX                        57
FREE SMO INDEX                    60
FUNCTION IDENTIFIER               80
FUNCTION STATEMENT                79

G

GLOBAL DECLARATION                51
GLOBAL TAIL                       50
GO TO STATEMENT                   99

I

IDENTIFIER                         4
IF CLAUSE                         93
IF STATEMENT                      95
INCLUDE STATEMENT                121
INCREMENT                        101
INITIAL VALUE                     46
INITIAL VALUE LIST                45
INSTRUCTION IDENTIFIER            12 
INTEGER ACCUMULATOR               31
INTEGER TYPE                      36
INTEGER VALUE                     27
INTERPRET STATEMENT              122
ITEM                              43

K

K ACCUMULATOR ASSIGNMENT          68
K ACCUMULATOR IDENTIFIER           5
K ACCUMULATOR SYNONYM DECLARATION 85
K CELL ASSIGNMENT                 78
K CELL DECLARATION                40
K CELL DESIGNATOR                 54
K CELL IDENTIFIER                  6
K CELL SYNONYM DECLARATION        83
K NUMBER                          20
K PRIMARY                         62
K WORD ADDRESS                    65


L

LABEL DEFINITION               110
LABEL IDENTIFIER                11
LETTER                           3
LIMIT                          102
LOGICAL OPERATOR                72
LONG INTEGER ACCUMULATOR        33
LONG INTEGER TYPE               37
LONG INTEGER VALUE              28
LONG REAL ACCUMULATOR           35
LONG REAL TYPE                  39
LONG REAL VALUE                 30
LOWER BLOCK                     52
LOWER DECLARATION               53
LOWER K CELL IDENTIFIER          9

M

MODIFIER                        32
MONADIC OPERATOR                67

N

N PARAMETER                     82


O

OBEY STATEMENT                 100
OCTAL DIGIT                     21
OCTAL VALUE                     22
OPEN STRING                    130

P

PART ADDRESS                    89
PART OPERATOR                   77
PROCEDURE DECLARATION          118
PROCEDURE HEADING              117
PROCEDURE IDENTIFIER             7
PROCEDURE STATEMENT            120
PROGRAM                        115


R

REAL ACCUMULATOR                34
REAL TYPE                       38
REAL VALUE                      29
RELATION                        87
RETURN                         135
REVERSE OPERATOR                71

S

SHIFT OPERATOR                  73
SIMPLE ITEM                     41
SIMPLE K ACCUMULATOR ASSIGNMENT 63
SIMPLE K CELL ASSIGNMENT        75
SIMPLE K CELL DESIGNATOR        55
SIMPLE SMO INDEX                59
SIMPLE STATEMENT               108
SMO INDEX                       61
STATEMENT                      109
STORE OPERATOR                  76
STRING                          25
SYNONYMOUS CELL                 84
T

TERM                        126
TRUE PART                    94
TRUNCATED NUMBER             23

U

UNSIGNED INTEGER NUMBER      14
UNSIGNED LONG INTEGER NUMBER 15
UNSIGNED LONG REAL NUMBER    19
UNSIGNED REAL NUMBER         18
UPPER K CELL IDENTIFIER      10

V

VARIABLE INDEX               56

W

WHILE CLAUSE                105
WHILE STATEMENT             106

X

X PARAMETER                  81



A7. PLASYD Syntax

This Appendix gives the syntax of PLASYD in BNF and definition number order (See Appendix 6).

  1  <CHARACTER> ::=<LETTER> | <DIGIT> |
         + | - | * | / | < | = | > | # | ← | , | . | ; | : | @ | % | " | & | 
         ( | ) | [ | ] | £ | $ | ? | ' | !
  2 <BASIC SYMBOL> ::= <CHARACTER>|
        ACC|AND|BASE|BEGIN|CARRY|CASE|CASEND|CH|CHAR|CNT|DATA|DEFINE|DO|
        ELSE|END|ENTRY|ER|EX|EXTERNAL|FIX|FLOAT|FOR|FOVERFLOW|FROM|FUNCTION|
        GLABEL|GLOBAL|GLOBEND|GO|GOTO|IF|INCLUDE|INTEGER|INTERPRET|LA|
        LOGICAL|LONG|LOWEND|LOWER|MINUS|NEG|NOT|NULL|OBEY|OF|OR|OVERFLOW|
        PROCEDURE|REAL|SA|SLA|SLC|SLL|SRA|SRAV|SRC|SRL|STEP|SYN|THEN|TO|
        UNDER|UNTIL|WHILE
        ???PURE|PUREND|RETURN|BRINGOVERLAY|NONPLASYD??
  3 <LETTER> ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|%
  4 <IDENTIFIER> ::= <LETTER>|<IDENTIFIER><LETTER>|<IDENTIFIER><DIGIT>
  5 <K ACCUMULATOR IDENTIFIER> ::= <IDENTIFIER>
  6 <K CELL IDENTIFIER> ::= <LOWER K CELL IDENTIFIER>|<UPPER K CELL IDENTIFIER>
  7 <PROCEDURE IDENTIFIER> ::= <IDENTIFIER>
  8 <BLOCK IDENTIFIER> ::= <IDENTIFIER>
  9 <LOWER K CELL IDENTIFIER> ::= <IDENTIFIER>
 10 <UPPER K CELL IDENTIFIER> ::= <IDENTIFIER>
 11 <LABEL IDENTIFIER> ::= <IDENTIFIER>
 12 <INSTRUCTION IDENTIFIER> ::= <PROCEDURE IDENTIFIER>|<LABEL IDENTIFIER>
 13 <DIGIT> ::= 0|1|2|3|4|5|6|7|8|9
 14 <UNSIGNED INTEGER NUMBER> ::= <DIGIT>|<UNSIGNED INTEGER NUMBER><DIGIT>
 15 <UNSIGNED LONG INTEGER NUMBER> ::= <UNSIGNED INTEGER NUMBER>D
 16 <FRACTIONAL NUMBER> ::= <UNSIGNED INTEGER NUMBER>.<DIGIT>|
      <FRACTIONAL NUMBER><DIGIT>
 17 <EXPONENT> ::= <INTEGER NUMBER>
 18 <UNSIGNED REAL NUMBER> ::= <FRACTIONAL NUMBER>|
         <FRACTIONAL NUMBER>&<EXPONENT>|
         <UNSIGNED INTEGER NUMBER>&<EXPONENT>
 19 <UNSIGNED LONG REAL NUMBER> ::= <UNSIGNED INTEGER NUMBER>L|
        <UNSIGNED REAL NUMBER>L
 20 <K NUMBER> ::= <UNSIGNED K NUMBER>|MINUS <UNSIGNED K NUMBER>
 21 <OCTAL DIGIT> ::= 0|1|2|3|4|5|6|7
 22 <OCTAL VALUE> ::=#<OCTAL DIGIT>|<OCTAL VALUE><OCTAL DIGIT>
 23 <TRUNCATED NUMBER> ::= <INTEGER NUMBER>T<UNSIGNED INTEGER NUMBER>
 24 <COUNT> ::= <INTEGER NUMBER> CNT
 25 <STRING> ::= "<OPEN STRING>"
 26 <CHARACTER SEQUENCE> ::= '<CHARACTER>'|'<CHARACTER>' '<CHARACTER>'|
        '<CHARACTER>' '<CHARACTER>' '<CHARACTER>'|
        '<CHARACTER>' '<CHARACTER>' '<CHARACTER>' '<CHARACTER>'
 27 <INTEGER VALUE> ::= <INTEGER NUMBER>|<OCTAL VALUE>|<TRUNCATED NUMBER>|
        <COUNT>|<CHARACTER SEQUENCE>
 28 <LONG INTEGER VALUE> ::= <INTEGER NUMBER> D|<OCTAL VALUE> D
 29 <REAL VALUE> ::= <REAL NUMBER>|<OCTAL VALUE> R
 30 <LONG REAL VALUE> ::= <REAL NUMBER> L|<OCTAL VALUE> L
 31 <INTEGER ACCUMULATOR> ::= X0|X1|X2|X3|X4|X5|X6|X7
 32 <MODIFIER> ::= X1|X2|X3
 33 <LONG INTEGER ACCUMULATOR> ::= X01|X12|X23|X34|X45|X56|X67|X70
 34 <REAL ACCUMULATOR> ::= A1
 35 <LONG REAL ACCUMULATOR> ::= A12
 36 <INTEGER TYPE> ::= INTEGER|LOGICAL
 37 <LONG INTEGER TYPE> ::= LONG INTEGER|LONG LOGICAL
 38 <REAL TYPE> ::= REAL
 39 <LONG REAL TYPE> ::= LONG REAL
 40 <K CELL DECLARATION> ::= <K TYPE><ITEM>|<K CELL DECLARATION>,<ITEM>
 41 <SIMPLE ITEM> ::= <IDENTIFIER>|<IDENTIFIER> = <INITIAL VALUE>
 42 <ARRAY ITEM> ::= <IDENTIFIER>(<ARRAY LENGTH>)|
        <IDENTIFIER>(<ARRAY LENGTH>) = (<INITIAL VALUE LIST>)>
 43 <ITEM> ::= <SIMPLE ITEM>|<ARRAY ITEM>
 44 <ARRAY LENGTH> ::= <UNSIGNED INTEGER NUMBER>
 45 <INITAL VALUE LIST> ::= <INITIAL VALUE>|<INITIAL VALUE>=<ARRAY LENGTH>|
        <INITIAL VALUE LIST>,<INITIAL VALUE LIST>
 46 <INITIAL VALUE> ::= <K VALUE>|<STRING>|<FIXED ADDRESS>|
    <FUNCTION STATEMENT>|<COUNT> + <FIXED ADDRESS>|<COUNT> + <INTEGER NUMBER>|
        <COUNT> + <TRUNCATED NUMBER>|<COUNT> + <OCTAL VALUE>
 47 <DECLARATION LIST> ::= <K CELL DECLARATION>|<BASE DECLARATION>|
        <DECLARATION LIST>;<DECLARATION LIST>
 48 <BASE DECLARATION> ::= BASE
 49 <BLOCK DECLARATION>::= <BLOCK IDENTIFIER>:<DECLARATION LIST>
 50 <GLOBAL TAIL> ::= <BLOCK DECLARATION>GLOBEND|<BLOCK DECLARATION>;<GLOBAL TAIL>
 51 <GLOBAL DECLARATION> ::= GLOBAL <GLOBAL TAIL>
 52 <LOWER BLOCK> ::= <DECLARATION LIST>|<GLOBAL DECLARATION>|
        <LOWER BLOCK>;<LOWER BLOCK>
 53 <LOWER DECLARATION> ::= LOWER <LOWER BLOCK> LOWEND
 54 <K CELL DESIGNATOR> ::= <SIMPLE K CELL DESIGNATOR>|(<FREE SMO INDEX>)|
        <K CELL IDENTIFIER>(<SMO INDEX>)
 55 <SIMPLE K CELL DESIGNATOR> ::= <LOWER K CELL IDENTIFIER>|(<FREE INDEX>)|
        <LOWER K CELL IDENTIFIER>(<FIXED INDEX>)|
        <K CELL IDENTIFIER>(<VARIABLE INDEX>)
 56 <VARIABLE INDEX> ::= <MODIFIER>|<MODIFIER>+<UNSIGNED INTEGER NUMBER>|
        <MODIFIER>-<UNSIGNED INTEGER NUMBER>
 57 <FREE INDEX> ::= <UNSIGNED INTEGER NUMBER>|<MODIFIER>|
        <MODIFIER>+<UNSIGNED INTEGER NUMBER>
 58 <FIXED INDEX> ::= <UNSIGNED INTEGER NUMBER>|-<UNSIGNED INTEGER NUMBER>
 59 <SIMPLE SMO INDEX> ::= <SIMPLE INTEGER CELL DESIGNATOR>|£<K CELL IDENTIFIER>|
        <BLOCK IDENTIFIER>
 60 <FREE SMO INDEX> ::= <SIMPLE SMO INDEX>|<SIMPLE SMO INDEX>+<FREE INDEX>
 61 <SMO INDEX> ::= <FREE SMO INDEX>|
        <SIMPLE SMO INDEX>-<UNSIGNED INTEGER NUMBER>|
        <SIMPLE SMO INDEX>+<MODIFIER>-<UNSIGNED INTEGER NUMBER>
 62 <K PRIMARY> ::= <I ACCUMULATOR>|<K VALUE>|
        <K CELL DESIGNATOR> (I=::INTEGER|LONG INTEGER)
 63 <SIMPLE K ACCUMULATOR ASSIGNMENT> ::= <A ACCUMULATOR>←<K PRIMARY>|
        <A ACCUMULATOR>←NEG<K PRIMARY>|<R ACCUMULATOR>←<R ACCUMULATOR>|
        <INTEGER ACCUMULATOR>←<MONADIC OPERATOR><INTEGER PRIMARY>|
        <INTEGER ACCUMULATOR>←CNT<C OPERAND>|<ADDRESS ASSIGNMENT>
        (A=::K|LONG K; R=::REAL|LONG REAL)
 64 <ADDRESS ASSIGNMENT> ::= <INTEGER ACCUMULATOR>←<ADDRESS>|
        <INTEGER ACCUMULATOR>←<INTEGER ACCUMULATOR>+<ADDRESS>
        <INTEGER ACCUMULATOR>←<INTEGER ACCUMULATOR>-<K WORD ADDRESS>
 65 <K WORD ADDRESS> ::= @<K CELL DESIGNATOR>|$<K CELL DESIGNATOR>|
        £<K CELL IDENTIFIER>|@<K CELL IDENTIFIER>(<FIXED INDEX>)|
        $<K CELL IDENTIFIER>(<FIXED INDEX>)
 66 <ADDRESS> ::= <K WORD ADDRESS>|CHAR <UNSIGNED INTEGER NUMBER>|
        CHAR <UNSIGNED INTEGER NUMBER> OF <K WORD ADDRESS> |
        @ <INSTRUCTION IDENTIFIER>
 67 <MONADIC OPERATOR> ::= CARRY|EX|CH|NEG CARRY                       
 68 <K ACCUMULATOR ASSSIGNMENT> ::= <SIMPLE K ACCUMULATOR ASSIGNMENT>|
        <ADDRESS ASSIGNMENT>|
        <LONG INTEGER ACCUMULATOR>←<I PRIMARY><ADD OPERATOR><I PRIMARY>|
        <LONG INTEGER ACCUMULATOR ASSIGNMENT>/<INTEGER CELL DESIGNATOR>|
        <A ACCUMULATOR ASSIGNMENT><ARITHMETIC OPERATOR><K PRIMARY>|
        <REAL ACCUMULATOR ASSIGNMENT><REVERSE OPERATOR><REAL PRIMARY>|
        <INTEGER ACCUMULATOR ASSIGNMENT><LOGICAL OPERATOR><INTEGER PRIMARY>|
        <I ACCUMULATOR ASSIGNMENT><SHIFT OPERATOR><C OPERAND>
        <REAL ACCUMULATOR>←FLOAT<I CELL DESIGNATOR>
          (I=::INTEGER|LONG INTEGER;A=::INTEGER|REAL|LONG REAL)
 69 <ARITHMETIC OPERATOR> ::= <ADD OPERATOR>|*|/
 70 <ADD OPERATOR> ::= +|-|++|--
 71 <REVERSE OPERATOR> ::= FROM|UNDER
 72 <LOGICAL OPERATOR ::=  AND|OR|ER
 73 <SHIFT OPERATOR> ::= SLL|SRL|SRA|SRAV|SLA|SLC|SRC
 74 <C OPERAND> ::= <UNSIGNED INTEGER NUMBER>|<OCTAL VALUE>|<MODIFIER>|
                       <SIMPLE INTEGER CELL DESIGNATOR>
 75 <SIMPLE K CELL ASSIGNMENT> ::=
       <K CELL DESIGNATOR>←<K ACCUMULATOR>|
       <I CELL DESIGNATOR>←<0|
       <REAL CELL DESIGNATOR>←0.0|
       <INTEGER CELL DESIGNATOR>←<STORE OPERATOR><INTEGER ACCUMULATOR>|
       <INTEGER CELL DESIGNATOR>←<PART OPERATOR><INTEGER ACCUMULATOR>|
       <I CELL DESIGNATOR>←<I CELL DESIGNATOR>|
       <SIMPLE I CELL ASSIGNMENT><ADD OPERATOR><I ACCUMULATOR>|
       <SIMPLE I CELL DESIGNATOR><LOGICAL OPERATOR><I ACCUMULATOR>|
       <LONG INTEGER CELL DESIGNATOR>←NEG<LONG INTEGER ACCUMULATOR>
             (I=:: INTEGER|LONG INTEGER)
 76 <STORE OPERATOR> ::= NEG | CARRY | NEG CARRY
 77 <PART OPERATOR> ::= EX | SA | LA | CH
 78 <K CELL ASSIGNMENT> ::= <SIMPLE K CELL ASSIGNMENT>|
        <LONG INTEGER CELL DESIGNATOR>←FIX<REAL ACCUMULATOR>
 79 <FUNCTION STATEMENT> ::= <FUNCTION IDENTIFIER>(<X PARAMETER>,<N PARAMETER>)
 80 <FUNCTION IDENTIFIER> ::= !(IDENTIFIER> 
 81 <X PARAMETER) ::= <OCTAL DIGIT)|<INTEGER ACCUMULATOR>|
        <1ONG INTEGER ACCUMULATOR> 
 82 <N PARAMETER> ::= <SIMPLE K CELL DESIGNATOR>|<UNSIGNED INTEGER NUMBER>| 
        <OCTAL VALUE>|<CHARACTER SEQUENCE>|<INSTRUCTION IDENTIFIER> 
 83 <K CELL SYNONYM DECLARATION> ::= 
        <K TYPE> <IDENTIFIER> <SYNONYMOUS CELL>|
        <K CELL SYNONYM DECLARATION>,<IDENTIFIER><SYNONYMOUS CELL> 
 84 <SYNONYMOUS CELL> ::= SYN <FIXED K CELL DESIGNATOR>| SYN(<INTEGER VALUE>) |
        SYN(<INTEGER VALUE>)=<INITIAL VALUE>
 85 <K ACCUMULATOR SYNONYM DECLARATION> ::= 
        ACC<ACCUMLATOR IDENTIFIER> SYN <K ACCUMULATOR>| 
        <K ACCUMULATOR SYNONYM DECLARATION>,<K ACCUMULATOR IDENTIFIER>SYN <K ACCUMULATOR> 
 86 <FIXED K CELL DESIGNATOR> ::= <K CELL IDENTIFIER>|
        <K CELL IDENTIFIER>(<FIXED INDEX>)
 87 <RELATION> ::= <|≤|=|≥|>|NOT=
 88 <CONDITION> ::= <K ACCUMULATOR><RELATION><K PRIMARY>|
        <I ACCUMULATOR><RELATION><PART ADDRESS>|
        <I ACCUMULATOR><CHARACTER RELATION><I PRIMARY>|
        OVERFLOW|FOVERFLOW|CARRY|NOT OVERFLOW|NOT FOVERFLOW|
        NOT CARRY  (I=:: INTEGER| LONG INTEGER)
 89 <PART ADDRESS> ::= £<K CELL IDENTIFIER>|$<K CELL DESIGNATOR>
 90 <COMBINED CONDITION> ::= <CONDITION>|<COMBINED CONDITION> AND <CONDITION>
 91 <ALTERNATIVE CONDITION> ::= <CONDITION>|<ALTERNATIVE CONDITION> OR <CONDITION>
 92 <COMPOUND CONDITION> ::= <COMBINED CONDITION>|<ALTERNATIVE CONDITION>
 93 <IF CLAUSE> ::= IF <COMPOUND CONDITION> THEN
 94 <TRUE PART> ::= <SIMPLE STATEMENT> ELSE
 95 <IF STATEMENT> ::= <IF CLAUSE> <STATEMENT>|<IF CLAUSE><TRUE PART><STATEMENT>
 96 <CASE CLAUSE> ::= CASE <MODIFIER> OF
 97 <CASE SEQUENCE> ::= <STATEMENT>|<CASE SEQUENCE>;<STATEMENT>
 98 <CASE STATEMENT> ::= <CASE CLAUSE><CASE SEQUENCE> CASEND
 99 <GO TO STATEMENT> ::= GOTO <INSTRUCTION IDENTIFIER>
100 <OBEY STATEMENT> ::= OBEY<INTEGER CELL DESIGNATOR>
101 <INCREMENT> ::= <INTEGER PRIMARY>|-<INTEGER PRIMARY>| CHAR
102 <LIMIT> ::= <INTEGER PRIMARY>
103 <FOR CLAUSE> ::= FOR <INTEGER ACCUMULATOR ASSIGNMENT>STEP <INCREMENT>UNTIL <LIMIT> DO
104 <FOR STATEMENT> ::= <FOR CLAUSE><STATEMENT>
105 <WHILE CLAUSE> ::= WHILE <COMPOUND CONDITION> DO|DO
106 <WHILE STATEMENT> ::= <WHILE CLAUSE><STATEMENT>
107 <DECLARATION> ::= <K CELL DECLARATION>|<FUNCTION DECLARATION>|
        <PROCEDURE DECLARATION>|<K CELL SYNONYM DECLARATION>|
        <K ACCUMULATOR SYNONYM DECLARATION>|<BASE DECLARATION>|
        <GLOBAL DECLARATION>|<LOWER DECLARATION>|<DEFINE DECLARATION>|
        <EXTERNAL DECLARATION>
108 <SIMPLE STATEMENT> ::= <K ACCUMULATOR ASSIGNMENT>|<K CELL ASSIGNMENT>|
        <FUNCTION STATEMENT>|<PROCEDURE STATEMENT>|<CASE STATEMENT>|
        <BLOCK>|<GOTO STATEMENT>|<DATA STATEMENT>|<OBEY STATEMENT>|
        NULL|<LABEL DEFINITION><SIMPLE STATEMENT>
109 <STATEMENT> ::= <SIMPLE STATEMENT>|<IF STATEMENT>|<INCLUDE STATEMENT>|
        <INTERPRET STATEMENT>|<WHILE STATEMENT>|<FOR STATEMENT>|
        <LABEL DEFINITION><STATEMENT>
110 <LABEL DEFINITION> ::= <LABEL IDENTIFIER>: |GLABEL<LABEL IDENTIFIER> :|
        ENTRY <DIGIT>:
111 <BLOCK HEAD> ::= BEGIN|<BLOCK HEAD><DECLARATION>;
112 <DATA STATEMENT> ::= DATA <INITIAL VALUE>|DATA(<INITIAL VALUE LIST>)
113 <BLOCK BODY> ::= <STATEMENT>|<BLOCK BODY>;<STATEMENT>
114 <BLOCK> ::= <BLOCK HEAD><BLOCK BODY>END
115 <PROGRAM> ::= <STATEMENT>
116 <COMPILABLE SEGMENT> ::= <PROGRAM>|<PROCEDURE DECLARATION>
117 <PROCEDURE HEADING> ::= PROCEDURE<PROCEDURE IDENTIFIER>(<INTEGER ACCUMULATOR>);|
        PROCEDURE<PROCEDURE IDENTIFIER>(<INTEGER ACCUMULATOR>,<UNSIGNED INTEGER NUMBER>);
118 <PROCEDURE DECLARATION> ::= <PROCEDURE HEADING><STATEMENT>|
        GLABEL <PROCEDURE HEADING><STATEMENT>
119 <EXTERNAL SPECIFICATION> ::= <INSTRUCTION IDENTIFIER>|
        <INSTRUCTION IDENTIFIER>(<INTEGER ACCUMULATOR>)
120 <PROCEDURE STATEMENT> ::= <INSTRUCTION IDENTIFIER>
121 <INCLUDE STATEMENT> ::= INCLUDE (<IDENTIFIER>)|INCLUDE(<IDENTIFIER>,SL)
122 <INTERPRET STATEMENT>::= INTERPRET<IDENTIFIER>
123 <DEFINE DECLARATION> ::= DEFINE<EQUATION>|<DEFINE DECLARATION>,<EQUATION>
124 <EQUATION> ::= <DEFINEE> = <EXPRESSION>
125 <DEFINEE> ::= <IDENTIFIER>
126 <TERM> ::= <INTEGER VALUE>|<DEFINEE>
127 <EXPRESSION> ::= <ABSOLUTE EXPRESSION>|<TERM>|
        <EXPRESSION><D OPERATOR><TERM>
128 <ABSOLUTE EXPRESSION> ::= $<FIXED K CELL DESIGNATOR>|
        @<FIXED K CELL DESIGNATOR>-@<FIXED K CELL DESIGNATOR>|
        £<K CELL IDENTIFIER>-£<K CELL IDENTIFIER>|  
        @<INSTRUCTION IDENTIFIER>-@<INSTRUCTION IDENTIFIER>
129 <D OPERATOR> ::= + | - | * | /
130 <OPEN STRING> ::= <CHARACTER> | <OPEN STRING><CHARACTER>
131 <FIXED K WORD ADDRESS> ::= @<FIXED K CELL DESIGNATOR> |
        $<FIXED K CELL DESIGNATOR> | £<FIXED K CELL IDENTIFIER>
132 <FIXED ADDRESS> ::= <FIXED K WORD ADDRESS>|CHAR <UNSIGNED INTEGER NUMBER>|
        CHAR <UNSIGNED INTEGER NUMBER>OF<FIXED K WORD ADDRESS> |
        @<INSTRUCTION IDENTIFIER>
133 <CHARACTER RELATION ::= <CH | >CH | ≤CH | ≥CH
134 <EXTERNAL DECLARATION> ::= EXTERNAL <EXTERNAL SPECIFICATION>|
        <EXTERNAL DECLARATION>,<EXTERNAL SPECIFICATION>
135 <RETURN STATEMENT> ::= RETURN | RETURN(<UNSIGNED INTEGER NUMBER>)



PLN 3

On PL1900: Note 1

Note: PLASYD was originally called PL1900.

It appears to me that certain common practices which are easy in PLAN are difficult in PL1900.

For example, one often wants to deposit a load of preset items in a table by merely labelling the first item, writing down the items one after the other and then causing (say) an equivalent amount of working space to be left following the table. In PLAN this is done by something like

TABLE |  -
      |  -
      |  -
      |  -   preset items
      |  -
      |  -
      |  -
LAST  |  -
          WORK (LAST - TABLE +1)

(This may be inexact PLAN, but the flexibility is the same).

In PL1900 one must write, apparently

 INT    LENGTH   SYN   10 
 ARRAY @LENGTH   INT     TABLE = (

     -----,
     -----,
     -----,     preset items
     -----,
     ----- )
     
 ARRAY @ LENGTH   INT  WORK

(what a lot of writing!)

When an item is inserted or deleted the SYN line must be changed as well. (Perhaps this is not too bad, although I think it is, but the situation becomes absurdly worse, if not impossible, if the length of the WORK area is made to depend, say, on the length of a number of previous preset tables).

Suggested remedy:

Allow labelled data items and permit compiler-time arithmetic on data address of all kinds. We need, I think, something like PLAN's DEFINE directive and the kind of parameters it defines. If labelled data just won't fit into PL1900, something further should be done to allow flexible establishment of lists whose lengths depend on easily-changed parameters.

A. Wilson

17.7.68.


PLN 4

On PL1900: Note 2

Note: PLASYD was originally called PL1900.

Concerning the requirement that 'All identifiers (except label identifiers) must be declared before they are used'.

This is a pity. It prevents one from using the self-organising device of imagining the lists and tables one wishes to use and writing down a table of pointers to them at the beginning of the segment while one has the overall structure in mind.

If branch aheads are allowed a way can probably be found ( e.g. reading the whole segment into the store, mini-compiler fashion) to allow the other as well.

A similar inconvenience arises if procedure references can appear only after the procedure is declared, since the several procedure declarations in a given block heading must be sorted into a certain order to allow one procedure to call another. This too would be time-wasting, error-prone, etc. (It could even lead to impossible requirements if the programmer has written mutually-calling recursive procedures of his own: they would have to go in simultaneously!)

A. Wilson

17.7.68.


PLN 5

Example of the use of PL1900 to Define Basic List Processing Procedures

D.M. Foster

22.7.68

This example shows how the basic list processing procedures can easily be defined using PL1900. The procedures could, with minor modifications, be used as machine functions in IL1900.

The scheme assumed here, which is not necessarily the best, is the classical one. It assumes a list consists of a string of two word pairs. The first word in each pair is an item which could either be an atom or a pointer to another list. The second word in each pair points to the next pair in the list. The last pair in the list has its second word zero. Thus a list of three items of which the first is the atom A, the second a list of two atoms B and C, and the third the atom D, is represented as follows:

A D 0 B C 0

We will assume for the sake of this exercise that as in the EMA system there is an area of store available whose address is kept in FREESTORE. This is used for building up lists. The address of the next available store is kept in NEXTFREESTORE. At the top of the freestore is a stack built up downwards. As the freestore is built upwards and stack downwards a check must be made as to whether they are encroaching on each other. If they do a jump is made to FSERROR.

The address of the top of the stack is kept in X2 (the top of the stack is the end with the lowest numbered address). All procedures take their arguments from, and leave their results on, the top of the stack.

Pointers are distinguished by having their first bit set to 1.

The following block is a block of procedures that use X0 as their link and assume that X3, X6 and X7 are free for use.

BEGIN 
LOWER INTEGER LINK, RUBATOM = #37777777; 
      GLOBAL LAYOUT: INTEGER FREESTORE, NEXT FREESTORE GLOBEND LOWEND; 

PROCEDURE STOREITEM (X0) ; 
     [STORES A TWO WORD PAIR FROM X67 ON FREESTORE IF NOT ALREADY PRESENT 
     AND LEAVES POINTER TO IT IN X3] 
BEGIN 
      X3←FREESTORE; 
  L1: IF X3 = NEXT FREESTORE THEN 
      BEGIN (X3)←X6; (X3+1)←X7; X7←X3+2; 
             IF X7>X2 THEN GOTO FSERROR; 
             NEXT FREESTORE←X7; GO TO OUT; END 
      IF X6 = (X3) AND X7 = (X3+1) THEN GO TO OUT; 
      X3←X3+2; GO TO L1; 
 OUT: X3←X3 OR 256 CNT; 
END 

PROCEDURE LIST1 (X0) 
     [CREATES A LIST OF ONE ITEM FROM TOP ITEM OF STACK] 
BEGIN 
  LINK←X0; X6←(X2); X7←0; 
  CALL STOREITEM; (X2)←X3; X0←LINK; 

PROCEDURE LIST 2 (X0) 
     [CREATES A LIST OF TWO ITEMS FROM TOP TWO ITEMS OF STACK] 
BEGIN 
  LINK←X0; 
  X6←(X2); X7←0; CALL STOREITEM; 
  X6←(X2+1); X7←X3; CALL STOREITEM; 
  X2←X2+1; (X2)←X3; X0←LINK; 
END 

PROCEDURE LIST 3 (X0)
     [CREATES A LIST OF THREE ITEMS FROM TOP THREE ITEMS OF STACK ] 
BEGIN 
  LINK←X0; 
  X6←(X2); X7←0; CALL STOREITEM; 
  X6←(X2+1); X7←X3; CALL STOREITEM; 
  X6←(X2+2); X7←X3; CALL STOREITEM; 
  X2←X2+2; (X2)←X3; X0←LINK; 
END 

PROCEDURE FIRST (X0) 
     [EXTRACTS THE FIRST ITEM FROM A LIST. A SPECIAL RUBBISH ATOM IS 
      GIVEN AS RESULT IF TOP ITEM OF STACK IS NOT A LIST] 
BEGIN 
  X3←(X2); 
GLABEL FIRSTL: IF X3>=0 THEN X3←RUBATOM ELSE X3←(X3); 
  (X2)←X3; 
END 

PROCEDURE SECOND (X0) 
     [EXTRACTS THE SECOND ITEM FROM A LIST. THE RUBBISH ATOM IS GIVEN 
     AS RESULT IF LIST HAS NOT AT LEAST TWO ITEMS] 
BEGIN 
  X3←(X2); 
GLABEL SECONDL : IF X3>=0 THEN X3←RUBATOM ELSE X3←(X3+1) 
  GOTO FIRSTL; 
END 

PROCEDURE THIRD (X0) 
     [EXTRACTS THE THIRD ITEM FROM A LIST. THE RUBBISH ATOM IS GIVEN 
      AS RESULT IF LIST HAS NOT AT LEAST THREE ITEMS]
BEGIN 
  X3←(X2); 
  IF X3 >=0 THEN X3←RUBATOM ELSE X3←(X3+1); 
  GO TO SECONDL; 
END 

PROCEDURE TAIL (X0) 
     [REMOVES THE FIRST ITEM FROM A LIST. THE RUBBISH ATOM IS GIVEN 
      AS RESULT IF TOP ITEM ON STACK IS NOT A LISTJ 
BEGIN 
  X3←(X2); 
  IF X3 >=0 THEN X3←RUBATOM ELSE X3←(X3+1);
  (X2)←X3; 
END 

PROCEDURE CONS (X0) 
     [ADDS THE ITEM ON THE TOP OF THE STACK TO THE FRONT OF THE LIST 
      ON THE SECOND WORD OF THE STACKJ 
BEGIN 
  LINK←X0; X6←(X2); X7←(X2+1); CALL STOREITEM; 
  X2←X2+1; (X2)←X3; X0←LINK; 
END 
END 

Notes

  1. It is not necessary to use the rubbish atom, but it does allow more freedom when analysing lists.
  2. Note that if two identical lists are built up they are represented by the same list, not two separate lists. Hence if lists are used to represent arithmetic expressions, common subexpressions are represented by the same list.
  3. A less elegant although perhaps more efficient way of representing lists is used in 1900 EMA. A list of n items is represented by n consecutive words and the pointer to it contains n in its top bits. The forming of lists thus becomes more complicated (CONS is horrible if we want to check for identical lists) but analysing of lists is more efficient.
  4. I am not sure whether jumping to global labels within procedures is permissable, but I think that it should be.

PLN 6

PL1900: Note 3

Note: PLASYD was originally called PL1900.

A number of comments have been received on the PL 1900 documents so far produced and four programs have been written. One or these by IMF has been distributed, the other three are attached. The programs themselves suggest further alterations that are necessary and more have arisen in discussions. Some comments have been caused by errors in the PF 1900. syntax document, some by insufficient explanation. The necessary corrections and other minor amendments will be incorporated in the next issue of this document. Other comments and ideas that have arisen in the course of conversation are dealt with below or in further notes.

1. On PL 1900: Note 1 (A.W.) PLN3

Labelled data items are a red herring since anything PLAN can do in this respect PL 1900 can do better. For example

#UPPER 
ITEM      3, 5, 9, 6, 7 
LAST      10 

is equivalent to

ARRAY 5 INTEGER 1TEM = (3, 5, 9, 6, 7), LAST = 10 

and

ITEM+5 in PLAN is equivalent to ITEM(5) in PL 1900. 

Some things are in fact neater for example:

BUFFER    #41
          DUMMY (30) 

to set up a line printer buffer in PLAN does not need the unused DUMMY in PL 1900

ARRAY 31 INTEGER BUFFER = #41

will do. The array declaration format is a bit long winded however and mature reflection suggests a FORTRAN approach rather than ALGOL e.g.

INTEGER I, J, K(60), L(50), M, N = 3, M(3) =(0,1,1) 

where K, L are arrays of 60, & 50 integer elements. Note that this is not in general the same as PLAN since

REAL A, B(20) 

assigns 2 words for A and 40 for B.

Another enhancement is to allow FORTRAN like repeat statements in initial value lists e.g. for a large zero array one could write

INTEGER B(40) = (0 * 40) 

Both these changes will be introduced if there are no violent reactions.

To return to the main problem there does seem to be a need for "absolute quantities" and "define" or "set" statements à la PLAN and to allow absolute definees or absolute expressions to be used, in particular, as array lengths.

On PL 1900: Note 2 (A.W.) PLN4

I dislike the idea of use before definition and there appears to be a body of opinion on my side (e.g. PLAN, SYMPL, ALGOL 60, ALGOL 68, even K.F. James on one occasion at least). It is error prone, and with the ' base and displacement system of PL 1900 it is impossible to provide a general look ahead as envisaged in paragraph two of the note since address of labels are l5 bits and of data are 12 bits plus a displacement. The content of the last parentheses is incorrect even on the meagre evidence supplied by 19(c) and 20(c) of the document since each of the mutually recursive procedures could contain a specification of the other of the form

             PROCEDURE F (X1) ; EXTERNAL

and they could be compiled separately.

In fact the system is more flexible than appears from that description since internally labels and procedure names are identical and labels have associated with them the same link accumulator as the procedure in which they occur, to allow the much requested facility of alternative entry points. Thus local labels within procedures may be treated as glabels as defined in section 19(c). This also answers Note 4 of D.M.F.'s document, PLN5.

External procedures or Glabels must however be specified before use (this is trivial) to allow the overlay system to deal with them properly. Any undefined and unspecified labels and procedures remaining at the end of the segment cause errors and are not implicitly external as in PLAN.

3. Layout

What about tabs? 72 internal or external characters? Any reserved word should be abbreviated to any unique set of letters followed by a . e.g. INT. or IN. but not I. for INTEGER. Short forms should not be expanded on the listing because of editing problems, nor should implied semicolons although comment should be made. Can NOT= be replaced by # (I know X6# # 20 looks messy). (V.W.) --- punch girl's comments that absence of tabs made punching difficult---. @ is not printed on a Flexowriter listing. (PHD) : = should always be listed as such (DMF)

Tabs were not considered in the document and they should be. Plan settings are not very useful and variable layout, though nice is probably more complicated than required in the first version at least. The suggestion is that tabs should be assumed at 6 character intervals across the 72 character line. The facility will in any case be in the operating system which will expand the lines before the compiler sees them. As defined the language used only α shift characters anyway so there is no distinction between internal and external characters. Now that tab is allowed we should talk of character positions.

The abbreviation system proposed by V.W. is attractive. However, the non-expansion of short forms is problematical. The author of the PL 1900 document was in a woolly state of mind at the time and while agreeing that for editing listing ≡ source file was essential he had a vague idea that the source would be expanded as well. This is obviously impractical but, since the second aim of PL 1900 is readability a listing like

   GLA.X:W.X1 NO. = A AN. NO.OV.D.B. X1← Y; X2←X1 EN. 

is hardly acceptable. Subsequent conversation between the language specifier and the implementers designate revealed that none were really in favour of abbreviations anyway and they were included to please certain potential users who objected to writing. Since the chief of these was absent at the time it was decided to remove all abbreviations from the language proper and to allow the routine that wrote source to disc to accept abbreviations of the V.W. type and expand them ready for compilation. This would be a relatively trivial process and would mean only that amendments must be written in full form. := and would both be accepted and listed as such to allow for possible on-lining. This expander could accept # for NOT= if written correctly (by the demander?) but the compiler couldn't as it would confuse our helpful insertion of ;'s (and I don't like ## anyway).

@ is such a good character for address that I think we must accept the liability specially since it would appear on a LP listing.

"One tends to write algol e.g.

A(I) ← B(I) 

and I = 1 STEP 1 UNTIL 10 with I not an accumulator (PHD)."

True, but I think you'd fairly soon get out of it after the compiler objected a couple of times and you got used to PL 1900.

J.K. Buckle


PLN 7

Notes on the Trusted Program Controlling PL1900

P. H. Dove

24.7.68

It is intended the trusted program will control editing, input and output to PL1900, consolidation, and the run of the consolidated program. Initially the trusted program (TRPL) will have to be controlled entirely by directives similar to those currently in use in the scientific compilers. Later it is hoped that one or two line amendments will be sufficient to control a complete edit → run process. In this case a master file will be held on disc containing all the latest steering information (possibly a cycle). The system will list the current states of files etc., to enable the user at a disaster to manually re-instate the system. A copy of this file could be generated on magnetic-tape after every run.

Editing will initially be carried out by calling in XMED (a subfile version is essential for the first version of PL1900). Parameters as required by XMED must be created as for a free-standing run. The files and subfiles created by XMED will then be available to the compilation control (which may be an overlay of TRPL). The directives to control compilation and consolidation are listed below.

1) SEND TO (ED, f(g), S(gs))
f(g), S(gs) are the file and subfile on which the new semi-compiled is to be held.
2) SEMICOMPILED (ED, f(g), S(gs))
f(g), S(gs) are the file and subfile holding previously compiled semi-compiled which is to be consolidated regardless of cues or force in bits.
3) LIBRARY (ED, f(g), S(gs))
f(g), S(gs) are the file and subfile holding previously compiled semi-compiled which is to be consolidated selectively (e.g. segments or procedures called when compiling in trace mode).
4) DUMP ON (ED, f(g))
f(g) is the file on which the compiled program in binary is to be held.
5) MACROFILE (ED, f(g))
f(g) is a file of subfiles whose names are macros required to be inserted into existing source by the PL1900 statement INCLUDE(...)
6) READ FROM (ED, f(g), S(gs))
f(g), S(gs) file and subfile which contain source to be compiled (or possibly semi-compiled to be copied across to the SEND TO file). This directive can appear anywhere after the initial directives in logical places between slow input source segments and procedures.

The trusted program will in certain circumstances have to merge two EDS inputs from 5) and 6). At a request for a macro search TRPL will store its current READ FROM information, search for the macro subfile, hand this information to PL1900 till the macro (i.e. subfile) is exhausted and then return to the original EDS subfile or slow input. TRPL will attempt to consolidate once FINISH is read. A segment will consist of either a procedure where the segment name is the procedure name, or a labelled begin followed by a matching end. In this case the label will be the segment name. The master segment containing the priority and name block and possibly overlay information will be generated by TRPL from certain steering information possibly passed to PL1900 for output as semi-compiled.

Listing (always to a line printer) will be controlled by TRPL, full listing will occur unless SHORTLIST is requested , It will also be possible to omit listing completely by NOLIST. Error numbers and comments will whenever possible occur immediately after the line or statement to which they refer. Shortlisting will consist of segment names, procedure names, errors and comments.

Semi-compiled will be output to the SEND TO subfile through an interface which consists of a record of semi-compiled (or leader information). This record will be batched accordingly by TRPL and blocks output when necessary. The EDS files will be extended when necessary by TRPL and file reporting will be carried out by TRPL.

Errors occurring during operation of TRPL or the programs entrusted to it e.g. XMED or XPCL will be output to the listing peripheral in a similar format to the PL1900 errors with an indication of the originating program

e.g. XMED HALTED E1 

Unless TRPL can sensibly continue the sequence of programs wil be halted, all files and subfiles closed such that a restart is possible.

XPCL will be entrusted and the object program automatically loaded, this will be effected by a 'RUN' record in the steering bucket for XPCL. It is likely that the number of semi-compiled subfiles will be above the current limit of XPCL i.e. more than one bucket containing steering information.

The object program will be automatically run and a core print at a failure given. Details of the core required could be specified as parameters to TRPL.

Most of the controlling aspects of TRPL are available under George but this would mean that the Input/Output part of PL1900 could not entrust PL1900 and any automatic update system would still require a lengthy job description.


PLN 8

PL1900: Note 4

Note: PLASYD was originally called PL1900.

Comments continued.

1. "Logical seems to get lost in the document (PLN 2) .... one cannot say IF <logical variable> (VDW)"
True. LOGICAL is merely a synonym for INTEGER and is retained from PL360 merely because they must presumably have found it useful. It could be deleted if anyone felt violently that it should be. The IF is certainly not allowed since it would involve using an accumulator not specified by the programmer.
2. "The trace facility should be in the first version".
Who said it wasn't? Trace is not a part of the language itself and the '-' facility provides for conditionally compiled calls to a standard or non-standard trace package. The form of the standard one has yet to be agreed but this is language independent. Two further comments have been made on this subject. Firstly it would be nice to have levels of conditional compilation, possibly dependent on switches. e.g.
'5 means - if switch 5 is off ignore everything to the next '5 
         - if switch 5 is on, carry on compiling and ignore the next '5 
Secondly the ' symbol is easily missed by a human and a better convention is needed but the same facilities. Agreed; can someone please suggest one and we'll adopt it.
3. "Something should be done about side effects. X1 ← N/X should be written as either X01 ← N/X, or X[0]1 ← N/X or maybe the compiler should comment." (VDW)
Admittedly, they are nasty. We cannot remove them from the hardware and therefore we cannot from the language either. Your first suggestion unfortunately means something else (X01 ← N ⇒ LDXC 1 N, LDN 0 0) but the second is allowed in the language as it stands and I agree that we should comment whenever an accumulator which is not explicitly declared is corrupted.
4. "Is X1 ← LA X2 or X1 ← SA X2 allowed i.e. DLA 2 1, DSA 2 1" (VDW)
No. An accumulator on the L.H.S. always implies a LOAD type operation. There are two reasons for this - to simplify compilation and to force the programmer to think about the way he is using accumulators - see 5 below. However if you wish to treat an accumulator as a store address, which is what this implies, you can refer to it as (1) for example - (1) ← LA X2.
5. "Definition of (simple SMO index) should include <integer accumulator> e.g. A(X2 + X3)" (VDW).
No for the same reasons as 4 above. As far as compiling is concerned as defined the compiler can examine the first element of the index and, if it's not a constant or modifier it must involve a SMO, which it can get out of the way. Your example contradicts this. Secondly, the facility is liable to lead to gross inefficiency - a programmer who can write A(X1) and A(X6) is unlikely to remember that the first generates half as many instructions as the second. If you do need to use an accumulator as a SMO address and I admit this is very useful you must consider it as the store location it is and write A( (2) + X3). You can also of course write INTEGER I SYN (3) implying I is not an accumulator and use I instead.
6. "Both mnemonic and octal equivalents of function statements should be allowed"
Why?
7. "If a parameter or T - cell is missing 0's should be inserted". (VDW)
We will recognise those functions where accumulators can be omitted (BVSR for eg.) and not expect to find them. For laziness we do not especially want to have to recognise a missed field which implies zero in other cases although we would probably accept the MILL convention that , is equivalent to 0,.
8. "Is it not preferable to have some construction like
      INTEGER X; 
      REAL Y; 
      SYN (X,Y)
" (VDW)
Only if you are a FORTRAN programmer. It makes it much more difficult for the compiler since it cannot assign storage as it goes. (Y does not need any).
9. "In an acc. syn. declaration <simple K type> should be optional so that ACC A SYN X1 can be written implying A integer". (VDW)
Very reasonable. We'll do it. Note that INTEGER A SYN X1 is not the same though; neither is REAL A SYN X1.
10. "Appendix 2. TR and punch would not have a count of characters. Is reply information handled by routine?". (VDW)
True. Maybe we should have a character and not a word count at the beginning. We would hope certainly that reply information should be handled by the routine although the programmer should perhaps be able to provide a "trap mask". This section is not well thought out yet and we are not doing anything about it at present. However more comments on needs in this area will be appreciated.
11. "Character handling facilities are lacking. One would like X6 ← CHAR(X1)" (PHD)
Very true. This point also becomes obvious from Alan Wilson's program for example. The CHAR data type was first introduced to correspond to the BYTE data type of PL360. However it soon became obvious that CHAR was much less useful than BYTE because the 6 bit entity cannot be directly addressed. By the time PLN2 was published the only useful facility was that
      X1 ← A 
would be compiled as LDX if A is integer, but LDCH if A is character. The programs show that this is useless if the whole address is held within a modifier,
      X1 ← (X2) 
and that this is quite common. It may be that this use is caused by PLAN conditioning and would lessen in time but there are definite cases where it is needed for example when passing a character address as a parameter in A.W's example. For this reason a CH operator is being introduced and the whole need for the artificial CHAR data type disappears. It is therefore removed. CHAR remains as a FOR step and as an address (CHAR 1 OF@A, X1←X1+CHAR1). It should more logically be @CHAR but this looks clumsy although I'd be prepared to accept this if anyone demanded.
Incidentally it would be advisable to think twice about loading whole addresses into modifiers unless absolutely necessary since the power of base registers is then lost. For example if one is prepared to set aside a modifier to hold the current data base all data items in that domain can be accessed by the one modifier. e.g.
BEGIN BASE INTEGER A, B(3); 
     X1←£A; . 
     X6←A(X1); ........X7←B(X1+2)....... 
12. The INCLUDE facility (called introduce in PLN7)
This is a facility borrowed from SYMPL. It is a simple macro-like facility to enable sections of PL1900 program which are not complete in themselves to be inserted into a PL1900 program at specified points. The inserts are stored as subfiles on a disc on a file specified outside the PL1900 language and are included in the program by the statement
         INCLUDE (Subfile name); 
This causes the compiler to pass control to the operating system which will access the subfile and hand it as source to the compiler. Inserts cannot be nested i.e. the source on the subfile cannot include an INCLUDE statement. This facility is most useful for data statements common to several segments and the associated defined quantities.

J.K.Buckle


PLN 9

PL1900: Note 5

Renaming PL1900

1. For reasons beyond the control of the language definer the language in the PLN series documents must be renamed. The new name is

                     PLASYD 

which should be sufficiently restful to arouse no hostility and can, if really necessary, be considered to stand for Programming Language for System Development. The PLN series of documents will continue but in future notes will be called PLASYD notes.

2. A revised version of PLN 2 has been written and will be distributed after the IFIP congress.

3. There is an interesting reference to PL/360 and similar languages in Tony Hoare's article in Computer Weekly, August 1st, page 6. The relevant section follows :

Advantage

The solution to this dilemma may be found in the more skilful design of a programming language, such as to permit full advantage to be taken of the characteristics of individual hardware designs, without losing machine-independence.

In this prospect, the new BCL language, developed by David Hendry at London University Institute of Computer Science (Computer Weekly February 29), offers great promise. But if my theory is correct a language which guarantees machine-independence can never be applicable to those ranges of problem which require essentially machine-dependent solutions.

The area of application which enforces on programmers the greatest degree of machine-independence is that of the construction of the software itself - executives, operating systems, compilers etc.

The machine-dependence here arises largely from the nature of the problem itself, and only partly from the need to achieve very high efficiencies in both running space and running time. However, the impossibility of machine-independence does not mean that the software programmer will always be barred from the other benefits of high-level language utilisation, and be forever condemned to use the inelegant and inexpressive notations of assembly code.

Among the chief advantages of high-level languages is the use of nested, bracketed, and indented notations to reveal the basic structure of the algorithm to be executed. There is no reason why these notational advantages should not be grafted onto assembly language, or at least a language which is in one-to-one correspondence with assembly language.

Tool

An early example of such a language is Niklaus Wirth's PL/360 (for 360-like computers) developed and used as a software-writing tool at Stanford University.

In this language the programmer retains complete control over the use of store, of registers, and has every machine code function and facility at his disposal. Furthermore, there is absolutely no overhead in the shape of run-time routines; in fact, there must not be, since the language is intended to be used for constructing run-time routines for other programming systems.

J.K.Buckle.


PLN 10

PLASYD Linkage with Functional Language

The Linkage with functional Language as defined in Appendix 1 to PLN2 does not deal with situations in which the function required is determined at run-time rather than compile-time. In the EMA compiler the functions were always used in this way. Three possible solutions are proposed :-

  1. If the function number, N, were available the sequence
          X3 ← N; INTER 
    
    could be used.
  2. The IL1900 compiler could output a subfile INTERDEF, say, defining the function numbers e.g.
          DEFINE CHANGE = 63 
          ......
    
    INCLUDE(INTERDEF) would appear in the PLASYD segment and the sequence
          X3 ← CHANGE; INTER
    
    could then be used. The function names could then not be used for other purposes.
  3. If constructions like
          INTEGER TABLE (60) = (@ CHANGE! ...) 
    
    were allowed
          X3 ← TABLE (X1) ; INTER 
    
    could be used.

This would require that ! be accepted in this and other appropriate contexts.

Alternatively ! as a means of distinguishing interpreted functions could be dropped entirely from the system, leaving the user to define his own convention to avoid conflict with PLASYD names.

V. D. West.

5.8.68.


PLN 11

Amendments to PLN 2 Version 2


PLN 12

POLGEN and relations

JKB/JFM

29.8.68

1. Program POLGEN

POLGEN is a procedure for generation of a polish string from an arithmetic expression consisting of the operators given in the string PRI and operands which are single letters. It is written in the PLASYD of the second version of PLN 2.

2. Relations

As stated in the first paragraph of PLN 1 more effort is made to simplify flow of control than data manipulation in PLASYD. There will probably, therefore, be a tendency among PLASYD progranmers to use all control facilities equally although some will produce much more efficient object code than others. In general this should not cause too much inefficiency since the extra code generated (to restore the contents of accumulators after a test for example) would be required anyway. Where the number of instructions generated is of great importance the programmer can however restrict himself to facilities which have direct machine code equivalents. To help this an extra facility is being introduced and the table below shows the size of the code produced for various types of relations in IF statements. Note that WHILE statements also contain conditions which are dealt with in a similar way and that FOR statements have an implied NOT = condition.

The new facility is to allow the operator CH to appear before the right hand side of a condition involving <, <=, >, or >= and integer operands. This implies that a TXL can be used i.e. the comparison is between character sequences or both the items being tested are of the same sign (e.g. addresses). CH is implied if the RHS is a character sequence. Thus

      X1 < CH '%' and X1 < '%' 

are equivalent.

The table of code production below gives the conditions in an approximate order of efficiency. Conditions such as OVERFLOW and all those above the double line do not corrupt accumulators and therefore do not generate restore operations which may be unneccessary in some cases. Thus if the accumulator contents do not need to be preserved in the cases below the double line and efficiency is paramount the programmer should do his own subtractions and compare with zero. Only integer and real are considered in the table. Long integer is a fairly obvious extension of integer (one extra TXV or TXL or a separate comparison of the second word). Long real has not been even remotely considered. As a general point note that < and ≥ are always the least efficient relations.

RelationRHS of ConditionTypeGenerated Code
=
NOT =
<
0 or 0.0Integer or Real if 076 is availableOne instruction (05 group or 076).

>
0 or 0.0Integer or Real if 076 is availableTwo instructions (05 group or 076).
=
NOT =
≥ CH
>
Non zeroIntegerTwo instructions (026 or 027 and 074) plus one lower location if RHS is a value.
≤ CH
> CH
Non zeroIntegerFour instructions (026, 027 and two 074) plus lower location as above.
<
Non zeroInteger4 instructions (003 or 103, 05 group, 001 or 101, 001 or 101) plus a lower location if RHS is a value of more than 12 bits.
=
NOT =
<
Non zeroReal with 076 available4 instructions (133, 076, 132, 132) plus two lower locations if RHS is a value.
>
Non zeroReal with 076 available or IntegerAs above plus one extra 076 or 05 group instruction.

If 076 is not available real conditions are carried out by generating the following instructions:-

    FSB (absent if test is with zero) 
    Dump X1 in a common area 
    SFP in a common area, say WS 
    LDX 1 WS 
    FAD to restore A1 (absent if test with zero) 

The test is then carried out as an integer test involving X1 only, since the FP operations are normalized. In this case considerable savings can be made if the programmer knows of fixed point accumulators with unwanted contents or if A1 need not be restored. In the first case however the code produced may not be the fastest if the 076 is available.

Alternatively, does anyone know what the effect of SFP 7 is?

                            GENERAL LISTING (XRLP) 22/08/62
 1    PROCEDURE POLGEN (X0);
 2    BEGIN LOWER INTEGER OP(10)=(0),PR(10)=(0),PRI(4)=("00)=+-/*010 ");
 3          [PRIORITY VECTOR] LOWEND;
 4          GLOBAL BUFF :INTEGER IN(19) , OUT(18) GLOBEND;
 5          ACC MODI SYN X1, MOD0 SYN X2 ,MODP0 SYN X3 , [POINTERS FOR ARRAYS]
 6          ALPHS SYN X6 ;
 7          MODI←£IN ; MOD0←£OUT ; MODP0←0 ;ALPHA ←0;[ASSIGN BASE ADDRESS
 8          TO MODIFIERs AND CLEAR SWITCH]
 9          IN(MODI+18) ←0 ; [SET TO ZERO TO TERMINATE INPUT STRING]
10    XCHAR :X4 ←CH IN(MODI) ; MODI ←MODI +MODI +CHAR ;[PICK UP NEXT CHARACTER]
11                       IF X4 <='Z' AND X4 >='A' THEN [IS IT AN OPERAND?]
12                       BEGIN OUT(MOD0) ←X4 ; [PLACE IN OUT STACK]
13                             MOD0 ←MOD0 +CHAR ; ALPHA ←1 END ;
14          X5 ←MODI ; MODI ←0 ;  [STORE POINTER]
15          WHILE X4 NOT= PRI(MODI) DO MODI ←MODI +CHAR ;[SEARCH FOR OPERATOR
16          IN PRIORITY VECTOR]
17          MODI ← MODI SLC 1; X7 ←MODI AND #77 + 1; [OBTAIN PRIORITY FROM
18          MODIFIER]
19          MODI ← X5 ; [RESTORE POINTER]
20    FIN : X5←OP(MODP0); [PICKUP LAST OPERATOR]
21          IF X5 ='(' THEN IF X4 =')' THEN [IF BRACKETS THEN SET POINTER
22          IGNORE BRACKET IN STACK]   BEGIN MODP0 ← MODP0 SLC 2 -1 SRC 2;
23                                           GO TO XCHAR END 
24                                     ELSE  GO TO ALPH ;
25          IF X7 <= PR(MODP0) THEN  [IF PRIORITY IN STACK LESS MOVE THE
26          OPERATOR TO OUT STACK]
27                             BEGIN OUT(MOD0) ←X5 ; MOD0 ← MOD0 +CHAR ;
28                                   MODP0 ← MODP0 SLC 2 -1 SRC 2;
29                                  GO TO FIN END;
30          IF X4 = 0 THEN GO TO EXT ;
31    ALPH :IF ALPHA =0 THEN IF X4 ='+' THEN GO TO XCHAR   [SEARCH FOR A
32          PLUS OR MINUS]              ELSE IF X4 ='-' THEN
33                                           BEGIN X4 ←'+' ;
34                                                 X7 ← 6  END;
35          MODP0 ←MODP0 +CHAR ; [PLACE OPERATOR & PRIORITY IN STACK]
36          OP(MODP0) ←X4 ;PR(MODP0) ←X7;
37          ALPHA ←0;
38          GO TO XHAR ;
39    EXT:  END

PLN 13

Monitoring and Trace Facilities in PLASYD


PLN 14

PLASYD - A Programmer's Guide

PLASYD

A PROGRAMMER's GUIDE

PLN14, Version 2

J K Buckle, P H Dove

1969

1. Introduction

PLASYD, standing for Programming LAnguage for SYstem Development, is a language for the 1900 series. It is Algol-like in its block structure and control facilities but is otherwise closely tied to the basic machine code of the series.

The initial part of the guide describes the facilities available for simple complete PLASYD programs, the later sections describe the segmentation facilities and the compiler and operating system.

A more formal description of the language can be found in the document

PLASYD Syntax and Notes: PLN 2.

An understanding of 1900 storage formats and instruction code is assumed.

PLASYD programs are written using the 1900 64-character card set of symbols and can have a maximum of 72 characters in any line. If the program is to be punched on paper tape tab characters may be used. Tabs are considered to be at six character intervals by the compiler.

A space, tab, newline or end of card will serve to terminate an identifier or fixed word symbol (see 2.2). Spaces outside strings and character sequences, and tabs are non-significant otherwise and may be used to improve layout. Newline or end of card are also in general non-significant with the exception of INCLUDE statements (see 12.5) and at one point in assignment statements (see 6.3(a) and 6.6).

2. Identifiers, Accumulators and Storage Cells

A PLASYD program consists of a series of declarations and statements. A statement corresponds to one or more computer instructions to be executed at object program run time. A declaration gives information to the compiler notably about storage layout and intercommunication.

Statements are basically of two kinds: control statements and assignment statements. Control statements can cause the normal sequence in which statements are obeyed to be altered. This can be used for example to conditionally omit the execution of statements or to loop over a number of statements. Assignment statements are the means by which calculations are carried out. Their effect is to cause a value to be calculated and assigned to a variable. Variables are themselves of two kinds (which correspond closely to the internal structure of the 1900) called accumulators and cells. Each cell corresponds to one or more words in the main storage of the computer.

Variables are also divided into classes in PLASYD according to the type of data that they are used to hold and the mode of arithmetic that can be carried out on them. Types of data are dealt with more fully in the next section and section 11.

Each variable has an identifier or name by which it is referenced in the PLASYD program. The remainder of this section is devoted to consideration of these identifiers.

2.1 Accumulators

Accumulators have fixed identifiers. These are as follows:

  1. Integer accumulators: These are eight known as X0, X1, X2, X3, X4, X5, X6, X7. Integer accumulators can hold integer values such as numbers, 24-bit patterns and addresses. Three of them X1, X2 and X3 can be used for special purposes and are known as modifiers.
  2. Real accumulator: There is one called A1, which is used to hold values that are real or floating point numbers.
  3. Long integer accumulators: There are eight called X01, X12, X23, X34, X45, X56, X67, X70. Each long integer accumulator is formed from two integer accumulators in an obvious way e.g. X01 is formed from X0 and X1. Long integer operations are dealt with in section 11. It should be noted that any alteration to the value of a long integer accumulator will in general destroy the values of its component integer accumulators, and vice versa. From this it also follows that alteration to X01 for example will in general destroy the values of X70 and X01 as well.
  4. Long real accumulator: There is one with the identifier A12. This is made up of the real accumulator A1 and a mantissa extension for increased accuracy. It is available only on some 1900's. Long real operations are dealt with in section 11.

All the accumulators may be given extra identifiers at the programmer's request by means of the synonym declaration defined in section 10.1.

2.2 Cells

Cells have no fixed names and may be assigned identifiers of the programmer's choice which conform with the following rules:-

  1. They must consist of letters and digits. For this purpose the symbol % is considered as a letter.
  2. The first character must be a letter (or %)
  3. The total number of characters must not exceed 32.
  4. The identifier must not contain layout characters such as spaces or new lines.
  5. The identifiers used for accumulators and the fixed word symbols (see below) may not be used for other purposes.

Examples of cell identifiers:

A    X    X9    KAREN    CATCH22     A1B2
ROOT1	  ROOT2   PLASYD     ANDY     %ABHEAD

Note that ANDY is legal although AND is a fixed word symbol. Similarly CHAR1 is allowed.

There are 70 fixed word symbols. They are:-

ACC    AND  
BASE   BEGIN      BRINGOVERLAY
CARRY  CASE       CASEND     CH        CHAR     CNT   CUEOVERLAY
DATA   DEFINE     DO
ELSE   END        ENTRY     ER         EX       EXTERNAL
FIX    FLOAT      FOR       FOVERFLOW  FROM     FUNCTION
GLABEL GLOBAL     GLOBEND   GO         GOTO
IF     INCLUDE    INTEGER   INTERPRET
LA     LOGICAL    LONG      LOWEND     LOWER
MINUS   
NEG    NONPLASYD  NOT       NULL
OBEY   OF         OR        OVERFLOW
PROCEDURE         PURE      PUREND 
REAL   RETURN  
SA     SLA        SLC       SLL    SRA   SRAV   SRC   SRL   STEP   SYN
THEN   TO  
UNDER  UNTIL  
WHILE   

Within these limitations identifiers may be freely chosen to aid human understanding of the program. Identifiers have no inherent meaning and, for example ROOT1 and ROOT2 need have no connection in the program. Identifiers are terminated by any layout character (space, tab, newline) or by any non-alphanumeric character other than %, for example + or /. Fixed word symbols are terminated in the same way. No two items within a program which is a single segment may be given the same identifier.

3. Types and Values

This section deals only with the simple types REAL and INTEGER (or LOGICAL). LONG types are discussed in section 11.

3.1 Integer values

The 24-bit 1900 storage word which makes up an integer cell, or an integer accumulator may be considered to hold:

24 bits considered as separate values of 0 or 1,
four six-bit characters,
an octal number in the range 0 to octal 77777777,
or a decimal number in the range - 8388608 to 8388607.

A cell used to hold any of these is said to be of type INTEGER. If no arithmetic is to be carried out on its contents, for example if the bits are being used as markers, the cells may be said to be of type LOGICAL. The compiler makes no distinction between cells of integer and logical type.

Integer cells and accumulators may be used to hold integer values. These take one of the following forms in a PLASYD program:-

  1. integer number: a positive or negative decimal integer within the range given above. Positive integers are written without a sign thus:
    3671   29        0  4052
    
    Negative integers are preceded by the fixed word symbol MINUS thus:
    MINUS 6      MINUS 2732    MINUS 372615
    
    Note that MINUS must be terminated by a layout character, usually space (MINUS6 is an identifier), and that the integer must not contain spaces or other non-numeric characters. The integer number is held in the machine in 24-bit two's complement binary form.
  2. octal value: a sequence of from 1 to 8 octal digits preceded by the symbol # e.g.
    #12       #2763        #77777
    

    Spaces or other layout characters may occur between the # and the first digit but nowhere else. The number will be stored in the right most octal positions of the word. Unspecified octal positions to the left are set to zero.

  3. truncated number: these are dealt with in section 13
  4. count: this is an integer number in the range 0 to 511 which is to be held in the most significant 9 bits of the word with zeros elsewhere. It is written as an integer number followed by CNT with no intervening spaces or other characters:-
    257CNT         326CNT         2CNT
    
  5. character sequence: a sequence of from one to four characters of the 64 character 1900 set, enclosed within single quote marks ('). The single quote character itself is represented in the sequence by two consecutive single quotes which count as one of the four possible characters.
    '%'   '+23'   'ABCD'   '''A'''   '2  3'
    
    Note that a space counts as one character. The characters will be held in the right-most six-bit character position of the integer variable, any unspecified characters being zero filled.

Integer cells and accumulators may also be used to hold addresses.

This is dealt with in 6.7.

3.2 Real values

A real variable consists of either the floating point accumulator A1 or two consecutive 24-bit words in main storage which constitute a real cell. A real variable can hold a (generally normalized) floating point binary number in standard 1900 format. The numbers are held with an accuracy of about 11 decimal digits and can be in the approximate ranges -5.6 × 1076 to -10-77 and 10-77 to 5.6 × 1076, numbers between the two ranges being held as zero. Real values can be written in PLASYD as decimal numbers or, if strict accuracy of representation is required, as octal numbers. The formats are:-

  1. fractional number: consists of an integer number followed by a decimal point followed by one or more integers -
    0.13261         321.67         215.0
    
    The number may be signed in the same way as integer numbers
    MINUS 136.0         MINUS 0.141579
    
  2. fractional number with exponent: any fractional number may be followed by an & and an integer number. The integer is taken to be a power of ten by which the fractional number is to be multiplied -
    1.4&20        MINUS 0.5613&3         1.414&MINUS 6
    
    There must be no spaces between the fraction and the & symbol. Spaces between the & and the exponent are permitted but unnecessary. MINUS must be terminated by a space as usual.
  3. integer number with exponent: an integer number followed by an exponent will also be considered a real number -
     3& MINUS 6         41107&4
     
  4. octal value: a sequence of from 1 to 16 octal digits preceded by the symbol # and followed by R. Spaces are allowed between # and the first octal digit but not elsewhere. This format is taken as being a right justified representation of a 1900 floating point number -
    #2000000000000400R   #400R
    
    The first example represents 0.5, the second unnormalized zero (0×100)

4. Declarations

Before any cell is used it must be given an identifier and the compiler must be told its type by means of a declaration. All declarations must appear at the beginning of a block. Blocks are dealt with more fully in section 8 but a brief description is given here. A block begins with the fixed word symbol BEGIN which is followed by one or more declarations separated by semicolons. This is called the blockhead. Then follow one or more statements (which may themselves be blocks) and finally the fixed word symbol END. The cells that are defined in the blockhead may be used throughout the block. A simple PLASYD program takes the form of a block.

The data storage on the 1900, in which cells can be located is divided into two parts, upper storage and lower storage. Lower storage consists of the first 4096 words of store and variables in this area can be directly addressed. Upper storage consists of the rest of the store and variables placed in upper store can be accessed only by indirect means described below. The PLASYD programmer may direct the compiler to place particular cells in lower store for immediate access and certain data generated automatically by the compiler will also go into lower store. The remainder of the programmer's declarations will go into upper store.

If a program is written in separately compilable sections (called segments) the programmer can designate that certain cells are to be placed in a section of store (called a global block) which is accessible by more than one segment. This facility is dealt with in section 12.3.

The following subsections are concerned with some of the more common forms of declarations.

4.1 Integer (or logical) cell declarations

This is written as the fixed word symbol INTEGER (or LOGICAL) followed by a number of items which will be given consecutive storage locations. Each item is separated from the next by a comma. Items can take one of the following forms:-

  1. an identifier. This specifies that one word of storage is to be allocated to this cell which will be used to hold integer values, strings or addresses (see 4.5 below).
    Example: INTEGER I, VW, MGB
    
  2. an identifier followed by an integer in parentheses. This is called an array item and it specifies that the number of integer cells specified, each of one 1900 word, is to be allocated to this name. The first cell may be referred to by the identifier as a simple integer identifier. The method of referring to the rest is given in section 5 below.
    Example:  INTEGER A(41), B(22)
    
  3. either of the items (a) or (b) together with an initial value setting. These are defined in section 4.5 below.

4.2 Real cell declarations

This is written in a similar form to an integer cell declaration except the first symbol is REAL. Each identifier and each cell requested in an array item will occupy two 1900 words and will be used to hold a floating point or real number.

Example:  REAL F, FP, ARRY(20).

4.3 Lower declarations

Any sequence of declarations (other than lower declarations) may be placed between the fixed word symbols LOWER and LOWEND to form a lower declaration. All storage cells declared within a lower declaration will be placed in lower storage and can be directly accessed. All other cells will be placed in upper storage.

4.4 Base declarations

Cells that are not in lower storage cannot be directly accessed by the 1900. To enable such cells to be used the upper storage may be divided into arbitrary sections called domains which must not exceed 4096 words. An upper cell is then accessed by specifying the address of the first word of its domain called the base of the cell and the number of words (which must be less than 4096) between this, base and the cell required. This number is called the displacement of the cell. These two quantities are specified in a PLASYD program by preceding the cell identifier by the symbol £ and $ respectively. Thus £A means the address of the first word of the domain in which A appears and $A means the displacement of the cell A from that word. The two added together i.e. the actual address of A, are denoted by @A. For lower cells $A = @A and £A = 0. The first upper declaration will cause a new domain to be set up and successively declared items will be assigned store locations in that domain in order until the appearance of a base declaration or until the next declaration would cause the size of the domain to exceed 4096 words. A new domain will then be started in the next available word. A base declaration takes the form

BASE

and is separated from other declarations by a semi-colon in the normal way. Whenever a new base is started one word of lower storage will be used to store the address of the first word of the base.

Note that if a single array item is more than 4096 words a new base will be started coinciding with its first word, and another new base will be started immediately after it. Any cells above the 4096th will have to be addressed by a specially set up modifier. This is explained more fully in section 5.

4.5 Initial value declarations

A real or integer storage cell which is declared in the outermost block only may be given an initial value of the appropriate type. For a simple cell this is done by following the cell identifier by the symbol = and a value, for example

REAL A, B, C=36.5, D=MINUS 215.4;
INTEGER X=3, Y=#1151;

For array items the equals sign is followed by a list of initial values, separated by commas and enclosed in parentheses thus:-

INTEGER I(20)=(3, 7, 9, 15), J(20), K(3)= (1,2,1);

These values will be assigned to successive array elements beginning at the first. If the same value appears several times in a list, for example

REAL X(6)=(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)

an alternative form is allowed. For this the value is written once followed by * followed by the number of times it is to be repeated. Thus the example above is equivalent to

REAL X(6)=(0.0*6)

In the case of integer items some initial values are allowed which are not strictly integer values. These are

  1. string: this is a sequence of characters enclosed in double quotes ("). The double quote symbol itself is denoted by two double quotes in succession. String is unique as an initial value in that one string may provide initial values for several items of an array. The characters are inserted in sequence, four per 1900 word and spaces are added at the end if necessary to bring the total number of characters to multiple of four. Examples:
     
    INTEGER A="AB", X(4)=("1234567890", 6)
    
    Note that "A" and 'A' are not the same. "A" is the same as 'A ' and 'A' is the same as "000A".
  2. address: addresses specify the position of a cell within store or within its domain and are used for indirect accessing. More details are given in 6.7 below.
  3. count+: any of the preceding types of initial value, except another count or a string, may be preceded by a count and the symbol +. The count will be placed in the top 9 bits of the integer cell and the remainder, which must be expressable in 15 bits or less, will be placed in the remainder of the word. Examples:
    INTEGER LIST (4) = (6CNT+3, 17CNT + #7777)
    
  4. a function statement: this is a method of expressing a machine instruction which is to be stored in a word. Details are in 9.1 below.

5. Cell Designators

Once a cell has been declared it can be referenced in a statement in order to assign a value to it, to use its value in an expression or to test its value. Simple cells or the first element of an array in lower storage may be specified merely by quoting the identifier. Other elements must be specified by quoting the identifier and an index which specifies the particular element or by denoting a base and displacement. The index may take various forms and with some of them the identifier may be omitted. The reference to the cell is known as a designator and the various possible types are given below. In the examples the following declarations are assumed to have appeared:

LOWER REAL X, A(20), C;   INTEGER B; LOWEND; BASE; 
INTEGER U(12), V;

5.1 Simple cell designators

  • (a) Lower cell identifier: This can be referenced by its identifier alone. For this purpose the first element of an array is considered to be a simple cell as well. Examples:
    A, B, C, X.
    
    Note that V cannot be referred to in this way since it is in upper storage.
  • (b) lower cell identifier and fixed index: A fixed index is an unsigned integer or - and an unsigned integer and is enclosed in parentheses. The number specifies the number of words by which the required element is displaced forward or backwards from the cell designated by the identifier. Thus A(0) is equivalent to A and the next item of A, which is real and therefore of two word elements is A(2). The next is A(4) and so on up to the twentieth element A(38). Note that there is no check on the size of the index and we can refer to A(40) which designates the same cell as C. A(42) designates the integer B and the next word (which is indeterminate from the given declarations) to be considered as a real item. This should not in general be a useful facility. A(-2) is the same as X. The address obtained by adding the fixed index to the identifier must always be in the range 0 to 4095.

    There is also no check to see that an identifier refers to an array so that for example one can designate X(0) which is the same as X and X(2) which is the same cell as A or A(0). These facilities allow the programmer to effectively declare one array but to name individual elements of it, and if necessary to give them values. Thus we could consider X as a 22 element real array whose second element is called A and whose last element is called C.

  • (c) free index: A free index is an unsigned integer or a modifier, or a modifier + an unsigned integer and is written enclosed in parentheses e.g.
    (30)     (X1)      (X3+1)
    
    These are taken as elements of a hypothetical array whose first word is word 0 of the store. Thus (30) is the thirtieth word of store. Similarly (1) is X1 considered as a storage cell. The size or type of the cell designated is not immediately apparent in this form and is determined from context. In the case of the modifier index the cell is that whose first word is specified by the contents or value of X1, modified by the integer if necessary. This value will be 15 or 22 bits depending on the addressing mode in use. The value of the integer must be in the range 0 to 4095 but the value of the expression if a modifier is involved may be any possible store location of the machine. By loading the modifier with an address this provides one method of accessing upper storage cells. Thus if X1 has the current value @V, (X1) designates the cell V.
  • (d) cell identifier and variable index: This designator is written as a cell identifier, upper or lower, followed by a variable index in parentheses. A variable index is either a modifier or a modifier ± unsigned integer. Examples:
    A(X1)  U(X2-3)   X(X3+4)
    
    With a lower identifier the index is evaluated in the same way as in the free index (minus also being allowed) and this is taken as a number of words beyond the identifier specified, e.g. if X1 has value 3, A(X1-1) is equivalent to A(2) the second real element of the array A. With an upper identifier the value of the index is added to the displacement of the identifier from the base of its domain. Thus if X2 contains the address of the base, U(X2) designates U itself, U(X2+3) designates the third word following U and so on. The method of setting a base address in a modifier is given below. Note that U(3) is illegal and meaningless. When the integer in the index if any, is added to the address of a lower identfier or the displacement of an upper identifier the result must be in the range 0 to 4095. Thus V(X1-20) is illegal. The modifier is not restricted to have only the value of the base of the identifier's domain. For example if the value of X1 were the address of the base of V (i.e. £V) minus 10 the designator
    V(X1-2) 
    
    would access the first word of the array U.

Designators (a) to (d) are known as simple cell designators and are available on all machines of the 1900 series. The designator types which follow make use of a machine instruction (SMO) which is only available on larger machines of the range. The PLASYD compiler can be made to insert code to simulate this instruction on other machines but there is a corresponding drop in efficiency.

5.2 SMO designators

  • (e) simple free SMO index: A simple SMO index is any simple integer cell designator or a base designator (or a block identifier - see 12.3) which is written enclosed in parentheses. A base designator is an upper cell identifier preceded by the symbol £ indicating a base address.
    Examples: ((30))  (B)   (U(X1+3))   ((X3))  (£V)
    
    In the case of a cell designator the value currently assigned to that cell is used as the address of designated cell. Thus if the cells (30), B or U(X1+3) have the value @V, the address of V, the first three examples designate the cell V. If X3 also has the value @B then (X3) designates the cell B so that ((X3)) designates the cell V. If a base is placed in parentheses the cell designated is the first of the domain in which the identifier appears. Thus (£V) and (£U) both designate the first element of U. As with the free indices of (c) the type of the cell designated must be determined from context.
  • (f) complicated free SMO index: This consists of a simple SMO index, without the surrounding parentheses, followed by a sign and any of the free index forms specified under (c). The whole is then enclosed in parentheses. Examples:
    (B+3)   (U(X1+3)+X2)  ((X3)+X2)  (£V+X3)
    
    The order (SMO index, fixed index) is essential. The two parts of the index will be calculated and the values obtained added. The resulting address is taken to be that of the cell designated. Again the type of the cell designated is not immediately apparent. As examples if B has the value @U (B+3) designates the fourth word of U, and if X3 has the value 12, (£V+X3) would designate the cell V itself.
  • (g) cell identifier and SMO index: This is similar to (d) except that instead of a variable index we can write any of the forms (e) and (f) or an index which consists of a simpler free SMO Index (e), the symbol -, and unsigned integer.
    examples:  C(B-3) V(£V)  U(V(X1)+X2)
    
    The designator is evaluated in similar fashion to (d) and as in (d) if the outside identifier is lower the index specifies a number of words beyond it, while if an upper identifier is used its displacement is added to the value of the index. Thus the second example V(£V) is probably the simplest way of designating the cell V. If SMO is not available the same effect can be achieved by setting a modifier, say X1, to the value £V and then designating V by V(X1). This is in fact in general more efficient than using the SMO if it is not frequently required to alter the value of X1. For example since U and V have the same base, without altering the value of X1, U(X1) designates the first cell of U and V(X1+12) designates V. U(£U+1) designates the same cell as U(X1+1) i.e. the second cell of U but, assuming that X1 did not have to be set up specifically, the first form generates one extra machine instruction. It is thus convenient when working with upper quantities which are in one domain to set aside a modifier to refer to the base of this domain. It also follows that upper quantities which are logically connected by the processing should be placed in the same domain.

    Note that if it is required to consider the contents of a non-modifier accumulator in an index or it is is required to specify that the SMO cell should be a second modifier, the accumulators should be called as store locations. For example X6 can be referred to as (6) in the designator U((6)) and the contents of X1 and X2 can be added to produce an index by the designators ((1) + X2) or ((2)+X1).

    The constant part of the index when added to the displacement of the outer identifier must as usual be in the range 0 to 4095.

6. Assignment statements

Assignment statements are the means by which storage cells and accumulators are given values. The form of the value assigned to a variable can vary from a simple value as described in section 3 to a complicated expression involving the current values of other variables. There is a distinction between cell and accumulator assignment, cell assignments being in general much more restrictive, since few 1900 machine orders are available to do arithmetic in cells. In most cases therefore calculations are carried out using accumulators and the resulting values are then assigned to storage cells. A new term primary is used in the descriptions that follow. A primary of a given type is either a value of that type as defined in section 3), or the designator of a cell of that type as defined in section 5. In the case of integers only it can also be an integer accumulator.

In the following subsections accumulator assignment is dealt with first, and, as in preceding sections only real and integer types are dealt with. Assignment statements may run over several lines if necessary, or several short statements may be placed on one line. Statements, like declarations are separated by a semicolon. Assignments in general affect only the value of the accumulator or cell to the left of the assignment operator. Cases where this is not so are specifically mentioned.

6.1 Basic accumulator assignment

This takes the form

accumulator identifier ← primary

and results in the accumulator specified being given the value specified by the primary; that is, either an actual value is used, or a value previously assigned to the cell by an initial value declaration or previous assignment statement. Examples:

A1←3.0; X2←132; X6←#1332;
X6←421CNT; X7←B;     X4←(£U);
A1←A(X1); A1←(1);    X2←(X1);
A1←MINUS 3.1415; X5←'%%';  X1←X3;

The following points should be noted:

  1. The type of the accumulator and the primary must be identical. Thus A1←0 is illegal and must be written A1←0.0. Where the type of the primary is indeterminate it is assumed to be correct. Thus the statements A1←(1) and X2←(X1) cause A1 to be loaded with the floating point number in X1 and X2, and X2 to be loaded with the integer whose address is in X1 . A1←(1) is the only method of loading a floating point number from fixed point accumulators. A1←X1 does not type match and is illegal.
  2. Assignment of the value 0.0 to the real accumulator is more efficient than any other real assignment. Assignment of an integer value which can be stored in 12 bits takes no extra storage. Assignment of other values (as opposed to cell designators) to integer accumulators and all values other than 0.0 to the real accumulator cause words to be assigned in lower storage to hold the values. Several uses of the same number in one segment will result in only one lower storage cell being set aside.
  3. := can be used as an alternative to .

6.2 Monadic operators

The primary on the right of the assignment symbol may be preceded by a monadic operator. For real assignments only one operator is allowed which is denoted by the reserved word NEG. Examples:

 A1←NEG X; A1←NEG A(X1)

The effect is to assign to A1 the value of the primary, negated. Note that this operation takes two machine instructions and for this reason should not normally be used with values as primaries.

A1←NEG 3.0
and       
A1←MINUS 3.0

achieve the same effect but in the first case 3.0 is stored in lower and is negated to A1 by two instructions while in the second case MINUS 3.0 is stored in lower and is loaded into A1 by one instruction.

For integer assignments several monadic operators are allowed:-

NEG       -    has a similar effect to real NEG
EX        -    cause B only the bottom 9 bits of the primary to be assigned 
               to the accumulator
CH        -    causes a 6-bit character to be assigned to the accumulator - 
               more of this in 6.7 below.
CARRY     -    causes the value of the primary without its most significant bit 
               to be assigned to the accumulator and the top bit to set the 
               carry register, which is included in any immediately following 
               integer arithmetic operation - see the PLAN Manual.
NEG CARRY -    CARRY is performed on the negated value of the primary

Each of these assignments, unlike real NEG, is performed by one machine instruction. In addition, as with basic assignments if the primary is a value of less than twelve bits no lower store location is used. Thus in the case of integers

X1←NEG 3
and
X1←MINUS 3

again have the same effect but the former is both faster and uses no lower storage.

There is also a special integer operator CNT which may have as its primary only one of the following:-

  • an unsigned integer less than 512
  • an octal value less than #1000
  • a modifier
  • simple integer cell designator, providing SMO is available.

The effect is to assign to the most significant nine bits of the accumulator the least significant nine bits of the primary. The last type of primary involves an extra machine instruction. These three primary types are known as C operands.

6.3 General accumulator assignments

Sections 6.1 and 6.2 specified methods of assigning a single value to an accumulator. A general assignment statement can assign a value and then cause various arithmetic or logical operations to be performed on that value. These operations are performed in the order specified within the statement, that is left to right and not in the normal arithmetical hierachy order. A general accumulator assignment is written as one of the previously defined simple assignments or possibly A1←A1 followed by any number of operator-primary pairs. For example:

X1←X2+B
A1←A1+A(X1) UNDER X
X6←U(X3) SLL 6 - (X2-1) * V(X3-4);

The possible operators are as follows:

a) arithmetic operators: + - * /

These operators have the effect of addition, subtraction, multiplication and division respectively. They are available with both real and integer assignment statements. Examples:

X1←X1  + B + B
A1←A(X1)/A(X2) - A(X1 - 1) 
X2←NEG B*2

The following points must be noted.

  1. integer multiplication and division have side effects. If the accumulator that is assigned a value is Xn, multiplication leaves the result in Xn but clears Xn+1 (where if n = 7, n+1 = 0). Similarly division places an unrounded result in Xn and a remainder in Xn-1.
  2. real arithmetic is rounded.
  3. A1 is not a primary so that although
    A1←A1+X
    
    is legal A1←X+A1 is not.
  4. If the same accumulator appears before and immediataly after ← and on the same line no code is generated for that operation.
  5. Assignment is executed first and then the operations in strict left to right order. Thus the sequence
    X1←3; X2←2;
    X1←X1+X2
        gives X1 the value 5
    X1←3; X2←2;
    X1←X2+X1;
    gives X1 the value 4 (i.e. X1←X2;X1←X1+X1)
    
  6. If an integer primary is less than 12 bits the comments for monadic operators apply for + and -.

b) carry setting operators: ++ --

These have the effect of + or - compounded with the effect of the operator CARRY in simple assignment statements. They are available only for integer operands. Examples:

X1←X1++B

c) reverse operators: FROM UNDER

These are available only with real operands and have the effect of a reverse subtraction and division respectively. That is, the accumulator is set to the value of the operand minus, or divided by, the previous accumulator value. Examples:

     
A1←A1 FROM X(2);
A1←(X2) UNDER A(3)

d) logical operators: AND OR ER

These are available only with integer operands and specify collation, logical or, and logical non-equivalence respectively. Comments (v) and (vi) of (a) apply. Examples:

     
X1←X2 AND B OR #1770004

e) shift operators: SLL SRL SLC SRC SLA SRA SRAV

These are available only with integer operands and specify binary shifts right or left. The shifts may be logical, circular, arithmetic or arithmetic taking care of carry (SRAV - see PLAN manual). The operands of shift operators are restricted to C operands as defined for the CNT operator in 6.2. Examples

X1←X1 SRL 4 AND #77
X7←TEST SLA X2 
X3←X3 SLC 2 - 1 SRC 2

6.4 Basic cell assignments

The forms of assignment statement which give values to cells are much more limited than those to assign values to accumulators. Indeed in the case of real cells only the value of the real accumulator or zero may be assigned. A basic assignment takes the form

Cell designator ← accumulator
     or
integer cell designator ← 0
     or 
real cell designator ← 0.0

As with accumulator assignments the left and right hand sides of the statement must agree in type and the performance of the assignment only alters the value of the left hand side. Examples:

B←X7;      A(X1)←A1;          U(£U)←X3;
(X1)←X0;   (1)←A1;            B←0

Assignments of the value zero are more efficient than any other. Note that absolute values cannot be directly assigned to cells so that to give B the value 3 two statements would be needed, for example:

X7←3; B←X7;

The basic forms are the only forms of real cell assignment allowed.

6.5 Monadic integer cell operators

These operators are analagous to those described in 6.2 but in the case of cell assignments none are available for real quantities.

The general form of an assignment involving a monadic operator is:

integer cell designator←operator  integer accumulator

The possible operators and their effects are:-

NEG       - similar to the NEG of 6.2, this causes the negated value 
            of the accumulator to be assigned to the cell.
CARRY     - similar to the monadic operator of section 6.2
NEC CARRY - similar to the monadic operator of section 6.2
EX        - causes the bottom nine bits of the accumulator to be assigned to the 
            cell designated but does not alter the value of the other 15 bits. 
            It is thus not strictly analagous to the 6.2 EX which 
            clears the rest of the accumulator.
CH        - causes the bottom character of the accumulator to be placed in 
            the designated cell - see 6.8 below.
SA        - this has a similar effect to the EX described above but deposits 
            12 bits instead of 9. The remaining bits are unaltered.
LA        - this is again similar to EX but deposits 15 bits without changing 
            the rest of the cell value.

Examples:

B←NEG X6;   U(X1)←CH X4;

6.6 General integer cell assignments

Certain arithmetic and logical operations can be carried out on the values of integer cells without going via an accumulator. A general integer cell assignment statement takes one of the forms of 6.4 or 6.5 followed by any number of operator-accumulator pairs in a similar manner to the operator-primary pairs of 6.3.

Examples:

B←X2+X1
U(X3)←X7 AND X1-X6

If it is required to perform an operation on a value which the cell already has, for example to add the value of X1 to B's current value, one may write

B←B+X1

The two occurrences of B must be on the same line.

This is the only way in which a cell designator can appear on the right of a cell assignment. It must be the cell to which the assignment is being made and it must be the first item after ←. Thus B←B(1)+X1 and B←X1+B are both illegal. The effect of the former must be achieved by using an intermediate accumulator for example:-

X7←B(1)+X1; B←X7
       or
X1←X1+B(1); B←X1

which would be faster but destroys X1.

The possible operators, which have the same effect as in accumulator assignments are:

a)   add operators: + - ++ --
      and 
b)   logical operators:  AND OR ER

As for accumulator assignments all operations are carried out from left to right and assignments of the type B←B+X take only the time of the add operation.

It should be noted that when the left hand cell designator involves a modifier or SMO index then a modification or SMO will be involved in every operation in the right hand side. This can be inefficient particularly where SMO's are concerned. For example:

U(B)←X7+X6+X5+X3

produces eight machine instructions (one store, three adds and four SMO's) if SMO is available and a fantastic number if pseudo-SMO instructions are used. If, say, X7 is not needed again the same effect aay be achieved by

X7←X7+X6+X5+X3;  (three adds)
U(B)←X7;         (one store, one SMO)

a total of 5. Alternatively for one extra instruction another accumulator (say X4) could be used as intermediate storage.

6.7 Address assignments

Integer cells and accumulators may be assigned integer values by the statements already specified in this section. However, they can also be given a value which is an address. The use of variables with such values has been described in the section on cell designators. This subsection shows how such values can be assigned. Address assignments can only be made to accumulators and, if it is necessary to assign an address as value to an integer cell, for use as temporary storage or in a SMO designator, an intermediate accumulator must be used. Addresses may also be specified as initial value settings as described in 4.5.

An address takes one of the following forms

  1. $ cell designator - the displacement of a cell. Examples:
    $B  $U(3) $V(B+X1-3)
    
    The displacement has as value the number of words that the cell designator is displaced from the base of its domain. In the case of a lower cell, of course, this is the address of the cell itself. If the cell designator does not consist of a simple identifier the displacement of the cell designated by the identifier alone will be modified by the value of the index in the normal way. Values of such addresses may thus be greater than 4095. In addition to normal cell designators with $ an upper identifier with a fixed index is legal. Thus $U(3) is allowed although U(3) is not.
  2. £ cell identifier - the base of an identifier. Examples:
    £B  £U   £V
    
    The base is the address in words of the first word of the domain in which the identifier appears. In the case of lower cells it is identically zero. Note that only identifiers are allowed, not general cell designators. Thus £B(3) is illegal.
  3. @ cell designator - the address of a cell. Examples:
    @B     @U(3)   @V(B+X1-3)
    
    This is the complete address in words of the cell designated. @X is identically equal to £X + $X. As with $ upper cell identifiers with fixed indices are allowed.
    Types (a) to (c) are called word addresses
  4. @ instruction identifier - the address of a label or procedure. Example:
    @ SIGN
    
    An instruction identifier is the address in words of a label or procedure. These are explained in sections 7.1 and 9.2.
  5. a character address. Examples:
    CHAR 3     CHAR 1 OF @B     CHAR 0 OF $U(X1)
    
    This takes the general form of the fixed symbol CHAR followed by an unsigned integer, optionally followed by OF and a word address. The effect is to specify a particular six-bit character within the word address which follows. Characters are dealt with in the next subsection.

Any of the addresses above may be given as a value to an integer accumulator or added to the value of an integer accumulator by an address assignment e.g.

X1←CHAR 1 OF @B 
X2←£U
X0←X0+$V(3)

It should be noted however that the character portion of an address may cause the two most significant bits of the accumulator to be set and an addition should not therefore cause an overflow into these two bits. Addition of the CHAR part of a character address will be done by BCHX instructions. Assignment of CHAR n will be more efficient if n < 4. It is also possible to subtract the value of a word address (but not a character address) from an accumulator. Example:

X7←X7 - @V(B+X1-3)

Once an address has been loaded into a modifer that modifer can be used in subsequent cell designators. Similarly addresses may be stored and their values used in SMO indices. If an address is used as an initial value it must be a fixed address. That is the index if any must not be a SMO index nor contain a modifier. Indices are thus restricted to an unsigned integer, or - and an unsigned integer i.e. the fixed index of 5.1.(b)

To assign, add or subtract an identifier base always takes only one machine instruction. To assign, add or subtract a word displacement takes one instruction, modified if a modifier is used in the index, plus a SMO if a SMO index is used. A cell address takes one more instruction than a displacement and if the address has a character part an extra instruction is involved.

An address assignment of the form specified above may be followed by any operator/operand pairs as defined in section 6.3. Example:

    
X1←$A(3)+6-X1 SRL 1

However, addresses may not be used as primaries so that X1←6+$A(3) is illegal. Thus the address part, if any, of an expression must always appear immediately after the symbol.

As an example of the use of address assignments consider the various ways of setting an upper integer cell I to zero. We could load the complete address of I in a modifier thus

X1←@I; (X1)←0;

However, loading the @ address takes one more instruction than loading the base and it is not immediately obvious what the second statement is doing. Better would be

X1←£I; I(X1)←0;

Not only does this take one less instruction and read better but, if J is in the same domain as I we can write, for example

J(X1)←X3;

without resetting X1.

If SMO is available we can use any store location at the cost of one extra instruction in the first case and none in the second e.g.

X7←@I; ((7))←0;

or for one more instruction

X7←@I; B←X7;  (B)←0;
  or
I(£I)←0;

The latter is obviously a neat method but is not as flexible as the use of a modifier. For example

J(£J)←0

takes as long as I(£I)←0 even though £I and £J are the same. Similarly if I is a 100 element array, to set all elements to zero we can set X1 by

X1←£I; 

and then arrange to obey

I(X1)←0;    X1←X1+1

100 times. There is no comparable way using a SMO of £I since the value of £I cannot be altered.

6.8 Character operations

Each integer cell or accumulator can, if desired, be considered as four 6-bit characters. If all four are to be dealt with at once normal assignments or initial values involving character sequences or strings may be used. If it is necessary to deal with characters separately the CH operator and, normally a modifier must be used. (Note that a SMO'ed cell is not equivalent in effect to a modifier in this case).

A character address as described in 6.7(e) is held in a modifier as a word address in the bottom 22 bits and a character number (0, 1, 2, or 3) in the top two bits. Examples:

CHAR 3       is word address    0,     character number 3 
CHAR 1 OF @B is word address    @B,    character number 1 
CHAR 6 OF @B is word address    @B+1,  character number 2

If such a modifier appears as part of a normal cell designator only the word address is used. However when used with the monadic operator CH a particular character will be designated. Thus to place in accumulator X7 character 1 of the upper integer I we can write

X1←CHAR 1 OF @I; X7←CH(X1)
or
X1←CHAR 1 OF £I; X7←CH I(X1)
or
X1←CHAR 1 ; X7←CH I(£I+X1)
etc

If CH is used without a modifier then character 3 is considered to be designated. Note that this is not the same as using a modifier of zero.

If X6←'ABCD'; X1←0 have been obeyed X7←CH (6) is equivalent to X7←'D' but X7←CH (X1+6) is equivalent to X7←'A'

CH can also be used as a monadic store operator, in which case, in common with other store operators, only the character designated is altered, the remainder of the cell remaining unchanged. The bottom character (number 3) of the accumulator is used others being ignored. Thus with X6 and X1 as above and the value of the lower integer B intitally '1234'.

B←CH X6 sets B to '123D' while
B(X1)←CH X6 sets B to 'D234'

A modifier containing a character address may be altered by normal assignment statements. In particular it can be made to point to the next character address by

X1←X1+CHAR 1

This construction takes care of crossing word boundaries. It is not however possible to step backwards in the same way and the best way of doing this is probably

X1←X1 SLC 2 - 1 SRC 2

Note also that if + CHAR 1 is used in 15AM, bits 2-8 of the modifier will be altered (BCHX is used). If this is unwelcome the sequence

X1←X1 SLC 2 + 1 SRC 2

must be used. In addition one machine instruction is generated for each character specified by CHAR n. Thus numbers of more than 3 should never be used and for

X1←X1 + CHAR 6 (6 instructions) 

one should write instead

X1←X1+CHAR 2 OF 1  (3 instructions) 
   or
X1←X1+CHAR 2 + 1   (3 instruotions)

7. Control Statements

Normally a PLASYD program will be entered at the first statement following the initial declaration and the following statements will be obeyed in the order in which they appear, intervening declarations being skipped. If it is required to alter the order in which statements are obeyed a control statement must be used. Control statements either cause a number of statements to be obeyed out of line before continuing in sequence or they cause a new sequence to be started beginning with a designated statement. Some of the first type are dealt with in section 8. The remainder of the first type and all the second type are dealt with here.

7.1 Labels

In order to designate a statement to which control is to be passed the statement must be labelled. The simplest way of doing this is to precede the statement by an identifier and a colon. The identifier must be unique within the program (or separately compiled segment - see 12 ). Examples:

L: X1←X1+6;
NEXTCH: B←X4-X2;
DB4: X1←$NEST(X1) 

Several labels may be given to one statement if desired, thus

A:B:C:OLE: X3←B(£B);

7.2 The GOTO statement

The simplest way to transfer control unconditionally is by a GO TO statement written

GO TO label; 

GO TO can be written as one or two words.

The effect of this statement is to cause the statement designated by the label and all statements following it to be obeyed in sequence until another control statement is reached. Examples:

GOTO  L;
GO TO NEXTCH

7.3 The OBEY statement

This statement is written

OBEY integer cell designator 

Example:

OBEY B(U(X1)+1)

The integer cell in question must contain a binary representation of a 1900 machine code instruction (which will usually be stored there by a function initial value see 4.5 (d) and 9.1). The result will be to obey this instruction, and if it does not cause a change of control to return to the next instruction in sequence after the OBEY. (See PLAN reference Manual OBEY instruction).

7.4 The CASE statement

This causes one of a number of statements to be obeyed according to the value of a modifier.It is written

CASE modifier OF

followed by a sequence of statements, each of which take only one word, followed by CASEND. Example:

CASE   X1 OF    A1←A1+B;
                A1←A1-B;
                A1←A1*B;
                A1←A1 UNDER B;
                GO TO L3;
                X1←NEG BZ;
CASEND;

The effect of the statement is to cause the ith instruction of the sequence to be obeyed where the seguence is numbered beginning at zero and i is the value of the modifier. The value of the modifier is thereby destroyed and unless a control statement has been executed, the statement following CASEND is the next to be executed. The more common statements which generate only one machine instruction are the following, none of which may contain SMO indices:-

1. a function statement (see section 9.1)
2. an accumulator assignment whose right hand side consists of a single 
   primary (e.g.  X1←B(-2)); or whose right hand side consists 
   of the left hand side, an operator and  a primary (e.g. X1←X1+B(X2)). 
   The operator must not be * with integer operands.
3. a cell assignment of an equivalent form.
4. a procedure  statement  (see 9.3)
5. a GOTO statement
6. an OBEY statement
7. a NULL statement  (see 8.3)

If the modifier value specifies a non-existent instruction the effect is undefined.

8. Block Structure and Conditional Statements

8.1 Blocks

A block consists of the word BEGIN, possibly followed by some declarations separated by semicolons, possibly followed by some statements separated by semicolons, followed by END. A block is itself a statement and thus blocks may be nested. The statements in a block may only make use of those quantities which are declared in the block itself or in surrounding blocks. For example consider

BEGIN INTEGER  I;
---------------;
BEGIN INTEGER  J;
---------------;
END;
---------------;
BEGIN INTEGER K; 
P:-------------;
END;
---------------;
END

At the point labelled P use can be made of the quantities I and K but not J. In fact with this simple set-up J and K will share the same storage.

Only cells in the outermost block of a program (or separately compiled segment) may be given initial values and normally it is in the outermost block that most variables will be declared. Cells declared in inner blocks will share storage with those in parallel blocks and their values are thus indeterminate on entry to the block. Entry to a block may be made either by coming to the BEGIN in a normal sequence of control, in which case the first statement of the block will be the next obeyed, or by jumping to an internal label by a GOTO statement.

A label may be placed before the END symbol of a block thus

L : END

If a GOTO L statement is then obeyed the effect is as though a jump was made to a NULL statement placed immediately before the END. However unless NULL is actually written, no instruction is generated.

8.2 Declarations

Type, lower and base declarations have already been dealt with in section 4. Other types of declaration and the section in which they are described are:

  • function declarations - not dealt with in this document.See PLN2
  • procedure declarations - 9.2
  • synonym declarations - 10.1
  • global declarations - 12.3
  • define declarations - 10.2

8.3 Statements

There is a subclass of statements called simple statements. These are:

  • function statements - 9.1
  • procedure statements - 9.3
  • case statements - 7.4
  • obey statements - 7.3
  • goto statements - 7.2
  • blocks - 8
  • null statements - see below
  • data statements - see below

A null statement is written as

NULL; 

and has no effect but occupies one instruction position.

It can therefore be used in CASE instructions for example.

A data statement is written either

DATA initial value 
  or
DATA (initial value list)

Its effect is to store the initial value(s) at that point in the program. The programmer must arrange not to obey this data as instructions. The chief use envisaged for this statement is in conjunction with procedure calls - see 9.3. Examples:

DATA 6
DATA (2.4, 6.8, @BETA, 7)

Note that real initial values will occupy two words and integer initial values one.

All simple statements can be labelled as described in Section 7.1.

The other possible statements in a PLASYD program, beside simple statements are:-

  • if statements
  • for statements
  • while statements
  • include statements

The first three are conditional statements which cause a statement or group of statements to be obeyed only if certain conditions hold. These are dealt with in the following sections. The INCLUDE statement is an operating system facility and is dealt with in section 12.5.

8.4 The IF statement

A typical example of an IF statement is:

IF X1 = 0 THEN GOTO L3

Here the statement GOTO L3 will be obeyed only if the condition X1 = 0 is true i.e. X1 has value zero. If the condition is not true then the next statement in sequence will be obeyed. If the statement following THEN does not cause a change of control and if the condition is true, after the statement has been obeyed, processing will continue in sequence.

The general IF statement takes one of two forms

IF condition THEN statement 
  or    
IF condition THEN simple statement ELSE statement

In the second example if the condition is false the statement following the ELSE will be obeyed instead of the statement following THEN. In either case if the statement obeyed does not cause a change of control, the next statement in sequence will then be obeyed. Note that if this form is used the statement following the THEN must be a simple statement. This is to remove ambiguity from such statements as

IF X1 = 0 THEN IF X2 = 0 THEN GO TO L1 ELSE GO TO L2 

By the above definition this must mean the same as

IF X1 = 0 THEN BEGIN IF X2 = 0 THEN GO TO L1 ELSE GO TO L2; END 
and not
IF X1 = 0 THEN BEGIN IF X2 = 0 THEN GO TO L1; END ELSE GO TO L2

BEGIN and END can always be used in this way if necessary.

Note also that there must be no semicolon immediately before ELSE.

There are two chief types of condition - status conditions and accumulator conditions.

A status condition is one of the following:-

OVERFLOW       - true if the overflow indicator is set 
FOVERFLOW      - true if the floating point (real) overflow indicator is set.
CARRY          - true if the carry bit is set
NOT OVERFLOW   - true if the overflow indicator is not set
NOT CARRY      - true if the carry bit is not set
NOT FOVERFLOW  - true if real overflow is not set

Accumulator conditions depend on the current value of an accumulator and are written

accumulator relation primary

where the primary and accumulator are the same type, or

integer accumulator relation part address 

A relation takes one of the following forms

< <= = >= > NOT=

which are self explanatory or

<CH  <=CH  >CH   >=CH

These are mainly concerned with character comparisons and can be used only with integer (or long integer) accumulators. The effect is to test the accumulator value considered as four six-bit characters against the primary similarly considered. They may also be used for arithmetic comparisons providing both operands are of the same sign. If they are of different signs a negative number will be considered greater than a positive one. CH comparisons are more efficient than normal relations. CH is implied if the primary is a character sequence or string in a normal relation. For full details of efficiency of relations and code generated see PLN 12. Note that relations such as <= and >=CH are single symbols and should not therefore contain spaces.

A part address is either a base (i.e. £ identifier) or a displacement ($ cell designator).

Conditions may also be compounded

Example:

IF X1<B AND X3>CH X5 THEN  SUM←SUM+X1

A compound condition is either a combined condition or an alternative condition.

A combined condition is any number of simple conditions connected by AND's. Example:

X1<B AND X1>=A AND NOT OVERFLOW

It is true only if all the component conditions are true.

An alternative condition is any number of simple conditions connected by OR's. Example:

X1<0 OR A1<0.0 OR OVERFLOW

It is true if any of the component conditions are true.

NOTE that AND's and OR's cannot be mixed and to jump to L2 if X1 is zero and either X2 or X3 are also zero a construction of the form

IF X1 = 0 THEN IF X2 = 0 OR X3 = 0 THEN GO TO L2

must be used.

8.5 The FOR statement

Although loops can be written using an if statement and a goto statement the FOR statement provides an easier method of causing a group of statements to be obeyed a specified number of times.

The general form of a for statement is

FOR integer accumulator assignment
STEP increment
UNTIL limit
DO statement 

Example:

FOR X1←3 STEP 1  UNTIL 10 DO X7←X7 + X3

Its effect is to carry out the accumulator assignment and obey the statement, add the increment to the accumulator and obey the statement and repeat the last step until the accumulator takes the value of the limit. The statement is obeyed with this value and control then passes to the next statement in sequence. Note that the loop continues until the exact value of the limit is reached. Thus the statement:

FOR X1←3 STEP 2 UNTIL 10 DO X7←X7 + 3 
and 
FOR X1←3 STEP 1 UNTIL 2  DO X7←X7 + 3

are both infinite loops. If it is not known whether exact agreement will ever occur a WHILE statement should be used.

Any integer accumulator assignment, including an address assignment is allowed after the reserved word FOR. An increment may be any integer primary optionally preceded by a - sign. Examples:

FOR X1←10+B  STEP - 1 UNTIL 0 DO  .....
FOR X6←S(X1) STEP - B(X2  + 1)  UNTIL 0 DO .....

The increment may also be the fixed word symbol CHAR. This will cause the value of the accumulator, treated as a character address to be incremented by one character address at each iteration of the loop. Note that a BCHX is used to do this and if the compilation is in 15AM the count position of the accumulator will be altered. The limit value must therefore take account of this. The second example below is probably only meaningful in 22AM.

A limit must be an integer primary so if the final value is a complicated expression this should be calculated first and assigned to an accumulator or store location. Any statement may follow the DO including a block or another FOR statement.

Examples:

FOR X3←S STEP 1   UNTIL BEG(X1)  DO BEGIN
    B(X3)←0;
    (X3)←1;
    END; 
X7←£BUFF + 6 + X1;       ENDBUFF ← X7;
FOR X2←CHAR 1   OF £ BUFF STEP CHAR UNTIL ENDBUFF DO 
      BEGIN X6←CH BUFF(X2); 
      IF X6>'Z'  THEN GO TO EXTRA; 
      END;

8.6 The WHILE statement

This is similar in effect to a FOR statement in that it allows a statement to be executed repeatedly but in this case execution ceases when a condition specified by the programmer no longer holds. Example:

       
WHILE A1 < MAX(X1) DO BEGIN
                      X1←X1 + 1; 
                      A1←A1 + STEP; 
                      END;

The general form is

WHILE condition  (possibly compound) DO statement

The effect is to test the condition and if it holds to execute the statement and repeat the test. If the condition does not hold control passes to the next statement in sequence. This is more flexible than a FOR statement e.g.

X6←2; or X6←10;      followed by
FOR X1←3 STEP 2 UNTIL X6 DO  .......

will both be infinite loops. On the other hand

X6←2;  or X6←10; followed by X1←3;
WHILE X1<X6 DO BEGIN.......;  X1←X1+2 END

will cause ....... to be executed zero or four times respectively.

There is a special form of WHILE statement for the repeated execution of a block from which there is some conditional exit. This could be done by labelling the start of the block and making the last instruction a GOTO label. It can also be done however by a DO statement. Example:

DO BEGIN
   X1←X1+1;
   X7←BUFF(X1); NEW(X1)←X7;
   IF X7 = '*' THEN GO TO END1
ELSE IF X1 = 0 AND X7 = 0 THEN GOTO END2;
   END;

9. Procedures and Functions

A procedure is a named group of PLASYD statements which may be obeyed at any point in a program by a procedure statement. After they have been obeyed control will normally return to the statement following the call. Functions on the other hand are means of inserting 190O machine instructions into a program either to serve as data (in a compiler for example) or to be obeyed by a CASE or OBEY statement, or to be obeyed as normal statements. The latter form is normally useful only if the particular instruction is not available directly by means of other PLASYD statements. Examples of this are the 126 order (MOVE), the 127 (SUM) and the 150 and 160 groups of extracode instructions.

9.1 Functions

A function statement is written as the symbol ! followed by an identifier which designates the machine instruction required. The identifier is not a reserved PLASYD word and can be used as a normal identifier at other points of the program. The identifier is followed by a pair of parentheses which enclose the X and N fields of the machine instruction. The instruction identifiers are those used as PLAN mnemonics with the following exceptions.

F = 111           Nt = 0 is SLC2
                  Nt = 1 is SLL2
                  Nt = 2 is SLA2
F = 113           Nt = 0 is SRC2
                  Nt = 1 is SRL2
                  Nt = 2 is SRA2
                  Nt = 3 is SRAV2
F = 115           is NORM2

Examples:

! CDB(X3,C(X1));  ! SMO(0,7);    ! FAD(3,B);
! DISP('%%');     ! BVCI(LABI);  ! FSB(,A(XD))

Additional mnemonics for writing TRUSTED programs have been introduced namely:

! SPP (Set PUC parameter)
! ACT (Activate PUC)
! RMS (Request console message)

The parameters representing the X and N fields will vary according to the instruction involved !SUSAR, !NULL and !LFPB are written without X and N fields. The following instructions require only an N parameter:

!BRN, !BVS, !BVSR, !BVC, !BVCR, !BCS, !BCC, !BVCI, 
!SUSTY, !DISTY, !DELTY, !SUSWT, !DISP, !DEL, !OBEY, 
!MODE, !FLOAT, !FIX, !SFP, !SFPZ, !LFP, !STOB, !ACT, !RMS.

All other instructions require an X parameter and an N parameter which must be separated by a comma. If the X parameter is zero it may be omitted but the comma must appear e.g. !FAD(,A). An X parameter may be an octal digit or an integer (or long integer) accumulator identifier. If it is an accumulator identifier the corresponding octal number will be inserted in the X field of the instruction.

A function which is not a branch instruction may have as an N parameter an unsigned integer number or octal value which does not exceed 12 bits (10 bits in the case of shifts) or a one or two character sequence. The binary representation of any of these quantities will be placed in the N field of the machine instruction. Alternatively the N parameter may be a simple cell designator. In this case the address specified will be placed in the N field of the instruction.

For branch instructions the N field may be either a label or the name of a procedure. The address of the statement so designated will be placed in the N field of the instruction. Alternatively an unsigned integer number or octal value will be interpreted as an absolute address.

9.2 Procedure declarations

A procedure declaration specifies the group of statements that are to form the procedure and assigns a name to them. It also specifies an accumulator called the link accumulator. When the procedure is invoked from another part of the program the address of the next instruction to the call will be placed in this accumulator. Procedure declarations, like other declarations, must appear at the head ot a block. However it is permissible to call a procedure at a point in the program before the declaration, if required and even to call it from outside the block in which it is declared. The form of a procedure declaration is

PROCEDURE identifier (integer accumulator, integer); statement;

The identifier is the name by which the procedure will be known; the accumulator is the link accumulator; and the statement is the definition of the procedure. Normally this statement will in fact be a block but it can be any statement. It is called the procedure body. The integer which is optional and, if absent is assumed to be zero, specifies the number of words of data (for example in a DATA statement, which must be ignored when control is changed at the end of the statement or at the occurrence of a RETURN statement (see 9.6).

Example:

PROCEDURE SORT(X0);
      BEGIN LOWER INTEGER ENDA LOWEND; X1←£A + 10; 
             ENDA←X1;
             FOR  X1←X1-10  STEP 1 UNTIL ENDA DO 
             BEGIN X6←A(X1);  X3←X1;
                FOR X2←X1 + 1 STEP UNTIL ENDA DO 
                IF X6< A(X2) THEN
                BEGIN X6←A(X2); X3←X2 END; 
                X2←A(X1); A(X1)←X6; A(X3)←X2; 
                END; 
      END;

9.3 Procedure statements

A procedure may be activated at any point in the program by a procedure statement. This is a simple statement and consists merely of the procedure identifier. Examples:

         
SORT;
IF A(1) > 0 THEN SORT ELSE GOTO OUT;

The effect of a procedure statement is to store the address of the word following the call in the designated link accumulator and to change control to the beginning of the statement that forms the body of the procedure. When the end of this statement is reached, providing the link accumulator has the value it had on entry, control will pass to the statement following the call and proceed in normal sequence from there. If it is required to use the link accumulator for other purposes in the body of the procedure its entry value should be stored and restored before exit. Exit can be achieved from within the procedure body either by jumping to the final END of the body, which must therefore be labelled, or by use of the !EXIT function or by use of the RETURN statement see 9.6.

Procedures should not directly or indirectly call themselves since recursion is not catered for by the PLASYD system. If recursion is necessary the user must make his own arrangements to stack the link unless return down the recursion train is not needed. In this case the final procedure must be left by a GOTO an external label. Exit by GOTO is permissible in non-recursive procedures as well, for example the SORT procedure above could have contained the statement

IF A(X1) < O THEN GO TO ERRORLAB;

Normally when a procedure is called it will have already been declared or it will be declared in the current block or some enclosed block.

If it is declared within a parallel block the programmer must take special arrangements to store vital data in accumulators (or common areas - see 12.3) since crossing block boundaries causes the loss of corresponding storage (see 8.1).

9.4 Parameters

Normally data will be passed between a procedure call and the body of the procedure by using the accumulators and common variables. There is no standard method of passing parameters. However the programmer may use any method he likes. For example the standard 1900 method may be used by following the call by statements to load X3 with addresses.

Examples:

SIN;            SPLURGE;
X3←@FP1;  or    !LDN(3,25);

(Note that in the first of these FP1 must be in lower storage since otherwise the assignment will take two instructions).

These instructions may be obeyed from the procedure by using the OBEY instruction and the link accumulator, providing this is a modifier. Examples:

OBEY(X1);       OBEY(X2 + 3);

The programmer must then arrange to jump round these instructions on return from the procedure either by adding to the link -

X1←X1 + 1; 

or by using an !EXIT -

!EXIT (X1, 1); 

or by using the RETURN statement (see 9.6).

An alternative way of passing parameters is to store actual values following the procedure statement by using the data statement. Example:

        
ADD;
DATA(3,7, @A);

This could be a call of the following procedure:

PROCEDURE ADD (X3,3) 
    BEGIN
       X7←(X3) + (X3 + 1); 
       X2←(X3 + 2); 
       (X2)←X7;
    END;

As with the previous method the programmer must arrange to exit round the DATA statement. Any combinations of these forms may also be used if desired.

Note that the use of overlays imposes certain restrictions on the passing of parameters - see 12.4, 9.5.

9.5 Labels and procedures

Labels and procedures are to a large extent interchangeable. This can be exploited in two ways:-

  1. The first statement of the body of a procedure may be jumped to by a GO TO statement. Examples:
    GO TO SORT;  
    GO TO SIN;
    
    No link will be stored and if the end of the body is reached the next instruction will be determined by the contents of the link accumulator at that pont. This facility will normally be used to obey a sequence of procedures from which no return is required.
  2. A label declared in the body of a procedure may be treated as a procedure with the same link as the procedure itself. This can be used to provide alternative entry points to a procedure:-
    PROCEDURE SIN (X1); 
         BEGIN
         ..........
    COS: .......
         .........;
         END;
    

    Label identifiers and procedure identifiers are collectively known as instruction identifiers.

9.6 RETURN statement

This statement causes the compiled program to exit from the procedure in which the RETURN statement appears and to return control to a statement other than the one after the procedure call. The format of the statement is RETURN optionally followed by an integer in parentheses. Examples:

      
RETURN;
RETURN (3);

If the integer is absent, control is returned to the (n+1)th statement after the procedure call, n is as specified in the procedure declaration (see 9.2). If the integer m is present then control is returned to the (m+1)th instruction after the procedure statement. The link must if necessary be restored into the accumulator before the RETURN statement. Note that a RETURN is automatically compiled, at the end of a procedure so in normal circumstances the user does not need a RETURN statement.

10. Synonyms and Defined Variables

10.1 Synonym declarations

It is sometimes convenient to refer to a cell by more than one name, to give individual array elements names of their own or to treat say a real cell as two integer cells on occasion. It also often increases the readability of a program if accumulators can be given other identifiers so that one can talk of A(I) or A(COUNT) and mean A(X1). All these can be achieved by a synonym declaration.

A cell synonym declaration consists of the type of the new cell being declared, the identifier chosen for the new cell followed by the word SYN and the designator of the cell which is to be given the extra identifier. For example:

INTEGER  B3  SYN XX ;

gives the extra name B3 to the cell XX if XX is integer. If XX is real it considers the first word of the real cell to be called B3 and this word may now be used as an integer cell. To name the second word of a real XX one could write

INTEGER XXEND SYN XX(1)

The cell designator following SYN must be a fixed cell designator, that is either an identifier or an identifier followed by a fixed index. If an index is used it should not be such that it designates a cell in a different domain to the identifier. Thus if A and B are declared

BASE;  INTEGER A(3), B(3)

then X SYN B(-2) is legal but X SYN B(-12) is not. Designators of the type A(X1) are not allowed. The identifier following the SYN must have been previously declared by a normal or synonym declaration. Several synonyms may be specified within the same type declaration e.g.

REAL A SYN X, B SYN X(12),Y SYN Z(-3);

Each synonym is separated from the next by a comma. An identifier declared by synonym can be used anywhere that a more conventionally declared identifier could be used.

Cell synonym declarations may also be used to give names to absolute store locations. In this case initial values can be assigned as long as these do not upset the loading process.

For example:

INTEGER MEM SYN (0), SWITCH SYN (30) = #7700; 
REAL FP SYN (0)

In particular this form allows the fixed point accumulators to be considered as integer or real storage cells.

To assign extra identifiers to accumulators the accumulator synonym declaration must be used. This is similar to a cell synonym declaration but the type is replaced by the fixed word symbol ACC and only accumulator identifiers may follow SYN. An example is:

ACC I SYN X1, J SYN X2, IJ SYN X3, SUM SYN A1;

The new identifiers can then be used whenever the corresponding fixed accumulator identifier could be used.

For example:

J←A(I + 3);  SUM←SUM + FP(I,J)

10.2 The DEFINE declaration

This declaration serves to associate absolute integer values with identifiers at compile time. Whenever the identifiers subsequentially appear the corresponding integer value will be substituted. Once an identifier has been defined in this way it can appear whenever the corresponding integer value can be written.

As an example of the use of defined variables consider the following program:-

LOWER INTEGER TABLE (10) = (0*10),  TABLE2 (10);
................................................
FOR X1← 0 STEP 1 UNTIL  9 DO
     BEGIN X6←TABLE (X1) ;  TABLE2(X1)←X6;   END;

If it is later found that the size of the tables should be 11, not 10, at least four alterations must be made and there may be others throughout the program. If the program were written instead as

DEFINE    N = 10, P = N-1
LOWER INTEGER TABLE (N) = (0*N), TABLE2 (N);
.....................................
FOR X1←1 STEP 1 UNTIL P DO .......

only the DEFINE line would need to be altered.

A define statement, which must always appear in a block head before the identifier defined is used, takes the general form

DEFINE identifier1 = expression1, identifier2 = expression2, ..........

Identifiers defined in this way may not be used for other purposes in the program (or segment). An expression may take one of four forms

  1. Any integer value, example:
    DEFINE A=3, B= 7, C= #37377, D='%%%';
    
  2. A previously DEFINEd identifier, example:
    DEFINE AA = A, BE = B; 
    
  3. An absolute expression. This takes one of the forms:
    1. $ fixed cell designator (see 10.1)
    2. @ fixed cell designator - @ fixed cell designator
    3. £ cell identifier - £ cell identifier
    4. @ instruction identifier - @ instruction identifier
    In classes (ii) and (iii) the cells must either be both in upper or both in lower storage (and both in the same common block or neither in common.) The value of absolute expression (i) is the displacement considered as a number of words. The other forms give the number of words that separate the two words designated. Examples:
    INTEGER X(A), Y(20), Z(16); 
    REAL XX(12), YY(BB); 
    INTEGER W(24); 
    DEFINE E = $X(6),F = $YY(-2), G = @YY-@XX,
           H = £W-£X, I =@COS - @SIN;
    
    All identifiers appearing to the right of the = sign in a define statement must have been previously defined or declared.
  4. Any of the expressions (a) to (c), followed by any number of operator - operand pairs. The permitted operators are:
    + - * /
    
    and the operands must be either integer values or previously defined identifiers. The final and intermediate results must be acceptable integer values. All operations are carried out from left to right. Examples:
    DEFINE J = G + 5/2, K = F + J + BB * 4, 
    L = @W(4) - @X(BB) /2 + 1;
    

11. Long Types

Preceding sections have dealt mainly with the types INTEGER and REAL although mention has been made of the types LONG INTEGER and LONG REAL. This section examines the long integer type more closely. Long real types are available only on some 1900's and are not implemented in the first versions of PLASYD. They are therefore not considered in detail in this edition.

Long integer accumulators were considered in 2.1 (c). Long integer cells may be declared in a similar fashion to real or integer cells by use of the fixed word symbols LONG INTEGER. Examples:

LONG INTEGER X, Y, Z(20), NEXT (3);

They may be assigned initial values in the same way as other cells. Example:

LONG INTEGER X = 37D, Z(20) = (0D * 20);

Possible long integer values are given below. Long integer cells occupy two 1900 words each and are therefore the same size as real cells. Cell designators obey the same rules for long integers as for other types.

11.1 Long integer values

There are two forms of long integer value and each consists of a form of integer value following by D. The two integer forms allowed are integer numbers and octal values. The integer number may be between MINUS 140,737,488,355,328 and 140,737,488,355,327. The octal value may be up to sixteen octal digits. The D must in both cases follow the last digit without intervening spaces. Examples:

27D MINUS 37221567D  #7676767676767676D

11.2 Long integer accumulator assignments

Accumulator assignments for long integers are very similar to those for integers and in some cases the two can be mixed. A long integer primary is either a long integer accumulator or a long integer cell or a long integer value. For the following examples these declarations are assumed to be in force

INTEGER I, J, K;
LONG INTEGER II, JJ, KK;

A basic cell assignment takes the form

accumulator identifier ← primary 

Examples:

X10←II;  X34←X70;  X45←MINUS 3722D;

It is also possible to assign an integer primary to a long-integer accumulator. The effect is as though an integer assignment were made to the second word of the long integer, and then the sign bit removed and propagated through the first word. The operators +,-,++,-- cannot be followed by integer primaries when the cell assignment is long integer. Examples:

X70←I;  X34←X2;  X45←3;  X45←32679;

From the description above it can be deduced that the last example is less efficient than the penultimate, since this is true for integer assignments of the same quantities.

The monadic operator NEG can be used on either of these forms. Examples:

X70←NEG II;  X34←NEG X1;  X12←NEG JJ(K);

To build more complicated assignments the operators +,-,++ and -- may be used with either long integer or integer primaries. If the primaries are integer there is a similar effect to that in the assignment of integer primaries described above. Example:

X01←X67 + X67 - JJ;

Shift operators may be used with C operands. Examples:

X34←X34 SLA 2 - KK (X1)  SRL 3;

A long integer assignment may also be followed by a / and an integer cell designator. Example:

X23←JJ(X1 + 2) + II/J

The effect of this operator is to cause the current double length integer in the accumulator to be divided by the value of the integer cell. The integer result of this is placed in the second word of the double length accumulator (i.e. X3 in the case above) and the integer remainder is left in the first word (X2). The resulting contents of X23 are thus not a standard long integer value and it would not therefore be usual to follow this operator by any others. X3 and X2 could then be used separately. In order to produce a long integer result from the product of two integers a function must be used. Example:

X1←I;    !MPY(X1,J);

X12 now contains the product and may be used as a long integer:-

X12←X12 - II(2);

11.3 Long integer cell assignments

These are very similar to the corresponding integer cell assignments. The four possible forms are:-

  1. long integer cell designator← 0;

    Examples:

    II←0; JJ(K(X1 + 3) +X2 - 1)←0;
    
  2. long integer cell designator ← long integer accumulator

    Examples:

    KK←X01; JJ(K)←X67;
    
  3. long integer cell designator←NEG long integer accumulator

    Example:

    II← NEG X67;
    
  4. any of the forms a) to c) followed by any number of add operator (+,-,++ or --) long integer accumulator pairs.

    Example:

    II← NEG X67 - X67 + X34;
    

12. Segmentation and the Include Statement

Up to this point PLASYD programs have been considered as monolithic sections of program which are compiled in one run. It is however possible to split a program into segments which may be compiled separately, and then consolidated to form a program. The mechanics of compilation and combination are defined in section 13.

Each segment must be either a master segment which takes the form of a block, or a procedure which takes the form of a procedure declaration. Any complete program must contain one master segment and zero or more procedure segments.

All identifiers used for the purposes described in earlier sections will be local to the segment in which they are declared. Thus the same identifier may be used for different purposes in different segments. Other means are available for communication between segments and a means is provided to tell the compiler certain attributes of other segments, for example the link accumulator used by a separately compiled procedure. The methods of dealing with this form of intersegment communication are dealt with in the rest of this section.

12.1 Glabels

Since identifiers are normally local to the block in which they are declared, special steps must be taken to indicate to the compiler procedure names and labels to which control may be passed from separately compiled segments. This is done by preceding the label definition or the procedure declaration by the reserved word GLABEL (Global LABEL). Examples:

GLABEL OUT : X←X + X3
GLABEL PROCEDURE FRED (X1);...........................

This will cause the compiling system to remember the identifier concerned for use in other segments. The name of a separately compiled procedure is automatically a glabel and the symbol GLABEL is not required.

A glabel may be called or GOTOed from any external segment in the same way as a local label or procedure name could. However each separately compiled segment must inform the compiler of the external glabels that it is using and, if it is to call any of them the link accumulators which are to be used. This is done by an EXTERNAL declaration. Example:

  
EXTERNAL OUT, IN, FRED (X1), IGNATIUS (X4);

This specifies the identifiers of all external glabels which are to be used and, in the case of FRED and IGNATIUS the link accumulators. Note that if an identifier does not appear in an EXTERNAL declaration it can be used as a local identifier in spite of the fact that it may be declared as a glabel in another segment of the program. There is the same interchangeability between glabel labels and procedures as between local ones. Thus one may write

EXTERNAL FRED (X1), OUT (X7); 
...........
GO TO FRED;
............
OUT;
.............

12.2 Entry points

Every program must contain at least one entry point at which the program may be started. This is done by an entry label which is written

ENTRY digit: 

and may precede any statement in the same way as a label. Examples:

ENTRY 0: GO TO START;
ENTRY 9: MONITOR←X1;

The particular entry point needed during any particular run may be specified to the operating system by reference to the digit (see section 13).

12.3 Common storage

The accumulators are common to all segments and may be used to pass information across. It is also possible to specify that certain store locations are common to more than one segment by means of a global declaration. This declares one or more named common blocks of storage. A block is written as

identifier: declaration list

The identifier is assigned to that block and the same identifier must be used in all segments which wish to make use of that storage. The declaration list may be made up of any number of type declarations (INTEGER, REAL, LONG INTEGER or LONG REAL) and BASE declarations separated by semicolons. All the entities declared will be placed in the common block in the order stated and their identifiers will be local to the segment in which they are declared. The size of the common block will be the largest specified in any segment of the complete program. Initial values may be assigned to variables in a common block but they should either be identical in all segments using the block or should be assigned in only one segment. If the global declaration is in upper (see below) a new domain will be started for each common block.

A global declaration consists of the word GLOBAL followed by any number of common blocks, separated by semicolons followed by the reserved symbol GLOBEND. A block identifier and a cell identifier must not have the same name e.g. GLOBAL JACK: JACK is not allowed. Example:

GLOBAL BUFF: INTEGER B(32), CB = 32CNT;
       PARAMS: REAL A(3) = (7.1, 2.6, 9.4);
       INTEGER BB = 27; 
GLOBEND;

All the blocks of a global declaration can be made to occupy lower storage by placing the global declaration within a lower declaration. Block identifiers may be used as simple SMO indices in the same way as bases. Example:

X3←CB(BUFF);

12.4 Overlays

In general the code generated by the PLASYD compiler will allow for any overlay structure to be set up between segments (see section 15 and PLN2 page 23). If it is known that a segment or at least some of its glabels are to be called only from places in the same overlay unit or that program identifiers addressed are in the same overlay unit some redundant code can be avoided. This is done by preceding the segment by a local directive which takes one of three forms.

LOCAL:  a list of glabels;
LOCAL ALL:
LOCAL ALL BUT:  a list of glabels;

The first of these says that all the glabels in the list, which are written separated by commas and appear in the following segment are only accessed from the same overlay unit and that glabels appearing in the list and in the EXTERNAL declarations of that segment are always in the same overlay unit as the segment. Example:

LOCAL:  FRED,  JIM;

The second form says that all glabels including the identifier of the segment if it has one are local in the sense given above. This would be the normal statement for a non-overlayed program. The last form says that all glabels except those in the list are to be treated as local. Note that these statements are not part of the PLASYD language proper and LOCAL, ALL and BUT are thus not reserved words.

If a procedure is called from a different unit in the same area there are certain restrictions imposed on it. First it cannot access data following the call instruction in the way described in section 9.4 and any parameters must be passed in accumulators or permanent common areas. Secondly, no return can be made at the end of the procedure. The last restriction also applies if the unit from which the call is made is not in store, even if it is in a different area. Any attempt to return to a unit which is not in store will not be detected and a jump will be made to the corresponding word in the current unit in the relevant area.

A BRINGOVERLAY statement is available to allow the user to bring an overlay into core store without actually entering the overlay. The format of the statement is as follows (note there is no space between the G and O):-

BRINGOVERLAY instruction identifier

Any instruction identifier in the overlay may be specified provided it has been specified in compiling directives see 15.2. Example:

BRINGOVERLAY JACK;

12.5 The INCLUDE statement

This statement provides a macro-like facility for incorporating into PLASYD segments, sections of PLASYD program which have been previously stored on disc. Each section of program, which may consist of any number of statements or declarations or even parts of statements, must have previously been stored as a subfile in a file whose name is given to the PLASYD operating system CALM (see section 16). Such sections may not contain INCLUDE statements. A particular subfile may then be included in the PLASYD segment by writing.

INCLUDE (subfile name); or INCLUDE (subfile name, SL);

The effect will be as though the contents of the subfile had been written at that point in the segment. INCLUDE statements must always appear on a line by themselves. Note that lines included by this means will be compiled and listed as normal statements by the PLASYD compiler but will not be line numbered but they will be preceded by *. If SL is present the subfile is short listed.

The facility is particularly useful in connection with quantities that are used in several segments. For example, the definition of a common block need only be written once and can then be INCLUDE'd in all segments which require it. Similarly DEFINE'd variables may effectively be made global to several segments by INCLUDEing their definitions.

13 Miscellaneous Features

13.1 Comments

Comments may be placed at any point in a program, except within a string or character sequence, by enclosing them within the characters [ and ]. The brackets and everything between them will be completely ignored.

13.2 Conditional computation

If a section of PLASYD program is enclosed between the symbols

? integer (     and      ) ? integer

the contents of the parentheses will be treated as comment unless the switch specified by the integer is on. There must be no spaces between the parenthesis, the integer and the ?. Example:

   
?3( DEFINE N = 45;  X←X1 + X2 )?3

The integer must be between 0 and 10 and since zero is used for other purposes as well it will normally be between 1 and 10. Methods of setting the switch are described in section 15.

Conditional parentheses may be nested. Thus

?1(A?2(+)?2?3(B?2(-)?2)?3;)?1

will have the following effect

Switch 1       Switch 2       Switch 3       Code Compiled
OFF             ON or OFF     ON or OFF         NONE
ON              OFF            OFF              A;
ON              OFF            ON               AB;
ON              ON             OFF              A+;
ON              ON             ON               A+B-;

13.3 Type changing

Although normally quantities of different types cannot be mixed in statements it is sometimes necessary to convert from one type to another. Automatic conversion from integer to long integer has been discussed in 11.2. Conversion from long integer to integer can be done merely by taking the second word if the long integer is positive. If its sign is not known special steps must be taken to put the correct sign bit in the second word. There are many ways of doing this of which the following example is one. This places a single length representation of II in I. The value of II is assumed to be within single length limits.

X12←II; X2←X2 SLL 1; 
X12←X12   SRL 1; T←X2;

Two special functions are also provided for conversion between integer and real. These are FLOAT and FIX. Both are rather non-standard functions. FLOAT is used in a special form of accumulator assignment -

A1 ← FLOAT cell designator

The cell designated must be either an integer or a long integer cell. If it is integer there should be another integer cell following with zero contents. The effect is then to convert the integer to real form in the floating point accumulator. If the following cell is not zero its contents will be taken as the binary representation of a fraction (i.e. its integer value multiplied by 2-23) and included in the conversion. If a double length integer is designated its two words are treated in exactly the same way as the integer and following word. Thus if II is long integer

II←3;
A1←FLOAT II

FIX is used in a special form of cell assignment -

long integer cell designator ← FIX A1

This is the opposite of the FLOAT operation and will place in the first word of the long integer the integer part of the value of A1 and the fractional part in the second word. Thus to set the integer I to the integer part of the accumulator one could say

(6)←FIX A1;   [(6) is X6 and X7] 
I←X6;
or   
LONG INTEGER II; 
INTEGER T SYN II; 
II←FIX A1;

13.4 Truncated numbers

These are an alternative form of integer value and are written

integer number T unsigned integer number 

Examples:

MINUS 12T15      1976215T22

There must be no spaces between the T and either of the numbers. If the number is considered as

aTb

its value is the rightmost b bits of the number a. It will normally only be used with b = 12, 15 or 22 although other values are possible. If a is negative it can be used to set up negative addresses.

13.5 MEMBER statement

This statement allows the user when compiling multimember programs to specify the member number and priority of individual members. The statement which must appear before the head of a procedure, similar to LOCAL, has the following format

MEMBER (m,n)

where m and n are integers

m ≤ 5    Member Number
n ≤ 99   Priority

The statement need only appear once for each member although there may be more than one segment in a member. Example:

 
MEMBER (3,25);

13.6 NONPLASYD declarations and statements

The nonplasyd declarations and nonplasyd statements enable segments with multiple unlabelled entry points to be incorporated into a PLASYD program. The nonplasyd declaration has the same format as an external declaration with NONPLASYD replacing EXTERNAL. Example:

NONPLASYD JACK (X0), JOHN (X1)

A nonplasyd statement which must refer to an identifer declared in a nonplasyd declaration allows the user to enter a procedure at other than the first statement of the procedure or to goto an instruction after a glabel. The formats are

instruction identifier (  unsigned integer number  ); 
and
GOTO instruction identifier (  unsigned integer number  ); 

The bracketted sequence may be omitted, in which case 0 is assumed. Examples:

JACK (3);  JOHN (2); 
GOTO FRED (4);

13.7 CUEOVERLAY statement

The CUEOVERLAY statement enables programmers to compile the A/U (Overlay Area and Unit number) of an identifier. The identifier must be either a glabel name or a segment name. The A/U appears in the body of the compiled code at the occurrence of the statement and hence can be used as data similar to the code compiled at a DATA statement. The format of the statement is

CUEOVERLAY instruction identifier;

Example:

CUEOVERLAY JACK;

14. Operating System

An operating system, CALM (Control And Logistics Monitor), is used when compiling programs with the PLASYD language compiler described in this document and also the PSFUL (Plasyd System FUnctional Language) compiler. The monitor, which requires an executive offering range compatible trusted program facilities, not only controls the operation of any program entrusted to it (hereafter called PUC (Program Under Control)), but also controls the generation of the source records for the PLASYD and PSFUL compilers and transfers the semi-compiled records output by these compilers to specified disc files. Paper tape, card and disc files are accepted as source media for the compilers. The directives to control CALM are interleaved with the parameters, data and source for the programs it controls, enabling extra programs to be easily inserted into a batch. Every program to be run is identified by its standard four character name and its data is terminated by ****.

The monitor, although primarily intended to control the PLASYD and PSFUL compilers, can control any batch of programs, but in this case it may be necessary to supply an events list before each PUC name. For standard batches it is not necessary to supply event lists as there are predefined actions on standard halts and unexpected occurrences in the PUC such as illegal. Programs entrusted to CALM may be found and loaded from magnetic tape.

No operator action is required except to find the monitor, to activate the monitor, and to take standard error action if

  1. the PUC loops
  2. there is insufficient data for the slow peripherals
  3. a peripheral or file is required
  4. more core store is required but not available
  5. the monitor has to be deleted.

The monitor always requires a line printer and one slow input peripheral. The monitor will open all disc files necessary for the two compilers but all other peripheral activity such as the use of disc files by #XMED or of magnetic tapes by #XPMU is allowed without intervention. Programs with trusted status such as #XJEC (file allocator) cannot be run under CALM. The CALM monitor program name is #YAPC and it changes its name to that of the PUC when the PUC is loaded although there are in effect two programs operating in the same program slot.

All the directives described in the subsequent parts of this chapter are terminated by newline if on paper tape or the end of a card; spaces are ignored except within brackets and the directives may start at any character position on a line.

14.1 YAPC directive

The initial card or line on paper tape of a batch of programs must be YAPC optionally qualified. The format of the directive is

YAPC, yyyy, g

where yyyy is the last four characters of the disc file PROGRAM yyyy from which YAPC was loaded and g is the generation of the file. If yyyy is omitted tho file is assumed to be PROGRAM YAPC and if g is omitted a file of appropriate name but of highest generation number will be opened.

It is intended that most programs required will be held in the PROGRAM YAPC file.

The occurrence of a YAPC directive reinitialises and enables more than one batch of jobs to be run without refinding the system. Note that if YAPC is not qualified the file name PROGRAM yyyy remains unchanged. If g is present yyyy must be specified.

14.2 NAME directive

This directive which can occur only once in a batch of jobs is used by CALM for two purposes namely:

  1. to take special action whenever this program is run. The program specified in the NAME directive is assumed to be under development and if this is a compiler for example, failure of a particular run is not fatal for the remaining jobs in the batch. CALM will output standard error information and search for the next occurrence of the NAME Program.
  2. to specify to the PLASYD or PSFUL compilers the name of the program that is to be compiled.

The format of the directive is

NAME (xxxx, yyyy, g) 

where

xxxx is a four character program name.

yyyy is the first four characters of the name of a file PROGRAM yyyy holding xxxx. The file may be on disc or magnetic tape.

g is the generation number

yyyy must always be present (even if xxxx is identical to yyyy) unless xxxx is held in the file from which #YAPC is loaded or if xxxx is being generated by the PLASYD or PSFUL compilers, when it can be omitted. If g is omitted a file of highest generation number will be opened on disc or the first on line if on magnetic tape. If g is present yyyy must be specified.

xxxx may have a charge code added for use with PLASYD or PSFUL

Examples:

NAME(JACK)
NAME(FRED16041) 
NAME(XALE, DISC, 730)

14.3 Status directive

CALM has a built in list of the names of programs it recognises. This list will be published whenever a version of the system is issued. All these programs are known to the monitor and are automatically entrusted to CALM which assumes they are to be found in the file from which itself was found. A further class of programs is also automatically entrusted, this class contains programs which have been consolidated by #XPCL earlier in the same run and which #XPCL has attempted to load into store.

One further program known to CALM and automatically entrusted is the program specified in the NAME directive (see 14.2).

To add programs to the list held in CALM or exceptionally to free a program from the control of CALM two directives are available. The first directive ENTRUST may appear any number of times and both directives must appear before the first program name directive. The directives are:-

  1. ENTRUST (xxxx, yyyy, g)
    where 
    xxxx is a four character program name
    yyyy is the first four characters of the name of a 
          file PROGRAM yyyy holding xxxx.  The file may be 
          on disc or magnetic tape
    g   is the generation number
    
    g must always be present (even if xxxx is identical to yyyy) unless xxxx is held in the file from which #YAPC is loaded, when it can be omitted. If g is omitted a file of highest generation number will be opened on disc or the first on line if on magnetic tape. If g is present yyyy must be specified. Examples:
    ENTRUST (XALE, DISC)
    ENTRUST (XPMV, TAPE, 100) 
    ENTRUST (XPLZ)
    
  2. FREETRUST (xxxx) where xxxx is a four character program name. In exceptional circumstances it may be necessary to operate a program by means of console messages and other operator action. The FREETRUST directive causes the monitor to delete itself and find xxxx when the program directive xxxx is encountered. The file from which xxxx is to be found must have been previously specified in an ENTRUST or NAME directive. Example:
    FREETRUST (XPCL)
    

14.4 Card and paper tape directives

Two directives are available to change the medium of a slow input; they may appear between programs or between source segments of the PLASYD and PSFUL compilers

  1. READ FROM (TR) If the current input is from cards then on reading this directive CALM will allocate a tape reader and read from that device. The card reader is released.
  2. READ FROM (CR) If the current input is from paper tape then on reading this directive CALM will allocate a card reader and read from that device. The tape reader is released.

If the device specified in the directive is the same as the current input then the directive is ignored. There should be a blank line or card after the READ FROM directive.

14.5 PUC control directive

The parameters, source, etc for any particular program are enclosed in what can be considered as matching brackets namely

  1. the four character name of the PUC, possibly qualified
  2. ****

The four character name is only read by CALM and is required for every program that is to be run under the system, even those which outside the system would be loaded by DELTY FIND or DELTY LOAD instructions. If a PUC does a DELTY FI then the accumulators are carried forward if and only if the program is found from disc. If a PUC does a DELTY LO or DELTY FI, the program name and if specified the file name, are stored by CALM. The program is not loaded until the occurrence of the corresponding program name and it is then loaded by the standard FI technique.

**** must be present even if the data of the PUC is terminated by ****. **** is ignored after a successful run but is used by CALM in its search for the end of data of an unsuccessful PUC run.

The four character name can be qualifed to give the entry point required and whether the PUC, if already in core store, is to be used without reloading. The format is

name, xy, INCORE

where

name     is the four character name
xy       is the entry point in the range 20 to 29
INCORE   indicates the PUC is not to be reloaded.

Either or both of the qualifiers may be omitted. If the entry point is omitted then the one corresponding to the current slow input medium is assumed:-

20       for paper tape
21       for cards

xamples:

XPCL
XALE, 22 
XMED, INCORE

There is one further pair of brackets outside the batch of jobs. The opening bracket is the YAPC directive, and the closing bracket is the batch terminator, ***E. YAPC, wherever it appears, reinitialises the system. Thus it is possible to run several batches in one run by removing the ***E from the end of each sub-batch except the last.

14.6 Standard and error halts

There are three classes of PUC halts:-

  1. halts which require operator intervention. These halts are transmitted to the console typewriter and the system halts until the operator takes appropriate action.
  2. halts which do not require operator intervention and are standard to the system. These halts include messages that occur when a program is loaded or is terminated and also DELTY LO and DELTY FI messages. The action taken is to run the next program specified by the directives unless the usual action has been overridden by action specified in the events list.
  3. halts which do not require operator intervention and are either in the PUC's events list (see 14.7) or are not specified. Included in this class are all illegal messages that may occur in the PUC. If the halt appears in the event list the halt is listed on the line printer and the appropriate action is taken but if the halt is not in the event list the action taken by CALM is dependent on the type of the PUC. If the PUC has been specified in the NAME directive or has been generated by #XPCL using disc parameters as against slow peripheral parameters then CALM lists the halt on the line printer, outputs 3000 words of core store of the PUC starting at word 0, searches for the next PUC name then activates that program. If the PUC is not of this type CALM merely lists the halt unless it is an illegal message on the line printer. If it is an illegal message a 3000 word core dump is given. The batch is then considered to be terminated and CALM searches for a YAPC directive or ***E.

Halts which are currently in type (a) are:

  1. HALTED CP, HALTED CR, HALTED LP, HALTED TP, HALTED TR, the operator will if possible make the required peripheral available and should then type GO # name where name is the current PUC or possibly #YAPC itself.
  2. HALTED ST more core is required, the operator will if possible make more core available and type GO# name as above
  3. HALTED PL more paper is required in the line printer. The operator will type GO# name after loading the paper
  4. HALTED OK the system has read ***E
  5. LOAD.............or NEED .............. these halts cover all disc file or magnetic tape requests to the operator. The operator will if possible make available the file or magnetic tape and type GO# name.
  6. HALTED SYSTEM OVERLOAD. The operator will if possible wait until other programs have been deleted and continue with GO# name.

Halts which are currently in (b) are:-

  1. HALTED LD the PUC has been loaded, CALM automatically activates the program
  2. HALTED EC, HALTED OK, HALTED AH, HALTED HH, HALTED EN,
    DELETED HH, DELETED MX, DELETED EC,
    HALTED AE, DELETED AE: the PUC has terminated its run, the next PUC required is then loaded and activated
  3. HALTED EE, HALTED ZZ: the PUC has terminated its run. If the PUC is either the one specified in the NAME directive or has been generated by XPCL the the next PUC required is then loaded and activated. If the PUC is not as above the batch is terminated.
  4. DELTY FI the PUC has deleted specifying: the next program to be run. CALM loads the next PUC which need not be the one specified in the FI message, although the accumulators will be remembered
  5. DELTY LO the PUC has deleted specifying the next program to be run. CALM loads the next PUC which need not be the one specifind in the LO message. The accumulators are not passed to the next program, go type entry blocks are only allowed from magnetic tape if the load peripheral is to be retained.

14.7 Event list

Each program may have an event list describing the action CALM is to take on any specified halt. The event list may over-ride the standard action described in 14.6. If the PUC does not have an event list or the halt that occurs does not appear in the event list then the action described in 14.6 is taken.

The event list will appear immediately before the PUC name and will apply to that run of the PUC unless the PUC is not reloaded (see 14.5 INCORE).

Each directive in the list consists of three parts:-

  1. AT followed by one of HALTED, DELETED, DISPLAY, LOOPING, ILLEGAL, FAIL. Each of these is terminated by the first open bracket of the qualifier or if no qualifier by a comma.
  2. an optional qualifier which if present is enclosed in round brackets. This qualifier can consist of any two characters including ▽▽ or ▽ "non space character".
  3. the action to be taken by CALM if this event occurs. This action can take one of the following forms
    1. GO: the program under control is continued at the next instruction
    2. GO m: where m is an integer. The PUC is continued at instruction m.
    3. GO abcd: where abcd is any four character program name. The current PUC is deleted and a search made through the remaining parameters of the system for the program specified by abcd. This program is then loaded.
    4. HALT: the system will display the message in the event list and HALT awaiting operator action
    5. FINISH: the system will display ZZ and then search for either a YAPC line or ***E
    6. CONTINUE: the system will display the message, terminate the current PUC and search for the next PUC control
    7. OU m n: where m, n specify the core dump required, namely, n words starting at decimal address m
    8. AL p q: where p is a core store address in decimal, q is in octal format. At the specified event the system will alter word p to the new contents
    9. ON (n1,n2,..... , nq) 0<nq<23: At the event the system will set to 1 the bits of word 30 of the PUC specified in the ON action
    10. OF (n1,n2,..... , nq) 0<nq<23: At the event the system will set to 0 the bits of word 30 of the PUC specified in the OF action

    Actions (vii) to (x) can be followed by any of (vii) to (x) enabling more than one action to be taken at an event, and must be terminated by one of the actions (i) to (vi). Continuation lines are allowed for actions (vii) to (x) as one of the actions (i) to (vi) must appear. Examples:

    AT ILLEGAL, OU 0 10000, FINISH
    AT HALTED (ER) , CONTINUE
    AT LOOPING, OU 5000, GO JACK
    AT DELETED, GO FRED
    AT DISPLAY (AB), GO
    AT HALTED (LD), AL 60 *10, AL 70 *20,
                    AL 2056 *76542121,
                    ON (0,1,2,3), GO 20
    AT HALTED (AB), OF (0,23), ON (2),
                    AL 2765 *7, GO
    

    Event list messages are listed when they occur on the line printer and displayed on the console typewriter unless suppressed (see 14.8).

14.8 Changes to standard CALM actions

It is possible to change the standard action of CALM when a display message or an error occurs. The changes are carried out by altering the state of bits in word 30 of CALM. Note that CALM's word 30 is not the same as word 30 of the PUC. The initial state of CALM's word 30 is all bits set to 0. Two directives are available namely

ON  (n , n2,.... nq) 0<nq<23
and
OFF (n , n2,.... nq) 0<nq<23

At ON, CALM will set the specified bits to 1 and at OFF, CALM will set the specified bits to 0. Word 30 of CALM after ON or OFF remains set for all subsequent PUC, until the occurrence of another ON or OFF directive or a YAPC directive when word 30 is set to 0.

At present the setting of bits 0,1,2,3, 4 and 5 of word 30 only have an effect.

Bit 0      1 Complete core print of PUC at an unexpected event
           0 Core print of the first 3000 words of the PUC at an unexpected event

Bit 1      1 All display messages from the PUC are suppressed 
           0 Display messages cause typing

Bit 2      1 Excutive message referring to name changing is suppressed
           0 Name changing message is typed :- 
           AAAA was BBBB

Bit 3      1 Page throws to the line printer generated by
             the TRACE package (see 16) are suppressed 
           0 Page throws are not suppressed

Bit 4      1 Event list messages are not "displayed" or listed when they occur
           0 Event list messages are "displayed" on the console typewriter and 
             listed on the line printer

Bit 5      1 Disengage messages from the PUC will cause a fix message to be displayed 
             on the console typewriter 
           0 Disengage messages are ignored
           

14.9 CALM entry points

There are at present six entry points in use in the CALM system 20, 21, 22, 25, 26, 27. The operator is informed by a console message when the PUC name changes and in the following name represents the current program name; when #YAPC is initially loaded name is YAPC.

  1. GO #name 20,#YAPC will read from eight track paper tape and search for a line which says "YAPC"
  2. GO #name 21, #YAPC will read from a standard card reader and search for a card which says "YAPC"
  3. GO #name 22 This causes the system to skip forward to the next program and continue.
  4. GO #name 25 This entry is used if the operator considers the PUC is looping. CALM will search the current PUC event list for AT LOOPING or AT FAIL (see 14.7) and if present will take the action requested otherwise an automatic core dump of the PUC is given.
  5. GO #name 26 This entry enables the operator to give an automatic core dump of the PUC if an unexpected halt occurs.
  6. GO #name 27 This entry enables the operator to give an automatic core dump of the PUC and the controlling system if it is suspected that CALM has broken.

14.10 Operation

CALM is normally a disc based operating system but it is possible to hold the system on magnetic tape provided the executive has disc find facilities.

The CALM system program is #YAPC and the following programs can appear in the same program file as #YAPC and used in a CALM batch of jobs without being referenced in an ENTRUST directive.

#XMED Disc editor
#YAPP PLASYD compiler
#YAPI PSFUL compiler
#XPCL Disc consolidator
#XPEU Disc program library update
#XPES Disc subroutine library update
#XPMX Disc cosy editor
#XPMY Disc cosy create
#XPLZ Disc Plan compiler
#YADM Disc to magnetic tape dump
#SCPR Semicompiled print

Other programs may be added to the program file containing YAPC but these must be referenced by ENTRUST or NAME directives

Once the program file is established the operator action required to run a batch of programs is minimal. The operations are

  1. FI # YAPC # yyyy: where PROGRAM yyyy is the file holding #YAPC
  2. load card or paper tape directives and any magnetic media required
  3. GO # YAPC 20 if first directive is on paper tape
    GO # YAPC 21 if first directive is on cards

The directives will be read by #YAPC and the required programs in the batch will be run as described in the previous section of this chapter. Name changes will appear on the console and the batch will finally HALT OK. If an error has occurred in the batch DISPLAY ZZ appears on the console and the batch parameters are then searched for a YAPC line or ***E when either a new batch will be started or CALM will HALT OK. The only action required of the operator after the initial GO is to load parameter, source or data packs as required.

A very simple standard job sheet is also possible. The CALM program occupies approximately 7000 words of core store and is resident in core all the time and there are no overlays held on disc.

The latest version of YAPC is described in PLN 16 which is reissued when a new version of CALM is available.

Messages from YAPC are described in Chapter 16.

An example of a CALM batch in which a program #XMFR is compiled and consolidated using PLAN and then a number of tests run on the compiled program is given below

YAPC, MINE, 100
ENTRUST (JACK)
ENTRUST (XRAA, DISC)
NAME (XMFR, EMF1)
XPMX
....       Data XPMX
****
XPLZ
....       Data XPLZ   
****
XPCL
****
XMFR
....       Data XMFR
****
AT HALTED, CONTINUE 
XPCL
....       Data XPCL
****
AT HALTED (AB), GO 
JACK, 20
****
XMFR
....       Data XMFR
****
AT HALTED, CONTINUE 
XRAA
....       Data XRAA
****
***E

Note. JACK has to be entrusted as it is created by XPCL using slow parameters. XMFR and JACK have standard default actions on error. Any unexpected halts in XPMX, XPLZ, XPCL will cause the system to scan to ****E and HALT. XPMX, XPLZ, XPCL are not entrusted as it is assumed they are found from the file containing YAPC i.e. #PROGRAM MINE, generation number 100. XRAA is assumed to be on PROGRAM DISC.

15. Compilation System

As described in Chapter 14 CALM is used to control the generation of PLASYD and PSFUL programs. In this chapter are described the directives that specify the mode and type of program to be compiled, the environment of the source and semi-compiled, and the type of listing required.

15.1 Listing format directives

All listing is carried out on a line printer allocated by CALM unless the PUC specifies some other device in which case CALM's printer and the other device will both be used. There are three types of information output:-

  1. the directives controlling the system
  2. the source or pseudo semi-compiled of the PLASYD and PSFUL compilers
  3. PUC output not included in (ii) but using a line printer e.g. #XMED or #XPCL output.

(i) is listed as it appears on the input medium without line numbers unless it was input from a file specified in a READFROM directive

(ii) is listed as it appears on the input medium and if input from a file specified in a READFROM, the line is preceded by line numbers (except when input from an INCLUDE subfile), for use with the disc editor #XMED

(iii) is listed in the format that the PUC specifies, this may or may not include line or statement numbers depending on whether or not the PUC produces them. The CALM system may add comments to the directive lines and also add, to the type (ii) output, messages output by the two standard compilers. All such messages start in column 93 of the line printer enabling the pages of listing to be photo-copied onto A4 paper without including the comments. Types (i) and (iii) are always listed regardless of the steering directives. This steering directive influences the type (ii) output. The directive may take one of three forms:-

  • (a) NOLIST: all listing from the compilers will be inhibitted; this should only be used if no errors are expected
  • (b) SHORTLIST: the only information to be listed will be those lines which have had comments and error numbers appended, together with information detailing the core requirements of the segments
  • (c) LIST: all source and information output by the compilers together with a full map of the core store required by each segment will be listed. Note that all blank lines are listed but otherwise ignored.

The form of listing; can be changed between segments. The default action is LIST. Details of the comment and error numbers will appear in Appendix 2.

There is a further directive TAB n which effects tab settings.

  • (d) TAB n: the tab setting initially is six spaces. TAB n will cause all subsequent tabs to be taken as n spaces.

15.2 Program specification directives

The following directives specify the name and priority of the program CALM is generating. They also specify the structure and mode of the program. The directives include the NAME directive previously described in 14.2. but repeated here as far as it affects the generation of new programs. Programs generated in a previous run using the PLASYD and PSFUL compilers and intended for use under CALM with full development facilities should be specified using the full NAME directive as in 14.2. The directives are:

  1. NAME (xxxx): where xxxx is a four character program name, xxxx may be followed by up to eight characters which are taken as the account code. xxxx is the name of the program CALM is generating. If the NAME directive is omitted the name is taken to be #XXXX. This directive must appear before the first YAPP or YAPI line, examples:
    NAME(JACK)
    NAME(XFOC16003)
    
  2. PRIORITY (ab): where ab is a two digit integer and specifies the priority to be given to the program specified in the NAME directive. A priority of 50 is assigned if the directive is omitted. This directive must appear before the first YAPP or YAPI line. Example:
    PRIORITY (87)
    
  3. OVERLAY (A,U) n1 , n2 , n3 ....: where
    • A is tho area number of the overlay A < 255
    • U is the unit number of the overlay U <1023
    • n1 , n2 , n3 are names of segments and procedures in overlay A,U. This directive must appear immediately after the first YAPP line.
    Examples:
    OVERLAY (1,2) FRED, JACK, JIM 
    OVERLAY (2,1) JOHAN
    
  4. OVERCOMMON (A,U) m1, m2, m3......: where A and U are as in (c) and m1 , m2 , m3 are the names of global areas in overlay A,U. Examples:
    OVERCOMMON (1,2) WORKBUFF, STORE
    OVERCOMMON (6,5) FUNCTIONS, SYMBOLTABLE
    
    There may be any number of OVERLAY and OVERCOMMON directives but each one must be at most one line in length. This directive must appear immediately after the first YAPP line.
  5. PROGRAM MODE (nAM, xBM, mCH): where
    • nAM can be 15AM or 22AM
    • xBM can be DBM or EDM
    • mCH can bo 15CH, 22CH, or MIXAM

    nAM specifies the address mode in which the program is to operate after loading. xBM specifies the branch mode of the program. mCH specifies the checks the consolidator carries out on the segments comprising the program, MIXAM implies make no check.

    The parameters of PROGRAM MODE nAM, xBM and mCH may appear in any order. The directive must appear before the YAPP or YAPI line.

    If nAM is omitted tho mode of the machine is taken to be 15AM.

    If xBM is omitted DBM is assumed.

    If mCH is omitted then 15CH is assumed if nAM≡15AM, 22CH is assumed if nAM≡22AM

    If the directive PROGRAM MODE is omitted then PROGRAM MODE (15AM, DBM, 15CH) is assumed.

    Examples:

    PROGRAM MODE (22AM, EBM, 22CH)
    PROGRAM MODE (MIXAM, EBM)
    PROGRAM MODE (22AM, DBM)
    

15.3 Disc file and subfile directives

The file and subfile directives specify all files to be used by CALM in compiling the program specified in the NAME directive. All other files used, for example, in an #XMED run are specified in the parameters for that program. In the directives described in this section the following definitions hold:-

  1. f is a filename
  2. s is a subfile name

    Each file or subfile name can consist of up to 12 characters chosen from the set A to Z, 0 to 9, space, and "-" (hyphen). The first character must be a letter.

  3. g is the generation number
  4. gs is the subfile generation number

    Generation numbers are optional and if omitted, together with enclosing brackets, the file or subfile name of highest generation number is taken. If g is omitted in a SENDTO directive (see 15.3 a) then 0 is substituted.

  5. YAPP is a qualifier to indicate a file or subfile for use with the PLASYD compiler for holding semi-compiled.
  6. YAPI is a qualifier to indicate a file or subfile is for use with the PSFUL compiler for holding semi-conpiled.

    If the qualifier is omitted and the compilation consists of runs of both the PLASYD and PSFUL compilers then all output from both compilers will go to this file and subfile. The qualifiers are only required if in a mixed compilation the semi-compiled output is required to be to separate files.

The directives are:-

  • (a) SEND TO: This directive can take one or two forms:-
    1. SENDTO (f(g). s(gs)) /YAPP (or /YAPI) A file f(g) is opened and searched for a subfile s(gs). If the subfile is not found then it is created in the existing composite structure. If the structure is not a composite structure then an error is given. This directive is not as yet implemented and ",." is assumed. Examples:
      SEND TO (PROGRAM FILE(10).SUBFILE (G))/YAPP 
      SEND TO (PROGRAM MINE.PSFULSEG)/YAPI)
      
    2. SEND TO (f(g),.s(gs))/YAPP (or YAPI) A file f(g) is opened and a composite subfile structure is created with s(gs) as the only subfile in the file (apart from the space subfile necessary for spare buckets in the file). Example:
      SEND TO (PROGRAM OPEC,.SOURCE 1)/ YAPP
      
      There may be at most two SEND TO directives. One may be used to specify the file and subfile for the new PLASYD segments and the other may be used for the new PSFUL segments. The first subfile so referred to will also hold the steering information for #XPCL, the disc consolidator. The order in which the subfiles are read by #XPCL is given after 15.3 c.
  • (b) SEMICOMPILED (f(g).s(gs)) All segments in subfiles s(gs) of file f(g) will be consolidated into the "NAME" program. This will enable previously compiled segments to be included without recompiling from source. Example:
    SEMICOMPILED (PROGRAM JACK.  MASTERSEG)
    
  • (c) LIBRARY (f(g).s(gs)) Only segments in subfile s(gs) of file f(g) which have been called by earlier segments accepted by the consolidator will be consolidated. Neither the LIBRARY nor the SEMICOMPILED directive require a qualifier. Example:
    LIBRARY (MONITOR FILE.TRACESEGS)
    
    Use of the SEMICOMPILED and the LIBRARY directives enable segments written in other languages such as PLAN to be consolidated with PLASYD and PSFUL segments.

Any number of the preceding subfile directives may appear before the first PUC name directive. The subfiles will be presented to the consolidator in the order that they appear as parameters to CALM hence the user must ensure that these parameters are in the order in which he wishes the segments to be consolidated. The first directive does not have to be a SEND TO directive. Thus steering and master segments generated in a previous run can be presented to the consolidator before the new code output to a SENDTO file. This facility also allows users to specify the order of segments in core store as, in general, non-overlay program segments are loaded in the order of presentation to the consolidator.

One further directive required for use by the consolidator is:

  • (d) DUMP ON (f(g)) f(g) is a file to which a binary version of the "NAME" program is to be dumped. The program can then be used either as a PUC for CALM, or external to the system.

    If this directive is omitted the compiled program is automatically loaded into core store. If an overlayed program is consolidated it is necessary to have a DUMP ON directive. Example:

    DUMPON (PROGRAM JOHN(100))
    

Note that if there is no SEND TO directive then it is not possible to consolidate and the directives (b), (c) and (d), if they appear, will be ignored. No semi-compiled will be generated from any source read but syntax checking and the appropriate listing will take place.

The following two directives specify the disc files that can be used to hold source for the PLASYD and PSFUL compilers and, optionally, in the case of the file specified in the READFROM directive, control directives for CALM as described in 14.1 to 14.10. The files and subfiles specified in these directives must have been created by #XMED. The directives are:-

  • (e) READ FROM (f(g).s(gs)) All the records in the subfile s(gs) will be handed as source to the compiler currently in use. Example:
    READ FROM (FORTSOURCE (4).  INPUT SOURCE (6))
    
  • (f) MACROFILE (f(g)): There is no subfile specified in this directive. MACROFILE is used in conjunction with the INCLUDE statement described in 12.5. When an INCLUDE directive referring to a subfile appears in a PLASYD program the system opens the file last specified in a MACROFILE directive and searches for the specified subfile. The contents of the subfile are passed as source to the compiler. At the end of the subfile, source is read from the original input. Example:
    MACROFILE (GLOBAL FILE (1))
    

The file names and subfile names are used only by the CALM monitor so these can be the same as procedure names in a PLASYD segment.

In the following example only the parts relevant to these directives have been included. It is assumed there is an INCLUDE directive in the PLASYD source held in the source subfile NEWSEG. Example:

SEMICOMPILED(PROGRAM JACK(10). MASTER) 
SENDTO (PROGRAM FRED(1). FIRSTSEG) 
SEMICOMPILED (FORTSEGS. OUTPUT) 
LIBRARY (TRACE. MONITORSEGS) 
DUMP ON (PROGRAM COMP(1)) 
YAPP
MACROFILE (PLASYD MACRO) 
READ FROM (COMPSOURCE.NEWSEG)
****
YAPI
READ FROM (COMPPSFUL.FIRSTSEG)
****
..........

15.4 Switch directives

To implement conditional compilation described in 14.2 and to list the code compiled by PLASYD, it is necessary to set bits in word 30 of the PLASYD or the PSFUL compiler. The directive takes the form

SWITCH (n1, n2, n3,......ni) 0<ni<10

where n1, n2, n3,...... etc correspond to the bits of word 30. Example:

SWITCH(0,1,3,5)    

this sets bits 0, 1, 3 and 5 to one, the remaining bits are zero.

The directive can appear after the YAPP or YAPI line before a segment, or between segments. The directive and hence the bit setting applies only to the next segment to be compiled from source. Once this segment has been compiled word 30 is set to 0 unless another SWITCH directive occurs. Successive directives before a segment of source have an additive effect. The example SWITCH (0, 1, 3, 5) could have been written:

SWITCH(0)
SWITCH(1)
SWITCH(3)
SWITCH(5)

15.5 Segment description directives

These directives describe the environment of the PLASYD or PSFUL segments that follow the directives which must appear after a YAPP or YAPI line before the first segment, or between segments are as follows:

  • (a) SEGMENT MODE (nAM, xBM) where nAM can be 15AM, 22AM or MIXAM and xBM can be DBM, EBM or MIXBM.

    If nAM is omitted MIXAM is assumed.

    If xBM is omitted currently MIXBM is assumed.

    nAM and xBM specify the program modes that the following segments will run in. SEGMENT MODE has the same scope as the directives LIST etc, in that it holds for all succeeding segments unless changed. If the directive is omitted SEGMENT MODE MIXAM,MIXBM) is assumed. Examples:

    SEGMENT MODE (22AM)
    SEGMENT MODE (DBM, 22AM)
    
  • (b) SMOMACRO: The action of this directive which has the same scope as SEGMENT MODE is to cause YAPP, the PLASYD compiler, to generate SMO MACROS
  • (c) COMPILESMO: The action of this directive which has the same scope as SEGMENT MODE is to cause YAPP to compile SMO instructions.

    If both SMOMACRO and COMPILESMO are omitted the environment of the machine is taken as to whether SMO instructions are allowed.

The following directives affect the size of the compiled program's cue list and only have a limited use and are not recommended for general use.

  • (d) LOCALSEGMENTS: Action of this directive which has the sane scope as SEGMENT MODE is to inhibit the generation of 9 ENTRY cues for globals etc. This reduces the size of the cue list of the program.
  • (e) GLOBAL SEGMENTS: Action of this directive which has the same scope as SEGMENT MODE is to cause YAPP to generate 0 ENTRY cues. This directive is only required if in one compilation the user wants to compile sements with and without 0 cue's.

    The default action if no directive is specified is to generate 9 cues.

    Note that if a user has specified LOCALSEGMENTS all other segments in that program must have external procedures and glabels referenced by LOCAL directives if they appear in segments compiled after the LOCALSEGMENTS directive.

15.6 Editing and dump facilities

There are no basic editing and dump facilities in the CALM system. All editing of source on disc files must be carried out using #XMED. Both the PLASYD and the PSFUL compilers accept disc source via the CALM system. The job directive referred to in XMED can until a specific one is available for PLASYD be *ALGOL, *EMA or *FORTRAN. The system checks only that it is a source subfile.

A special progran #YADM is available for security dumps of disc files. The program is described in PLN 17.

15.7 Operation of the PLASYD compiler YAPP

YAPP is the name of the PLASYD compiler and all source must be preceded by the PUC control directive YAPP and terminated by ****. The directives specifying the input and output media are described in 15.1 to 15.5. All errors and comments listed by the PLASYD compiler are described in chapter 16. The examples in the following section (15.8) show how PLASYD is used in conjunction with XMED etc.

15.8 Examples

Examples of three jobs using PLASYD and PSFUL follow:-

(a) All the standard facilities of CALM are used:-

  1. to specify the name of the program and its overlay structure
  2. to specify previously compiled segments
  3. to alter one line in the PLASYD source of the subfile LISTSYSTEM
  4. to compile the subfile LISTSYSTEM using the PLASYD compiler YAPP
  5. to consolidate the specified subfiles using XPCL
  6. to run two test programs JACK and JOHN

If an error halt occurs during the first test program a core dump of 3000 words is obtained and then the second test program JOIIN is run.

YAPC
SEND TO (PROGRAM OPEC. SYNTAX)
DUMP ON (PROGRAM FILE (6))
SEMICOMPILED (XFOC(1).  INPUT SEGS)
SEMICOMPILED (XFOC(100).  OUTPUTSEGS)
LIBRARY (PLASYD. TRACESEGS)
NAME (XFOC76103)
PRIORITY (60)
OVERLAY (1,1) PROGDSC, FILE OPEN
OVERLAY (1,2) SYNTAX, LIST
OVERCOMMON (1,1) LISTSYST, TABLE
LIST
XMED
*OUT (OPTSOURCE(106))
*IN  (OPTSOURCE(105))
*FORTRAN LISTSYSTEM
*ALTER 10,1 
X1 ← @TABLEA;
****
////
****
YAPP
SEQUENT MODE(EBM,22AM)
MACROFILE (FORTGLOBAL) 
READFROM (OFTSOURCE(106). LISTSYSTEM)
****
XPCL
.......
****
XFOC
PROGRAM (JACK)
........
****
XFOC 
PROGRAM (JOHN)
.........
****
***E

(b) A similar job to (a) but in this case the standard actions are overridden by the event lists. It is assumed that the changes in the two XMED runs are independent such that the test programs will yield useful results provided the second XMED run was correct. The action on the XFCS runs is specified in the XFCS event lists.

YAPC
ENTRUST (SCPR, DISC)
SEND TO (PROGRAM XFCS.MASTER)
NAME (XFCS76104)
PRIORITY (70)
LIST
PROGRAM MODE (22AM, DBM)
AT HALTED (ZZ), GO XMED
XMED
*OUT (OPTSOURCE(106))
*IN  (OPTSOURCE(105)).
*FORTRAN MASTERSEG  1
*ALTER 12,1
****
////
****
XMED
*OUT (XFCS SOURCE(107))
*IN  (XFCS SOURCE(105))
*FORTRAN MASTERSEG2
*ALTER 14,3 
X6 ← JACK;
****
////
****
YAPP
COMPILESMO
READ FROM (OPTSOURCE.MASTERSEG1)
SWITCH (0,1,2,3)
READ FROM (XFCS SOURCE.MASTERSEG2)
****
XPCL
****
AT HALTED (AB) GO 900
AT HALTED (CD), OU O 5000, GO SCPR
AT ILLEGAL, OU O 10000
AT HALTED (DE), GO
XFCS
PROGRAM (JACK)
.........  source for JACK
****
ON (O)
AT LOOPING, OU O 5000
AT HALTED (JK), GO SCPR  
AT HALTED (CD), HALT
XFCS
PROGRAM (JOHN)
................source for JOHN
**** 
SCPR
.............
****
***E

(c) This example shows how a previously consolidated program such as one produced in (a) can be run using CALM. The programs TES1 and TES2 are also consolidated and run.

YAPC
NAME (XFOC, FILE)
XFOC
PROGRAM (TES100)
...............source for TES1
****
XPCL
****
TES1
...............data for TES1
****
XFOC
PROGRAM (TES200)
.............. source for TES2
****
XPCL
****
TES2      TES2 has no data 
****
***E

16. Debugging Facilities

The error messages produced by CALM and the PLASYD compiler are described in this chapter together with the action taken. The last section describes the TRACE facilities available.

16.1 CALM messages

As CALM handles all the input and output media for the PLASYD and PSFUL compilers the standard slow peripheral, disc and tape messages may occur. These are described in 14.6 together with the relevant operator action. There are two console messages which may occur during the search for a PUC.

  1. NEEDS FILE "PROGRAM yyyy"
    This will occur if the file specified in the ENTRUST, NAME or YAPC directive is not available. The operator should make the file available and type GO. Note that accumulators carried forward will be lost and set to zero if this message occurs. The file may be on disc or magnetic tape.
  2. xxxx NOT FOUND IN FILE "PROGRAM yyyy"
    This will occur if xxxx is not in the file PROGRAM yyyy as specified in the ENTRUST, NAME directives. Generally there is no operator action possible unless another file PROGRAM yyyy can be put on line when the operator can type GO.

The other console messages referring to disc failures on opening and extending files are given below as are messages which may occur on reading from or writing to disc. Some of these halts should never occur in practice, but are listed below because they correspond to particular reply information from Executive

HALTED Gl File not in system or incorrect generation number. 

HALTED G2 Failure of integrity code check.

HALTED C2 Insufficient space in core store for further file descriptions.

HALTED D1 Purge date not exceeded.

HALTED L1 Other file opened when trying to open System File for writing.

HALTED L2 System File opened for writing when trying to open another file.

HALTED C1 System control area full.  Unable to extend file.

HALTED M1 No space for file extension.

HALTED M2 Should not occur.

HALTED M3 File to be extended is not open as a write file.

HALTED M4 Insufficient space for file extension.

HALTED I1 Logical bucket number out of range or zero.

HALTED I2 Should not occur.

HALTED K1 Unclearable parity error.

HALTED C3 Auxiliary control area full 

HALTED Z1 Should not occur.

Of the above error halts, only the first six may be recoverable.

The following messages may occur on the line printer against any of the directives described in chapters 14 and 15.

(a) YAPC DIRECTIVE ERROR
YAPC will ignore the line, which may cause subsequent lines to be listed as if in error.
(b) INVALID NAME OR ENTRY POINT
YAPC has read a PUC name directive which has not been referenced in a NAME or ENTRUST directive, or has not been created incore by XPCL. YAPC will ignore this line and scan for ****. It will then run the next PUC specified.
(c) LINE TOO LONG
A line of more than 72 characters has been read from paper tape, cards or disc. The remaining characters on the line are ignored.
(d) NO SUBFILE FOUND
A subfile specified in a READFROM or MACROFILE directive is not in the given file. The line is ignored.
(e) DATA SUBFILE WITHIN LIST
A subfile, which is not the last subfile specified in a subfile string, is a data subfile. The line is ignored.
(f) WRONG SUBFILE TYPE
The subfile has type other than source. The line is ignored.
(g) NO MACROFILE DIRECTIVE
This occurs if an INCLUDE statement occurs in PLASYD and no file has been specified by a MACROFILE directive.
(h) EVENT LIST ITEM ERROR
There is an error in the event list, the rest of the line is ignored.
(i) PROGRAM NOT AVAILABLE
A program specified by the PUC directive is not in core store and has not been specified in an ENTRUST or NAME directive.
(j) PROGRAM TO FREETRUST ALREADY IN STORE
A program specified by the FREETRUST directive has been created in corestore by XPCL. Line is ignored; CALM searches for either **** or the next YAPC card after displaying ZZ.
(k) LONG BUCKET READ AND IGNORED
A bucket read from disc is longer than 128 words.
(l) ENTRUST LIST FULL
CALM cannot add to its known program list, either the name of a program specified in the ENTRUST or NAME directive, or the name of the program generated in core store by XPCL. Subsequent references to this program will cause message described in (i).
(m) FILE abcdefghijkl NOT pqr BUCKETS
This message is listed if the file specified in the SEND TO directive has been extended.
(n) SUBFILE abcdefghijkl OCCUPIES mno BUCKETS IN pqrstuvwxyz
This message is listed when the subfile specified in the SEND TO directive is closed.

A normal CALM batch will end with the following message on the console

#name HALTED OK 

where name is the current PUC name

If CALM itself goes illegal a postmortem dump is automatically produced and the system halts with the message

#name HALTED!!

Note that during the loading of a PUC any of the messages occuring in XPED may occur, see Library Specifications Manual.

16.2 PLASYD messages

The PLASYD compiler attempts to recover from most of the compilation errors that occur. The error number is listed on the line printer beside the relevant source line. A list of errors is given in Appendix 2 together with a list of comment numbers. Comment numbers do not imply errors but are used to give to the user additional information about the code compiled.

At the end of the compilation if errors have occurred and YAPP has been able to recover then YAPP halts ER. To consolidate, ignoring errors, the user must specify an event list item to cover the halt.

AT HALTED (ER), CONTINUE

If errors have occurred and it has been impossible to generate sensible semi-compiled YAPP will continue to syntax check until the end of the source and will then halt EX. It is not then possible to continue.

The action taken by YAPP at any error is also described in Appendix 2.

Other messages:-

   
HALTED YY 

Symbol or literal tables full at this point.

HALTED XX

More than 64 global areas in this segment at this point.

At both these halts compilation ceases. No attempt to re-enter YAPP should be made.

16.3 Listing of code generated

The code generated by the PLASYD compiler can be listed against the relevant source by the use of the SWITCH directive described in 15.4. To obtain a listing bit 0 must be set by

SWITCH (0)

Note that the switch setting only covers the next PLASYD segment. Further SWITCH (0) directives must appear for later segments.

16.4 Symbol table listing

After each PLASYD segment, an optional listing of the storage usage of that segment may be produced, depending on the setting of SWITCH (21). If this switch is off, the listing is produced, starting on a new page. The summary appears under the following headings:

(a) SEGMENT
If the segment is a procedure, details are given in the form:
Segment name.    Link.    n WORDS
If the segment is a master segment, details are given thus:
 MASTER SEGMENT OF Program Name, n WORDS
 
(b) GLABEL PROCEDURES
Details are given in the form:
Procedure name.    Link.    Entry W
where W indicates the word of the segment at which the procedure starts
(c) INTERNAL PROCEDURES
Details as for glabel procedures
(d) EXTERNAL
Details are given in the form:
Name of item.    Link.
(e) DEFINEES
Details are given in the form:
Name of item    value of item (#abcdefgh)
(f) LITERALS n WORDS
Details are given in the form:
No. of literal.  Value (#abcdefgh) R.  Value (As four characters). 
The R in the second item is the appropriate two character relativiser if this is needed.
(g) GLABELS
Details are given in the form:
m.    Glabel name.
m is the word of the segment at which the glabel occurs. Glabels are listed in ascending values of n.
(h) LABELS
Details as for glabels.
(i) LOWER PRESET n WORDS
Details are given in the form:
m    (t)    Symbolic name
m is the position of the item; t is the type of the item (where t is one of I = integer, LI = long integer, R = Real, LR = Long Real).
(j) UPPER PRESET
Details are given as for lower preset
(k) LOWER GLOBAL block name. n WORDS
Details of the items in the block are given as for lower preset. This format is repeated for each lower global block.
(l) UPPER GLOBAL block name n WORDS
Details are given as for lower global.
(m) SYNONYMS OF ABSOLUTE ADDRESSES
Details are given in the form:
m    (t)    Synonym name
m is the absolute location, t is type as in lower preset etc.
(n) ACCUMULATOR SYNONYMS
Details are given in the form:
Accumulator name.    Synonym name 

Absence of any items (apart from (a) which must occur) is indicated by 'NONE'.

16.5 TRACE facilities

Facilities are available to trace the action of a program compiled by the PLASYD system. These facilities take the form of procedures which can be called at any point in a run. The procedures must be declared EXTERNAL at the head of any segment of procedure in which calls to them occur. It is assumed that a line printer is available. The procedures will be held in semi-compiled form in a library file. The "calls" to these procedures could appear as conditional compilation (PLN 2 pg.2). The "call" to the trace procedures consists of a procedure statement followed by a data statement which may be an initial value or an initial value list (PLN 2 pg.21).

The accumulators except for the link accumulator will be preserved. The Trace procedures must be in permanent or in the same overlay as the calls or in a different overlay area to the call.

PROCEDURE OUTIDENT (X0);

The data statement consists of a string of up to four characters. Example:

OUTIDENT; DATA "AB";

A call to the procedure OUTIDENT will cause the characters in the string to be output to the line-printer on a new line.

PROCEDURE OUTACC (X0);

The data statement consists of a string of up to four characters. Example:

OUTACC; DATA "CD";

A call to the procedure OUTACC will cause the contents of the INTEGER accumulators X0 to X7 and the REAL accumulator A1 to be output in octal, character and integer formats preceded by a line identifying the procedure call. Example:

ACCUMULATORS AT CD
X0   00004142   00AB  2146 
etc.
PROCEDURE OUTINTEGER (X0);

The data statement consists of a string of up to four characters followed by the address of the integer value. Examples:

OUTINTEGER: DATA ("EF"; @X);

A call to the procedure OUTINTEGER will cause the contents of the integer X to be output in octal, character and integer formats preceded by a character string identifying- the procedure call Example:

INTEGER VALUE AT EF 00004143  00AC 2147
PROCEDURE OUTREAL (X0);

The data statement consists of a string of up to four characters followed by the address of the real value. Example:

OUTREAL; DATA ("GH", @Y);

A call to the procedure OUTREAL will cause the contents of the real value Y to be output in octal, character and integer formats preceded by a character string identifying the procedure call. Example:

REAL VALUE AT GH  01004142  10AB  264290
                  00000000  0040     256
PROCEDURE OUTCORE (X0);

The data statement consists of a string of up to four characters followed by the address of the location in core store and the number of 1900 words required. Example:

OUTCORE; DATA ("IJ", @Z, 100); 
OUTCORE; DATA ("KL", 0, 2000);

It can be seen from the examples that an address can be specified either as a relative value or an actual value. The output is two words to a line in instruction, octal and character format preceded by the core location in decimal and octal.

All the procedures so far described require YAPC to be present when they are incorporated in a program compiled by the PLASYD system. The following procedure does not require YAPC to do its printing.

PROCEDURE FREEOUTCORE (X0);

The data statement consists of a string of up to four characters followed by the address of the location in core store and the number of 1900 words required. Example:

FREEOUTCORE; DATA ("IJ", @Z, 100); 
FREEOUTCORE; DATA ("KL", 0, 2000);

It can be seen from the examples that an address can be specified either as a relative value or an actual value.

If the start address and number of words parameters have bit 0 set to 1 the contents of the word specified in address field will be used. Example:

FREEOUTCORE; DATA("AB",#400CNT+@BILL,#400CNT+@FRED);

The number of words specified in FRED starting at the address specified in BILL will be printed.

Appendices

1. Examples of a PLASYD procedure segment

PROCEDURE MAGICSQUARE(X0); [EXAMPLE Of PLASYD PROGRAMMING]
      [THIS PROCEDURE ESTABLISHES A MAGIC SQUARE OF ORDER N WHERE
       N IS ODD AND > 1,X7 MUST CONTAIN N ON ENTRY AND THE ARRAY 
       A, INTO UHICH THE MAGIC SQUARE IS PLACED IN A LINEARIZED 
       FORM, MUST HAVE ITS FIRST N^2 LOCATIONS SET TO ZERO.

       X2-6 ARE USED AS WELL AS ONE LOWER LOCATION ] 
      BEGIN  ACC N SYN X7,IJ SYN X3,AIJ SYN X4,J SYN X6 ,I SYN X5,
                           K SYN X2;
                 LOWER INTEGER NSQ LOWEND;
                 X5←N*N; NSQ←X5; [OR QUICKER !MPY(X5,N);NSQ←X6]

                 I←N SRL 1; J←N-1 [INITIAL POINT HALFWAY DOWN RIGHT COL]; 
                 FOR K←1 STEP 1 UNTIL NSQ DO
                     BEGIN IJ← I*N+J; [QUICKER TO DO X2←I,IJ←J; 
                     !MPA(X2,N);BUT NOT MUCH]
                     AIJ←A(IJ);
                     IF AIJ NOT=0 THEN [WE'VE DONE THIS ALREADY] 
                           BEGIN  I←I-1; J←J-2; 
                           IF I<0 THEN I←I + N; 
                           IF J<0 THEN J←J+N; 
                           IJ←I*N+J; [STEP LEFT TO NEXT DIAGONAL]
                           END;
                     A(IJ)←K;
                     I←I+1;IF I=N THEN I←0; [MOVE DOWN A DIAGONAL] 
                     J←J+1;IF J=N THEN J←0; [LOOPING IF NECESSARY] 
                  END; [OF FOR LOOP]
     END;

2. PLASYD error list

Error
Number
MeaningCorrective action taken
0; or END scanned and STACK brokenSTACK is discarded until correct symbol appears.
1END not matched by BEGIN on STACKSTACK is discarded until BEGIN appears or STACK terminates.
2BASE statement in LOWER declarationThe statement is ignored.
3**** read as sourceEND's forced in to match BEGIN's on stack
4Type declaration not followed by identifier listSkip to a recognisable symbol.
5Illegal symbol in identifier listSkip to a recognisable symbol.
6Incorrect array length (not absolute const, or defined) Array length 1 is assumed.
7Identifier declared twiceIdentifier ignored
8Incorrect structure of LOCAL (ALL) (BUT)The statement is ignored.
9Illegal symbol in label listThe statement is ignored.
10Unmatched bracketingAssume )
11Identifier already declaredSkip to ;
12Illegal source constructionSkip to ;
13
14LOWEND or GLOBEND missingNo action
15PURE storage not initialisedSets to zero
16
17Too many items in an arraySurplus items ignored
18$ of a lower item used in a DEFINE statementSkip to a, or ;
19LOWEND without corresponding LOWERLOWEND ignored
20DEFINE not followed by identifierSkip to a comma or ;
21Identifier after DEFINE already declaredSkip to a comma or ;
22Identifier not followed by = in DEFINE statementSkip to a comma or ;
23Separator missing in initial value list, assumed
24GLOBEND without matching GLOBALGLOBEND ignored
25Impossible error (Stack not free for begin)Error ignored
26LOWER not followed by a type or GLOBALType INTEGER is assumed
27GLOBAL not followed by block identifierAn area %%%G is created
28Block identifier not followed by :A colon is assumed to be present
29Block identifier followed by illegal declarationType INTEGER is assumed
30LONG not followed by xtype or rtype declarationType INTEGER is assumed
31SYN of item already declaredSkip to a comma or ;
32Illegal displacementZero substitued
33Error after ACC or SYNSkip to a comma or ;
34ACC αidentifier not followed by SYNSkip to a comma or ;
35Identifier list not terminated by SYN or ;; assumed
36Illegal expression in DEFINE declarationValue of definee indeterminate
37Illegal format in DEFINE declarationSkip to a comma or ;
38Illegally formed absolute expression in DEFINE declarationSkip to a comma or ;
39Error in initial value list (incorrect type, undefined ident. etc.)Zero substituted
40Illegal symbol within (----) sequenceAssume constant of 0
41Illegal symbol following a modifierAssume closing right bracket
42Illegal symbol following SMO indexAssume closing right bracket
43Illegal symbol in simple SMO indexThe statement is ignored
44Closing bracket not foundAssume closing right bracket
45Link accumulator not specified in PROCEDURELink accumulator X0 is assumed
46Illegal accumulator given for PROCEDURELink accumulator X0 is assumed
47PROCEDURE not followed by identifierSkip to ;
48OBEY, not an xcellThe statement is ignored
49Illegal operand.Zero substituted
50Undeclared identifier in L.H.S.The statement is ignored
51Identifier undeclared at current blockThe statement is ignored
52Unmodified cell asignment to UPPERNo action
53Undeclared identifier in statement R.H.S.A null instruction is generated
54Identifier undeclared at current blockA null instruction is generated
55Incompatible typesA null instruction is generated
56Cell assignment: αcell := αcellRest of statement is ignored
57Accumulator assignment ofThe statement is ignored
58Cell assignment of constant not equal zeroThe statement is ignored
59Illegal operatorA null instruction is generated
60Identifier too longThe identifier is truncated to 32 characters
61Real number out of rangeZero substituted
62Illegal characters following & of real numberNumber is ignored
63NOT encountered on its ownNOT is ignored
64Too many characters in character sequenceTruncated to four characters
65Count (CNT) greater than 511Count field is zeroised
66Octal longer than 16 digitsOctal is truncated
678 or 9 appearing in an octal numberPut in as #10 or #11
68#, or & standing aloneCharacter is ignored
69Subfile name after INCLUDE too longStatement is ignored
70Subfile name in INCLUDE not found on MACROFILEStatement is ignored
71INCLUDE statement not on a line by itselfOther code on the line is ignored
72MINUS not followed by a numberMINUS ignored
73?number not followed by (( is assumed
74Conditional compilation switch >10No conditional action taken
75? not followed by a numberNo conditional action taken
76String longer than 244 charactersString is truncated
77Truncation to >23 bits No truncation done
78Error in function statementStatement ignored; NULL output
79Accumulator used as label:= assumed
80Undeclared identifier in a bracketed sequenceIdentifier ignored
81END found within a CASE statementCASEND inserted before END
82Illegal operatorRest of statement is ignored
83More than 100 branch aheads at this pointBranch ahead table cleared
84WHILE clause not terminated by DOThe statement is ignored
85IF clause not terminated by THENThe statement is ignored
86Stack error on fixing-up IF statementThe statement is ignored
87Label identifier previously declaredItem redeclared as label
88Not :=0 in a cell assignmentNull generated
89Illegal modifier in CASE clauseModifies X1 is assumed
90Multiple assignment in a single statementRest of statement is ignored
91Illegal symbol in place of operatorA semicolon is inserted following previous operand
92Program or segment starts with illegal symbolA BEGIN is assumed missing
93Illegal first character of a statementThe statement is ignored
94Statement starts with identifier and illegal symbolA semi-colon is inserted between identifier and symbol
95Cell designator not followed by ← or :=The statement is ignored
96Illegal symbol in place of operandThe statement is ignored
97END, ELSE or; should have been foundA semi-colon is inserted
98Wrong type of identifier in PROCEDURE or GOTO statementThe statement is ignored
99ENTRY not in range 0-9Entry not generated
A0@ or £ not followed by identifierThe statement is ignored
A1Illegal operator before addressThe statement is ignored
A2Illegal address assignmentThe statement is ignored
A3CHAR sequence incorrectly terminatedThe statement is ignored
A4Undeclared identifier after $No action
A5Undeclared identifier after £No action
A6Illegal declarationOperand set to zero
A7Illegal identifier after @Operand set to zero
B0BRINGOVERLAY not followed by identifierThe statement is ignored
B1CUEOVERLAY not followed by identifierThe statement is ignored
B2Identifier not correctly declaredThe statement is ignored
C0Illegal condition statementThe condition is ignored skip to next THEN or DO
C1Illegal symbol following relationThe condition is ignored skip to next THEN or DO
C2Base symbol not followed by identifierThe condition is ignored skip to next THEN or DO
C3Displacement symbol not followed by identifierThe condition is ignored skip to next THEN or DO
C4Character comparison with $'CH' is ignored
C5$ identifier (index) outside range 0 - 4095The condition is ignored skip to next THEN or DO
C6AND, OR appear in same compound conditionThe first to appear is assumed
C7Undeclared identifier in conditionZero is substituted
C8Incompatible types in conditionThe condition is ignored skip to next THEN or DO
C9Not integer accumulator on LHS of conditionThe condition is ignored skip to next THEN or DO
D0SMO in a condition when SMOMACRO is set or assumedThe condition is ignored skip to next THEN or DO
E1FOR not followed by integer acc. assignmentNo action
E2Illegal increment in FOR clauseThe statement is ignored up to DO
E3UNTIL not found in FOR clauseNo action
E4Illegal limit in FOR clauseThe statement is ignored up to DO
E5DO does not terminate FOR clauseNo action
E6Illegal item following '-' in limitThe statement is ignored up to DO
E7Stack is broken on fixing-up DONo action
E8No STEP between FOR and UNTILStep 1 assumed
E9END not followed by ; END or ELSE; inserted
F1Illegal operand in function statementThe statement is ignored
F2Illegal constant operandThe statement is ignored
F3Function statement not terminated by )No action
F4Undeclared operand in function statementThe statement is ignored
G0GOTO not followed by identifierThe statement is ignored
G6Illegal character in DATA statementThe symbol is ignored
G7Block identifier declared differently elsewhereSkip to ;
G8Redefinition of GLOBAL area in different modeThe area is forced into LOWER
G9Too many GLOBAL declarations in segmentCompiler HALTS:-XX at this point
M0Monadic operator in wrong contextThe statement is ignored
M1Unrecognised monadic operatorRest of statement is ignored
M2MEMBER not followed by (The statement is ignored
M3Member number >5The statement is ignored
M4Member number not followed by commaThe statement is ignored
M5Member priority >99The statement is ignored
M6No ) at close of member statement) assumed
M7) not followed by ; in member statement; assumed
P0Not integer or definee after comma in a procedure statement0 substituted
P1Procedures nested to depth > 16SENDTO file (if any) is closed
P2Number after comma in a procedure statement >630 substituted
P3Accumulator not followed by comma or ) in a procedure statement) assumed
R0Identifier not found where expectedSkip to ;
R1Identifier not followed by ( in replacers statementSkip to ;
R2( not followed by integer in replacers statementSkip to ;
R3Integer >510 in replacers statement510 substituted
R4Integer not followed by ) in replacers statementSkip to ;
R5; should terminate a replacers statement; asumed
Comment
Number
Meaning
1Section of source not compiled as conditional compilation switch is off
2A second [ has been found before a ]
3A ] has been found without a matching [
4a double-length 'shift-type' instruction has been generated
5Nested LOWER declarations have been used
6, not followed by SL in an INCLUDE statement, SL assumed
7A SMO macro has been generated
8CARRY or NOT CARRY not the first in a compound condition
9Trivial condition, eg >=#400CNT
10No D after a double length integer
11Base generated, though no BASE statement present
12Attempt to access item outside normal domain
20Other than one machine instruction generated by a statement in a case sequence
21Division will corrupt an accumulator not explicitly mentioned in the statement (as in PLAN)
22Multiplication will use an accumulator not explicitly mentioned in the statement (as in PLAN)

3. Index

A

ABSOLUTE EXPRESSION            10.2
ACCUMULATOR                    2 2.1 
ACCUMULATOR ASSIGNMENT         6.1 6.3 11.2
ACCUMULATOR CONDITION          8.4
ADD OPERATOR                   6.6 
ADDRESS                        3.1 4.1 4.4 4.5 6.7
ADDRESS ASSIGNMENT             6.7 
AL                             14.7 
ALGOL                          1 
ALTERNATIVE CONDITION          8.4
AND                            6.3 6.6 84
ARITHMETIC OPERATOR            6.3 
ARRAY                          4.1 
ASSIGNMENT STATEMENT           2 6 11.2 11.3
AT DELETED                     14.7 
AT DISPLAY                     14.7 
AT FAIL                        14.7 
AT HALTED                      14.7 
AT ILLEGAL                     14.7 
AT LOOPING                     14.7 

B

BASE                           4.4 6.7
BASE DECLARATION               4.4 
BASIC CELL ASSIGNMENT          6.4 
BEGIN                          4 8 
BLOCK                          4 8.1
BLOCK STRUCTURE                8 
BLOCKHEAD                      4 
BRINGOVERLAY                   12.4 

C

C OPERAND                      6.2 
CALM                           12.5 14
CALM ENTRY POINTS              14.9 
CALM MESSAGES                  16.1 
CARRY                          6.2 6.5 8.4
CARRY SETTING OPERATOR         6.3 
CASE STATEMENT                 7.4 
CELL                           2 2.2 6.7
CELL ASSIGNMENT                6.4 6.6 11.3
CELL DESIGNATOR                5
CH                             6.2 6.5 6.8 8.4
CHAR                           6.8 8.5 
CHARACTER ADDRESS              6.7 
CHARACTER OPERATIONS           6.8 
CHARACTER SEQUENCE             3.1 
CNT                            3.1 6.2
CODE GENERATED                 16.3 
COMBINED CONDITION             8.4 
COMMENTS                       13.1 
COMMON BLOCK                   12.3 
COMPILATION SYSTEM             15
CCMPILESMO                     15.5
COMPOUND CONDITION             8.4 
CONDITION                      8.4 
CONDITIONAL COMPUTATION        13.2
CONDITIONAL STATEMENT          8 8.3 
CONTINUE                       14.7
CONTROL DIRECTIVE              13.6 
CONTROL STATEMENT              2 7
COUNT                          3.1 4.5
D

DATA STATEMENT                 8.3 9.4 
DEBUGGING                      16 
DECLARATION                    2 4 8.2
DEFINE DECLARATION             10.2 
DESIGNATOR                     6.7 
DISC DIRECTIVES                15.3 
DISPLACEMENT                   4.4 5.1 6.7
DO                             8.5 8.6 
DOMAIN                         4.4 
DUMPING                        15.6 
DUMPON                         15.3 

E

EDITING                        15.6
ELSE                           8.4
END                            4 8 
ENTRUST                        14.3
ENTRY                          12.2 
ENTRY POINT                    12.2
ER                             6.3 6.6 
ERROR HALTS                    14.6 
EVENT LIST                     14.7
EX                             6.2 6.5 
EXPONENT                       3.2 
EXTERNAL                       12.1 

F

FINISH                         14.7 
FIX                            13.3
FIXED ADDRFSS                  6.7 
FIXED CELL DESIGNATOR          10.1
FIXED INDEX                    5.1 
FIXED WORD SYMBOL              2.2 
FLOAT                          13.3 
FOR                            8.5 
FOR STATEMENT                  8.5
FOVERFLOW                      8.4 
FRACTIONAL NUMBER              3.2 
FREE INDEX                     5.1
FREETRUST                      14.3 
FROM                           6.3 
FUNCTION                       9 9.1
FUNCTION STATEMENT             4.5 
G

GLABEL                         12.1 
GLOBAL                         12.3 
GLOBAL BLOCK                   4 
GLOBALSEGMENTS                 15.5 
GLOBEND                        12.3 
GO                             14.7 
GOTO STATEMENT                 7.2 

H

HALT                           14.7 

I

IDENTIFIER                     2 2.2 5.1 6.7
IF                             8.4
IF STATEMENT                   8.4 
INCLUDE                        15.3 
INCLUDE STATEMENT              12.5 
INDEX                          5 5.1 
INITIAL VALUE                  4.5 8.3 
INSTRUCTION IDENTIFIER         9.5 
INTEGER                        4.1 
INTEGER ACCUMULATOR            2.1 
INTEGER CELL DECLARATION       4.1 
INTEGER NUMBER                 3.1 
INTEGER VALUE                  3.1 

L

LA                             6.5 
LABEL                          7.1 9.5 
LIBRARY                        15.3 
LINK                           9.2 
LISTING                        15.1
LOCAL                          12.4 
LOCALSEGMENTS                  15.5 
LOGICAL                        3.1 4.1 
LOGICAL OPFRATOR               6.3 6.6 
LONG INTEGER                   11.1 
LONG INTEGER ACCUMULATOR       2.1 
LONG REAL ACCUMULATOR          2.1 
LONG TYPE                      11 
LOWEND                         4.3
LOWER                          4.3 
LOWER DECLARATION              4.3 
LOWER STORAGE                  4 

M

MACROFILE                      15.3
MEMBER STATEMENT               13.5 
MINUS                          3.1 
MODIFIER                       2.1 
MONADIC INTEGER CELL OPERATOR  6.5
MONADIC OPERATOR               6.2 

N

NAME                           15.2 
NAME DIRECTIVE                 14.2 
NEG                            6.2 6.5 
NEG CARRY                      6.5
NONPLASYD STATEMENT            13.6 
NOT                            8.4
NULL STATEMENT                 8.3 
NUMBER                         3.1

O

OBEY STATEMENT                 7.3 
OCTAL VALUE                    3.1 3.2
OF                             14.7 
OFF                            14.8
ON                             14.8 14.7
OPERATING INSTRUCTIONS         14.1
OPERATING SYSTEM               14 
OPERATOR                       6.2 6.3 6.5 6.6
OR                             6.3 6.6 8.4
OU                             14.7 
OUTACC                         16.5 
OUTCORE                        16.5 
OUTIDENT                       16.5 
OUTINTEGER                     16.5 
OUTREAL                        16.5 
OVERCOMMON                     15.2 
OVERFLOW                       8.4
OVERLAY                        15.2
OVERLAYS                       12.4 

P

PAPER TAPE                     1 
PARAMETER                      9.4 
PART ADDRESS                   8.4 
PLASYD                         1 
PLASYD MESSAGES                16.2 
PLN2                           1 
PLN 17                         15.6
PRIMARY                        6
PRIORITY                       15.2
PROCEDURE                      9 
PROCEDURE BODY                 9.2
PROCEDURE DECLARATION          9.2 
PROCEDURE STATEMENT            9.1 9.3 
PROGRAM MODE                   15.2
PSFUL                          14 
PUC CONTROL DIRECTIVES         14.5 

R

READFROM                       15.3
READFROM DIRECTIVES            14.4 
REAL                           4.2 
REAL ACCUMULATOR               2.1 
REAL CELL DECARATION           4.2 
REAL VALUE                     3.2 
RELATION                       8.4
RETURN                         9.3 
RETURN STATEMENT               9.6 
REVERSE OPERATOR               6.3 

S

SA                             6.5 
SEGMENT                        4 12 
SEGMENT MODE                   15.5 
SEMICOMPILED                   15.3 
SEND TO                        15.3 
SHIFT OPERATOR                 6.3 
SIMPLE CELL DESIGNATOR         5.1 
SIMPLE STATEMENT               8.3 
SLA                            6.3 
SLC                            6.3 
SLL                            6.3 
SMO                            5.1 6.6
SMO DESIGNATOR                 5.2 
SMOMACRO                       15.5 
SRA                            6.3 
SRAV                           6.3
SRC                            6.3 
SRL                            6.3 
STANDARD HALTS                 14.6
STATEMENT                      2 8.3 
STATUS CONDITION               8.4 
STATUS DIRECTIVES              14.3 
STFP                           8.5 
STORAGE CELL                   2 
STRING                         4.1 4.5
SWITCH                         15.4 13.2 
SYMBOL TABLE LISTING           16.4 
SYN                            10.1 
SYNONYM DECLARATION            10.1 

T

TAB                            15.1 
TAB CHARACTER                  1 
THEN                           8.4 
TRACE FACILITIES               16.5 
TRUNCATED NLMBER               3.1
TRUNCATED NUMBERS              13.4 
TYPE                           3
TYPE CHANGING                  13.3 

U

UNDER                          6.3 
UNTIL                          8.5 
UPPER STORAGE                  4 

V

VALUE                          2 3 3.1
VARIABLE                       2 
VARIABLE INDEX                 5.1 

W

WHILE                          8.6 
WHILE STATEMENT                8.6 
WORD                           5.1 
WORD ADDRESS                   6.7 

X

XMED                           14 

1900 CHARACTER SET             1.0 
:=                             6.1 
;                              6.0 
<                              8.6 
=                              8.4 
>                              8.4 
?                             13.2 
!                              9.1 
"                              4.5 
#                              3.1    6.3
£                              4.4    5.2   6.3 
%                              2.2 
&                              3.2 
'                              3.1 
*                              6.3 
****                          14.0   14.5
***E                          18.5 
+                              5.1    6.3   6.6 
++                             6.3    6.6
-                              5.2    6.3   6.6 
--                             6.3    6.6
/                              6.3 
@                              4.4    5.2   6.7 
[                             13.1 
$                              4.4    6.7
]                             13.16.1 

PGEN 1

Some Notes on the PLASYD Programming System

J. K. Buckle

A general introduction to the PLASYD and PSFUL languages and the CALM operating system for the 1900 Series computers.

Version 1: 1969

Introduction

The PLASYD programming system was designed as a basic tool for the production of new optimising and conversational FORTRAN compilers for the ICL 1900 series of computers. Although previous scientific compilers for the 1900 had used special purpose languages for such purposes as syntax analysis, a large amount of the coding was done in PLAN [1] . It was felt that for the new projects a more systematic, easily intelligible and maintainable system would be preferable and an investigation of software production tools was undertaken. The system chosen had to meet the following requirements:-

  1. The language should itself provide a high standard of documentation.
  2. A special purpose operating system was needed which would maximise throughput of compiler production jobs on the most easily accessible machine (an ICL 1903, and later a 1903A, with magnetic tape and disc storage).
  3. The language should be capable of interfacing with segments of existing ICL 1900 compilers which could be lifted for use in the new compilers.
  4. The code generated should be efficient since the compilers to be produced had strict limits both on total size and on compilation time.
  5. If the chosen language did not already exist it should be easy to implement.

Any assembly language was ruled out by the first condition. The functional language used for list processing and tree handling in the ORION and 1900 EMA compilers [2] was considered to be very powerful for particular parts of compiler production but not as a general purpose language for all aspects. It did however have the added advantage that it was well known by the team implementing the conversational compiler. After due consideration it was decided that a two tier system would be most useful. An extended form of the functional language, called PSFUL (pronounced peaceful), would be used for some sections of the projects while an efficient low level language, called PLASYD, would be devised and written for the remainder.

PLASYD needed to be able to use all the machine facilities efficiently but in order to meet the condition of readability it was necessary to have an algorithmic structure. These conditions pointed to a language similar to Wirth's PL360 [3] but adapted for the 1900 Series order code, and the final language followed Wirth's ideas closely. PL360's block structure and all operations concerned with flow of control were adopted almost intact, being virtually machine independent. On the other hand storage types and methods of manipulating them had to be modified to fit with the 1900 series architecture. In particular a method of exploiting the directly and indirectly addressable areas of data storage on the 1900 was devised. To satisfy requirement 3 the output of both PSFUL and PLASYD is semi-compiled form, the form of output of all 1900 series compilers ( see [1] ).

The third part of the PLASYD system was the operating system or monitor specified as requirement 2 above. This was produced by exploiting the trusted program facility of the 1900 series. A trusted program is one which is specially recognised by the basic operating system, EXECUTIVE, and is allowed to control another program, called the program-under-control or PUC. Certain actions by the PUC such as the initiation of peripheral transfers or the issue of console directives to the operator, which would normally be dealt with by EXECUTIVE, are trapped and the trusted program is informed. The trusted program has access to the PUC's store and can cause a PUC to be deleted and a new one loaded.

The PLASYD system monitor,called CALM, is a trusted program and, while it can run any series of jobs it is primarily intended for the sort of run that has been found to be most common in compiler writing. This consists of an editing run on a PLASYD or PSFUL source disc file, compilation of the segments so produced, possible amalgamation of these with previously compiled segments, running the program produced with one or more sets of test data, and, since this latter step may be a run of a FORTRAN compiler, running the results of that as well.

The following sections provide a brief introduction to CALM and PSFUL and a rather more detailed description of PLASYD.

The CALM monitor

Input to CALM consists essentially of a list of program names, each followed by the parameters which that program needs. These parameters may be either complete sets of data or indications of backing store files where such data is stored. The monitor reads the program name, causes the program to be loaded, entered at a designated start point and fed the parameters. At a recognised successful termination any unused input data is skipped and the next program designated is activated. At a non-successful termination standard error actions are taken depending on whether the program under control was a recognised one (such as the PLASYD compiler) or not. Typical error actions are dumping programs, giving core printouts or semi-compiled language listings, or printing a compiler's symbol table. The standard actions may be overridden by the programmer by supplying CALM with an events list, which specifies possible actions of the PUC and the corresponding reactions which CALM should make.

CALM input is normally from a slow input device but commonly used job sequences may be stored on disc and referenced from the slow input. Thus a complicated sequence of jobs may be activated by a single card or paper tape line.

CALM also has a special relationship with the PLASYD and PSFUL compilers. Neither of these compilers handle peripherals directly but demand input records from CALM. Similarly output records, either semi-compiled or listing, are passed to CALM for output.

The PSFUL language

The general form of PSFUL is similar to the functional language described in [2]. Unlike the Orion input however the 1900 PSFUL compiler accepts functions described in the original function notation. Effectively the PSFUL programmer defines a function in terms of other functions or recursively in terms of itself. Such functions are translated into sequences of six or twelve-bit items which are interpreted at run-time by a compact interpreter.

The functions operate on a push down stack from which they take their parameters and on which they leave their results. A number of basic functions, called machine functions, are provided and these are written in PLASYD. The user may if he wishes write new machine functions in PLASYD and incorporate them into the system, thus defining his own pseudo-machine.

PSFUL allows complicated tree- and list- handling procedures to be written quickly and extremely compactly at the cost of some loss in run time efficiency. Where the latter is significant it is easy to write the necessary parts of the program in PLASYD.

General form of the PLASYD language

As mentioned earlier PLASYD is superficially Algol-like having a block structure, type and procedure declarations, the same form of identifiers and similar assignment and control statements. However recursion is not provided automatically and all storage assignments may be made at compile time. It has some FORTRAN-like features such as segmentation (the ability to compile procedures separately) and common storage. The form of the declaration is also similar to FORTRAN. Unlike Algol, spaces are in general significant and reserved words (e.g. BEGIN) are not distinguished by underlining. Examples of PLASYD programming are given in figures 1 to 3.

There are more fundamental differences between PLASYD and high level programming languages. To begin with there are two distinct classes of variables in PLASYD - accumulators and cells. The first correspond directly to the 1900 fixed and floating point accumulators; the second occupy core storage locations. Both types may be assigned symbolic identifiers although the accumulators also have standard identifiers - for example, X0 to X7 for the fixed point accumulators and A1 for the floating point accumulator. Only those forms of assignment statements are allowed which may be simply translated into efficient machine code. Thus if I is an integer accumulator and A and B are integer cells it is possible to write

    I ← A   and I ← A+B 

which will load or load and add to the accumulator value. ( may be replaced by := ) It is not however possible to write

    A ← B 

since direct store to store transfers are not available on the 1900. To carry out such a transfer the user must nominate the intermediate accumulator to be used and write for example

    I ← B;   A ← I 

The 1900 order code does permit the values of accumulators to be added to or subtracted from store and for store locations to be cleared so such operations as

    A ← A+I+I   and A ← 0 

are permitted in PLASYD.

In general each operator/operand pair in an assignment statement produces one machine code instruction but a few commonly used operations which have no direct 1900 machine code equivalent may generate several instructions. The available operators permit normal arithmetic or logical manipulation, binary shifting etc. and an assignment statement may include any number of operator/operand pairs. Parentheses are not allowed in the normal way and all operators, including the assignment, are obeyed strictly from left to right. Thus

    I ← A+I

has an equivalent effect to

    I ← A+A

and is not equivalent to

    I ← I+A

The statement

    I ← A-B SRL 2 AND B(X1)-1

means:

    load I with the contents of the cell A 
    subtract B from I 
    shift I right logically 2 binary places 
    collate I with the contents of B(X1) 
    and subtract 1 from I. 

The meaning of B(X1) is explained below.

Other forms of statement are similar to Algol. Changes of flow of control are caused by GOTO followed by a label, or by a procedure call. Conditional statements are like the simpler forms available in Algol 60, for example

IF X1>3 THEN ..... 

or

IF X2<7 AND X6 NOT = A THEN ..... ELSE ......

It is also possible to test various machine status conditions for example

IF OVERFLOW THEN .....

Two forms of loop statement are provided - a FOR statement, which is similar to an Algol 60 for with a step .. until element, and a WHILE statement which provides similar facilities to the Algol 60 for ... while statement. There is also a CASE statement which enables one of a number of statements to be obeyed according to the value of an accumulator.

Cell types, declarations and designators

The data types recognised in the language are INTEGER, LONG INTEGER, REAL and LONG REAL. Only the first is really necessary for compiler production. The others are intended mainly for object time subroutines. It was found to be cumbersome and inefficient to provide an equivalent of the BYTE type of PL 360. Instead characters are treated as quarters of integer cells and special operators are provided to handle them. Character sequences of up to four characters are allowed as integer values and facilities are provided to store strings of any length.

Decimal or octal values of any type may be written in the PLASYD program and special forms of value are available to provide a simple means of setting various bit fields used by the 1900 order code. Cells are declared in a similar way to FORTRAN type statements. Arrays, which may be only one dimensional, are described by an integer in parentheses following the identifier, for example

      REAL FA, FB, C(20), E(30)

The number specifies the number of cells the array is to contain. The size of a cell depends on the type; INTEGER cells occupy one 1900 word (24 bits), REAL and LONG INTEGER cells two words and LONG REAL cells four words.

Initial values may be assigned to variables in the declaration statements. The declaration

      INTEGER L, M = 36, N(20) = (19, 1, 0*8) 

assigns an initial value of 36 to M, and various values to the first 10 elements of N. The item 0*8 indicates 8 repetitions of the value zero.

Since the 1900 instruction format for non-jump instructions allows 12 bits for the address field, only the first 4096 data locations of any program are accessible without modification. Cells in this region, called lower cells, are dealt with simply in a PLASYD program. However if the PLASYD compiler were to automatically handle references to cells in the remainder of store (upper cells) this could result in considerable inefficiency, with modifier registers being constantly loaded and unloaded.

On the other hand to forbid direct references to all upper cells, force the programmer to preload addresses to modifiers and from then on to use only the modifier name, as the assembly language effectively does, produces code which is too obscure for the first requirement of the language. It also has the effect of either using lower storage to hold the addresses of all upper locations to which direct reference is to be made, or of making the programmer calculate the relative positions of some of the upper items in terms of certain key items whose addresses are stored in lower. The system adopted in PLASYD is a compromise. The programmer:is given close control over the way in which storage is allocated to cells and is required to load modifiers himself, but a less obscure reference system is provided and the compiler calculates relative positions of cells to minimise the usage of lowe! storage.

The programmer can force cells of any type into lower store by enclosing their declaration between the symbols LOWER and LOWEND. Such variables may be addressed directly in the PLASYD program. The remainder of the data storage is divided into variable length areas called domains. Domains are usually of 4096 words or less but a single array of greater size may form a domain. The compiler assigns storage to cells in the order in which they are encountered, automatically starting a new domain every 4096 words. Some domains may be smaller to ensure that a cell or an array does not cross a domain boundary. The programmer may also cause a new base to be started at any time by inserting a BASE declaration. This ensures that the next declared item begins a new domain and can be used to force logically connected cells into the same domain. The address of the first word of each domain is stored in lower storage and is known as the base of the domain. The base for any particular cell may be referred to in the PLASYD program by preceding the cell identifier by the symbol £. The displacement of a cell, which is the number of words separating it from its base, can also be referred to in a program by preceding the identifier by $. The absolute address of a cell may be referenced by prefixing the symbol @. Obviously for any cell A, @A=£A+$A.

The contents of a lower cell may be specified by merely writing the identifier

e.g.  L   M    N

Lower array elements may be designated by following the identifier by a constant index

e.g.  N(3)   N(7) 

This specifies the number of words by which the desired element is displaced from the first. Thus the first element of an array always has index zero and the second element of a REAL array has index 2, not 1. Indices may also include modifiers (on the 1900 this is one of the accumulators X1 to X3)

e.g.  N(X3)   N(X2-1) 

The current value of the modifier is used to calculate the displacement of the cell. On larger machines of the series where the necessary hardware exists, the index may also contain integer cells

e.g. N(L+X1-4) 

If an index of the latter type is used on a smaller machine a macro is generated to produce the same effect. This is in general inefficient but allows programs intended for the larger machines of the series to be tested on the smaller ones.

To access upper cells the base must first be loaded into a modifier (or integer cell) by an operation such as

      X1  ←  £A ;

Writing A(X1) in a program would then refer to the cell A; the appearance of the identifier represents the displacement of A only. This is compatible with the treatment of lower cells if the lower area is considered to be a domain with zero base. The displacement of a lower cell is thus also its address. If B is in the same domain as A, B(X1) will reference the cell B. Similarly A(X1+1) references the word next to A; this cell could also be accessed by increasing the value of X1 by 1 (for example round a loop) and referencing A(X1). In short, to reference an upper cell the user must ensure that the base of that cell's domain is a component part of the index. The PLASYD compiler cannot check that this has been done but it can reject such obviously erroneous designators as A or A(3).

The most efficient way of dealing with upper cells is therefore to ensure that related data is stored in the same domain. The base of this domain can then be loaded into a modifier before processing begins and the modifier can be used as part of all designators within that domain.

Define, Include and Common Storage

It is possible to make particular domains or sections of lower storage common to several separately compiled segments by preceding the relevant series of declarations by a common block identifier and enclosing any number of such blocks between the symbols GLOBAL and GLOBEND.

The common blocks correspond to those in FORTRAN and may thus be laid out differently in different segments. However normally the blocks will be treated similarly in each segment that accesses them, and it is convenient to use the same cell identifiers for elements of the blocks. To facilitate this and indeed to simplify the inclusion of any common code, a facility is provided whereby arbitrary sections of PLASYD program may be stored on a disc file whose name is given to the CALM monitor. Each section is given an identifier and the statement

      INCLUDE (identifier) 

in a PLASYD segment will cause the relevant statements or declarations to be included at that point.

Another use of the INCLUDE statement is in connection with the DEFINE statement. The latter allows parameters to be assigned absolute values which can then be used wherever the corresponding value could have been used, for example to give the size of an array. This can be useful within one segment to allow, for example, table sizes and the associated coding to be easily amended. By placing such definitions on disc and INCLUDEing them into all segments, parameters common to the whole program may be adjusted in a similar easy fashion.

Functions and Library Routines

As mentioned earlier the syntax of the language is such as to make optimum code production easy in many cases. For example the left to right evaluation of assignment statements means that statements such as

      X1 ← X1 + A 

generate a single add instruction, It is simple for the compiler to recognise that both sides of the are the same, The compiler also takes advantage of special instructions wherever possible. For example use of integer constants of less than 4096 will cause generation of immediate operand instructions for arithmetic operations (see [1] ).

Nevertheless there are some things that can be programmed more efficiently by descending to machine code. In addition there are some instructions of the 1900 order code which do not fit into the syntactic scheme of PLASYD. Functions are provided to make use of such instructions and also to provide absolute efficiency where this is necessary. A function consists of the symbol ! followed by the PLAN mnemonic for the particular machine code. The operands are enclosed in parentheses and may either be absolute or make use of the identifiers and defined quantities of the rest of the PLASYD program.

Since there are no standard language statements for input and output, functions can be used to obtain basic I/O facilities. However there are also a number of simple standard routines provided, to read and print records. While the compiler does not automatically incorporate such routines into programs they can easily be incorporated by use of INCLUDE statements. Similarly calls to a debugging package to provide trace printing may be incorporated in a program and the package itself called in by INCLUDE.

For debugging the programmer can also make use of conditional compilation. This is a facility whereby sections of program within special brackets may be optionally omitted according to the state of switches in the compiler. These switches are set by instructions to the CALM system. If debugging package references are incorporated in this way they can be removed by recompilation with the relevant switch settings.

The conditional compilation facility can also be used for producing versions of a program with large amounts of common code. Where the two differ the alternatives may be enclosed in conditional brackets and the section included in any particular compilation will depend on the switch setting.

Examples

Listings for the three Figures were provided separately.

Perhaps the best way to appreciate the basic characteristics of the PLASYD language is to study the examples in figures 1, 2 and 3.

Figure 1 is a procedure called SETRAND being declared at the head of a block. Procedures have no parameters as such, the parameter passing mechanism being carried out usually by use of accumulators or common or global variables. In the case of SETRAND for example, it is assumed that before the procedure is called, X7 has been set to an initial value and X1 has been set to the address of two contiguous cells where the bounds of the random number sequence are stored. The X0 in line 2 indicates the accumulator that is to be used as the link. All the items which follow in square brackets are comment and will be ignored by the compiler. The body of the procedure begins on line 9 with a !ower declaration specifying two integer and three real variables. The integer MASK and the real variable M20 are in addition given initial octal values (denoted by the # symbol).

The first assignment to X7 on line 12 masks out the top four bits of the 24 bit 1900 word and logically OR's a one bit into the bottom position. This reduces the value of X7 to an odd number in the range 1 ≤ X7 < 220, which is then stored in the integer cell X. On entry to SETRAND, X1 contained the address of two consecutive real numbers which formed the bounds of the random number sequence. The lower bound is loaded into the floating point accumulator A1 and stored in A. The difference between the bounds is then calculated and stored in AB. Notice that since the bounds are real numbers and therefore two words long, the second is found at the address (X1 + 2). FROM is a reverse subtraction operator which is provided by the 1900 order code and the statement

      A1 ← A1 FROM (X1 + 2) 

in line 13, has the same effect as, but is faster than

      A1 ← (X + 2) - A;

Line 13 concludes the body of SETRAND and line 14 initiates a jump to the end of the procedure.

A possible calling sequence for SETRAND is

BEGIN REAL LIMITS (2) = (0.0, 1.0) ; 
      X1  ←  @ LIMITS; X7 ← 1021013; 
      SETRAND; 

The symbol GLABEL on line 15 introduces a global label RANDOM which forms an alternative entry point to the procedure. In effect this specifies another procedure which has the same link as SETRAND and access to the same cells.

Once SETRAND has been called, each time that RANDOM is called by the statement

      RANDOM; 

a pseudo-random floating point number in the desired range will be placed in the floating point accumulator A1.

On line 15, [X0] is merely a comment on the link used. Line 16 loads X into accumulator X6, multiplies it by 5 and collates with MASK to produce the result modulo 220. This is stored in X ready for the next entry. The contents of accumulator 6 are then floated in the floating point accumulator, divided by 220 , multiplied by AB, and have A added to them, before exit.

The example of figure 2 creates a magic square using the method of Algorithm 118 in the Communications of the ACM Volume 5. The procedure is essentially the same as Wirth's first example in [3] so PL/360 and PLASYD may be compared. This introduces three new features: the synonym declaration used in this case, to assign new identifiers to accumulators; conditional statements; and the possible use of functions. A call of the procedure which satisfies the conditions mentioned in the comments of lines 3 to 7 is

      BEGIN INTEGER A(121) = (0 * 121); 
            A7 ← 11; MAGICSQUARE; 

Lines 9 and 10 form an accumulator synonym declaration introduced by ACC which gives extra names to accumulators X2, X3, X4, X5, X6, X7. In particular the identifier IJ is assigned to the modifier X3.

Lines 13 and 17 show the most straightforward way of setting NSQ to N2 and IJ to I × N + J respectively. In comments after each are shown less straightforward but slightly faster ways using functions. The latter methods would of course require more detailed knowledge of the 1900 order code but would only be necessary in those cases where 100% efficiency was required. Line 15 begins a simple for loop the body of which extends to the END of line 30. Lines 20, 23, 24, 28 and 29 illustrate simple if statements. Lines 19 and 27 show the use of a modifier in a cell designator.

The final example in figure 3 is a complete program which uses functions to obtain a very basic form of output. Line 1 consists of a define statement which assigns absolute values to the quantities LP and LPTYPE which are later used in peripheral control areas. The value 2CNT means a value of 2 in the count portion or top 9 bits of the 1900 word.

Line 5 begins a lower declaration. LPBUFFER and array are later considered as one contiguous area for printing purposes and the octal number #41 is a printer control character. Similarly the array MESSAGE on line 6 contains a control character and a string for output. Lines 7 and 8 are peripheral control areas accessed by the ! PERI function and contain in order the peripheral type, a word for a reply, a character count and the address of the first character to be output. Note the method of specifying a character within a word address. Lines 10 and 11 are synonym declarations similar to those in figure 2.

After two blank comment lines, line 14 specifies an entry point to the program. Up to 10 entries, numbered 0 to 9 may be specified in this way. Lines 15 and 16 ask for a line printer and if none is given (location 9 is negative) request operator action by ! SUSWT ('LP') which causes these two characters to be printed on the console typewriter. Note that ALLOT is not a reserved word and is here also used as a label identifier.

Line 17 uses the PERI function to output a heading and the initial order of ARRAY and then halts the program until this is complete.

The DO statement beginning on line 19 is an infinite loop from which conditional exit can be made by the statement on line 20. Line 21 illustrates a while statement. The contents of the following compound statement will be repeated until the relation K > J is false.

The program finishes at line 42 having output the sorted values of ARRAY. The output produced by the program follows. The compiled program occupied 114 words of which 41 were program instructions.

References

1. The ICL 1900 PLAN Reference Manual (Technical Publication 4004)

2. FOSTER D.M. A Simple List Processing Interpreter, The Computer Journal, 8, 2 (July 1965) 120 - 129.

3. WIRTH N. PL/360, A Programming Language for the 360 Computers. Journal of the ACM, 15, 1 (January 1968), 37 - 74.

ICT PLASYD CODING SHEET TITLE PROGRAMMER SHEET/ DATE// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 © International Computers and Tabulators Limited 1964 TABS AT 6 CHARACTER INTERVALS IDENTIFICATIONANDSEQUENCE No.