Contact us Heritage collections Image license terms
HOME ACL Associates Technology Literature Applications Society Software revisited
Further reading □ Overview1962: An outline of Fortran1962: Operating experience with Fortran1962: Implementation of Fortran on Atlas1962: Proposed target language (BAS)1962: BAS binary card1963: Intermediate Atlas symbolic programming language (INTERASP)1963: Addendum1963: A primer for Fortran programming1964: Atlas Fortran manual: Part I1964: Part II1964: Using HARTRAN1965: System note 41966: Fortran on Atlas □ Atlas 2 at AWRE □ 1965: BAS subroutines1965: System notes1966: S3 Fortran □ Titan □ 1966: System note 11966: System note 21966: Fortran on Titan1966: Compile Master on Titan1966: System Note 31966: Differences between S3 dialect and Fortran II1966: Magnetic tape library subroutines1967: T3 Fortran reference manual
ACD C&A INF CCD CISD Archives Contact us Heritage archives Image license terms

Search

   
ACLApplicationsHartran :: Hartran and Fortran on Atlas
ACLApplicationsHartran :: Hartran and Fortran on Atlas
ACL ACD C&A INF CCD CISD Archives
Further reading

Overview1962: An outline of Fortran1962: Operating experience with Fortran1962: Implementation of Fortran on Atlas1962: Proposed target language (BAS)1962: BAS binary card1963: Intermediate Atlas symbolic programming language (INTERASP)1963: Addendum1963: A primer for Fortran programming1964: Atlas Fortran manual: Part I1964: Part II1964: Using HARTRAN1965: System note 41966: Fortran on Atlas
Atlas 2 at AWRE
1965: BAS subroutines1965: System notes1966: S3 Fortran
Titan
1966: System note 11966: System note 21966: Fortran on Titan1966: Compile Master on Titan1966: System Note 31966: Differences between S3 dialect and Fortran II1966: Magnetic tape library subroutines1967: T3 Fortran reference manual

The T3 Fortran Reference Manual

J Larmouth

July 1967

University Mathematical Laboratory, Cambridge

The T3 Fortran Reference Manual

The T3 Fortran Reference Manual
Full image ⇗
© UKRI Science and Technology Facilities Council

This manual was produced using the paginating program written Dr. and Mrs J. H. Matthewman.

Preface

This manual is not intended as an introduction to programming. Those with no previous experience of programming languages should refer to any of the many commercially available primers on FORTRAN programming. However, this manual should enable those who have used FORTRAN elsewhere to write FORTRAN programs for Titan.

T3 FORTRAN is a dialect of FORTRAN II with some extensions. Users should note that some of the facilities provided - notably the use of general expressions for subscripts, arrays of any dimension, and the POSTMORTEM statement, may not be available on other FORTRAN compilers.

Contents

1. Introduction

The T3 FORTRAN compiler is part of the Titan Mixed Language System (MLS). Within this system a job is made up of routines, each of which may be written in any language for which a compiler exists in the system, or may be in a pre-compiled binary-symbolic form. Routines are compiled independently into binary-symbolic form, and the routines forming a program are loaded into store by a linking loader, which carries out relocation of store addresses, and ties up cross references between routines. MLS provides facilities for making up a program in this way, and also makes it possible to perform in a convenient and simple manner operations such as editing and macro-generating prior to compilation.

The programs that perform these functions (compiling, editing, etc) are called processors. Initially, the system includes the following processors:

  1. The T3 FORTRAN compiler
  2. The ETAL assembler (ETAL is identical to IIT, except that alphanumeric names may be used as parameters)
  3. A context editor
  4. The E3 line editor
  5. The ML/I macro-generator
  6. The SARA assembler (SARA is a symbolic assembler)

Those who do not wish to use the full facilities of MLS will find in this document sufficient to enable them to run FORTRAN Jobs. For information about the complete system they should refer to:

  1. MLS - User's Manual
  2. ETAL - User's Manual
  3. SARA - User's Manual
  4. Titan machine-code programming manuals
  5. Specifications of E3 and EDIT

2. The structure of a program

2.1 The character set

Input for the T3 compiler may be in any code accepted by the Titan supervisor.

The basic character set is

The alphabet A - Z (Upper and lower case letters are synonymous)

The numerals 0 - 9

Others + - = / ( ) . , * space erase tab backspace

The character ' is available, and is treated everywhere in the same way as a letter. In addition the following equivalences hold:

[ is treated as (
] is treated as )
× is treated as *
: is treated as , 

Runout and stopcode are everywhere ignored.

2.2 The items in a program

A FORTRAN program is made up of a set of routines which may be compiled independently. A routine is sometimes called a subprogram. Each routine is made up of a set of statements which will usually occupy one line each, and may be preceded by a label and/or followed by comment. Each statement is made up of a set of items. An item is a name or a number or an element.

2.3 The elements of a statement

The following are the elements of a statement:

Addition operator        +
Subtraction operator     -     (binary or unary)
Multiplication operator  *
Division operator        /
Exponentiation operator  **    ((A**B is AB)
                         **+   (A**+B is AB)
                         **-   (A**-B is A-B)
Bra                      (              
Ket                      )
Comma                    ,

2.4 FORTRAN names

A name is any string of letters or digits beginning with a letter, and not containing spaces. Only the first eight characters of a name are used, and names of less than eight characters are left-Justified and filled out with spaces. Thus the names

A1234567
A1234567'

will appear as identical names to the compiler.

2.5 FORTRAN numbers

There are three sorts of number used in a FORTRAN program.

2.5.1 Integers

An integer is any string of digits which, when read as a decimal number, has a value strictly less than 220. That is, an integer must be less than or equal to 1048575.

Examples:

Of the following numbers, all but the last are integers

        1
       29 
      029
  1028264 
001028264
  1048576     (not an integer)

For those familiar with Titan, an integer is held in a half-word or B-line with zero octal fraction, and is operated on with B-line orders.

2.5,2 Long integers

A long integer is any string of digits whose total length (excluding non- significant zeros) is less than or equal to ten, and which does not form an integer.

Examples:

Of the following numbers, all but the last are long integers

      1048576
   2496273984
0009997943210
  10002013270  (not a long integer)

For those familiar with Titan, a long integer is held in a full word of store as a non-standard number with exponent 812. It is operated on using accumulator instructions.

2.5.3 Real numbers

A real number is any string of digits longer than ten characters, or any string of digits containing a decimal point, or followed by an exponent.

Examples

1.0    1.     .1   0.1     0.00000656    1002013270

There is no limit on the number of digits in a real number, but only the most significant twelve will be used. The decimal exponent immediately follows the number, and is written by placing E and then the signed or unsigned exponent after the number. Note that the exponent may not stand alone. An exponent should lie between -27 and 27-1.

Examples:

1.23 E2
1.23 E+2
123. E-2
123  E-2 

Note that E256 is not a number, but a name.

For those familiar with Titan, a real number is held standardised in a full word, and is operated on with accumulator orders.

2.6 Labels and comments

In FORTRAN the printed line, or the card, is broken down into a set of four fields. The label field consists of columns 1 - 5 of the card (note that the first column is numbered one not zero) or the positions 1 - 5 on the printed page. The continuation field is column 6 (sometimes called the continuation marker). The statement field is columns 7 to 72 inclusive, and the comment field is columns 73 to 80 for cards, 73 to 120 for paper tape. Anything printed in the comment field is totally ignored, even illegal characters, so great care must be taken to ensure that an instruction never overflows into the comment field. It is not necessary to fill out with spaces any field terminated by a newline.

2.6.1 Comment

In addition to characters placed in the comment field, a line will be totally ignored if the character in the first printed position on the page is a C. (For those familiar with line-imagers, it should be noted that although the compiler does line-image, the C must actually be in the first print position. Erase C will not do, nor will space C. See 2.8)

2.6.2 Labels

The only other characters which may appear in the label field are digits, spaces, and erases. A label is formed if the field contains any digits. Erase and space are totally ignored in forming the label, as are non-significant zeros. The same label set twice, or referred to but not set, will usually produce a diagnostic at load time, not at compile time.

2.7 The continuation marker

If there is a printed character, other than erase or zero, in the continuation field, the newline terminating the previous statement is ignored. Thus it is possible for statements to spread over more than one physical line. A continuation line is treated as a continuation of the last non-empty record which was not a comment line. If there was no such line before the current line, then there will be a diagnostic (e.g. if the continuation marker appears on the first line of the routine). If a line contains a continuation marker, the label field is totally ignored.

2.8 The line-image - treatment of erase and space

The characters tab and backspace are correctly dealt with, and the compiler forms an image of the printed line. Note that if the printed line contains overprints or erase, these are preserved in the image, with overprints turned into erase, so that it is possible to have overprints in a comment. Within the label and continuation fields, erases are treated as spaces, and both are wholly ignored in forming a label.

Note that most other line-imaging programs on Titan will remove erases from the label field and shift some characters left from the statement field into the label field. This was not done in T3 FORTRAN in order to make it easy to see whether a continuation marker exists by inspection of column 6 of the printed page. Similarly, on no account will T3 FORTRAN shift characters from the comment field into the statement field. Other line-imagers will, and care must be taken if the program is to be line-imaged by anything other than the T3 compiler. A general rule is that, in the absence of a continuation marker, a tab before both the statement and comment fields will allow successful line-imaging by all the relevant laboratory software.

Within the statement field, erases are ignored, and a space inserted at the end of the statement field. Spaces may appear in the statement field at any point within a number, or at any place between items. Note that nowhere is there any distinction between one, two, or more spaces. The places where spaces cannot occur are

  1. within a name
  2. within the multicharacter operators (**, **+ and **-)

The only place where they must occur is between two names (e.g. INTEGER A) or a name followed by a number (e.g. DO 36).

2.9 Line numbering

Diagnostics will refer to a line as

line m after label n
or, if there has been no label in this routine, as
line m

The first line of the program is line 1. The line number is increased for every line, whether empty or not. The line on which label n appears is line 0 after label n.

2.9.1 Empty lines

Empty lines may appear anywhere, as may lines containing only labels (in which case the label is attached to the next executable statement).

WARNING: This is not true of S3 and other card-oriented FORTRAN systems.

3. The classification of names

3.1 The type of a name

A name may be one of several types

(i) A system name
This is one of the words recognised specially by the compiler, e.g.
FUNCTION
DO 
PRINT
GOTO
INTEGER
LONGINTEGER
Note that the rule that names may not contain spaces is relaxed in the case of system names which are two or more words. Thus
LONG INTEGER
is allowed, with an arbitrary number of spaces between LONG and INTEGER. This gives rise to the one exception to the rule that newline continuation marker is ignored. The system name END FILE must occur all on one line. END newline terminates a subroutine no matter what occurs on the next line. If a word is used which matches a system name, and it appears in a place where a system name is not possible - not the first item in the statement field - then it is not treated as a system name, but will be taken as one of the types (iii) to (v) below, on this and every subsequent occurrence.
(ii) A built-in function
This is one of the names in the list 7. Such a name cannot be used for any other purpose. These names all end with F, so that to avoid danger, no user name should end with F. This rule is not enforced, however.
(iii) A simple variable
This is the default case. Any name not in categories (i) or (ii), and not declared otherwise, is treated as a simple variable.
(iv) An array name
This has many of the properties of a simple variable. It can in general be used alone in an arithmetic expression, or appear on the left-hand side of an assignment statement. Its value is the base address of an array. In addition it can appear subscripted, when an element of the array is referred to. Note that, as in the case of S3 FORTRAN, but unlike several other versions of FORTRAN, the value of the array name used alone is not the value of the first element of the array, but is the base address of the array. For a more complete discussion of arrays see 11. A name is declared as an array name by including it in a DIMENSION statement. (This is equivalent to the declarations following program 0 in a Titan Autocode program.)
(v) An external function name or external subroutine name
This is a name referring to another routine. If a name has not been declared an array, and is immediately followed by a bra, then it is taken to be of this type from this point on. A warning message is printed for each external function. The appearance of such a message (Autocode programmers please note) could mean that an * for multiplication had been omitted between a name and an arithmetic bra.

At the end of each subroutine a list is printed of every name which has appeared of types (iii), (iv), or (v). This should help to locate otherwise undetected punching errors in names.

3.2 The mode of a name

Any name can have one of three modes:

INTEGER      mode 
LONGINTEGER  mode
REAL         mode

(Built-in functions are somewhat special; the mode of each function is given in 7. If the name begins with X, it is in INTEGER mode. Otherwise it is in REAL mode.) A name may be explicitly declared to be one of the three modes (see 12), but if there is no such declaration, then the mode is assigned in the following manner. If the first character of the name is one of the letters I to N, then the name is taken to be INTEGER. Otherwise it is taken to be in REAL mode.

The mode controls the way in which numbers are stored in the machine. In general, addition and subtraction, and the evaluation of an array element, will be faster with INTEGERS. Multiplication and division will be faster with REALS, followed by LONG INTEGERS. Operations involving the first few INTEGERS appearing in a routine will usually be faster than operations involving those appearing later, or those which have been equivalenced.

For those familiar with Titan, simple integer variables which are arguments (see 3.3), and the first 15 local integer variables (see 3.3)> are held in B-lines. Other integer variables, and any which have been equivalenced, use the low half of a word of store.

INTEGER and LONG INTEGER names can only be used for whole numbers. An INTEGER must be less than 220 in magnitude, and a LONG INTEGER less than 236.

Note that the mode declared for an external function must correspond to the mode declared in the routine defining that function. It corresponds to the mode Of the result which is handed over. The mode of an array is the mode of every element of that array. Note that no matter what mode has been declared for the array, when the array name appears unsubscripted, giving the address of the base of the array, it has INTEGER mode.

3.3 The scope of a name

A name can have one of three scopes

  1. local
  2. argument
  3. common

A name is assumed local unless declared common (by a COMMON declaration, see 10) or argument (by a FUNCTION or SUBROUTINE declaration, see 9).

If a name is local, then space is assigned for the storage of that name within the routine, and this space can only be accessed by other routines by handing the name over as an argument in a CALL statement (see 9.3)

If a name is an argument, then it is assumed that space will have been assigned for it by some outside routine, and this space is used.

If a name is common, then the space it refers to is under the user's control, and it can be used by every routine of the job. Complete details can be found in 10.

4. Subscripted array names and function calls

General form:

name(argl,arg2,...,argn)

Example:
A(B,C+D,E*A(B,C,D))

The syntax of function calls and subscripted arrays is identical, but the interpretation of the information differs. In both cases name is the array name or function name, and argl,arg2,...,argn are general expressions (which may contain other function calls or subscripted arrays to any depth). However, for subscripted arrays, each of the subscripts argl, arg2, etc. is evaluated, truncated to an integer (rounding always towards zero), and the result then used to produce the location of the array element thus specified. The value of this element will be of the mode declared for the name. An array name may have as many subscripts as desired (see 11 for further details). For function calls, the arguments argl, arg2, etc. are evaluated to produce a result whose mode is the mode of the expression forming the argument (see 5.4). This result is then handed over as the initial value of the arguments for the routine defining the function. There is no check that the modes of the arguments in the call are the same as the modes in the definition. Users should normally be careful to ensure that this is the case. The function routine is now entered and will produce a value whose mode should agree (again there is no check) with the mode declared in the calling routine.

If a function changes any of its arguments, or any variables which are COMMON, it is dangerous to call it twice in the same statement, as the order of the calls cannot be guaranteed.

5. Expressions and arithmetic statements

An expression is used to produce a value at run-time which can be assigned to a simple or subscripted variable or to an array name. Note that it is not meaningful to assign a value to a function, or to a constant (or constant array name, see 11). This will cause a diagnostic.

5.1 The components of an expression

An expression is made up of simple or subscripted variables (or array names), arithmetic operators, arithmetic brackets, and function calls (either of external or built-in functions).

Example:

-A+B**-I/JK+B(I, J)/FUN(D)*SQRTF(G)

An expression will produce a result with a certain mode, usually called the mode of the expression.

The operators have the following meanings

+     Addition
-     Subtraction (or, if unary, sign change)
*     Multiplication
/     Division. 

In an expression whose mode is real, the result of I/J is a real number - e.g. 3/4 produces 0.75. In an expression whose mode is INTEGER or long integer, the result of I/J is an integer or long integer, produced if necessary by truncation towards zero. Care must be taken that this truncation does not occur when it is not wanted.

** or
**+   Exponentiation.  

There are two different actions on this operator depending on the expressions on either side of it.

  1. This case applies if the whole expression is in INTEGER mode, and also if the whole expression is in REAL or LONG INTEGER mode but the item on the right of the ** is an INTEGER or LONG INTEGER constant or variable. Note that this does not include the case A**(I). In this case, A**I means multiply A by itself I times. A may of course be negative. Note: In this case, and this case only, even if I is declared long integer, it is taken modulo 220.
  2. This case applies to a real or long integer expression where the item on the right of the ** is not an integer constant or variable. This includes the case of A**(I). In this case, A**B means EXPF(B*LOGF(A)). If the expression is long integer, the result is truncated towards zero.
**-  Exponentiation

is similar to **+, except that in case (i) a division occurs at the end, and for long integers truncation is applied; and for case (ii) B is negated.

Note: For exponentiation of type (ii), A must be positive. A run-time diagnostic will be given if it is not.

5.2 The hierarchy of operators

The order in which the operators are obeyed can always be dictated by arithmetic brackets. Parts of an expression within brackets will always be evaluated before parts immediately surrounding the brackets. If brackets do not force an order, then we have the following rules:

**,**+,**-  will be obeyed first,
unary minus will be obeyed second,
* and /     will be obeyed third,
+ and -     will be obeyed last.

Where these rules do not completely determine the order, the operators are obeyed from left to right (except where the result is independent of the order, assuming no round-off error or overflow). Thus the following expressions are equivalent:

A**B**C**-D      and    (((A**B)**C)**(-D)) 
A/B*C*D/F*G      and    (((((A/B)*C)*D)/F)*G)

It is, however, good practice always to include brackets in these cases, for although most FORTRAN compilers will obey the hierarchy rules, they will not all obey the left to right evaluation.

5.3 Sub-expressions

If an item in an expression is a function call, or a subscripted array name, it is sometimes important to know at what point its arguments or subscripts are evaluated, and at what point the function is actually called. A sub-expression is:

  1. Any array subscript which is not composed entirely of integer variables, constants, or function calls, or which involves operators other than + or -.
  2. Any function argument.
  3. Any function calls.

All sub-expressions are evaluated before evaluation of the main expression is commenced. Similarly, sub-expressions within sub-expressions are evaluated before starting the enclosing sub-expressions. Where this does not decide the order completely, the right-most sub-expression is evaluated first.

5.4 The mode of an expression

Any name within a sub-expression or integer subscript is said to be at a lower level than the other names, which are said to be in the outer level. That is, a name is in the outer level unless it is within a function argument or array subscript. An expression is in integer mode if every name or constant in the outer level is in integer mode. An expression is in long integer mode if every name or constant in the outer level is in integer or long integer mode. Otherwise the expression is in real mode.

Note: For expressions involving both real and integer quantities (mixed mode expressions),these rules are not identical to those of S3 FORTRAN. Programmers wishing to write programs compatible with S3 should keep mixed mode expressions as simple as possible. No difficulty should occur with expressions involving a single operator. Examples:

If I=4, J=3, A=3
I/J * J      has integer result 3
I/J * A      has real result 4.0 

In S3 FORTRAN, these examples would produce results 3, and 3.0

5.5 The arithmetic statement

This takes the form

variable = expression

and will assign the value of the expression to the variable. The variable and expression do not need to be of the same mode. If necessary, the result of the expression will be truncated towards zero before assignment to the variable.

Note: Overflow is undetected. If a real expression whose result is out of integer range but within long integer range is assigned to an integer, the result appears modulo 220. If the real was out of long integer range, then the result will bear little relation to the original. Titan Autocode users should note that

variable = variable = expression 

(i.e. a multiple assignment) is not permitted.

6. Control statements

Any statement other than the declarations may be labelled. The following statements change the order in which a program is obeyed.

6.1 Unconditional GOTO

General form:

      GO TO n or 
      GOTO n

where n is a statement label. Example:

      GOTO 5

This causes, the statement with the statement label n to be obeyed next. We say that there is a transfer of control to this statement.

6.2 Computed GOTO

General form:

      GO TO (n1,n2,n3,...,nm),i
or    GOTO (n1,n2,n3,...,nm),i

where n1, n2, etc. are statement labels, and i is a simple integer variable. Example:

      GOTO(30,42,50,9),K

Control is transferred to the statement with statement label n1, n2,..., nm depending on whether the value of i at the time is 1, 2, 3, ..., m, respectively. A run-time error diagnostic will occur if the value of i is not in the range 1 to m.

6.3 ASSIGN

General form:

  
      ASSIGN n TO i

where n is a statement label, and i is a simple integer variable.

Example:

      ASSIGN 12 TO K

This statement allows subsequent assigned GOTO (see below) statements to transfer control to the statement labelled n. It can also be used to communicate an address to a machine-code routine.

6.4. Assigned GOTO, checked

General form:

      GOTO i, (n1,n2, ...,nm) or 
      GO TO i, (n1,n2,. ..,nm)

where i is a simple integer variable, and n1, n2, etc. are statement labels, i must have previously appeared in an ASSIGN statement, or have been set equal to some other variable which has done so.

Example:

      GOTO K, (17, 1O, 19)

This statement causes transfer of control to the label held by i. nl , n2, n3, ..., nm are a list of the possible labels. If i does not have a value corresponding to one of these labels, then a run-time diagnostic occurs.

Note: To say that K holds the label 10 does not usually mean that its value is 10. Thus the following sequence will usually produce an error diagnostic:

      K = 10
      GOTO K, (17,10,19)

6.5 Assigned GOTO, unchecked

This may not be provided in every dialect of FORTRAN, but will be more time-efficient than the checked GOTO. General form:

      GO TO i     or   
      GOTO i 
      where i is a simple integer variable. 

Example:

      GOTO K

This statement causes transfer of control to the label held in i. If i is one of the arguments of the routine or in the common list, this can be used to return to a machine-code routine. Machine-code programmers should note that in this case all B-lines will be incorrect, the values of integer arguments will not have been updated, private monitor will not have been reset, and local integer variables in B-lines will not have been preserved. Real and long integer variables and arguments should be correct.

6.6 IF

General form:

      IF (e)n1,n2,n3 

where e is a general expression of any mode, and n1, n2, n3 are statement labels.

Example:

      IF(A(J,K)-B)10,14,30

Control is transferred to the statement with label n1,n2, or n3, as the value of e is less than, equal to, or greater than zero, respectively.

Note that REAL arithmetic is subject to round-off errors, so that a value produced by much computation is unlikely to be exactly zero. However, if all intermediate results are whole numbers within long integer range, it can be assumed that real arithmetic is exact. This may not be true on other machines.

6.7 SENSELIGHT

General form:

      SENSELIGHT i  or 
      SENSE LIGHT i where i is 0,1,2,3, or 4 

Example:

      SENSELIGHT 3

If i is 0, all four notional lights will be turned off; otherwise light i will be turned on.

6.8 IF SENSELIGHT

General form:

      IF(SENSELIGHT i) n1,n2   or
      IF(SENSE LIGHT i) n1,n2

where nl and n2 are statement labels and i is 1, 2, 3, 4

Example:

      IF(SENSELIGHT 3)80,40 

Control is transferred to the statement with label nl if light i is to n2 if light i is off. The light is turned off. (Mnemonic: on = one)

6.9 DO

General form:

      DO n i = m1, m2  or 
      DO n i = m1, m2, m3

where n is a statement label, i is a simple integer variable, and m1, m2, m3 are general expressions which must be in INTEGER mode. If m3 is absent it is taken to be 1.

Examples:

      DO 3 I = J+3/K, M, -L   or
      DO 7 J' = J+I*K, I1 

The DO statement is a command to perform repeatedly the statements which follow, up to and including the statement with label n. These statements are said to be in the range of the DO. Note that if the label n is on an otherwise empty line, the null statement terminates the DO.

If any other DO appears in the range of the DO, then its range must be entirely within the range of the enclosing DO. A diagnostic is given otherwise. The range of two DOs may end on the same statement.

The statements in the range of the DO are obeyed with i = m1, i = m1+m3, i = m1+2m3, and so on. The last value of i for which the statements are obeyed is the last value in this sequence which is less than or equal to m2. If the first character of the expression m3 is a minus sign, the last value of i for which the statements are obeyed is the last value in the sequence for which i is greater than or equal to m2. Note that it is possible for the loop never to be obeyed. e.g.

DO 31  I = 0,  1,  -1

will cause the statements up to and including that labelled 31 to be skipped whenever control reaches the DO.

The value of the i, the index of the DO, is preserved when the DO is entered, and restored if it is completed. The expressions m1, m2, m3 are evaluated before the loop is entered, and so cannot be changed by the loop. A transfer of control into the range of the DO from outside of it will thus produce unexpected results. A transfer out of the DO will be successful, with the index holding its current value. The index of the DO is given the first value after evaluation of m1. It has this value during evaluation of m2 and m3.

Titan Autocode programmers should note that the index of a DO may not be REAL, that jumping into a DO is not possible, and that changing the step-length or end-point from within the DO is not possible.

6.10 CONTINUE

General form:

      CONTINUE

This is a dummy statement which has no effect. It is useful in card-oriented FQRTRANs, where it is not possible to place the DO label on an empty line. It is equivalent to the Autocode REPEAT, and should be used to terminate most DO loops.

6.11 STOP

General form:

      STOP

This causes the job to return to the command program to obey the next command.

6.12 RETURN

General form:

      RETURN

This causes control to pass from a routine back to the routine calling it. It signifies the end of the routine at run-time, and may appear in several places. If used in the main program, its effect is the same as STOP.

6.13 END

General form:

      END

This is the last written statement of a routine, and signals the end of the written routine to the compiler. The next record is not read.

The END statement is not intended to be an executable statement, and will produce a diagnostic if labelled. However, if control should reach it, the effect will be identical to that of RETURN.

7. Built-in functions

These provide a number of commonly used arithmetic operations, including the full range of trigonometric, hyperbolic, and inverse trigonometric functions.

Note: Programs that are to be compatible with S3 FORTRAN must restrict their use of some of the trig functions, as S3 does not provide the full range.

For those familiar with Titan, these functions either compile into extracodes, or into a short sequence of orders. They do not produce a call to another (library) routine.

7.1 Functions of one argument

The functions in this section take a single argument which may be a general expression in REAL, INTEGER, or LONG INTEGER mode. The result of the function is in INTEGER mode if the name of the function begins with X, and in REAL mode otherwise.

SQRTF(V)    Square root
LOGF(V)     Natural logarithm
EXPF(V)     Exponential function
SINF(V)     Sine (V is in radians)
COSF(V)     Cosine (V is in radians)
TANF(V)     Tangent (V is in radians)
ASINF(V)    Arcsine. The result is in the first or fourth quadrant, and is in radians
ACOSF(X)    Arccosine. The result is in the first or second quadrant, and is in radians
ATANF(X)    Arcstangent. The result is in the first or fourth quadrant, and is in radians
SINHF(V)    Hyperbolic sine
COSHF(V)    Hyperbolic cosine
TANHF(V)    Hyperbolic tangent
ABSF(V)     Absolute value
XABSF(V)    Absolute value, with truncation towards zero if the argument is not an integer.
INTF(V)     Integer part - truncating towards zero, this INTF(3.14) = 3.0 and INTF(-5.3) = -5.0
XINTF(V)    As INTF, but the result is in integer mode.
XFIXF(V)    Synonymous with XINTF
FLOATF(V)   The result is the REAL form of the argument. If the argument is real, there is no action.

7.2 Functions of REAL arguments

The mode of the result of the following functions is INTEGER if the name begins with X, REAL otherwise.

MODF(A1,A2)            Defined as A1-A2*INTF(A1/A2). It gives the value of A1, modulo A2.
SIGNF(A1,A2)           The result has the sign of A2 and the magnitude of A1
DIMF(A1,A2)            Defined as A1-A2 if A1≥ A2 otherwise zero
MAX1F(A1,A2,..An)      The result is the largest of the two or more arguments. Fourth character is the digit one
MIN1F(A1,A2,...An)     The result is the smallest of the two or more arguments.
XMIN1F(A1,A2,...An)    The result is the smallest of the two or more arguments.

7.3 Functions of INTEGER arguments

The mode of the result of the following functions is INTEGER if the name begins with X, and REAL otherwise.

XMODF(I1,I2)            Defined as I1-I2*(I1/I2). It gives the value of I1, modulo I2.
XSIGNF(I1,I2)           The result has the sign of I2 and the magnitude of I1.
XDIMF(I1,I2)            Defined as I1-I2 if I1≥ I2 otherwise zero
MAX0F(I1,I2,..., In)    The result is the largest of the two or more arguments. Fourth character of the name is zero
XMAX0F(I1,I2,..., In)   The result is the largest of the two or more arguments. Fourth character of the name is zero
MIN0F(I1,I2,..., In)    The result is the smallest of the two or more arguments. Fourth character of the name is zero
XMIN0F(I1,I2,..., In)   The result is the smallest of the two or more arguments. Fourth character of the name is zero

8. Library functions and subroutines

User-defined routines (see 9) may be functions or subroutines. Any such routines which may be of general use can be added to the system library, held on the magnetic disc store, and will then be freely available to every program.

A separate document ("The IAL disc library') lists the routines which are currently available.

9.User-defined routines - functions and subroutines

Each program is made up of a series of routines (sometimes called sub-programs). These may be compiled separately and stored (see "The Titan mixed language system'). A program may be just a single routine.

In general, each routine will have a name by which it is identified, but there may be one routine in each program which is not so named, but is called the main program. It will be the first routine entered. All other routines must begin with one of the two statements:

      FUNCTION  or  
      SUBROUTINE

These are followed by the name identifying the routine, and by a list of arguments. The only difference between these two statements is that on reaching the RETURN statement at run-time, the FUNCTION routine will plant the value of the name of the routine (which can be used like any other local variable) ready to hand back to the calling routine. This does not occur with the SUBROUTINE routine. There should be a correspondence between routines defined as FUNCTION and routines called as functions in some other routine. Similarly, routines defined as SUBROUTINE should only be called using the CALL statement (see 9.3). There is no check on disobedience of this rule. The following rules will govern the effect of such calls.

  1. Routines called as functions are expected to return a result with the same mode as that declared for the function name in the calling routine.
  2. Routines called using CALL will be able to change the value of any argument in the CALL statement which would form a legal left-hand side of an arithmetic instruction. Any result which is returned is lost.
  3. Routines defined as functions will hand back a value equal to the value of the routine name, and with the mode declared for that name in the defining routine.
  4. Routines defined as SUBROUTINE will hand back a meaningless value.

9.1 FUNCTION

This statement, if present, must be the first statement of the routine. General form:

      FUNCTION name(a1,a2,a3,...,an)

where the a1 to an are non-subscripted variables, called the arguments. In general, the mode of each argument provided in the call must correspond to the mode of each of these names. There is no check on breaking this rule. Note that there must be at least one argument.

Example:

      FUNCTION INTRST ( RATE, YEARS )

The arguments of the routine are initialised to the value supplied in the call, but may then be used exactly as any other variable in the program. If defined as arrays, the base address is initialised to the value supplied by the call. Changing the values of the arguments will change the values of the corresponding variables in the calling routine.

9.2 SUBROUTINE

This statement, if present, must be the first statement of the routine. General form:

      SUBROUTINE name(a1,a2,a3,...,an)      or
      SUBROUTINE name

where the a1 to an are non-subscripted variables called the arguments. Note that if there are no arguments, the brackets must also be absent. Examples:

      SUBROUTINE MATMPY (A,N,M,B,LD,I)
      SUBROUTINE TIME

The arguments can be used throughout the routine like any other variable in the routine, and any change to the argument will change the value of the variable supplied as the argument in the calling routine (unless such an assignment would be meaningless).

9.3 CALL

General form:

       CALL name (a1,a2,a3,.. .,an) or 
       CALL name  

where the a1 to an are general expressions in any mode.

Example:

      CALL MATMPY (X,5,10,Y,17,3+4/7)
      CALL TIME

If the argument is a single variable, possibly subscripted, then any assignment of a value to the corresponding argument in the called routine will change the value of that variable. Otherwise such assignments will have no effect on the calling routine. Note that the arguments may be array names or variables holding the dimensions of an array (see 11). Note also that if an array is being handed over, the name must appear in DIMENSION statements in both the called and the calling routines.

10. The COMMON declaration

These declarations may be preceded only by the FUNCTION or SUBROUTINE statement, by other COMMON statements, or by mode declarations (see 12). General form:

      COMMON name, name, name, name

where name is a non-subscripted name in any mode not declared a subroutine argument. Note that the name may be an array. Example:

      COMMON A,B,C

Declaring a variable COMMON is a means of enabling the value of that variable to be available in all other routines. The nth variable declared COMMON in each routine uses the same space.

Note: The first loaded routine of a job must have at least as many items in its common list as any other routine. Note too that an array declared COMMON only takes up a single position in the list - the position holds the base address. (Those using machine code should note that the first variable declared COMMON uses location 101 (decimal), the second 102 etc.).

If a variable is subsequently declared to be an array name, then the common list location is expected to contain the base address of the array, but it is up to the user to put this base address there. The procedure is as follows. The space above the last location used by program (usually called the common area) is available for holding arrays declared COMMON - local arrays have space assigned by the compiler within the routine. The base address of common arrays and their dimensions may be freely varied (see 11).

For compatibility with S3 FORTRAN, if any name is declared COMMON more than once, no action is taken on the second and subsequent declarations. WARNING: This treatment of COMMON is identical to that of the S3 compiler, but differs from that of most other versions of FORTRAN.

11. The DIMENSION declaration

This may be preceded only by the FUNCTION or SUBROUTINE statements, COMMON statements, other DIMENSION statements, or by mode declarations (see 12).

General form:

      DIMENSION V1, V2, V3,  ..., Vn 
           where the V have the general form
      name (dim1,  dim2,  dim3,  ...,  dimn)

where dim1 to dimn are simple variables or constants in integer mode, and name is a non-subscripted variable in any mode. If the mode of the dim are later changed, there will be undetected chaos. The mode of name may be safely changed. Example:

      DIMENSION A(10),  B(J),  C(5,K,6)

name may have argument, common, or local scope. The allowed scopes for dim depend on the scope of name'. The details are as follows. The DIMENSION statement is used to declare a name to be an array name. Each array is characterised by a number of values.

  1. The number of dimensions, that is, the number of subscripts it will have.
  2. The dimensions, that is, the maximum size of each of the subscripts. Subscripts may run from 1 to dim, the value declared in the dimension statement. In most cases chaos, or possibly an immediate error, will result if the subscript is out of range.
  3. The base address of the array, that is, the place in store where the array is to be found.

Of these, (i) is absolutely constant throughout the routine, and takes the value implied in the DIMENSION statement, except that any array may at any time be used with only one subscript, (ii) and (iii) can often be changed by the programmer at will.

We consider first the base address.

If name is not common or argument, then the base address is constant, and assigned by the compiler. Any attempt to assign to the unsubscripted name will lead to an error diagnostic.

If name is common, then the base address can be set (or changed) by the programmer at any time by assigning to the unsubscripted array name. However, the value will often be set initially (see 18) and never changed.

If name is an argument, then the base address will be initialised to the value handed over by the calling routine, but can be freely changed by assigning to the unsubscripted array name. Note that if the routine is called using CALL, this will change the base address in the calling routine.

We now consider the dimensions. These are needed for two purposes. First, to discover the amount of store needed by the array, and secondly, to locate an individual element of the array. Example:

      DIMENSION A(DIM1,  DIM2,  DIM3) 

then the value of the element A(I,J,K) is to be found at location

  base address + I+(J-1 )*DIM1 +(K-1 )*DIM1*DIM2 

The array takes up DIM1*DIM2*DIM3 of space.

There are two ways in which the position of this location can be calculated. First by explicit multiplication every time an array element is used, and secondly by forming at the head of the routine a set of multiplication tables which can be looked at to provide the value of each term in the expression. Clearly, in the former case, the dimensions can be varied at any point in the routine, but in the latter case, the dimensions can not be changed. Note too that whilst the former method is the most space-efficient, it is the latter which is most time-efficient. There will be an immediate error diagnostic at run-time if any subscript for which tables are used goes out of range by one. Note that for one-dimensional arrays no tables or multiplication are needed. The dimension is required only to allocate space for local arrays. If the single subscript goes out of range there will be no direct error diagnostic.

In the following description we will refer to values set by PRELUDE. This is a special subroutine (see 18) which can be entered before the remainder of the job is loaded into the store. Its sole purpose is to set initial values in the common list locations.

We can now describe the rules which govern the method used to find the location of an array element. The general rule is: if possible use tables.

Case (i)
The name of the array is not in the common list or an argument. The dimensions must be constant or common. Any other dimension is diagnosed as an error. This is the case of a local array, where space is assigned by the compiler.
  1. Dimensions all constant. Multiplication tables are formed at compile time, and used throughout.
  2. Dimensions constant or common, with at least one common. The value of the common dimension must be set by PRELUDE, and must not be changed before the first entry to the routine. Chaos will result if this rule is disobeyed. Tables are set up by the compiler as far as possible, and the remainder are set up on the first entry to the routine and used throughout. Once the tables are set up, the variables holding the dimensions may be freely changed, but will not affect the array.
Case (ii)
The name of the array is common or is an argument of the routine. The dimensions may be constant, common, arguments, or local variables.
  1. Dimensions all constant. Multiplication tables are formed at compile time, and used throughout.
  2. Dimensions constant or common with at least one common. The value of the common dimensions must be set by PRELUDE and must not be changed before the first entry to the routine. Chaos will result if this rule is disobeyed. Tables are set up by the compiler as far as possible, and the remainder are set up on the first entry to the routine, and used throughout. Once the tables are set up, the variables holding the dimensions may be freely changed, but will not affect the array.
  3. At least one dimension is an argument, or is a local variable. Explicit multiplication is used for all subscripts, so that there are no restrictions on setting or varying the dimensions at any point during the running of the program, provided only that there is an initial setting before the first reference to an element of the array.

WARNING: In many FORTRAN compilers all dimensions are restricted to being constants, and even S3 does not allow a local variable as an array dimension, or run-time alteration or setting of dimensions.

12. The mode declarations

These declarations can occur at any time after the FUNCTION or SUBROUTINE statement, if present, and before the first arithmetic (see 5), control (see 6), format (see 15), or equivalence (see 13) statements.

General forms:

INTEGER     name, name, name, ..., name
LONGINTEGER name, name, name, ..., name
LONG        name, name, name, ..., name
INTEGER     name, name, name, ..., name
REAL        name, name, name, ..., name

Examples:

      INTEGER A, B, XYZ, '1
      LONG INTEGER A2, B', B'', I
      REAL I, KA

These declarations force the mode of the names listed to be of mode integer, long integer, and real, respectively; no matter what is the first letter of the name. The names may already have been used in the SUBROUTINE, FUNCTION, COMMON, or DIMENSION (as an array name) statements. Note that to change the mode of a name which has been used as an array dimension will not be diagnosed, and could lead to chaos.

If the same name is used more than once in such a declaration, it is the last occurrence which determines the mode of the name.

13. The EQUIVALENCE declaration

These declarations must follow all COMMON, DIMENSION, and mode declarations, and must precede any arithmetic, control or format statements.

The EQUIVALENCE statement has two functions. First to arrange for two or more simple variables to use the same working space, and secondly to arrange for the space taken by one array to be in a fixed place with respect to another.

General form:

      EQUIVALENCE (L,R), (L,R), ..., (L,R) 

where L and R take one of the forms (a) to (d) below.

Example:

      EQUIVALENCE  (A,B), (C,D(K))

An equivalence has no effect on R, only on L. Note that if L was declared COMMON, the space allocated to it in the common list remains allocated, but is not used. (S3 FORTRAN does not assign a location for L), and if it is a local array, space remains allocated for it. A subroutine argument may safely be used as L (or R), but if used as L its initialisation to the value handed over is lost, and any change to its value will not affect the variable in the calling routine.

We now enumerate the allowed combinations of types for L and R, the first and second arguments of each EQUIVALENCE. All other types are diagnosed as errors.

(a) L. R both simple variable names

Example:

      EQUIVALENCE (A,B),  (X,I),(J,W)

L retains its mode, but uses the same storage location as R. Those familiar with Titan should note that there is a small effect on R. If R is in integer mode, and would normally have been held in a B-line, and L is not in integer mode, then the integer R is held in store.

Equivalences of this type can be chained. The compiler forms a pointer from the name L to the name R. Thus the chain can be formed from either end; e.g. (C,D),(A,B),(B,C) is the same as (A,D),(B,D),(C,D).

Using a variable as an L-equivalent twice is diagnosed as an error, as is forming a circular chain.

(b) L a simple variable name, R an array element

Example:

EQUIVALENCE (A,B(15)),I,C(J,K+7))

L retains its mode, but uses the location of the array element R for storage.

Note: The subscripts of the array element are evaluated when L is actually used in an arithmetic expression. The mechanism used is to replace L in the compiler's line-image buffer by the sequence of characters of R every time L occurs. Note therefore that an error in R - e.g. incorrect number of subscripts - will be detected when L is first used, not in the EQUIVALENCE statement.

The equivalences (A,B(I)), (I,J(3)) will produce an error diagnostic when A is first used - the subscripts of R may not be equivalenced in this way, or lead through a chain to such an equivalence. An equivalence of this type may be the last element in a chain of equivalences of type (a).

(c) L, R both non-subscripted array names
The array L starts at the same point as the array R. Note that L retains its own mode, and its own dimensions. The effect is to cause the location holding the base address to be the same for each array. These equivalences can be chained exactly as in (a): the array R of (b) may appear in such a chain. Note that if R is a local array, and L is larger than R, unpredictable results may occur.
(d) L a non-subscripted array name, R an array name with a single subscript

Note that R may have more than one dimension.

Example:

      EQUIVALENCE (A,B(I+J))

The effect is to make the first element of A coincide with the (I+J+l)st element of B. This is done by replacing every occurrence of A(P,Q) by A(I+J+P, Q) in the compiler's line-image buffer, and then equivalencing A to E with a type (c) equivalence. These equivalences can not form part of a chain - if B has been equivalenced there will be a diagnostic. As in (b), any attempt at a replacement while in the middle of a replacement will lead to a diagnostic.

WARNING: The EQUIVALENCE statement is largely compatible with S3, but differs from the treatment by other FORTRAN compilers.

Note on efficiency: The compile-time, and run-time efficiency can be reduced by making excessive use of equivalences, especially the equivalencing of array names to subscripted array names, If A is in common, the equivalence (A,B(I+J)) is better done at run-time by A=B+I+J.

14. Input/output statements

Input/output in FORTRAN is geared entirely to fixed format operation. That is, it must be known precisely what is the layout of the information to be input - how many numbers there are on a line, how many digits before and after the decimal point, and how many spaces there are between numbers. All the input/output statements transmitting decimal numbers refer to a FORMAT statement (see 15) which must be provided to supply this information.

This is a perfectly satisfactory procedure for output, or for input from cards, but can be a cause of difficulty with paper-tape input. There is provided in the Titan disc library a set of subroutines to read and line-image a line of input, together with functions to read numbers from it in free format, (much as in Titan Autocode). Full details are to be found in the documentation on the Titan disc library, but a brief summary of the facilities can be found in Appendix 5.

14.1 Simple decimal input/output

This is obtained by three statements READ, PRINT, PUNCH; General form:

      READ  n, list 
      PRINT n, list 
      PUNCH n, list

where n is a statement label of a FQRMAT statement (15) and list is a transfer list (14.5).

The user does not need to take any action in the Job Description or command program in order to use the last two. They will come out on streams 0 and 15, respectively, which are created to PRINTER and PUNCH7 if they do not already exist. The READ statement reads information from stream 0.

14.2 Decimal input/output on other streams

This is obtained by the statements

      READ INPUT TAPE n
      WRITE OUTPUT TAPE n 

These cause information to be read from or written to stream n.

General form:

      READ INPUT TAPE n, m,  list 
      WRITE OUTPUT TAPE n, m,  list

(The spaces in READ INPUT TAPE and WRITE OUTPUT TAPE are optional) where n is an unsigned integer constant, or a simple integer variable, m is the statement label of a FORMAT statement (see 15) and list is a transfer list (see 14.5).

14.3 Decimal input/output to tape or disc

There are two ways of obtaining this transfer.

(a) By creating a stream in the Job Description or command program as a TO TAPE or FROM TAPE stream (see chapters 9 and 10 of 'Titan machine-code programming manual' and 'The MLS Commands'), and then using the READ INPUT TAPE n and WRITE OUTPUT TAPE n statements. This is the recommended procedure. The information can then be subsequently read by either another FORTRAN program, or by other software in the laboratory.

(b) By setting up a tape logical number n, taking care not to create stream n, and using the READ INPUT TAPE n and WRITE OUTPUT TAPE n statements. This procedure is not recommended for two reasons.

(i) Buffer space is required for the transfer, and is taken as locations 28K to 32K. Great care must therefore be taken that this is not overlaid by any arrays in the common area.

(ii) The information is written up in the FORTRAN variable-length record format, and cannot be read by other software in the laboratory. This method should only be used if the tape is to be read elsewhere.

14.4 Binary input/output to tape or disc

This form of transfer suffers from all the disadvantages of section 14.3 (b). The FORMAT specification nA8, used with the statements of section 14.3 (a), can sometimes be used instead. The transfer enables arbitrary bit patterns to be written to tape or disc, and allows a limited amount of random access - backspace a single record, and rewind a tape - although this is extended by some library routines to skip one record forward, and skip and backspace by one file. Full details are given in 17.

14.5 The transfer list

Each input/output statement finishes with a transfer list. This is a list of the quantities which are to be output, or a list of the variables into which input is to be read. The list may sometimes be empty, - as when calling a format statement which contains only text.

General form:

item, item, item, ..., item

In the simplest case, item is an arbitrary expression.

Example:

A, B(3), C(I+J+K), 56,3+4/C(I)

WARNING: Programs that are to be compatible with S3 FORTRAN must restrict their items to variables, possibly subscripted.

The items are transmitted in the order they appear in the list, reading from left to right. Note that if an array name is used unsubscripted, it is the base address of that array which is transmitted. Note too that for transmissions which input information, the information will be lost if the item in the list is not capable of appearing on the left of an arithmetic statement. This situation is not diagnosed.

When it is required to transmit the elements of an array, we can have a more general form for item:

(item, item, ..., item, i = expl , exp2 ) or 
(item, item, ..., item, i = expl , exp2, exp3)

Note that the items within this item can be either expressions, or other items of this form. This transfer is exactly equivalent to the following:

      DO 5 i = expl, exp2, exp3 
      transfer item, item, . . . , item
 5    CONTINUE

The implied DO has a specification identical to that of explicit DO's. (See 6.9).

An example of a complete transfer list for use in an output statement is

I,  J+I, SQRT(I), ((A(K,L),K=1,I),B(L),L=1,J,2)

Note that, on input, the new value will be used for any variable read earlier in the list.

Example:

K, (A(I),I=1,K)

can be used to read numbers from an input tape which contains first a count of the number of items. Similarly, K,A(K) can be used to read a number into a specified place.

WARNING:

(i) The operation of S3 FORTRAN in the last example is doubtful.

(ii) S3 allows items of the list to be bracketed:

item,  (item),  item

It should be noted that such brackets would prevent the item from appearing on the left of an expression, and cannot, therefore appear in an input list in T3 FORTRAN.

15. The FORMAT statement

15.1 Syntax of FORMAT specification

A FORMAT statement must be numbered and is written

 n    FORMAT (<Format specification>)

A format specification is written as a sequence of field specifications and/or control specifications, in general separated by commas or slashes. The specifications are:

  1. nH followed by n characters, where n is an unsigned decimal integer.
  2. S followed by 2 characters. [The characters following H and S may be chosen from the complete character set and spaces are significant. Elsewhere spaces are not significant and only the following characters may be used ( ) , * / 0 1 2 3 4 5 6 7 8 9 + - . A B E F G H I K L O P Q R S X Y and Z.]
  3. Any of A B G I K L or O followed by an unsigned decimal integer and optionally preceded by an unsigned decimal integer.
  4. Any of E F followed by an unsigned decimal integer then the character . and finally a second unsigned decimal integer, and optionally preceded by an unsigned decimal integer.
  5. Y or Z preceded by an unsigned decimal integer.
  6. Any of P Q R X preceded by a decimal integer signed or unsigned.
  7. A sequence of specifications may be enclosed in parentheses and be optionally preceded by an unsigned decimal integer; this constitutes a specification which may itself be included in a sequence enclosed in further parentheses and so on to depth 8.

15.2 Semantics of FORMAT specifications

When an input/output statement is executed the relevant FORMAT specification is scanned. Whenever a field specification is reached which refers to a list item the next item in the list is processed and transmitted, execution of the input/output statement being ended when all items have been transmitted. If the end of the format specification is reached and items still remain in the list then the format is rescanned from the last nest of repeated field specifications, due regard being paid to any associated count. If there are no repeated groups of field specifications then the format specification is rescanned from the beginning.

During repeated scanning of a format specification the scaling factors q and r, the zero suppression control Z and the sign control S are not reset but have the values as at the end of the previous scan. They are reset at each execution of any input/output statement.

15.2.1 Fields

A sequence of adjacent characters to be input or output which are processed together is called a field. The field width is the number of characters concerned and is specified in all field specifications. This width should not cause the field to extend beyond the end of the buffer, it will be appropriately reduced if necessary. On input a field of width zero is treated like an all blank field and on output a zero field width means ignore the next item in the list.

Each type of conversion has a style of adjustment, either right or left.

Each item has a natural field width which may depend on the value of the item: for example, in A-type output the natural width is 8; and I-type it is 1 + max (z,n) where 10n-1 ≤ item < 10n, and z is the specified minimum number of digits to be printed (see control Z). The item is conceptually converted in its natural field width and then put in the specified output field.

If the adjustment is to the left (A,B,L-type), the left-most character of the natural field occupies the left-most position of the actual field. Characters at the right-hand end of the natural field are lost if the actual field is too small; on the other hand, if the actual field is larger than the natural field, spaces are output to the right of the item.

Conversely, if the adjustment is to the right (E,F,G,I,K,O) the right-most character of the natural field occupies the right-most position of the actual field. Characters at the left-hand (i.e. more significant) end of the natural field are lost if the actual field is too small; but if the actual field is larger than the natural field, the characters in the buffer to the left of the natural field are undisturbed.

The input conventions are designed to be compatible, in the sense that anything output can be correctly re-input, provided that the actual fields are big enough. (The converse is not necessarily true). This means that for left-adjusted items, characters are collected starting at the left of the field, ending when either the actual field or the natural field ends. If the natural field ends first, the right-hand part of the actual field is ignored.

For right adjusted items, initial spaces are ignored, and the collection of characters proceeds all the way to the end of the actual field.

15.2.2 Basic field specifications

The basic field specifications are

Iw, Ew.d and Fw.d

with the successive specifications separated by commas. Thus the statement FORMAT (I2, E12.4 F10.4) might give the line

29 -0.9321E 02  -0.0076

As in this example, the field widths may be made greater than necessary so as to provide spacing blanks between numbers. In this case, there is 1 blank following the 29. 1 blank after the E (automatically supplied except in cases of (a) a negative 2 digit exponent when a minus sign will appear, and (b) a 3 digit exponent, the E being changed to N if negative), and 3 blanks after the 02. Within each field the printed output will always appear in the right-most positions.

It may be desired to print n successive fields within one record with the same specification. This may be specified by giving n before E, F or I. Thus, the statement FORMAT (I2,3E12.4) might give

29 -0.9321E 02 -0.7580E-02 0.5536E 00
15.2.3 Alphanumerical fields

T3 provides two ways by which alphanumerical data may be read or written; the specifications for this are Aw and wH. Both result in storing the alphanumerical information in BCD form. The difference is that information handled with the A specification is given a variable or array name and hence can be referred to by means of this name for processing. Information handled with the H specification is not given a name and may not be manipulated in storage in any way. The specification Aw causes w characters to be read into or written from, a variable or array name. On input nAw will store the next n successive fields of w characters as BCD information. If w is greater than 8, only the 8 right-most characters will be significant. If w is less than 8, the characters will be right adjusted and the word filled out with blanks. On output nAw will transmit n successive fields of w characters from storage as BCD characters without conversion. If w exceeds 8 then only 8 characters will be transmitted preceded by w-8 blanks. If w is less than 8 then the w right-most characters will be transmitted.

The specification wH is followed in the FORMAT statement by w alphanumerical characters. For example

28H THIS IS ALPHANUMERICAL DATA

Note that blanks are alphanumerical characters and must be included in the count w. The effect of wH depends on whether it is used with input or output.

(1) Input w characters are extracted from the input record and replace the w characters of the specification.

(2) Output The w characters following the specification, or the characters which replaced them, are written as part of the output record.

Example:

The statement FORMAT ( 1Hb, 3HXY=,F8.3,A8) might produce the following lines:

XY=b-93.21Obbbbbbbb
XY=9999.999bbOVFLOW
XY=bb28.768bbbbbbbb

(b is used to indicate blank characters: the first H specification is used for carriage control, see 15.3)

This example assumes that there are steps in the source program which read the data 'OVFLOW', store this data in the word to be printed in the format A8 when overflow occurs, and store six blanks in the word when overflow does not occur.

15.2.4 Conversions

The characters A, B, E, F, G, I, K, L and O specify the conversion of information between internal and external form according to the following table:


Code   Internal Form  External Form           Adjustment 
A      ANY            Characters                Left      
B      REAL           Octal digits              Left 
E      REAL           Decimal with exponent     Right 
F      REAL           Decimal without exponent  Right 
G      REAL           Decimal with or without   Right
                      exponent
I      INTEGER        Decimal integer           Right 
K      INTEGER        Characters                Right
L      Boolean        'TRUE' or 'FALSE'         Left
                      This form is not useful
                      in T3 FORTRAN 
O      INTEGER        Octal integer             Right

The decimal integer, w, following a conversion code letter specifies the field width (i.e. number of characters) in the external form. The decimal integer d in the forms Ew.d. and Fw.d. specifies the number of digits, following the decimal point. On input the decimal point need not be present and if present, need not be in the position indicated by the format specification; if not present the number of decimal places is defined by the format specification. An exponent must be present in an E field and absent from an F field. The internal form is determined by the format specification.

The standard external forms for E, F and G formats have field widths as follows:

Ew.d      sign,            1
          integral part,   max (z,q)   where z,q are defined in 15.2 
          decimal point,   1 
          fractional,      d 
          exponent,        4

Total field width required 6 + d + max (z,q). If this exceeds w the left-most characters are lost and the field adjacent and to the left is not affected.

Fw.d      sign,            1
          integral part,   max (z,n)
          decimal point,   1 
          fractional,      d 

The implicit exponent is -r (see scale factors, below) and n is defined by 10n-1 ≤ internal value * 10r < 10n. The total field width required is 2 + d + max (z,n). If this is greater than w the left-most characters are lost and the the adjacent field to left is not affected.

Gw is as for the F form if the value can be expressed without either an exponent or leading zeros, otherwise the E form is used.

15.2.5 Spacing

The next character of the line in the external medium to be processed at any stage is identified by a pointer. This pointer is adjusted automatically when fields with specified field widths are processed. It can also be adjusted explicitly by X or Y control. nX moves n places relative to its present position, nY moves it to the specified absolute position. It can be moved backwards or forwards allowing overwriting within the buffer. [Thus 60Y, 4H****, -4X, S*-, I4 will cause an integer to be printed, with preceding asterisks instead of spaces in columns 60-63.] There are checks to prevent the pointer being moved outside the buffer area.

15.2.6 Repetitions of specifications and of groups

A decimal integer preceding a conversion code A, B, E, F, G, I, K, L or O specifies that the conversion is to be applied to the specified number of consecutive items in the list. A group of conversions (field or control) enclosed in parentheses and preceded by a decimal integer is repeated the specified number of times (once if no integer is explicitly specified). A group is itself a control specification and may occur within another group and so on to depth 8.

15.2.7 Scale factors (P, Q and R)

Two scale factors q (for E type conversions) and r (for F type) are maintained during processing of a format statement. At the start of execution of an input/output statement they have the values q = 1, r = 0.

These values may be changed by the specifications nP, nQ and nR; P sets them both to the same values (n), Q and R each affects the appropriate one. In E-type output the mantissa is normalised to the range 10q-1 ≤ mantissa < 10q (so that there are q integer places) and the decimal exponent formed accordingly. On input q is irrelevant. In F-type output the number output has the value 10r times the value of the corresponding list item. On input the number read is multiplied by 10-r before assignment to the list item.

15.2.8 Control of sign printing

Sab is relevant to the output of numerical information. The character to be printed immediately to the left of the left-most digit is specified; a for zero or positive numbers, b for negative. In the absence of this specification blank and - are used.

15.2.9 Zero suppression

nZ specifies that n digits are to be printed in I fields, and n digits before the decimal point in E or F fields. It applies to all I, E and F fields processed after this control is processed. In the absence of this control, or before this control is reached, unity is assumed so that all leading zeros are suppressed except that single zero is printed for a zero integer or a zero integral part of a number printed in E or F form.

15.2.10 Line control

A line in the buffer is terminated by the character / in the format. Each input or output statement specifies the subsequent action. On input the buffer is filled with the next line from the input document. On output the buffer is taken as the next line of output and is then reset to spaces. In both cases the buffer pointer is reset to the beginning of the line.

15.3 Carriage control

In records output for printing, the initial (zeroth) character of each record serves a special purpose: carriage control. Subsequent characters (1 to 120) in the record constitute the line to be printed. The carriage control character determines where the line is to be printed, according to the following code (standard in FORTRAN).

space (single spacing) print on the next line; 
0     (double spacing) leave one blank line then print; 
+     print on the same line; 
1     print at the top of the next page; 
A     Leave one blank line before printing; 
B     Leave two blank lines before printing; 
C:F   Leave three to six blank lines before printing.

16. The POSTMORTEM statement

General form:

POSTMORTEM n, m, list      or 
POST MORTEM n, m, list

where m is the statement label of a FORMAT statement, and list is a transfer list.

The action of this statement when obeyed is identical to WRITE OUTPUT TAPE n - it causes the specified information to be output on stream n. However, in the normal running of a program these statements are totally ignored. If an error diagnostic should occur at run-time within the routine containing the statements, or within a routine it calls, (even if it is called indirectly), then and only then will printing take place.

Example; Routine A is entered from the main program, and then enters routine B. We have a run-time error in routine B.

(Note: A calls B calls A will be dealt with correctly if it occurs in error.) The following printing takes place:

(1) <A message stating the error> IN LINE n AFTER LABEL m OF SUBROUTINE B

(2) <The first POSTMORTEM statement written in routine B>

(3) <Subsequent POSTMORTEM statements from B, in the order they were written>

(4) IN LINE n AFTER LABEL m OF SUBROUTINE A [The location of the call for B]

(5) <POSTMORTEM statements written in routine A>

(6) IN LINE n AFTER LABEL m OF MAIN PROGRAM [The location of the call for A]

(7) <POSTMORTEM statements written in the main program>

Note that an error caused by the program being overwritten by data could lead to a second error during the POSTMORTEM printing. In an extreme case it could prevent any of the above printing from occurring. In this case, the supervisor will put out a message

MONITOR
FAULT n AT LOCATION x

together with a print-out of the region of store faulted, in machine-code orders. The interpretation of FAULT n is given in chapters 9 and 10 of 'Titan machine-code programming manual1. This case should be very rare.

The POSTMORTEM statements can be placed at any point in the body of the routine, but for the sake of time-efficiency they should not be placed in the middle of tight loops. The best place for them is immediately after a GOTO statement, or a RETURN statement.

17. Binary input/output

17.1 Statements involving variable length records

17.1.1 The READ and WRITE statements

General form:

      READ TAPE i,  list    or READTAPE 
      WRITE TAPE i,  list   or WRITETAPE

where i is a simple integer variable, or integer constant, and list is a transfer list, (l ≤ i ≤ 8). This transfers the bit pattern in the locations specified by list onto BACKING STORE DEVICE (BSD) i. This may be disk or tape, and is set up in the Job Description, or by commands to the command program. The information is written up in FORTRAN variable length record format, and is unreadable to other software. Note that even if a record is not fully read, the tape or disc will nonetheless move to the beginning of the next record after the transfer.

17.1.2 The ENDFILE, REWIND and BACKSPACE statements

General form:

      END FILE i    or 
      ENDFILE i
      REWIND i 
      BACKSPACE i

where i is a simple integer variable, or an unsigned integer constant. (1 ≤ i ≤ 8).

The ENDFILE statement causes an end-of-file mark to be written to BSD i. The REWIND statement causes BSD i to be taken back to its start point. The BACKSPACE statement causes BSD i to move back by one record.

17.1.3 Library subroutines for tape handling

These operations are performed by library subroutines. They all have a single integer argument, and operate on the BSD of that value.

CALL BFFORT(I)       Move the device back to the previous end-of-file mark
CALL SFFORT(I)       Move the device on to the next end-of-file mark. 
CALL SRFORT(I)       Move the device on by one record.
CALL ULFORT(l)       If the device is a tape, unload it. If the device is disk working space, lose it.

17.2 Statements involving block marks

General form:

READ DRUM i, j, list        or READDRUM
WRITE DRUM i, j, list       or WRITEDRUM

DISC, and DISK are synonymous with DRUM. i, j, are both either unsigned integer constants, or simple integer variables.

The transfer is to or from BSD i, beginning at block j. The BSD may be tape or a section of disk created in the command program.

18. Initialisation of variables

18.1 User initialisation of the common list

When variables in the common list are used as the dimensions of an array the common list must have values placed in it before the whole of the job is loaded (see 11). To make this possible, the loading may be done in two stages. First a subroutine - which is special only in that it is called PRELUDE and must not require any such presetting - is loaded. Any library routines it needs are loaded too, then the routine PRELUDE is entered. It is written by the user to compute values and plant them in variables of the common list. When the RETURN instruction is obeyed, PRELUDE and any other routines loaded are thrown away, but the common list is retained. The rest of the program is then loaded and entered. PRELUDE is only necessary when there are dimensions of an array which need presetting. It can, however, be used to set any item in the common list.

Note that the common area is also thrown away - it is only the list which is retained.

The setting of the base address of arrays in COMMON can be done at any time before the array is used, but is most conveniently done in a separate routine, which is called by the main program on entry. Note that base addresses must be set in INTEGER or LONG INTEGER mode.

18.2 Loader initialisation of the common list

WARNING; This paragraph is totally different from the case of S3 FORTRAN. It was introduced so that programmers could place their common arrays immediately above their programs, and not at the top of their store as in S3.

When loading of the main program is complete, and before it is entered, the common list is examined. Every item of the list which either has not been written to, or has been written to in INTEGER mode, is increased by a constant equal to the location of the next available full word of store above the program. Any location which has been written to in long integer or real mode is unchanged. (Machine-code programmers should note that location 100 is also initialised to this value.) Thus normal initialisation using PRELUDE, and in particular, initialisation of array dimensions, must be done with LONG INTEGERS, or, if floating point, with REALS. (Note that a location written to as a LONG INTEGER looks like an INTEGER as well, so any variables which are to be used as integers can safely be initialised as long integers. The initialisation of the base address of common arrays, however, should be done relative to the base of the common area, and the result planted as an integer. The base of this common area can be found at run-time by reading, in integer mode, from any location in the common list which has never been written to (or from location 100).

18.3 Loader initialisation of variables

For those familiar with Titan, the store is initialised to half-word zeros. In FORTRAN terms, all integers are initialised to zero; long integers and reals will be in a form which can lead to incorrect results or an error diagnostic if used in some ways, but which may sometimes be treated as zero.

Note; All variables local to a routine have their values retained from one exit to the next entry - they are not reinitialised to zero. This should be true of most FORTRAN compilers.

Appendix 1 Running a simple job

For those who do not require the full range of facilities provided by the supervisor and command program, a simple job involving only FORTRAN and no PRELUDE can be run by submitting a tape of the following form:

RUN ML3(<initials and job number>/<your own title>)
LIMOUT 1000
LIMSTORE 10K
***U
(FORTRAN, F*)
      <main program, terminated by END>
      <first routine, beginning with SUBROUTINE or FUNCTION, and ending with END> 
      <further subroutines> 
*
(ENTEFORT,F*)
<data to be read by READ (if any)>
*
***Z

The statements FORTRAN, ENTEFORT, *, ***U, and ***Z will not be line-imaged, and must occur at the extreme left of the line. There should be at least one inch of run-out after ***U, 3 inches after ***Z, and about 12 inches of run-out at the start of the tape. The tape should be labelled JD <initials and job number>/<anything> and submitted with a tape-ticket to the computing service.

Appendix 2 Economisation of store

It is an unfortunate side-effect of the FORTRAN practice of assigning a full word to each variable that integer arrays take up twice as much space as is actually required to hold the information. For programs using integer arrays with a total of more than about 8,000 elements, this can be a large overhead, and the following procedure should be adopted to reduce the wastage. Before describing the procedure, it should be noted that this is very much of an ad hoc fiddle. It will not work with other machines or compilers.

Suppose we use two integer arrays A and B of approximately equal size, and that A is larger. Then

  1. Declare A in the usual manner.
  2. Declare B as a common array.
  3. B=A-OCTAL(0,0,0,0,0,0,0,4)

The array B will now be using the high half of the words whose low half is used by A.

Restriction; Avoid assigning a real or long integer expression to an element of B or A. Use B(I) = XFIXF (expression) Violation of this rule cannot of course be detected, and will result in the previous elements of A and B being overwritten if used with B, and the same element of B being overwritten if used with A.

Appendix 3 Internal code tables

These can be found at the end of 'Titan machine-code programming manual'.

Appendix 4 Redundant statements

The statements NON-ECON and LISTING which are used in S3 FORTRAN are ignored by the T3 compiler.

Appendix 5 Library subroutines for free-format input

Full details of the following routines and others concerned with free-format input can be found in 'The IAL disc library1. This appendix merely gives a summary of their action. NOTE: LABEL is an integer argument and must be set using an ASSIGN statement. All functions are of integer mode if the first letter of the name is I, and of real mode otherwise.

      FUNCTION READREAL (LABEL)

The next number from the current stream is read and handed back as the value. The next character to be read is the terminator of the number. If some non-digit occurs before the number, then the routine will return to the place specified by label. The number may contain a decimal point and/or exponent.

      FUNCTION IREADINTEGER (LABEL)

Similar to READREAL, but point or exponent terminates the number.

      FUNCTION IREADCHAR (lABEL)

The value of the function is the internal code of the next character on the input stream. If the line is empty, it jumps to LABEL.

      SUBROUTINE SEIECTINPUT (N)

Selects input stream N.

Appendix 6 Compatibility vith other FORTRAN II compilers

There are a number of respects in which the compiler differs from most FORTRAN2 compilers:

  1. DO loops need not be obeyed at least once.
  2. An array name unsubscripted means the base address, not A(1)
  3. Calling a routine requiring an array as an argument with A(N) as the actual argument will not set up the dummy array so that the first element corresponds to A(N). The argument should be written A+N-1 to achieve this effect.

By writing the statement FORTRAN2 at the head of the first routine compiled, these three points will be treated as in conventional FQRTRAN2 i.e.

  1. All DO loops will be obeyed at least once.
  2. An array name standing alone in an expression or argument is always given the subscript (1) before compilation of the expression.
  3. Array arguments pick up their base addresses in such a way that supplying A(N) will cause the first element of the dummy array to correspond with A(N). It should be noted that library routines requiring array arguments must be used with great care when called from routines compiled in this mode.

Those bringing programs from elsewhere should note the other divergences, which are not affected by this directive:

  1. Mixed mode expressions may cause trouble.
  2. Spaces are not ignored in T3 FORTRAN, and are needed in certain places,
  3. The whole concept of a common list is not present in most variants of FORTRAN.
  4. The treatment of EQUIVALENCE differs.
  5. An array name in a transfer list does not cause the whole of the array to be transmitted.

Appendix 7 Information for machine-code programmers

Details of how to write machine-code subroutines are to be found elsewhere. This section merely indicates some features of T3 FORTRAN which machine-code programmers may find useful, and which are peculiar to FORTRAN.

  1. The structure of a routine is
    1. Store all necessary B-lines; store the link and private monitor.
    2. Set all necessary B-lines and set private monitor.
    3. Code for routine.
    4. Preserve or hand back value of B-lines.
    5. Reset all B-lines, private monitor, link, and then return.
    6. Monitor section.
    7. Local arrays, formats, multiplication tables.
    8. Temporary working space.
    9. Local variables.
    10. Constants.
  2. Throughout the routine, B62, 63 hold the symbolic form of the routine name. B64 holds the line number in the form B64=27*m+n where m and n are integers, and the line is line n after label m. If there has been no label, 27* m is replaced by J77776
  3. Each routine preserves B20 - B64. The link is held in B90.
  4. Integer functions hand back their value in Bl, and real and long integer functions in the accumulator.

Appendix 8 Compiler error messages

These are listed below in alphabetical order. Note that the message cannot give more than an indication of the fault. The full details of what produces each message are given after the message. Items in parenthesis indicate the statements concerned in the message. A diagnostic message has the form

<message> IN LINE n AFTER LABEL m OF ROUTINE <name of routine> 
<a print-out of the current line up to and including the last character read>

The print-out of the current line will usually contain the offending item as the last item of the print-out. However, if the whole line has been read, including the newline, before the offence is noted, then the print-out will contain only the label and continuation fields of the next line, and the line number given will be that of the next line. Any illegal characters in the line will be replaced by decimal point, and two spaces are inserted between the continuation field and the beginning of the statement field.

If more than 30 messages are output in any one routine, and at least one is an error diagnostic, then the remainder of the document is abandoned. The comment

I GIVE UP 

appears to indicate this.

The diagnostic messages:

A LABEL IS NEEDED (FORMAT)
No label on FORMAT statement. Continues with next statement.
AN ARRAY HAS THE WRONG NUMBER OF SUBSCRIPTS
Continues with next statement. The number of subscripts do not agree with the number provided in the DIMENSION statement.
AN ARRAY HAS TOO MANY DIMENSIONS (DIMENSION)
Continues with next array declaration (see the note on BRA EXPECTED AFTER ARRAY NAME).
ARGUMENT OF SUBROUTINE IN COMMON LIST
The argument is totally ignored; the common list is constructed as if it had not appeared.
ARITHMETIC BRACKETS NOT PAIRED
When reading an expression, a newline, equals, or upper level comma terminates it. This diagnostic will appear if there is an excess of bras
over kets. Note that the true error may be the appearance of a spurious comma or equals. The remainder of the statement is ignored.
ATTEMPT TO CHANGE MODE OF A BUILT-IN FUNCTION
A built-in function appears in an INTEGER etc. declaration. The name is ignored. Continues with next name.
BRA EXPECTED (FORMAT, EQUIVALENCE, FUNCTION, SUBROUTINE)
Continues with the next statement. A system name is not followed by a bra.
BRA EXPECTED AFTER ARRAY NAME
In the DIMENSION statement, a name declaring an array is not followed by a bra. The compiler reads to the next ket (or newline), treats that as the end of the faulty item, and continues with a search for a comma. The whole statement is not abandoned, because this could lead to many other errors later. However, note that an unsuccessful attempt at recovery may produce the fault 'ERROR IN DECLARATION' which abandons the statement.
BUILT-IN FUNCTION CALLED WITH THE WRONG NUMBER OR TYPE OF ARGUMENTS
Continues with next statement.
BUILT-IN FUNCTION IN THE DECLARATION (FUNCTION, SUBROUTINE, COMMON)
Continues with next statement.
CALL NOT FOLLOWED BY SUBROUTINE NAME (CALL)
Continues with next statement.
  1. Item after CALL not a name.
  2. Name not followed by bra.
  3. Name declared an array.
  4. A general expression has been written after CALL.
CHARACTERS AFTER THE END OF THE INSTRUCTION
Any statement with a well-defined end can produce this diagnostic. It is most likely to occur when some other error has caused the instruction to be terminated prematurely but correctly, or when another line-imager has moved the comment field into the statement field. The characters are ignored.
COMMA. EXPECTED (EQUIVALENCE,GOTO)
  1. The comma is omitted between the index and the bra in an assigned GOTO. This message is only a warning.
  2. (i) Left equivalent not followed by comma. or (ii) No comma or newline after an equivalence. Continues with next statement.
COMPILER OR M/C ERROR n
This should not occur. Compilation stops. If this should occur, it should be reported in the first place to the Titan operators.
DECLARATIONS IN THE WRONG ORDER
Continues with next statement. If any or all of the following are present, they must be at the head of the routine and in the order:
FUNCTION or SUBROUTINE         INTEGER 
COMMON                         LONG INTEGER 
DIMENSION                      REAL 
EQUIVALENCE                 in any order
DIMENSIONS TOO GENERAL
Continues with next array declaration. The array is local, and the dimensions are not all common or constant.
ERROR IN DECLARATION (INTEGER etc, FUNCTION etc, COMMON, DIMENSION, EQUIVALENCE)
Continues with next statement.
  1. A name is not terminated by comma, ket, or newline.
  2. Ket in DIMENSION not followed by comma or newline. (May occur through some other diagnosed error. )
  3. The right equivalent is an array name and is not followed by a ket or a bra.
ERROR IN DO STATEMENT (DO)
  1. Item after DO is not an integer.
  2. DO index is not a simple integer.
  3. No = after index.
  4. Expression in DO has an unmatched ket.
  5. Expression in DO is not in integer mode.
EXPONENT OVERFLOW
The most likely cause is too many digits in the exponent. The compiler continues, using an incorrect value. It is possible that the line numbering given may be one or two lines further on than the constant causing the error.
EXTERNAL FUNCTION
A variable which is not an array name has appeared subscripted for the first time. This is merely a warning message - it could mean an * has been omitted between the name and bra.
FAULT IN THE NESTING OF DO LOOPS (DO)
  1. The current line terminates a DO loop. There are DO loops within its range which have not been closed. The unclosed DO's are ignored, and the compiler continues.
  2. A DO terminates on another DO statement. The DO is not terminated. This can lead to a subsequent type (a) diagnostic.
FORMAT LABEL USED TWICE (FORMAT)
FUNCTION HAS NO ARGUMENTS
Continues with next statement. FUNCTION <name> <newline> has occurred.
HALF OF SYSTEM NAME WITHOUT REMAINDER
Continues with next statement. The words causing this are: GO ASSIGN LONG
ILLEGAL CHARACTER. INTERNAL CODE <code> INNER SET
ILLEGAL CHARACTER. INTERNAL CODE <code> OUTER SET
This is produced by illegal characters appearing
Note: The diagnostic does not occur until the line-image is complete. All illegal characters are treated as printing characters.
ILLEGAL EQUIVALENCE
  1. One of the equivalences requiring replacement of the input buffer by a string of characters has within that string a name which asks for a second such replacement - not necessarily directly. The rest of the statement is ignored.
  2. The left-equivalent has already appeared as a left-equivalent. The rest of the statement is ignored.
  3. The chain of which the right-equivalent is the start ends on the left-equivalent.
  4. When equivalencing an array name to a subscripted array name, the right-equivalent has already appeared as a left-equivalent.
ILLEGAL JUXTAPOSITION OF ITEMS
Two operands, two operators, bra and ket, adjacent in an expression, or ket followed by name, or bra follows name. An error which could produce this diagnostic is placing spaces within ** operator. Continues with next statement.
INCOMPLETE DO LOOPS AT THE END OF THE SUBROUTINE
INCOMPLETE ROUTINE
No END statement.
INSTRUCTION CANNOT BE RECOGNISED
Continues with next statement.
  1. The first character on the line is comma or ket.
  2. The instruction consists of an expression terminated a comma or unmatched ket.
  3. 'Expression =' where
    1. 'Expression' is a function call, possibly due to an error in the DIMENSION statement.
    2. 'Expression' is not a simple variable, possibly subscripted.
    3. 'Expression* is a local array name.
  4. 'Expression = <nevline>' - check continuation marker in the correct place.
  5. 'Expression = Expression'. The second expression terminated by comma, equals, or an unmatched ket.
INSTRUCTION TOO LONG
Continues with next instruction.
JOB WAS STOPPED BY OPERATOR
KET EXPECTED (FORMAT, DIMENSION, EQUIVALENCE)
  1. Newline has occurred before the closing ket in a FORMAT statement. Continues with next statement.
  2. No comma or ket after a dimension. Continues with next array - see note on BRA EXPECTED AFTER ARRAY NAME.
  3. R-equivalent is a simple variable and is not followed by a ket. Continues with next statement without equivalencing.
  4. When equivalencing a simple variable to a subscripted array, an unmatched ket cannot be found when reading the subscript. Continues as in (c).
LABEL ON DECLARATION
The declaration is ignored.
LABEL TOO LARGE (GOTO)
Continues with next statement. The integer provided in the GOTO as statement label is too large to be a label.
LINE-IMAGE BUFFER OVERFLOWED
There is a printed character further than 120 positions from the left-hand of the page. This is detected when there is an attempt by the compiler to write to the buffer, not when the pointer is moved. The line is treated as complete and the remainder of the record ignored.
MALFORMED NUMBER
A REAL number is produced and used instead of the malformed number. The remainder of the number may give rise to a second massage.
  1. E not followed by digit, + digit, or - digit.
  2. Two points.
  3. Two exponents.
  4. Point in exponent.
MESSAGES ARE NOT AVAILABLE
This is due to a break-down of the filing system. Try again.
NAME EXPECTED The remainder of the statement is ignored.
NO BRA AFTER FUNCTION NAME
The rest of the statement is ignored. A name which has previously appeared subscripted is now appearing unsubscripted. See the diagnostic EXTERNAL FUNCTION.
NON-DIGITS IN LABEL FIELD
The label is taken to be terminated by the non-digit. Note that this produces a zero label if the non-digit is the first character in the label field.
NON-EXISTENT INPUT/OUTPUT STREAMS
The compiler was requested to compile from streams which did not exist.
NUMBER EXPECTED (GOTO, ASSIGN)
Continues with next statement.
OVERFLOW OF COMPILER TABLE n
n = 1 Too many brackets in an integer expression using the accumulator,
n = 2 Too many parameters are needed. A parameter is needed for each function call, one for each dimension of an array using tables, one for each local array, three for each DO. 500 are allowed,
n = 3 Too many sub-expressions in an expression.
SIMPLE INTEGER EXPECTED (GOTO, ASSIGN, DIMENSION)
  1. Index in ASSIGN statement, computed or assigned GOTO, or a dimension of an array is not a simple integer.
  2. A statement number in a GOTO is not an integer.
SIMPLE VARIABLE EQUIVALENCED TO ARRAY NAME
Continues with next statement.
SOME FORMAT STATEMENTS ARE NOT PROVIDED
Detected at end of subroutine.
SYNTAX ERROR (IF, SENSELIGHT)
Continues with next statement.
  1. LIGHT does not follow SENSE.
  2. A digit 0, 1, 2, 3, or k does not follow SENSELIGHT.
  3. Bra does not follow IF.
  4. Ket does not follow IF (SENSELIGHT i.
  5. 'IF (expression' There is an error in the pairing of brackets so that a pairing ket cannot be found, or else a comma or equals has appeared at the outer level.
  6. Incorrect number of statement labels after 'IF (...)' or commas omitted.
SYNTAX ERROR IN TRANSFER LIST
  1. Double error in the pairing of brackets.
  2. Brackets enclosing two or more list items without an implied DO inside.
  3. An implied DO without brackets round it.
  4. Implied DO not of correct form.
SYNTAX ERROR IN THE INPUT/OUTPUT STATEMENT
Continues with next statement.
  1. READ, READUIPUTTAPE, not followed by integer constant or another word.
  2. Word after READ is not INPUT, INPUTTAPE, DRUM, DISK, DISC, TAPE.
  3. Word after READINPUT is not TAPE, or there is no word.
  4. WRITE not followed by TAPE, OUTPUT, OUTPUTTAPE, DRUM, DISK, DISC.
  5. Word after WRITEOUTPUT is not TAPE.
  6. POST not followed by MORTEM.
  7. Statement number not an integer.
  8. Stream number not an integer or simple integer variable,
  9. Commas missing.
THE PROGRAM IS REQUIRING TOO MUCH COMPILER OUTPUT
THERE IS NO TIME LEFT TO COMPLETE THIS JOB
TOO MANY BRANCHES (computed GOTO)
Continues with next statement.
TOO MANY NAMES OR ARRAYS
The compiler dictionary of user names is full.
TOO MANY NESTED DO LOOPS
The current DO is ignored.
TOO MUCH WORKING SPACE NEEDED
The expression will require more working space for evaluation than is available. The expression should be broken down into smaller expressions, and the occurrence and expression reported. Continues at the same point.
TWO ARGUMENTS WITH THE SAME NAME
Continues with next statement. This could be caused by the routine name appearing in the argument list.
UNEXPECTED CHARACTER (GOTO)
Continues with next statement.
  1. Statement number in GOTO not integer.
  2. Occurrence of an = or operator.
  3. GOTO not followed by letter, digit, or bra.
  4. No comma or ket after statement number.
ZERO DIMENSION (DIMENSION)
One of the dimensions is the constant zero.

Appendix 9 Syntax of arithmetic statements

<letter>::= '|A|B|C ... W|X|Y|Z
<digit>::= 0|l|2|3|4|5|6|7|8|9
<name>::= <letter> | <name><letter> | <name><digit> | <space><name> 
<integer>::= <digit> | <integer><digit> | <space><integer> | <integer><space>
<exponent marker>::= E | <exponent marker><space>
<exponent>::= <exponent marker><integer> | <exponent marker>+<integer> | <exponent marker>-<integer> | <space><exponent> 
<real mantissa>::= <integer>. | .<integer> | <integer>.<integer>
<real number>::= <real mantissa> | <real mantissa><exponent> | <integer><exponent> | <space><real number> | <real number><space>
<operator>::= + | - | * | / | ** | **+ | **- | <operator><space> | <space><operator> 
<subscript list>::= <expression> | <subscript list>,<expression> 
<subscript>::= (<subscript list>) | <space><subscript> 
<subscripted name>::= <name><subscript> 
<operand>::= <name> | <integer> | <real number> | <subscripted name> | (<expression>) 
<unsigned expression>::= <space><unsigned expression> | <operand> | <unsigned expression><operator><operand> 
<expression>::= <unsigned expression> | +<unsigned expression> | -<unsigned expression> | <expressicai><space> | <space><expression> 
<left-hand-side>::= <space><left-hand-side> | <left-hand-side><space> | <name> | <subscripted name> 
<arithmetic statement>::= <left-hand-side>=<expression>
⇑ Top of page
© Chilton Computing and UKRI Science and Technology Facilities Council webmaster@chilton-computing.org.uk
Our thanks to UKRI Science and Technology Facilities Council for hosting this site