@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             FTN041
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                           ISSUE 10~
~V9 -1
~P
~V9 1
~YFTN041
~S1~M~OFORTRAN 77 COMPILER IMPLEMENTATION DESCRIPTION
~S1~M~OSection 4~
~S1~OSection 4. Syntax Analysis
~S1~O1.1 General Description
~BTwo techniques are used for syntax recognition. The SYNTAB facility
of MUSS which employs a top down fast back scanner is used for the
majority of recognition except for certain parts of statements such
as expressions, names, constants, format strings, where informal
recognition techniques give improved efficiency. An operator precedence
method is employed for expression recognition to produce a
binary tree representation of the expression.
~BFormat strings are not handled by the compiler directly but by a
procedure of the Fortran 77 I/O library.
~S1~O2. Interfaces
~S1~O2.1 Section Interfaces Used~
~
   Section  1:   (Configuration Section)~
   Section  2:   (Statement Driver)~
   Section  3:   (Lexical Analysis)~
   Section  9:   (Input/Output Statement Processing)~
   Section 12:   (Property List Management)~
   Section 13:   (Fault Monitoring)~
   Section 22:   (Format Processing)~
~S1~O2.2 Section interface~
~
Exported Scalars:~
   FSS~
   END.SS.G~
   PROPS.I~
~
Exported Vectors:~
   AS~
   WS~
   DIGIT.STR~
   FMT.TABLE~
   FMT.STRINGS~
   PROPS.T~
~
Exported Procedures:~
   SYNTAX.CHECK~
~
Exported Types
~
   PROPS~
~S1~O3. Implementation
~S1~O3.1 Outline of operation
~S1SYNTAX.CHECK(LINE.POSITION,STATEMENT.TYPE)STATEMENT.NO
~BThis procedure attempts to recognise a statement contained in the
itemised line and create an analysis record for it on the AS stack.
~BIf recognition is successful then STAT.AP.G, END.AP.G and END.SS.G
is set, and if not FSS is set.
~S1Parameters:-~
~T# 17
~
LINE.POSITION~IIndex into itemised line LINE.G to start statement
recognition.~
~
STATEMENT.TYPE~ISpecifies which statements recognition is attempted on.~
~3
~T# 23
~
                 0 -~IProgram unit headers. FUNCTION, BLOCK.DATA,
SUBROUTINE, END.~
                 1 -~IAll other statements except assignments.~
                 2 -~IAssignments.~
                 3 -~IContext free directives.~
~0
~T# 17
~
STATEMENT.NO~IA result of -1 means statement not recognised
otherwise it gives an identifying number for the statement.~
~BThe SYNTAX.CHECK procedure is called by the statement driver for
each statement, and also the statement contained
within the LOGICAL.IF statement.
The syntax of the Fortran language is specified
as level zero of chart FTN04.1.1 and its subcharts.
This is processed by the SYNTAB
facility of MUSS to produce a SYNTAX table in MUSL, this table is included
as part of this section, as level one of the chart FTN04.1.1 and its subcharts.
~BIf the syntax needs modifying it would be necessary to use SYNTAB
to generate a new table to replace the one at present in the chart
FTN04.1.1.
A scanner uses
this table in a top down fast back algorithm. Complete analysis is
not done formally, the COSYNE facility of SYNTAB is used for
the recognition of names, expressions etc.
~BCOSYNES used for recognition are as follows:~
~3
~
      COSYNE       ITEM IT RECOGNISES~
      NAME         Name~
      INTEGER      Integer optionally signed~
      CONST        Signed constant~
      EXPR         Expression~
      FORMAT.SPEC  Format string~
      CHAR.CONST   Character constant~
      OPT          Optional character~
      IN.LETTER    Letter for Implicit statement~
      DIGIT.STRING In STOP and PAUSE~
      HOLL.CONST   In DATA statement~
      SLASH.SLASH  Itemised //.~
~0
~BInformation retained from the lexical phase
distinguishes which statements are assignments.
For non-assignment statements, the context of the statement and the
first character of the statement selects the subset of Fortran
statements on which recognition is attempted. During recognition
two stacks are used WS and AS, the complete analysis record is
left of the AS stack at the end of analysis.
~BThe format of the analysis record produced for each
statement is given in this section, but first
a description of the notation of the
representation to describe analysis record formats
is given.~
~BAn analysis record consists of cells of word size.
[] are used to group one or more consecutive cells
together, within a group cells are separated by |.
An optional repeat count for a group may
be specified after the group, this is of the form
[]n->m. Where n specifies the
minimum number of times the group may occur, and m the maximum.
When n is one, the n-> may be omitted; and when m has no upper
limit an asterisk is used for m.~
~BA part of an analysis record may be named and described
separately. It's name enclosed in
<> may then appear in other analysis records as a
description for the named part. If a cell contains
a pointer to a named part, then this is
represented by ^<name>. When a cell contains a
pointer to another part of the analysis which is not named,
the cell contains only a ^, and directly beneath the cell, indicated
by a line of ^, is the description of the part pointed at.~
~BCell alternatives are represented by having a /
between each cell alternative, which are given in sequence.
The alternative for groups of cells are given one beneath
the other, with a vertical line of / separating each
alternative.~
~X{\ }^
~BComments are included by enclosing them in {}.~
~X{{ }}
~BA cell holding an item is represented by the items name,
e.g. INTEGER, and a cell holding an
index to an items property entry is represented by the items name
followed by ^, e.g. NAME^.~
~BThere now follows in alphabetical order the
analysis record descriptions for all statements and
descriptions for any commonly used groupings of cells.~
~S1ANALYSIS RECORD DESCRIPTIONS~
~3
~Q 8
~
~O<ARRAY.DECL>~
~
~X{\ }#
~M[NAME^][^<SIMPLE.EXPR>/1{assumed size}|^<SIMPLE.EXPR>/0~
~N/1{assumed size}]*[-1]~
~
When a dimension has an upper and lower bound specified
these are given by the two pointers, respectively. If only
an upper bound is present then the second pointer is zero.~
~
~
~OASSIGNMENT statements~
~Q 10
~
EXPRESSION ASSIGNMENT~
~
[10|^<EXPR>]~
~
LABEL ASSIGNMENT~
~
[22|INTEGER|NAME^]~
~Q 5
~
~
~OBACKSPACE~
~
See REWIND~
~
~
~OBLOCK DATA~
~Q 4
~
[25][NAME^/0{block data name not specified}]~
~
~
~OCLOSE~
~Q 9
~
[41][{UNIT}-1/^<EXPR>]~
    [{ERR}-1/INTEGER]~
    [{STATUS}-1/^<EXPR>]~
    [{IOSTAT}-1/^<DATA.ITEM>~
~
A -1 indicates that the field was not present.~
~X{{ }}
~
~Q 13
~
~OCOMMON~
~
~X{\ }#
[3][NAME^|^]*[2]{A NAME of zero means unlabelled COMMON}~
          ^~
          ^~
         [^]*[-1]~
          ^~
          ^~
         [0|NAME^]~
          /~
          /~
         [1|<ARRAY.DECL>]~
~
~Q 4
~
~OCONTINUE~
~
[17]~
~
~
~OCALL~
~Q 4
~
[16][^<EXPR>]~
~
~Q 9
~
~OCONSTANT~
~
[0{REAL}/1{D.P}/2{COMPLEX}/3{INTEGER}/4{LOGICAL}/5{CHARACTER}]~
[CONSTANT^]~
~0
~BFor character constants the pointer is to the first char. of
the string and not the warning character.~
~
~Q 21
~
~ODATA~
~
[8][^{nlist}|^{clist}]*[-1]~
    ^        ^~
    ^        ^~
    ^       [[INTEGER|0]{repeat count}[<CONSTANT>]]*[-1]~
    ^        /                        /~
    ^        /                        /~
   [^]*[-1]  [CONSTANT.NAME^|1]      [8|CONSTANT.NAME^]~
    ^                                 /~
    ^                                 /~
    ^                                [6|HOLLERITH.STRING^]~
    ^~
    ^~
   [NAME^|^<SIMPLE.SUBSCRIPT>/0|^<SIMPLE.SUBSTRING>/0]~
    /~
    /~
   [0|<DATA.DO>]~
~
A zero subscript or substring pointer means that the
subscript or substring were not present.~
~
For a hollerith string constant the pointer is to the first
character of the string.~
~
~
~Q 14
~O<DATA.DO>~
~
   [^|NAME^|^<SIMPLE.EXPR>|^<SIMPLE.EXPR>|^<SIMPLE.EXPR>/-1~
    ^                                              {no incr}]~
    ^~
    ^~
   [^]*[-1]{nlist of DO}~
    ^~
    ^~
   [NAME^|^<SIMPLE.SUBSCRIPT>][0{means no substring present}]~
    /~
    /~
   [0|<DATA.DO>]~
~
~Q 9
~
~O<DATA.ITEM>~
~
[NAME^|0{no subscript}]~
       /~
       /~
       [SUBSCRIPT COUNT][^<EXPR>]~
~
~Q 4
~
~ODIMENSION~
~
[2][^<ARRAY.DECL>]*[-1]~
~
~
~ODO~
~Q 4
~
[7|INTEGER|NAME^|^<EXPR>|^<EXPR>|^<EXPR>/-1{no increment}]~
~
~
~OEND~
~Q 4
~
[9]~
~
~
~OENDFILE~
~Q 4
~
See REWIND~
~
~Q 8
~
~OEQUIVALENCE~
~
[4][^]*[-1]~
    ^~
    ^~
   [NAME^|^<SIMPLE.SUBSCRIPT>/0|^<SIMPLE.SUBSTRING>/0]*[-1]~
~
A zero subscript or substring pointer means that the subscript
or substring was not present.~
~
~Q 7
~
~OENTRY~
~
[34][NAME^][NAME^/0{label argument}]0->*[-1]~
~X{{ }}
~
Semantics check for wrong use of label argument within a function.~
~0
~
~
~OEXPRESSION~
~BThe analysis record for an expression is in
the form of a binary tree. Nodes are either terminal
or non-terminal. Basic operands such as constants, variables,
array element references, function references appear as
terminal nodes. For each non-terminal node there is an
operator to specify how the two immediately subservient nodes
are coerced to form the operand of the node. During code
generation the tree is pruned and updated. For reasons of
completeness the full specification of the analysis record
structure is here given.~
~S1~OTERMINAL NODE~
~3
~
WORD 0    Bit 4 = 1 Means terminal node~
~
          Bits 0->3 Operand kind~
          0  Explicit constant~
          1  Name of constant~
          2  Variable name~
          3  Array element name~
          4  Statement function reference~
          5  Subroutine reference~
          6  Function reference~
          7  Intrinsic function reference~
          8  Array~
          9  Function, subroutine or intrinsic name~
          10 Label~
          11 Substring~
          12 Operand in accumulator or B register~
          13 Operand stacked~
          14 Operand is a boolean function of the~
             contents of T register~
          15 Undefined name~
~0
~BDuring syntax recognition of statements the kind of
name is not determined, therefore terminal nodes have
an operand kind value of 0, 10 or 15. The
kind and types of all nodes is determined prior to
code generation in a reduce expression process
(REDUCE.EXPR in section 11), thus terminal nodes then
have a value between 0 and 11. During code
generation the tree is repeatedly pruned as coding
progresses and values 12, 13 and 14 indicate the
whereabouts of the intermediate operands used
during evaluation.~
~3
~T% 20
~
Bit 9 = 1
~IOperand is a dummy argument. Set during REDUCE.EXPR~
~
Bit 10 = 1
~IOperand has a subscript expression list or an
argument expression list~
~
Bit 11 = 1
~IOperand has a substring specifier~
~
Bits 12->14
~IType of the operand~
~I0 - Real, 1 - Double precision, 2 - Complex,
3 - Integer, 4 - Logical, 5 - Character,
6 - Undefined~
~IFor explicit constants the type is set at syntax
recognition time. For all other nodes the type is
determined during REDUCE.EXPR~
~
Bits 5 - 7
~IFor some nodes of type logical, their value (of true or false)
is determined by applying a boolean function to the T register
value. For such nodes this field indicates that function that
yields a true value~
~I1 = , 2 /= , 3 >= ,~
~I4 < , 5 =< , 6 >~
~
WORD 1
~ISpecifies operand information for code generation, this is
determined during REDUCE.EXPR. It normally contains the
MUTL name associated with the operand of the node, but for
intrinsic function references it contains the intrinsic
identifier number~
~
WORD 2
~ISpecifies further operand information. For all constants it
contains a pointer to the constant value. For label operands
it contains the integer value of the label. For other operands
it contains the address of the local property entry.~
~
WORD 3
~IIndex into itemised line LINE.G of item associated with this
operand. This information is maintained so that typing and
coercion errors yield an accurate diagnosis.~
~
WORD 4 and WORD 5
~IIf the node does not have a subscript/argument expression
list nor a substring specifier neither of these words are
allocated, but if both are present then word 4 contains
an index to the subscript/argument list and word 5 on
index to the substring specifier, and if only one is
present only word 4 is allocated~
~IA subscript/argument expression list commences with a
count followed by that number of indexes to the expressions.
A count of zero is valid and means that the function or
subroutine has no arguments.~
~IA substring specifier consists of an index to the
lower substring expression followed by an index to the
upper substring expression. An index value of zero
means that that part of the substring specifier was absent.~
~S1~ONON TERMINAL NODE~
~
WORD 0
~IBit 4 = 0 Means non-terminal node~
~
~IBits 0->3 Operator~
~
~I0 = , 1 //(concatenation), 3 .NEQV., 4 .AND.,
5 .OR., 6 **, 8 +, 9 -, 11 *, 12 /, 14 .EQV.,
15 compare.~
~IA compare operator is employed for the relational operators
.EQ., .NEQ., and the next field indicates what condition of
the comparision yield the value true~
~
~IBits 5 - 7 1 = , 2 /= , 3 >= ,~
~I           4 < , 5 =< , 6 >~
~
~IBit 8 = 1 do not prune tree at compile time if
both nodes are constant.~
~
~IBits 12-14 Type. See notes for corresponding field of
terminal nodes~
~
WORD 1
~IIndex into analysis record of left hand operand.~
~
WORD 2
~IIndex into analysis record of right hand operand.~
~
WORD 3~IIndex into itemised line LINE.Gof item
associated with this operand.~
~
~
~OEXTERNAL~
~Q 4
~
[5][NAME^]*[-1]~
~
~
~OFORMAT~
~Q 4
[6|FORMAT.ID]~
~
~Q 27
~
~Q 27
~X{\ }#
~OFUNCTION and SUBROUTINE~
~Q 27
~
[24][0{Real}][NAME^][NAME^/0{subroutine only,~
                             label argument}]0->*[-1]~
     /~
     /~
    [1{D.P.}]~
     /~
     /~
    [2{complex}]~
     /~
     /~
    [3{integer}]~
     /~
     /~
    [4{logical}]~
     /~
     /~
    [5{character}!<LENGTH.SPECIFICATION>]~
     /~
     /~
    [6{implicitly typed function}]~
     /~
     /~
    [7{subroutine}]~
~
~Q 19
~
~OGO TO~
~
UNCONDITIONAL~
~
[13][INTEGER]~
~
COMPUTED GO TO~
~
[11][^][^<EXPR>]~
     ^~
     ^~
    [INTEGER]*[-1]~
~
ASSIGNED GO TO~
~
[12][NAME^][INTEGER]0->*[-1]~
~
~Q 27
~
~OIF and ELSE statements~
~Q 26
~
ARITHMETIC IF~
~
[15|^<EXPR>|INTEGER|INTEGER|INTEGER]~
~
LOGICAL IF~
~
[14|^<EXPR>]~
~
BLOCK IF~
~
[36|^<EXPR>]~
~
ELSE IF~
~
[37|^<EXPR>]~
~
ELSE~
~
[38]~
~
END IF~
~
[39]~
~
~Q 25
~
~OINQUIRE~
~
[42][{UNIT}-1/^<EXPR>]~
    [{FILE}-1/^<EXPR>]~
    [{ERR} -1/INTEGER]~
    [{IOSTAT}-1/^<DATA.ITEM>]~
    [{EXIST}-1/^<DATA.ITEM>]~
    [{OPENED}-1/^<DATA.ITEM>]~
    [{NUMBER}-1/^<DATA.ITEM>]~
    [{NAMED}-1/^<DATA.ITEM>]~
    [{NAME}-1/^<DATA.ITEM>]~
    [{ACCESS}-1/^<DATA.ITEM>]~
    [{SEQUENTIAL}-1/^<DATA.ITEM>]~
    [{DIRECT}-1/^<DATA.ITEM>]~
    [{FORMATTED}-1/^<DATA.ITEM>]~
    [{FORM}-1/^<DATA.ITEM>]~
    [{UNFORMATTED}-1/^<DATA.ITEM>]~
    [{RECL}-1/^<DATA.ITEM>]~
    [{NEXTREC}-1/^<DATA.ITEM>]~
    [{BLANK}-1/^<DATA.ITEM>]~
~
A -1 indicates field not present.~
~
~Q 5
~
~OINTRINSIC~
~
[30][NAME^]*[-1]~
~
~Q 23
~
~OIMPLICIT~
~Q 22
~
[31][^]*[-1]~
     ^~
     ^~
    [0{real}][LETTER|LETTER/0{-option not used}]*[-1]~
     /~
     /~
    [1{D.P}]~
     /~
     /~
    [2{complex}]~
     /~
     /~
    [3{integer}]~
     /~
     /~
    [4{logical}]~
     /~
     /~
    [5{character}|<LENGTH.SPECIFICATION>]~
~
~
~Q 14
~O<LENGTH.SPECIFICATION>~
~
[0{not specified}/^]~
                  ^~
                  ^~
                 [0]{assumed size}~
                  /~
                  /~
                 [1|INTEGER]~
                  /~
                  /~
                 [2|^<SIMPLE.EXPR>]~
~
~
~Q 14
~OOPEN~
~
[40][{UNIT}-1/^<EXPR>]~
    [{ERR}-1/INTEGER]~
    [{FILE}-1/^<EXPR>]~
    [{STATUS}-1/^<EXPR>]~
    [{ACCESS}-1/^<EXPR>]~
    [{FORM}-1/^<EXPR>]~
    [{RECL}-1/^<EXPR>]~
    [{BLANK}-1/^<EXPR>]~
    [{IOSTAT}-1/^<DATA.ITEM>]~
~
A -1 indicates field not present.~
~
~Q 8
~
~OPARAMETER~
~Q 7
~
[33][^]*[-1]~
     ^~
     ^~
    [NAME^|^<SIMPLE.EXPR>]~
~
~
~OPAUSE~
~Q 10
~
[28][3|DIGIT OR STRING^]~
     /~
     /~
    [2]~
~
~
~OPROGRAM~
~Q 4
~
[35][NAME^]~
~
~Q 6
~
~OPRINT~
~
See READ~
~
~Q 16
~
~OREAD, WRITE and PRINT statements~
~
[19][0{READ}/1{WRITE OR PRINT}]~
    [{UNIT}-1/0{*}/^<EXPR>]~
    [{FMT}-1/0{*}/^<EXPR>]~
    [{REC}-1/^<EXPR>]~
    [{END}-1/INTEGER]~
    [{ERR}-1/INTEGER]~
    [{IOSTAT}-1/^<DATA.ITEM>]~
    [0{C.LIST present}/0{no C.LIST}]~
    [^<RWP.IO.LIST>/0{no iolist}]~
~
A -1 indicates field not present. Absence of UNIT is not checked
in syntax. Wrong use of END not checked in syntax.~
~
~
~ORWP.IO.LIST~
~Q 10
~
[^]*[-1]~
 ^~
 ^~
[0|<RWP.DO>]~
 /~
 /~
[^<EXPR>]~
~
~Q 14
~
~ORWP.DO~
~Q 13
~
[^|NAME^{DO var}|^<EXPR>|^<EXPR>|^<EXPR>/-1{no increment}]~
 ^~
 ^~
[^]*[-1]~
 ^~
 ^~
[0|<RWP.DO>]~
 /~
 /~
[^<EXPR>]~
~
~
~ORETURN~
~Q 4
~
[18|^<EXPR>/-1{no expression}]~
~
~Q 11
~
~OREWIND, BACKSPACE and END.FILE statements~
~
[20][0{REWIND}/1{BACKSPACE}/2{ENDFILE}]~
    [{UNIT}-1/^<EXPR>]~
    [{ERR}-1/INTEGER]~
    [{IOSTAT}-1/^<DATA.ITEM>]~
~
A -1 indicates field not present.~
~
~
~OSAVE~
~Q 7
~
[32][NAME^|0]0->*[-1]~
     /~
     /~
    [NAME^|1{of common block}]~
~
~
~OSUBROUTINE~
~Q 4
~
See FUNCTION~
~
~
~OSTOP~
~Q 10
~
[21][1|DIGIT OR STRING^]~
     /~
     /~
    [0]~
~
~
~O<SIMPLE.SUBSCRIPT>~
~Q 4
~
[NO OF SUBSCRIPT EXPRS][^<SIMPLE.EXPR>]~
~
~Q 6
~
~O<SIMPLE.SUBSTRING>~
~Q 5
~
[^<SIMPLE.EXPR>/0{lower bound not specified}~
 |^<SIMPLE.EXPR>/0{upper bound not specified}]~
~
~Q 23
~
~OTYPE~
~
[1][0{real}][^|<LENGTH.SPECIFICATION>{CHARACTER type}/NIL]*[-1]~
    /        ^~
    /        ^~
    /       [0|NAME^]~
    /        /~
    /        /~
    /       [1|<ARRAY.DECL>]~
   [1{D.P.}]~
    /~
    /~
   [2{complex}]~
    /~
    /~
   [3{integer}]~
    /~
    /~
   [4{logical}]~
    /~
    /~
   [5{character}|<LENGTH.SPECIFICATION>]~
~
~
~OWRITE~
~Q 4
~
See READ~
~
~O*EXPORT~
~
[44][NAME^]*[-1]~
~
~O*IMPORT~
~
[45][STRING^|0]*[-1]~
      /~
      /~
      /~
     [NAME^|1]~
~
~O*LIB~
~
~Q 13
~
~O*MAP~
~
[43][0{common}|NAME^][INTEGER{TL.SEGMENT.NO}][INTEGER{SIZE}]~
     /~
     /~
    [1{BLANK COMMON}|0]~
     /~
     /~
    [2{CODE}|0]~
     /~
     /~
    [3{DATA}|0]~
~X{{ }}
~BWithin this section the following five internal procedures
are worthy of discussion~
~Q 5
~
        REC.EXPR~
        REC.CONSTANT~
        REC.ARITH.CONST~
        REC.NAME~
        READ.I.~
~0
~S1~MINTERNAL PROCEDURE SPECIFICATION
~S1REC.EXPR(EXPR.KIND)STATUS
~BThis procedure attempts recognition of an expression. The
context of the expression determines what is a valid terminator
for the expression, and whether function or array references are
permitted. The analysis record is created on the AS stack and its
index yielded. On failing to recognise an expression FSS is
updated to indicate where in the itemised line failure occurred.~
~
Parameters:~
~
EXPR.KIND~
~3
~
  Bit 0=1 Assignment expression i.e. = allowed~
  Bit 1=1 NL a valid terminator~
  Bit 2=1 ) a valid terminator~
  Bit 3=1 , a valid terminator~
  Bit 4=1 : a valid terminator~
  Bit 5=1 Bracketed sub-expression i.e. possibly a complex~
          constant.~
  Bit 6=1 Simple expression, i.e. argument, substring and~
          subscripts prohibited.~
  Bit 7=1 Label arguments allowed.~
~
~Q 6
STATUS~
~
 >0   Expression recognised, index into AS stack of root~
      node of expression.~
 <0   Faults detected in expression.~
~
~
REC.NAME()
~0
~BThis procedure accepts a name of up to 6 characters from the itemised line.
Procedure assures next character from itemised line is a valid character
to start a name.~
~
~
REC.CONSTANT(CONSTANT.KIND)STATUS~
~BThis procedure attempts to recognise a constant, optionally signed,
from the itemised line. Prior to calling this procedure the
opening bracket of a complex constant will have already been
accepted from the itemised line, and the parameter
set accordingly to indicate the type of constants that are
contextually valid. If a complex constant is recognised the
closing bracket is checked but not accepted from the itemised line.
~BIf a valid constant is recognised two words are
pushed onto the WS stack.~
~3
~
WORD  0  Type of constant~
         0  Real~
         1  Double precision~
         2  Complex~
         3  Integer~
         4  Logical~
         5  Character~
WORD  1  For non-character constants address of constant~
         entry, and for character constants address~
         of first character of string in itemised line.~
~
~
Parameters:~
~
CONSTANT.KIND~
~
    0 - Any type of constant contextually valid~
    1 - Only complex constants valid~
    2 - Any type but complex valid~
~
STATUS~
~
    0  Constant recognised~
   -1  Constant not recognised~
~
~0
~
REC.ARITH.CONST()STATUS~
~BThis procedure attempts to recognise an integer, real, or a
double precision constant. On successful recognition a two
word entry (for format see REC.CONST above) is pushed onto
the WS stack.~
~BTo ensure an accurate representation of both real and double
precision constants, they are evaluated in the maximum precision possible.~
~
Parameter:~
~
STATUS~
~3
~
    0  Constant recognised~
   -1  Constant not recognised~
~0
~
~
READ.I()INTEGER~
~BReads an unsigned integer from the itemised line and returns its
value. Procedure assumes that next character of itemised line is a digit.~
~P
~MOUTLINE OF OPERATION OF INTERNAL PROCEDURES
~
~
REC.EXPR(EXPR.KIND)STATUS~
~BAn operator precedence algorithm is used to produce
an analysis record for the expression on the AS stack. The WS stack
holds alternating operator operand entries prior to their placement in the
analysis record.
On accepting an operand from the itemised line a
terminal expression node is pushed onto the AS
stack and an index to it pushed onto the WS stack.
On accepting an operator from the itemised line its
precedence is compared with the operator at the top
of the stack, if it is of higher procedure it is
pushed onto the WS stack; otherwise a non-terminal
node is created on the AS stack for the coercion
of the operand, operator, operand triplet at the top
of the WS stack, this triplet is removed and a
pointer to the newly created non-terminal node pushed onto
the WS stack, the comparison action of operators is then
repeated. An operator precedence table controls the
operator action for arithmetic, relational, character and
assignment operator.~
~BAt the start of recognition a special low precedence
operator is pushed onto the WS stack and throughout
recognition the WS stack contains a sequence
of alternating operator operands. On encountering a
bracketed expression REC.EXPR is called and an index
to the analysis record for the subexpression is pushed
onto the WS stack.~
~BA unary plus or minus on input gets replaced by a zero operand
and a plus or minus. Similarly, a unary .NOT. gets
replaced by a .TRUE. operand and a high precedence .NEQV..~
~BREC.EXPR is called recursively to recognise any embedded bracketed subexpressi
on,
subscript lists, parameter lists or substring list.
~T# 31
~
~Q 19
~
~OANALYSIS RECORD EXAMPLES~O~
~3
~
1.    A = B+C*D+E~
~
#|--=--|~
#|     |~
#|     |~
#A  |--+--|~
#   |     |~
#   |     |~
#|--+--|  E~
#|     |~
#|     |~
#B  |--*--|~
#   |     |~
#   |     |~
#   C     D~
~Q 20
~
2.    A = B**(-C*(D+E)/F)~
~
#|--=--|~
#|     |~
#|     |~
#A  |--**--|~
#   |      |~
#   |      |~
#   B   |--/-----|~
#       |        |~
#       |        |~
#   |--*----|    F~
#   |       |~
#   |       |~
#|----|  |--+--|~
#|    |  |     |~
#|    |  |     |~
#0    C  D     E~
~Q 23
~
3.    A = B//C.GE.H.OR.NOT.D.LE.E+F.AND.G~
~
#   |--=--|~
#   |     |~
#   |     |~
#   A  |--.OR.-------|~
#      |             |~
#      |             |~
#   |--.GE.--|    |--.NEQV.--|~
#   |        |    |          |~
#   |        |    |          |~
#|--//--|    H  .TRUE.    |--.AND.--|~
#|      |                 |         |~
#|      |                 |         |~
#B      C              |--.LE.--|   G~
#                      |        |~
#                      |        |~
#                      D     |--+--|~
#                            |     |~
#                            |     |~
#                            E     F~
~Q 17
~
4.   A = B(I+1,J)~
~
#|--=--|~
#|     |~
#|     |~
#A     B(|,|)~
#        | |~
#        | |~
#        | J~
#        |~
#        |~
#     |--+--|~
#     |     |~
#     |     |~
#     I     1~
~0
~P
~M~OOperator procedure table~O
~3
~
~MCURRENT OPERATOR
      ~O                                                        ~O~
     |  |  |  |  |  | R| N| A|  |  |  |  |  | N|EN|  |  |  |  |~
     |  |U |**| *| +| E|HE| N| O| N| =| ,| )| O|QE|//| (| :|U |~
     |~O  |N-|  | /| -| L|PQ| D| R| L|  |  |  | T|VQ|  |  |  |N+~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     |U | 9| 0| 0| 5| 5|10| 5| 5| 5| 6| 5| 5| 6| 5| 6| 7| 5| 9|~
     |~ON-|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     |**| 9| 0| 5| 5| 5|10| 5| 5| 5| 6| 5| 5| 6| 5| 6| 7| 5| 9|~
     |~O  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     | *| 9| 0| 5| 5| 5|10| 5| 5| 5| 6| 5| 5| 6| 5| 6| 7| 5| 9|~
     |~O /|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     | +| 9| 0| 0| 5| 5|10| 5| 5| 5| 6| 5| 5| 6| 5| 6| 7| 5| 9|~
     |~O -|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     | R|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     | E| 0| 0| 0| 0| 6|10| 5| 5| 5| 6| 5| 5| 6| 5| 0| 7| 5| 0|~
     |~O L|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     | N|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     |HE| 0| 0| 0| 0| 0|10| 5| 5| 5| 6| 5| 5| 6| 5| 0| 7| 5| 0|~
     |~OPQ|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     | A|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     | N| 0| 0| 0| 0| 0| 0| 5| 5| 5| 6| 5| 5| 6| 5| 0| 7| 5| 0|~
     |~O D|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     | O| 0| 0| 0| 0| 0| 0| 0| 5| 5| 6| 5| 5| 6| 5| 0| 7| 5| 0|~
     |~O R|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     | [| 0| 0| 0| 0| 0| 0| 0| 0| 1| 0| 3| 2| 6| 0| 0| 7| 4| 0|~
     |~O  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     | =| 0| 0| 0| 0| 0| 0| 0| 0| 8| 6| 6| 6| 6| 0| 0| 7| 6| 0|~
     |~O  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |EN|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     |QE| 0| 0| 0| 0| 0| 0| 0| 0| 5| 6| 5| 5| 6| 5| 0| 7| 5| 0|~
     |~OVQ|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     |//| 6| 6| 6| 6| 5|10| 5| 5| 5| 6| 5| 5| 6| 5| 5| 7| 5| 6|~
     |~O  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
     |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |~
     |U | 9|11|11|11|11|10|11|11|11| 6|11|11| 6|11| 6| 7|11| 9|~
     |~ON+|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  ~O|~
~
UN+     : Plus for processing unary plus.~
UN-     : Minus for processing unary minus.~
HP NEQ  : High precedence non-equivalence for processing~
          unary .NOT..~
[       : Special initial operator at beginning of expression.~
REL     : All relational operators.~
~0
~
The current operator selects the column, and the previous operator on WS selects
the row. The intersection of these determines the action.~
~3
~
    0 - STACK OPERATOR~
        Add an operator entry to WS for the current operator~
    1 - CHECK (NL) TERMINATOR~
    2 - CHECK ( )) TERMINATOR~
    3 - CHECK ( ,) TERMINATOR~
    4 - CHECK ( :) TERMINATOR~
~0
~T% 15
~
~IThe above four codes mean that the previous operator on the WS
stack is the initial operator, and the current operator is,
unless there is a fault, the terminating operator for the
expression. The terminator is checked for validity
against the permitted terminators for the expression.~
~
5 - REMOVE
~
~IThis pops the operand, operator, operand triplet
from the WS stack and creates a non-terminal expression
node on the AS stack, a pointer to this node is pushed
onto the WS stack.~
~
 6 - ILLEGAL USE OF SYMBOL~
 7 - MISPLACED (~
 8 - CHECK =~
~
Check that = occurs in an assignment expression.~
~
 9 - ILLEGAL USE OF UNARY MINUS~
10 - ILLEGAL USE OF UNARY NOT~
11 - REMOVE UNARY PLUS~
~BThis removes the redundant operator and operand entry from the WS
stack which was generated by a previous unary plus. The penultimate
operand (which is a zero) is replaced by the operand from the
top of the WS stack,
then the operand operator entry is removed from the top of the WS
stack.~
~BThe operator precedence table was constructed from an
ordered list of precedences for the operators, and a table showing
which combination of operators is illegal.~
~3
~Q 21
~
~
~
~
**~
*,/~
+,-,UN+,UN-~
~
//~
REL~
HP NEQV~
~
AND~
OR~
EQV,NEQV~
~
=~
~
Operators in descending order of precedence~
~Q 30
~
~
                    CURRENT OPERATOR~
    ~O                                                       ~O~
   |      |  UN+ | **   |      |      |  HP  |AND,OR|      |~
   |      |  UN- | *,/  |  //  |  REL | NEQV | EQV, |  =   |~
   |~O      |      | +,1- |      |      |      | NEQV |      ~O|~
   |  UN+ |      |      |      |      |      |      |      |~
   |  UN- |  I   |      |  I   |      |  I   |      |  I   |~
   |~O      |      |      |      |      |      |      |      ~O|~
P  |  **  |      |      |      |      |      |      |      |~
R  |  *,/ |  I   |      |  I   |      |  I   |      |  I   |~
E  |~O  +,- |      |      |      |      |      |      |      ~O|~
V  |      |      |      |      |      |      |      |      |~
I  |  //  |  I   |  I   |      |      |  I   |      |  I   |~
O  |~O      |      |      |      |      |      |      |      ~O|~
U  |      |      |      |      |      |      |      |      |~
S  |  REL |      |      |      |  I   |  I   |      |  I   |~
   |~O      |      |      |      |      |      |      |      ~O|~
O  |  HP  |      |      |      |      |      |      |      |~
P  | NEQV |      |      |      |      |  I   |      |  I   |~
E  |~O      |      |      |      |      |      |      |      ~O|~
R  |AND,OR|      |      |      |      |      |      |      |~
A  | EQV  |      |      |      |      |      |      |  I   |~
T  |~ONEQV  |      |      |      |      |      |      |      ~O|~
O  |      |      |      |      |      |      |      |      |~
R  |  =   |      |      |      |      |      |      |  I   |~
   |~O      |      |      |      |      |      |      |      ~O|~
~
   I  -  Illegal combination of operators.~
~0
~S1~O3.2 Data Structures~
~T# 11
~
AS~IAnalysis record stack. Note that other sections modify
or extend the analysis record.~
~
STAT.AP.G~IAn index into the analysis record stack AS to the
first element of the analysis record.~
~
END.AP.G~IAn index into AS of the word beyond the stack front.~
~
FSS~IIndex into the itemised line LINE.G to the rightmost
item successfully recognised.~
~S~O3.2 Data Structures
~BReferences to property entries and integers in the analysis record
structures (WS and AS) go via an intermediate table called
PROPS.T.  This is a vector of size PROPS.Z.L of type PROPS.
This type is a union of the following fields~
~3
~
~M:INT      integer of significant length for statement label~
~N          references, repeat counts in DATA, and character~
~N          length specififers.~
~N OR~
~N:ADDRESS  address length integer~
~N OR~
~N:LOC      pointer to local property entry (LOCAL.PROP)~
~N OR~
~N:GLOB     pointer to global property entry (GLOBAL.PROP)~
~N OR~
~N:COM      pointer to common property entry (COMMON.PROP)~
~N OR~
~N:CONST    pointer to constant property entry (CONST.PROP)~
~BPROPS.T acts as a stack, PROPS.I indexes the top of stack
element.  PROPS.I is reset at the start of each line compiled.
~0
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                FTN041
~V9 -1
~F
@TITLE FTN04(1,11)
@COL 1S-5R-6R-7R-2R-3R-4F
@FLOW 1-5-6-7-2-3-4
@BOX 1.0
SYNTAX ANALYSIS

21-DEC-82 ( JM) new release of this module
@BOX 5.0
EXTERNAL ENVIRONMENT
MODULE HEADING
@BOX 6.0
EXPORTED GLOBAL DECLARATIONS
@BOX 7.0
INTERNAL GLOBAL DECLARATIONS
@BOX 2.0
INTERFACE PROCEDURES
4.1: SYNTAX.CHECK
@BOX 3.0
INTERNAL PROCEDURES
4.2: REC.EXPR
4.3: REC.NAME
4.4: REC.CONST
4.5: REC.ARITH.CONST
4.6: READ.I
4.7: READ.REAL
4.8: N.POWER
@BOX 4.0
END
@BOX 1.1
@BOX 5.1
#FTN04/1
;MODULE(SYNTAX.CHECK,AS,WS,DIGIT.STR,FSS,END.SS.G,
       FMT.TABLE,FMT.STRINGS,PROPS,PROPS.T,PROPS.I);
@BOX 6.1
;TYPE PROPS IS
      $IN32 INT OR
      ADDR ADDRESS OR
      ADDR LOCAL.PROP LOC OR
      ADDR GLOBAL.PROP GLOB OR
      ADDR COMMON.PROP COM OR
      ADDR CONST.PROP CONST
;*GLOBAL 2
;PROPS[PROPS.Z.L] PROPS.T
;$IN PROPS.I
;$IN[AS.Z.L] AS
;$IN[WS.Z.L] WS
;$LO8[6] DIGIT.STR
;$IN FSS,END.SS.G
; $IN16[MAX.FMT.TABLE.L] FMT.TABLE
; $LO8 [MAX.FMT.STRINGS.L] FMT.STRINGS
@BOX 7.1
;$RE64 EDP.G,EDP.1.G,EDP.2.G
; *GLOBAL 0
@BOX 2.1
;PSPEC SYNTAX.CHECK($IN,$IN)/$IN
;PROC SYNTAX.CHECK(LP,SK)
;PSPEC REC.EXPR($IN)/$IN
;PSPEC REC.NAME()
;PSPEC REC.CONST($IN)/$IN
;PSPEC REC.ARITH.CONST()/$IN
:: @@@ BCT 30-DEC-82 Start of insert
;PSPEC READ.I(ADDR $IN,$IN)/$IN32
;PSPEC READ.REAL($IN,$IN,$IN,$IN,$IN,$RE64,$IN,$RE64,$IN)
;PSPEC N.POWER($IN,$IN)/$RE64
:: @@@ BCT 30-DEC-82 End of insert
#FTN04.1
@BOX 3.1
#FTN04.2
#FTN04.3
#FTN04.4
#FTN04.5
#FTN04.6
#FTN04.7
#FTN04.8
;END
@BOX 4.1
;*END
@END
@TITLE FTN04/1(1,11)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
EXTERNAL ENVIRONMENT
@BOX 2.0
TYPES
@BOX 3.0
LITERALS
@BOX 4.0
VARIABLES
@BOX 5.0
PROCEDURES
@BOX 6.0
END
@BOX 1.1
@BOX 2.1
; IMPORT TYPE EQUIV.PROP
;TYPE NAME.T IS $AD[$LO8] NAME :: ??? JM 27-DEC-82
;TYPE PROPS;
;TYPE CONST.PROP;
;TYPE LOCAL.PROP;
;TYPE GLOBAL.PROP IS
       ADDR GLOBAL.PROP G.NEXT.P
       NAME.T G.NAME
       $LO8 G.KIND
       $LO16 G.TL.NAME
       ADDR [$LO8] G.ARG.SPEC.P
;TYPE L.ALT.TYPE IS
       ADDR CONST.PROP L.CONST.P OR
       ADDR EQUIV.PROP L.EQT.P
       $IN L.DISP OR
       ADDR [$LO8] L.ARG.SPEC.P
       $LO8 L.INTR.NO
       $LO16 L.CH.RES.NAME
       $LO16 L.SPEC.TL.NAME OR
       ADDR [$IN] L.AS.DUMP
       ADDR [PROPS] L.PROPS.T.DUMP
;TYPE LOCAL.PROP IS
       ADDR LOCAL.PROP L.NEXT.P
       NAME.T L.NAME
       ADDR LOCAL.PROP L.LINK1, L.LINK2
       $LO8 LTYPE
       $LO16 LSPECS, LKIND
       $IN L.LEN
       $LO16 L.TL.NAME
       ADDR [$IN] L.ARR.SPEC.P
       L.ALT.TYPE L.ALT
;TYPE COMMON.PROP IS
       ADDR COMMON.PROP C.NEXT.P
       NAME.T C.NAME
       $LO8 C.KIND
       ADDR LOCAL.PROP C.HEAD, C.TAIL
       ADDR C.SIZE
       ADDR COMMON.PROP C.PREV.P
       $LO8 C.AREA.NO
;TYPE LABEL.PROP IS
       ADDR LABEL.PROP S.NEXT.P
       $LO24 S.NAME
       $LO8 S.KIND
       $LO16 S.LEVEL, S.BLOCK, S.TL.NAME, S.ID
;TYPE CONST.PROP IS
       $IN32 INT.CONST OR
       $RE32 REAL.CONST OR
       $RE64 DP.CONST OR
       $RE32 R.COMP.CONST, I.COMP.CONST OR
       $LO16 LOG.CONST OR
       ADDR[$LO8] CH.CONST OR
       $LO64 T.CONST OR
       $LO8[8] H.CONST
       $LO8 H.PR
@BOX 3.1
;IMPORT LITERAL AS.Z.L,PROPS.Z.L,WS.Z.L,ST.CH.Z.L,LINE.SZ.L,SPACE.L,LINE.SPACE
;IMPORT LITERAL $LO8 MARK.CH.L,MARK.HOL.L,NL.L,CONCAT.CH.L,L.TRUE.L,L.FALSE.L
;IMPORT LITERAL TRUE.CONST.L,FALSE.CONST.L,MAX.FMT.TABLE.L,MAX.FMT.STRINGS.L
:: @@@ BCT 30-DEC-82 Start of insert
;IMPORT LITERAL MAX.R.EXPONENT,MAX.DP.EXPONENT,MIN.R.EXPONENT,MIN.DP.EXPONENT
;IMPORT LITERAL MAX.INT,MIN.INT.D.TEN,MAX.INT.M.TEN,MAX.R.RESOLUTION,MAX.DP.RESO
LUTION
;IMPORT LITERAL $RE64 MAX.R.MANTISSA,MAX.DP.MANTISSA,MIN.R.MANTISSA,MIN.DP.MANTI
SSA
;IMPORT LITERAL $LO64 MAX.LO64.HEX.MASK.L,MAX.LO64.OCT.MASK.L
;IMPORT LITERAL MAX.INT.HEX.MASK.L,MAX.INT.OCT.MASK.L
:: @@@ BCT 30-DEC-82 End of insert
@BOX 4.1
;$IN STAT.AP.G,END.APG
;$LO8 [LINE.SZ.L] LINE.G
;$LO8 [ST.CH.Z.L] ST.CH
;$IN32 F.I.G
;$IN FMT.TBL.SZ.G :: @@@ BCT 30-DEC-82
@BOX 5.1
;LSPEC FIO.C.FORMAT(ADDR[$LO8],ADDR[$IN16],ADDR[$LO8])/$IN16
;PSPEC CHANGE.CONST.TYPE(ADDR CONST.PROP,$IN,$IN)
;PSPEC ADD.L.NAME(ADDR NAME.T)/ADDR LOCAL.PROP
;PSPEC ADD.G.NAME(ADDR NAME.T)/ADDR GLOBAL.PROP
;PSPEC ADD.C.NAME(ADDR NAME.T,$IN)/ADDR COMMON.PROP
;P.SPEC MAKE.CONST.PROP($IN)/ADDR CONST.PROP
;PSPEC FAULT($IN, $IN)
@BOX 6.1
@END
@TITLE FTN04.1(1,11)
@COL 1S-2R-3R-4C-5R-6C-7T-8R-9T-10F
@COL 16N
@COL 30C-31R-32C-33R-19C-20R-13C-14T-17R-18C-15C
@ROW 4-19
@ROW 6-16-13
@ROW 10-15
@FLOW 1-2-3
@FLOW 4-5-16-8-9N-10
@FLOW 6-7N-8
@FLOW 13-14N-17-18
@FLOW 9Y-15
@FLOW 7Y-15
@FLOW 14Y-15
@FLOW 19-20-8
@FLOW 30-31-8
@FLOW 32-33-8
@BOX 1.0
SYNTAX.CHECK(LINE.POS,STAT.KIND)STAT.NO
@BOX 2.0
SYNTAX TABLES
:4.1.1:
@BOX 3.0
SWITCH ON
STATEMENT TYPE
@BOX 4.0
HEADER
@BOX 5.0
SELECT PROGRAM HEADER
STATEMENTS
@BOX 6.0
OTHERS
@BOX 7.0
SELECT SET OF
POSSIBLE STATS
NULL SET?
@BOX 8.0
SCAN[FTN04.1.2]FOR
A STATEMENT
@BOX 9.0
INVALID STATEMENT?
@BOX 10.0
RETURN STATEMENT
NO
@BOX 13.0
ASSIGN-
MENT
@BOX 14.0
REC EXPR[FTN04.2]
FOR ASSIGNMENT
FAIL
@BOX 17.0
SET UP AS
@BOX 18.0
RETURN-
STAT NO
@BOX 15.0
RETURN
-1
@BOX 19.0
DIRECTIVES
@BOX 20.0
SELECT DIRECTIVE
STATEMENTS
@BOX 30.0
DEVIANT
PARAMETER
@BOX 31.0
SELECT PARAMETER
@BOX 32.0
OPTIONS
@BOX 33.0
SELECT OPTIONS
@BOX 1.1
;$IN TOS
;$IN AP,WP,SY,CH,SSS,T,SS,TSS
;$IN TAP,COUNT,I,TEMPWP
;ADDR [$LO8] SYNTAX1
;$IN [512] S
;NAME.T CURNAME
@BOX 2.1
;->PASSED;
#FTN04.1.1
;DATAVEC START.T($IN)
ZA    ZB    ZC    ZD    ZE
ZF    ZG    %FFFF ZI    %FFFF
%FFFF ZL    %FFFF %FFFF ZO
ZP    %FFFF ZR    ZS    %FFFF
%FFFF %FFFF ZW
END
;PASSED:
@BOX 3.1
;LP -1 => SS
;SWITCH SK\
   F4.1B4, F4.1B6, F4.1B13,F4.1B19,F4.1B30,F4.1B32
@BOX 4.1
;F4.1B4:
@BOX 5.1
;PROGRAM.UNIT.HEAD.ST => SY
@BOX 6.1
;F4.1B6:
@BOX 7.1
;IF ST.CH[LINE.G[1+>SS]] => CH > 22 OR
   START.T[CH] => SY = %FFFF
@BOX 8.1
#FTN04.1.2
@BOX 9.1
;IF WS[0] < 0
@BOX 10.1
;AS[STAT.AP.G-1] => SYNTAX.CHECK
;EXIT
@BOX 13.1
;F4.1B13:
@BOX 14.1
;9 => AP
;1 => WP
;IF REC.EXPR(3) => STAT.AP.G < 0
@BOX 17.1
;AP => END.AP.G
::END.SS.G NEED NOT BE SET
@BOX 18.1
;10 => SYNTAX.CHECK
;EXIT
@BOX 15.1
;-1 => SYNTAX.CHECK
;EXIT
@BOX 19.1
;F4.1B19:
@BOX 20.1
;DIRECTIVE=>SY
; 1+>SS
@BOX 30.1
;F4.1B30:  :: @@@ BCT 09-DEC-82
@BOX 31.1
;NEW.PARAMETER=>SY :: @@@ BCT 09-DEC-82
; 1+> SS :: @@@ BCT 09-DEC-82
@BOX 32.1
;F4.1B32:
@BOX 33.1
; OPTIONS => SY
@END
@TITLE FTN04.1.1(1,11)
@COL 1S
@FLOW 1
@BOX 1.0
BEGIN SYNTAX SPEC
DELIMITERS
END
PROCEDURE NAMES NONAMES


COSYNE NAMES#
NLS,#
INTEGA,#
S.INTEGER,#
HEX,#
NAME,#
EXPR,#
REP.I.COMMA,#
REP.I.COMMA.LETTER,#
IN.LETTER,#
OPT,#
NEG.IN,#
SET.LIST.CNT,#
CONSTANT,#
REPEAT.IF.NOT.DO.VAR,#
CHAR.CONST,#
COPY,#
SET.UP,#
CHECK.NO.SPEC,#
FORMAT.SPEC,#
SLASH.SLASH,#
DIGIT.STRING,#
SKIP.TO.COMMA



*SYNE<ZA>=#
  SSIGN<INTEGA>TO<NAME(1)><NLS(22)>


*SYNE<ZB>=#
  ACKSPACE<IN(1)><RBE.STATEMENT><NLS(20)>!#
  YTE<IN(3)><IN(0)><DECL.LIST><NLS(1)>

SYNE<BND.DECLS>=#
    (<BND.DECL><REP.I.COMMA(3)>)<UP>


SYNE<BND.DECL>=#
   [<EXPR(%5C)>[:[<EXPR(%5C)>!*<IN(1)>]!<IN(0)>]!#
  *<IN(1)><IN(0)>]<UP>


*SYNE<ZC>=#
  ONTINUE<NLS(17)>!#
  ALL<EXPR(%82)><NLS(16)>!#
  OMMON[/<NAME(2)>/!<SLASH.SLASH><IN(0)>!<IN(0)>]<COMMON.DECL.LIST>#
  <COMMON.LIST><NLS(3)>!#
  OMPLEX<IN(2)><COMPLEX.SIZES><DECL.LIST><NLS(1)>!#
  HARACTER<IN(5)>[<LENGTH.SPEC><OPT(",")>!<IN(0)>]#
      <CHAR.DECL>[/<DATA.C.LIST>/!<IN(0)>]<REP.I.COMMA(16)><NLS(1)>!#
  LOSE<SET.UP(4)>(<CLOSE.LIST>)<NLS(41)>

SYNE<COMPLEX.SIZES>=[*8<IN(3)>!<NEGIN>]<UP>

SYNE<CHAR.DECL>=<DECL>[<LENGTH.SPEC>!<IN(0)>]<UP>


SYNE<COMMON.LIST>=#
     <OPT(",")>[/<NAME(2)>/!<SLASH.SLASH><IN(0)>]<COMMON.DECL.LIST>#
  <COMMON.LIST><UP>!<IN(2)><UP>


SYNE<COMMON.DECL.LIST>=<DECL><REP.I.COMMA.LETTER(3)><NOVAL>


SYNE<CLOSE.LIST>=<CHECK.NO.SPEC><UNIT.ID><COPY(4)>#
  [,<CLOSE.SPEC.LIST><UP>!<UP>]!<CLOSE.SPEC.LIST><UP>


SYNE<CLOSE.SPEC.LIST>=<CLOSE.SPEC.LIST.ITEM><REP.I.COMMA(3)><UP>


SYNE<CLOSE.SPEC.LIST.ITEM>=[<SPEC.UNIT><COPY(4)>!#
  <SPEC.ERR><COPY(3)>!<SPEC.STATUS><COPY(2)>!#
  <SPEC.IO.STAT><COPY(1)>]<UP>

#FTN04.1.1.2
@BOX 1.1
LITERAL ZA=4;
LITERAL ZB=24;
LITERAL ZC=105;
LITERAL ZD=393;
LITERAL ZE=774;
LITERAL ZF=1017;
LITERAL ZG=1042;
LITERAL ZI=1093;
LITERAL ZL=1686;
LITERAL ZO=1777;
LITERAL ZP=1935;
LITERAL NEWPARAMETER=2013;
LITERAL PROGRAMUNITHEADST=2038;
LITERAL ZR=2188;
LITERAL ZS=2706;
LITERAL ZW=3095;
LITERAL DIRECTIVE=3112;
LITERAL OPTIONS=3421;
DATAVEC SYNTAX($LO8)
0 2 5 6 1 'S 1 'S 1 'I 1 'G 1 'N 11 0 1 'T 1 'O
14 1 10 22 0 25 1 'A 1 'C 1 'K 1 'S 1 'P 1 'A 1 'C
1 'E 9 1 2 8 244 10 20 1 'Y 1 'T 1 'E 9 3 9 0 2
2 113 10 1 1 '( 2 0 74 16 3 1 ') 4 0 24 15 %5C 0 16
1 ': 0 6 15 %5C 3 6 1 '* 9 1 3 4 9 0 3 8 1 '*
9 1 9 0 4 0 18 1 'O 1 'N 1 'T 1 'I 1 'N 1 'U 1
'E 10 17 0 12 1 'A 1 'L 1 'L 15 %82 10 16 0 40 1 'O 1
'M 1 'M 1 'O 1 'N 0 10 1 '/ 14 2 1 '/ 3 12 0 8 29
0 9 0 3 4 9 0 2 1 67 2 1 39 10 3 0 24 1 'O 1
'M 1 'P 1 'L 1 'E 1 'X 9 2 2 1 13 2 2 113 10 1 0
51 1 'H 1 'A 1 'R 1 'A 1 'C 1 'T 1 'E 1 'R 9 5 0
9 2 6 205 19 "," 3 4 9 0 2 1 26 0 11 1 '/ 2 2 49
1 '/ 3 4 9 0 16 16 10 1 1 'L 1 'O 1 'S 1 'E 26 4
1 '( 2 1 74 1 ') 10 41 0 10 1 '* 1 '8 9 3 3 4 20
0 4 2 2 132 0 7 2 6 205 3 4 9 0 4 0 25 19 "," 0
10 1 '/ 14 2 1 '/ 3 6 29 0 9 0 2 1 67 2 1 39 4
9 2 4 2 2 132 17 3 8 0 0 20 27 0 2 12 12 25 4 0
10 1 ', 2 1 98 4 3 3 4 2 1 98 4 2 1 104 16 3 4
0 9 2 10 210 25 4 3 25 0 9 2 10 224 25 3 3 16 0 9
#FTN04.1.1.2
@END
@TITLE FTN04.1.1.2(1,11)
@COL 1S
@FLOW 1
@BOX 1.0

*SYNE<ZD>=#
  O<INTEGA><OPT(",")><NAME(1)>=#
    <EXPR(%8)>,<EXPR(%A)>[,<EXPR(%2)>!<NEGIN>]<NLS(7)>!#
  IMENSION<DIMENSION.DECL>[/<DATA.C.LIST>/!<IN(0)>]<REP.I.COMMA(16)><NLS(2)>!#
  OUBLEPRECISION<IN(1)><DP.SIZES><DECL.LIST><NLS(1)>!#
  ATA<DATA.N.LIST>/<DATA.C.LIST>/<DATA.LISTS><NEGIN><NLS(8)>!#
  ECODE<IN(2)>(<ENDECODE.LIST>)<IN(0)>[<RWP.IO.LIST>!<IN(0)>]<NLS(19)>

SYNE<DP.SIZES>=<NEGIN><UP>

SYNE<DATA.C.LIST>=<DATA.C.LIST.ITEM><REP.I.COMMA(3)><NOVAL>


SYNE<DATA.C.LIST.ITEM>=[<INTEGA>*<IN(0)>!<NAME(1)>*<IN(1)>!<IN(1)><IN(0)>]#
  [<CONSTANT>!<IN(9)><NAME(1)>]<UP>


SYNE<DATA.ITEM>=<NAME(1)>[(<NEGIN><EXPR(%C)><REP.I.COMMA(2)><SET.LIST.CNT>)!<IN(
0)>]<NOVAL>


SYNE<DECL.LIST>=<DECL>[/<DATA.C.LIST>/!<IN(0)>]<REP.I.COMMA(16)><UP>

SYNE<DECL>=<NAME(1)>[<BND.DECLS><VAL(1)>!<VAL(0)>]

SYNE<DIMENSION.DECL>=<NAME(1)><BND.DECLS><NOVAL>

SYNE<DATA.LISTS>=<OPT(",")><DATA.N.LIST>/<DATA.C.LIST>/<DATA.LISTS><UP>!<UP>


SYNE<DATA.N.LIST>=<DATA.N.LIST.ITEM><REP.I.COMMA(3)><NOVAL>


SYNE<DATA.N.LIST.ITEM>=[<NAME(1)>[<S.SUBSCRIPT>!<IN(0)>][<S.SUBSTRING>!<IN(0)>]!
#
  <DATA.DO>]<NOVAL>


SYNE<DATA.DO>=(<IN(0)><DATA.DO.LIST><NAME(1)>=#
  <EXPR(%4C)>,<EXPR(%4C)>[,<EXPR(%4C)>!<NEGIN>])<UP>


SYNE<DATA.DO.LIST>=<DATA.DO.LIST.ITEM>,<REPEAT.IF.NOT.DO.VAR(5)><NOVAL>


SYNE<DATA.DO.LIST.ITEM>=[<NAME(1)><S.SUBSCRIPT><IN(0)>!<DATA.DO>]<NOVAL>


*SYNE<ZE>=#
  LSE[<NLS(38)>!IF(<EXPR(%4)>)THEN<NLS(37)>]!#
  ND[IF<NLS(39)>!<NLS(9)>]!#
  XTERNAL<NAME(1)><REP.I.COMMA(2)><NLS(5)>!#
  QUIVALENCE<EQUIV.LISTS><NLS(4)>!#
  NTRY<SUBR.SPEC><NLS(34)>!#
  NDFILE<IN(2)><RBE.STATEMENT><NLS(20)>!#
  NCODE<IN(3)>(<ENDECODE.LIST>)<IN(1)>[<RWP.IO.LIST>!<IN(0)>]<NLS(19)>

SYNE<EQUIV.LISTS>=(<EQUIV.LIST>)<REP.I.COMMA(7)><UP>


SYNE<EQUIV.LIST>=<EQUIV.ITEM>,<EQUIV.ITEM><REP.I.COMMA(3)><NOVAL>


SYNE<EQUIV.ITEM>=<NAME(1)>[<S.SUBSCRIPT>!<IN(0)>][<S.SUBSTRING>!<IN(0)>]<UP>

SYNE<ENDECODE.LIST>=<SET.UP(6)><EXPR(%C)><COPY(4)>,<EXPR(%E)><COPY(5)>#
      ,<EXPR(%E)><COPY(6)>[,<SPEC.ERR><COPY(2)><UP>!<UP>]

*SYNE<ZF>=#
ORMAT<FORMAT.SPEC><VAL(6)>


SYNE<FMT.ID>=[*<IN(0)>!<EXPR(%E)>]<UP>


*SYNE<ZG>=#
  OTO[<INTEGA><NLS(13)>!#
    (<LABEL.LIST>)<OPT(",")><EXPR(%2)><NLS(11)>!#
    <NAME(1)>[<OPT(",")>(<INTEGA><REP.I.COMMA(2)>)!<NEGIN>]]<NLS(12)>

#FTN04.1.1.3
@BOX 1.1
2 10 253 25 2 3 7 2 10 235 25 1 4 0 30 1 'O 11 0 19
"," 14 1 1 '= 15 %8 1 ', 15 %A 0 8 1 ', 15 %2 3 4 20
0 10 7 0 38 1 'I 1 'M 1 'E 1 'N 1 'S 1 'I 1 'O 1
'N 2 2 145 0 11 1 '/ 2 2 49 1 '/ 3 4 9 0 16 16 10
2 0 40 1 'O 1 'U 1 'B 1 'L 1 'E 1 'P 1 'R 1 'E 1
'C 1 'I 1 'S 1 'I 1 'O 1 'N 9 1 2 2 46 2 2 113 10
1 0 25 1 'A 1 'T 1 'A 2 2 171 1 '/ 2 2 49 1 '/ 2
2 152 20 0 10 8 1 'E 1 'C 1 'O 1 'D 1 'E 9 2 1 '(
2 3 218 1 ') 9 0 0 7 2 10 0 3 4 9 0 10 19 20 0
4 2 2 56 16 3 8 0 0 10 11 0 1 '* 9 0 3 16 0 10
14 1 1 '* 9 1 3 6 9 1 9 0 0 6 22 0 3 6 9 9
14 1 4 14 1 0 16 1 '( 20 0 15 %C 16 2 21 0 1 ') 3
4 9 0 8 0 2 2 132 0 11 1 '/ 2 2 49 1 '/ 3 4 9
0 16 16 4 14 1 0 9 2 0 64 7 1 3 4 7 0 14 1 2
0 64 8 0 0 18 19 "," 2 2 171 1 '/ 2 2 49 1 '/ 2 2
152 4 4 2 2 178 16 3 8 0 0 24 14 1 0 7 2 11 40 3
4 9 0 0 7 2 11 54 3 4 9 0 3 5 2 2 207 8 0 1
'( 9 0 2 2 237 14 1 1 '= 15 %4C 1 ', 15 %4C 0 8 1 ',
15 %4C 3 4 20 0 1 ') 4 2 2 246 1 ', 23 5 8 0 0 11
14 1 2 11 40 9 0 3 5 2 2 207 8 0 0 34 1 'L 1 'S
1 'E 0 6 10 38 3 22 1 'I 1 'F 1 '( 15 %4 1 ') 1 'T
1 'H 1 'E 1 'N 10 37 0 18 1 'N 1 'D 0 10 1 'I 1 'F
10 39 3 4 10 9 0 22 1 'X 1 'T 1 'E 1 'R 1 'N 1 'A
1 'L 14 1 16 2 10 5 0 27 1 'Q 1 'U 1 'I 1 'V 1 'A
1 'L 1 'E 1 'N 1 'C 1 'E 2 3 175 10 4 0 15 1 'N 1
'T 1 'R 1 'Y 2 11 78 10 34 0 21 1 'N 1 'D 1 'F 1 'I
1 'L 1 'E 9 2 2 8 244 10 20 1 'N 1 'C 1 'O 1 'D 1
'E 9 3 1 '( 2 3 218 1 ') 9 1 0 7 2 10 0 3 4 9
0 10 19 1 '( 2 3 185 1 ') 16 7 4 2 3 197 1 ', 2 3
197 16 3 8 0 14 1 0 7 2 11 40 3 4 9 0 0 7 2 11
54 3 4 9 0 4 26 6 15 %C 25 4 1 ', 15 %E 25 5 1 ',
15 %E 25 6 0 12 1 ', 2 10 224 25 2 4 3 3 4 1 'O 1
'R 1 'M 1 'A 1 'T 28 0 7 6 0 8 1 '* 9 0 3 4 15
%E 4 1 'O 1 'T 1 'O 0 8 11 0 10 13 3 37 0 17 1 '(
#FTN04.1.1.3
@END
@TITLE FTN04.1.1.3(1,11)
@COL 1S
@FLOW 1
@BOX 1.0

*SYNE<ZI>=#
  F(<EXPR(%4)>)[<INTEGA>,<INTEGA>,<INTEGA><NLS(15)>!THEN<NLS(36)>!#
    <VAL(14)>]!#
  NTEGER<IN(3)><INTEGER.SIZES><DECL.LIST><NLS(1)>!#
  NTRINSIC<NAME(1)><REP.I.COMMA(2)><NLS(30)>!#
  MPLICIT<IMPLICIT.LIST><REP.I.COMMA(3)><NLS(31)>!#
  NQUIRE<SET.UP(18)>(<INQUIRE.LIST>)<NLS(42)>

SYNE<INTEGER.SIZES>=[*1<IN(0)>!*2<IN(1)>!*4<IN(2)>!<NEGIN>]<UP>

SYNE<INQUIRE.LIST>=<CHECK.NO.SPEC><UNIT.ID><COPY(18)>#
  [,<INQUIRE.SPEC.LIST><UP>!<UP>]!<INQUIRE.SPEC.LIST><UP>


SYNE<INQUIRE.SPEC.LIST>=<INQUIRE.SPEC.LIST.ITEM><REP.I.COMMA(3)><UP>


SYNE<INQUIRE.SPEC.LIST.ITEM>=[<SPEC.UNIT><COPY(18)>!#
  <SPEC.FILE><COPY(17)>!#
  <SPEC.ERR><COPY(16)>!#
  <SPEC.IO.STAT><COPY(15)>!#
  EXIST=<DATA.ITEM><COPY(14)>!#
  OPENED=<DATA.ITEM><COPY(13)>!#
  NUMBER=<DATA.ITEM><COPY(12)>!#
  NAMED=<DATA.ITEM><COPY(11)>!#
  NAME=<DATA.ITEM><COPY(10)>!#
<INQUIRE.SPEC.LIST.ITEM.CONT>]<UP>


SYNE<INQUIRE.SPEC.LIST.ITEM.CONT>=[#
  ACCESS=<DATA.ITEM><COPY(9)>!#
  SEQUENTIAL=<DATA.ITEM><COPY(8)>!#
  DIRECT=<DATA.ITEM><COPY(7)>!#
  FORMATTED=<DATA.ITEM><COPY(6)>!#
  FORM=<DATA.ITEM><COPY(5)>!#
  UNFORMATTED=<DATA.ITEM><COPY(4)>!#
  RECL=<DATA.ITEM><COPY(3)>!#
  NEXTREC=<DATA.ITEM><COPY(2)>!#
  BLANK=<DATA.ITEM><COPY(1)>]<UP>


SYNE<IMPLICIT.LIST>=<TYPE>(<IMPLICIT.ITEM>#
  <REP.I.COMMA(3)>)<NOVAL>


SYNE <IMPLICIT.ITEM>=<IN.LETTER>[-<IN.LETTER>!<IN(0)>]<UP>

*SYNE<ZL>=#
  OGICAL<IN(4)><LOGICAL.SIZES><DECL.LIST><NLS(1)>

SYNE<LOGICAL.SIZES>=[*1<IN(0)>!*2<IN(1)>!*4<IN(2)>!<NEGIN>]<UP>

SYNE<LENGTH.SPEC>=*[<INTEGA><VAL(1)>!(*)<VAL(0)>!#
  (<EXPR(%44)>)<VAL(2)>]


SYNE <LABEL.LIST>=<INTEGA><REP.I.COMMA(2)><NOVAL>


*SYNE<ZO>=#
  PEN<SET.UP(9)>(<OPEN.LIST>)<NLS(40)>


SYNE<OPEN.LIST>=<CHECK.NO.SPEC><UNIT.ID><COPY(9)>#
  [,<OPEN.SPEC.LIST><UP>!<UP>]!<OPEN.SPEC.LIST><UP>


SYNE<OPEN.SPEC.LIST>=<OPEN.SPEC.LIST.ITEM><REP.I.COMMA(3)><UP>


SYNE<OPEN.SPEC.LIST.ITEM>=[<SPEC.UNIT><COPY(9)>!#
  <SPEC.ERR><COPY(8)>!#
  <SPEC.FILE><COPY(7)>!#
  <SPEC.STATUS><COPY(6)>!#
  ACCESS=<EXPR(%C)><COPY(5)>!#
  FORM=<EXPR(%C)><COPY(4)>!#
  <SPEC.RECL><COPY(3)>!#
  BLANK=<EXPR(%C)><COPY(2)>!#
  <SPEC.IO.STAT><COPY(1)>]<UP>

#FTN04.1.1.4
@BOX 1.1
2 6 235 1 ') 19 "," 15 %2 10 11 3 20 14 1 0 14 19 "," 1
'( 11 0 16 2 1 ') 3 4 20 0 10 12 0 42 1 'F 1 '( 15
%4 1 ') 0 16 11 0 1 ', 11 0 1 ', 11 0 10 15 3 18 0
14 1 'T 1 'H 1 'E 1 'N 10 36 3 4 7 14 0 24 1 'N 1
'T 1 'E 1 'G 1 'E 1 'R 9 3 2 4 205 2 2 113 10 1 0
24 1 'N 1 'T 1 'R 1 'I 1 'N 1 'S 1 'I 1 'C 14 1 16
2 10 30 0 23 1 'M 1 'P 1 'L 1 'I 1 'C 1 'I 1 'T 2
6 123 16 3 10 31 1 'N 1 'Q 1 'U 1 'I 1 'R 1 'E 26 18
1 '( 2 4 238 1 ') 10 42 0 10 1 '* 1 '1 9 0 3 24 0
10 1 '* 1 '2 9 1 3 14 0 10 1 '* 1 '4 9 2 3 4 20
0 4 0 20 27 0 2 12 12 25 18 0 10 1 ', 2 5 6 4 3
3 4 2 5 6 4 2 5 12 16 3 4 0 9 2 10 210 25 18 3
139 0 9 2 11 14 25 17 3 130 0 9 2 10 224 25 16 3 121 0
9 2 10 235 25 15 3 112 0 21 1 'E 1 'X 1 'I 1 'S 1 'T
1 '= 2 2 91 25 14 3 91 0 23 1 'O 1 'P 1 'E 1 'N 1
'E 1 'D 1 '= 2 2 91 25 13 3 68 0 23 1 'N 1 'U 1 'M
1 'B 1 'E 1 'R 1 '= 2 2 91 25 12 3 45 0 21 1 'N 1
'A 1 'M 1 'E 1 'D 1 '= 2 2 91 25 11 3 24 0 19 1 'N
1 'A 1 'M 1 'E 1 '= 2 2 91 25 10 3 5 2 5 159 4 0
23 1 'A 1 'C 1 'C 1 'E 1 'S 1 'S 1 '= 2 2 91 25 9
3 198 0 31 1 'S 1 'E 1 'Q 1 'U 1 'E 1 'N 1 'T 1 'I
1 'A 1 'L 1 '= 2 2 91 25 8 3 167 0 23 1 'D 1 'I 1
'R 1 'E 1 'C 1 'T 1 '= 2 2 91 25 7 3 144 0 29 1 'F
1 'O 1 'R 1 'M 1 'A 1 'T 1 'T 1 'E 1 'D 1 '= 2 2
91 25 6 3 115 0 19 1 'F 1 'O 1 'R 1 'M 1 '= 2 2 91
25 5 3 96 0 33 1 'U 1 'N 1 'F 1 'O 1 'R 1 'M 1 'A
1 'T 1 'T 1 'E 1 'D 1 '= 2 2 91 25 4 3 63 0 19 1
'R 1 'E 1 'C 1 'L 1 '= 2 2 91 25 3 3 44 0 25 1 'N
1 'E 1 'X 1 'T 1 'R 1 'E 1 'C 1 '= 2 2 91 25 2 3
19 1 'B 1 'L 1 'A 1 'N 1 'K 1 '= 2 2 91 25 1 4 2
11 117 1 '( 2 6 137 16 3 1 ') 8 0 18 0 0 8 1 '- 18
0 3 4 9 0 4 1 'O 1 'G 1 'I 1 'C 1 'A 1 'L 9 4
2 6 172 2 2 113 10 1 0 10 1 '* 1 '1 9 0 3 24 0 10
1 '* 1 '2 9 1 3 14 0 10 1 '* 1 '4 9 2 3 4 20 0
4 1 '* 0 8 11 0 7 1 3 22 0 12 1 '( 1 '* 1 ') 7
0 3 10 1 '( 15 %44 1 ') 7 2 11 0 16 2 8 0 1 'P 1
'E 1 'N 26 9 1 '( 2 7 2 1 ') 10 40 0 20 27 0 2 12
12 25 9 0 10 1 ', 2 7 26 4 3 3 4 2 7 26 4 2 7
32 16 3 4 0 9 2 10 210 25 9 3 103 0 9 2 10 224 25 8
3 94 0 9 2 11 14 25 7 3 85 0 9 2 10 253 25 6 3 76
0 22 1 'A 1 'C 1 'C 1 'E 1 'S 1 'S 1 '= 15 %C 25 5
3 54 0 18 1 'F 1 'O 1 'R 1 'M 1 '= 15 %C 25 4 3 36
0 9 2 11 27 25 3 3 27 0 20 1 'B 1 'L 1 'A 1 'N 1
'K 1 '= 15 %C 25 2 3 7 2 10 235 25 1 4 0 19 1 'R 1
#FTN04.1.1.4
@END
@TITLE FTN04.1.1.4(1,11)
@COL 1S
@FLOW 1
@BOX 1.0

*SYNE<ZP>=#
  RINT<IN(1)><SET.UP(6)><RWP.SHORT.FORM><NLS(19)>!#
  ARAMETER(<IN(0)><PARAM.LIST.ITEM><REP.I.COMMA(3)>)<NLS(33)>!#
  AUSE[<IN(3)><DIGIT.STRING>!<IN(3)><CHAR.CONST>!<IN(2)>]<NLS(28)>

*SYNE<NEW.PARAMETER>=ARAMETER<IN(1)><NEW.PARAM.LIST.ITEM><REP.I.COMMA(3)><NLS(33
)>

*SYNE<PROGRAM.UNIT.HEAD.ST>=#
  [<TYPE>!<IN(6)>]FUNCTION<NAME(0)>([<NAME(1)><REP.I.COMMA(2)>!<NEGIN>])<NLS(24)
>!#
  SUBROUTINE<IN(7)><SUBR.SPEC><NLS(24)>!#
  BLOCKDATA[<NAME(0)>!<IN(0)>]<NLS(25)>!#
  PROGRAM<NAME(0)><NLS(35)>!#
  *END<NLS(23)>

SYNE<NEW.PARAM.LIST.ITEM>=<NAME(1)>=<EXPR(%4A)><NOVAL>

SYNE<PARAM.LIST.ITEM>=<NAME(1)>=<EXPR(%4C)><NOVAL>


*SYNE<ZR>=#
  EAL<IN(0)><REAL.SIZES><DECL.LIST><NLS(1)>!#
  ETURN[<EXPR(%2)>!<NEGIN>]<NLS(18)>!#
  EAD<IN(0)><SET.UP(6)>[<RWP.LONG.FORM>!<RWP.SHORT.FORM>]<NLS(19)>!#
  EWIND<IN(0)><RBE.STATEMENT><NLS(20)>

SYNE<REAL.SIZES>=[*4<IN(2)>!*8<IN(3)>!<NEGIN>]<UP>

SYNE<RBE.STATEMENT>=<SET.UP(3)>[<UNIT.ID><COPY(3)>!#
  (<RBE.LIST>)]<UP>


SYNE<RBE.LIST>=<CHECK.NO.SPEC><UNIT.ID><COPY(3)>#
  [,<RBE.SPEC.LIST><UP>!<UP>]!<RBE.SPEC.LIST><UP>


SYNE<RBE.SPEC.LIST>=<RBE.SPEC.LIST.ITEM><REP.I.COMMA(3)><UP>


SYNE<RBE.SPEC.LIST.ITEM>=[<SPEC.UNIT><COPY(3)>!#
  <SPEC.ERR><COPY(2)>!#
  <SPEC.IO.STAT><COPY(1)>]<UP>


SYNE<RWP.LONG.FORM>=(<RWP.C.LIST>)[<RWP.IO.LIST>!<IN(0)>]<UP>

SYNE<RWP.SHORT.FORM>=<FMT.ID><COPY(5)><IN(0)>[,<RWP.IO.LIST>!<IN(0)>]<UP>

SYNE<RWP.C.LIST>=#
 <CHECK.NO.SPEC><UNIT.ID><COPY(6)>#
   [,[<CHECK.NO.SPEC><FMT.ID><COPY(5)>#
        [,<RWP.C.SPEC.LIST><IN(1)><UP>#
        !<IN(1)><UP>]#
     !<RWP.C.SPEC.LIST><IN(1)><UP>]#
   !'<EXPR(%C)><COPY(4)><RW.IBM.LIST><IN(2)><UP>#
   !<IN(1)><UP>]#
 !<RWP.C.SPEC.LIST><IN(1)><UP>


SYNE<RWP.C.SPEC.LIST>=<RWP.C.SPEC.LIST.ITEM>[,<RWP.C.SPEC.LIST><UP>!<UP>]


SYNE<RWP.C.SPEC.LIST.ITEM>=[FMT=<FMT.ID><COPY(5)>!#
  <SPEC.UNIT><COPY(6)>!#
  REC=<EXPR(%C)><COPY(4)>!#
  END=<INTEGA><COPY(3)>!#
  <SPEC.ERR><COPY(2)>!#
  <SPEC.IO.STAT><COPY(1)>]<UP>


SYNE<RWP.IO.LIST>=<RWP.IO.LIST.ITEM><REP.I.COMMA(3)><NOVAL>


SYNE<RWP.IO.LIST.ITEM>=[<EXPR(%E)>!<RWP.DO>]<NOVAL>


SYNE<RWP.DO>=(<IN(0)><RWP.DO.LIST><NAME(1)>=#
  <EXPR(%C)>,<EXPR(%C)>[,<EXPR(%C)>!<NEGIN>])<UP>


SYNE<RWP.DO.LIST>=<RWP.DO.LIST.ITEM>,<REPEAT.IF.NOT.DO.VAR(5)><NOVAL>


SYNE<RWP.DO.LIST.ITEM>=[<EXPR(%C)>!<RWP.DO>]<NOVAL>

SYNE<RW.IBM.LIST>=#
  [,[<CHECK.NO.SPEC><FMT.ID><COPY(5)>#
       [,<RW.IBM.SPEC.LIST><UP>#
       !<UP>]#
    !<RW.IBM.SPEC.LIST><UP>]#
   !<UP>]

SYNE<RW.IBM.SPEC.LIST>=<RW.IBM.SPEC.LIST.ITEM>[,<RW.IBM.SPEC.LIST><UP>!<UP>]

SYNE<RW.IBM.SPEC.LIST.ITEM>=[END=<INTEGA><COPY(3)>!<SPEC.ERR><COPY(2)>!#
                            <SPEC.IO.STAT><COPY(1)>]<UP>
#FTN04.1.1.5
@BOX 1.1
'I 1 'N 1 'T 9 1 26 6 2 9 78 10 19 0 31 1 'A 1 'R
1 'A 1 'M 1 'E 1 'T 1 'E 1 'R 1 '( 9 0 2 8 132 16
3 1 ') 10 33 1 'A 1 'U 1 'S 1 'E 0 8 9 3 30 0 3
12 0 8 9 3 24 0 3 4 9 2 10 28 1 'A 1 'R 1 'A 1
'M 1 'E 1 'T 1 'E 1 'R 9 1 2 8 124 16 3 10 33 0 45
0 7 2 11 117 3 4 9 6 1 'F 1 'U 1 'N 1 'C 1 'T 1
'I 1 'O 1 'N 14 0 1 '( 0 8 14 1 16 2 3 4 20 0 1
') 10 24 0 29 1 'S 1 'U 1 'B 1 'R 1 'O 1 'U 1 'T 1
'I 1 'N 1 'E 9 7 2 11 78 10 24 0 30 1 'B 1 'L 1 'O
1 'C 1 'K 1 'D 1 'A 1 'T 1 'A 0 6 14 0 3 4 9 0
10 25 0 20 1 'P 1 'R 1 'O 1 'G 1 'R 1 'A 1 'M 14 0
10 35 1 '* 1 'E 1 'N 1 'D 10 23 14 1 1 '= 15 %4A 8 0
14 1 1 '= 15 %4C 8 0 0 18 1 'E 1 'A 1 'L 9 0 2 8
221 2 2 113 10 1 0 22 1 'E 1 'T 1 'U 1 'R 1 'N 0 6
15 %2 3 4 20 0 10 18 0 24 1 'E 1 'A 1 'D 9 0 26 6
0 7 2 9 61 3 5 2 9 78 10 19 1 'E 1 'W 1 'I 1 'N
1 'D 9 0 2 8 244 10 20 0 10 1 '* 1 '4 9 2 3 14 0
10 1 '* 1 '8 9 3 3 4 20 0 4 26 3 0 9 2 12 12 25
3 3 9 1 '( 2 9 7 1 ') 4 0 20 27 0 2 12 12 25 3
0 10 1 ', 2 9 31 4 3 3 4 2 9 31 4 2 9 37 16 3
4 0 9 2 10 210 25 3 3 16 0 9 2 10 224 25 2 3 7 2
10 235 25 1 4 1 '( 2 9 97 1 ') 0 7 2 10 0 3 4 9
0 4 2 4 7 25 5 9 0 0 9 1 ', 2 10 0 3 4 9 0
4 0 66 27 0 2 12 12 25 6 0 38 1 ', 0 26 27 0 2 4
7 25 5 0 12 1 ', 2 9 169 9 1 4 3 5 9 1 4 3 8
2 9 169 9 1 4 3 21 0 16 1 '' 15 %C 25 4 2 10 68 9
2 4 3 5 9 1 4 2 9 169 9 1 4 2 9 183 0 10 1 ',
2 9 169 4 3 3 4 0 17 1 'F 1 'M 1 'T 1 '= 2 4 7
25 5 3 57 0 9 2 10 210 25 6 3 48 0 16 1 'R 1 'E 1
'C 1 '= 15 %C 25 4 3 32 0 16 1 'E 1 'N 1 'D 1 '= 11
0 25 3 3 16 0 9 2 10 224 25 2 3 7 2 10 235 25 1 4
2 10 7 16 3 8 0 0 6 15 %E 3 5 2 10 18 8 0 1 '(
9 0 2 10 48 14 1 1 '= 15 %C 1 ', 15 %C 0 8 1 ', 15
%C 3 4 20 0 1 ') 4 2 10 57 1 ', 23 5 8 0 0 6 15
%C 3 5 2 10 18 8 0 0 32 1 ', 0 22 27 0 2 4 7 25
5 0 10 1 ', 2 10 101 4 3 3 4 3 6 2 10 101 4 3 3
4 2 10 115 0 10 1 ', 2 10 101 4 3 3 4 0 16 1 'E 1
'N 1 'D 1 '= 11 0 25 3 3 16 0 9 2 10 224 25 2 3 7
#FTN04.1.1.5
@END
@TITLE FTN04.1.1.5(1,11)
@COL 1S
@FLOW 1
@BOX 1.0

*SYNE<ZS>=#
   AVE[<SAVE.ITEM><REP.I.COMMA(3)>!#
    <NEGIN>]<NLS(32)>!#
  TOP[<IN(1)><DIGIT.STRING>!<IN(1)><CHAR.CONST>!<IN(0)>]<NLS(21)>

SYNE <SAVE.ITEM>=[<NAME(1)><IN(0)>!/<NAME(2)>/<IN(1)>]<UP>



SYNE<SPEC.UNIT>=UNIT=<UNIT.ID><UP>


SYNE<SPEC.ERR>=ERR=<INTEGA><UP>


SYNE<SPEC.IO.STAT>=IOSTAT=<DATA.ITEM><UP>


SYNE<SPEC.STATUS>=STATUS=<EXPR(%C)><UP>


SYNE<SPEC.FILE>=FILE=<EXPR(%C)><UP>


SYNE<SPEC.RECL>=RECL=<EXPR(%C)><UP>


SYNE<S.SUBSCRIPT>=(<NEGIN><EXPR(%4C)><REP.I.COMMA(2)><SET.LIST.CNT>)<NOVAL>


SYNE<S.SUBSTRING>=([<EXPR(%5C)>!<IN(0)>]:#
  [<EXPR(%44)>!<IN(0)>])<NOVAL>


SYNE<SUBR.SPEC>=<NAME(0)>#
   [(<SUBR.ARG><REP.I.COMMA(3)>)!#
  ()<NEGIN>!<NEGIN>]<UP>



SYNE<SUBR.ARG>=[<NAME(1)>!*<IN(0)>]<UP>


SYNE<TYPE>=INTEGER<IN(3)><INTEGER.SIZES><UP>!#
REAL<IN(0)><REAL.SIZES><UP>!#
CHARACTER<IN(5)>[<LENGTH.SPEC><UP>!<IN(0)>]<UP>!#
COMPLEX<IN(2)><COMPLEX.SIZES><UP>!#
DOUBLEPRECISION<IN(1)><DP.SIZES><UP>!#
LOGICAL<IN(4)><LOGICAL.SIZES><UP>


SYNE<UNIT.ID>=[*<IN(0)>!<EXPR(%1E)>]<UP>


*SYNE<ZW>=#
  RITE<IN(1)><SET.UP(6)><RWP.LONG.FORM><NLS(19)>


*SYNE<DIRECTIVE>=MAP[/<IN(0)><NAME(2)>/!<SLASH.SLASH><IN(1)><IN(0)>!#
CODE<IN(2)><IN(0)>!DATA<IN(3)><IN(0)>]#
<INTEGA>[,<INTEGA>!<IN(0)>]<NLS(43)>!#
EXPORT<NAME(0)><REP.I.COMMA(2)><NLS(44)>!#
IMPORT<IMPORT.ITEM><REP.I.COMMA(3)><NLS(45)>!#
LIB[<CHAR.CONST>!<IN(0)>]<NLS(46)>!#
ANSISWITCH<NLS(47)>!#
SHORTINTEGER<NLS(48)>!#
OPENDEFAULT[IO<IN(12)>!<IN(0)>]<NLS(49)>!#
COMMON<NAME(2)>,<INT.OR.HEX>,<INT.OR.HEX>,<INT.OR.HEX>,<INT.OR.HEX><NLS(50)>!#
LIST<NLS(51)>!NOLIST<NLS(52)>

SYNE<IMPORT.ITEM>=[<CHAR.CONST><IN(0)>!<NAME(0)><IN(1)>]<UP>
SYNE<INT.OR.HEX>=[<S.INTEGER>!<HEX>]<UP>

#FTN04.1.1.6
@BOX 1.1
2 10 235 25 1 4 0 21 1 'A 1 'V 1 'E 0 9 2 10 193 16
3 3 4 20 0 10 32 1 'T 1 'O 1 'P 0 8 9 1 30 0 3
12 0 8 9 1 24 0 3 4 9 0 10 21 0 8 14 1 9 0 3
10 1 '/ 14 2 1 '/ 9 1 4 1 'U 1 'N 1 'I 1 'T 1 '=
2 12 12 4 1 'E 1 'R 1 'R 1 '= 11 0 4 1 'I 1 'O 1
'S 1 'T 1 'A 1 'T 1 '= 2 2 91 4 1 'S 1 'T 1 'A 1
'T 1 'U 1 'S 1 '= 15 %C 4 1 'F 1 'I 1 'L 1 'E 1 '=
15 %C 4 1 'R 1 'E 1 'C 1 'L 1 '= 15 %C 4 1 '( 20 0
15 %4C 16 2 21 0 1 ') 8 0 1 '( 0 6 15 %5C 3 4 9 0
1 ': 0 6 15 %44 3 4 9 0 1 ') 8 0 14 0 0 13 1 '(
2 11 106 16 3 1 ') 3 14 0 10 1 '( 1 ') 20 0 3 4 20
0 4 0 6 14 1 3 6 1 '* 9 0 4 0 22 1 'I 1 'N 1
'T 1 'E 1 'G 1 'E 1 'R 9 3 2 4 205 4 0 16 1 'R 1
'E 1 'A 1 'L 9 0 2 8 221 4 0 33 1 'C 1 'H 1 'A 1
'R 1 'A 1 'C 1 'T 1 'E 1 'R 9 5 0 8 2 6 205 4 3
4 9 0 4 0 22 1 'C 1 'O 1 'M 1 'P 1 'L 1 'E 1 'X
9 2 2 1 13 4 0 38 1 'D 1 'O 1 'U 1 'B 1 'L 1 'E
1 'P 1 'R 1 'E 1 'C 1 'I 1 'S 1 'I 1 'O 1 'N 9 1
2 2 46 4 1 'L 1 'O 1 'G 1 'I 1 'C 1 'A 1 'L 9 4
2 6 172 4 0 8 1 '* 9 0 3 4 15 %1E 4 1 'R 1 'I 1
'T 1 'E 9 1 26 6 2 9 61 10 19 0 72 1 'M 1 'A 1 'P
0 12 1 '/ 9 0 14 2 1 '/ 3 40 0 10 29 0 9 1 9 0
3 30 0 16 1 'C 1 'O 1 'D 1 'E 9 2 9 0 3 14 1 'D
1 'A 1 'T 1 'A 9 3 9 0 11 0 0 8 1 ', 11 0 3 4
9 0 10 43 0 22 1 'E 1 'X 1 'P 1 'O 1 'R 1 'T 14 0
16 2 10 44 1 ' 0 21 1 'I 1 'M 1 'P 1 'O 1 'R 1 'T
2 13 71 16 3 10 45 0 18 1 'L 1 'I 1 'B 0 6 24 0 3
4 9 0 10 46 0 24 1 'A 1 'N 1 'S 1 'I 1 'S 1 'W 1
'I 1 'T 1 'C 1 'H 10 47 0 28 1 'S 1 'H 1 'O 1 'R 1
'T 1 'I 1 'N 1 'T 1 'E 1 'G 1 'E 1 'R 10 48 0 38 1
'O 1 'P 1 'E 1 'N 1 'D 1 'E 1 'F 1 'A 1 'U 1 'L 1
'T 0 10 1 'I 1 'O 9 12 3 4 9 0 10 49 0 38 1 'C 1
'O 1 'M 1 'M 1 'O 1 'N 14 2 1 ', 2 13 84 1 ', 2 13
84 1 ', 2 13 84 1 ', 2 13 84 10 50 0 12 1 'L 1 'I 1
'S 1 'T 10 51 1 'N 1 'O 1 'L 1 'I 1 'S 1 'T 10 52 0
8 24 0 9 0 3 6 14 0 9 1 4 0 6 12 0 3 4 13 0
#FTN04.1.1.6
@END
@TITLE FTN04.1.1.6(1,11)
@COL 1S
@FLOW 1
@BOX 1.0
*SYNE<OPTIONS>=<OPTION><REP.I.COMMA(3)><NLS(0)>

SYNE<OPTION>=<INT.OR.HEX><VAL(0)>!#
             TL<INT.OR.HEX><VAL(1)>!#
             TLPRINT<INT.OR.HEX><VAL(2)>!#
             [DEBUG!DB]<VAL(3)>!#
             [NODEBUG!NDB]<VAL(4)>!#
             [LIBRARY!LB]<VAL(5)>!#
             [SYNTAXONLY!SO]<VAL(6)>!#
             [NOARGCHECK!NAC]<VAL(7)>!#
             [ONSTACK!OS]<VAL(8)>!#
             NOCLI<VAL(9)>!#
             CLI<VAL(10)>!#
             [LIST!LS]<VAL(11)>!#
             [NOLIST!NLS]<VAL(12)>!#
             [SHORTINTEGER!SI]<VAL(13)>!#
             [LONGINTEGER!LI]<VAL(14)>!#
             [OPENDEFAULT!OD][IO<IN(12)>!<IN(0)>]<VAL(15)>!#
             [LONGNAMES!LN]<VAL(16)>!#
             NOTLEND<VAL(17)>!#
             NOTL<VAL(18)>!#
             [HOLLERITHS!HO]<VAL(19)>!#
             [OLDPARAMETER!OP]<VAL(20)>!#
             [ALTDA!AD]<VAL(21)>!#
             [ENCODE/DECODE!ED]<VAL(22)>!#
             [HEX/OCTAL!XO]<VAL(23)>!#
             [RECURSION!RC]<VAL(24)>!#
             [LOOP77!L77]<VAL(25)>!#
             [LOOP66!L66]<VAL(26)>!#
             [EXTRACHARS!EC]<VAL(27)>!#
             [EXTRATYPES!ET]<VAL(28)>!#
             CV<VAL(29)>!#
             NON-ANSI<VAL(30)>!#
             [EX-RANGE!XR]<VAL(31)>!#
             [COMMON-SIZE!CZ]<VAL(32)>!#
             [MIX-CHAR!MC]<VAL(33)>!#
             [INIT-DECL!ID]<VAL(34)>!#
             [INIT-COMMON!IC]<VAL(35)>!#
             [QUOTE-HOLL!QH]<VAL(36)>!#
             [ERRORLIMIT!EL]<INT.OR.HEX><VAL(37)>!#
             <SKIP.TO.COMMA><VAL(38)>

COSYNES
END SYNTAX SPEC
@BOX 1.1
4 2 13 100 16 3 10 0 0 7 2 13 84 7 0 0 11 1 'T 1
'L 2 13 84 7 1 0 21 1 'T 1 'L 1 'P 1 'R 1 'I 1 'N
1 'T 2 13 84 7 2 0 22 0 14 1 'D 1 'E 1 'B 1 'U 1
'G 3 6 1 'D 1 'B 7 3 0 28 0 18 1 'N 1 'O 1 'D 1
'E 1 'B 1 'U 1 'G 3 8 1 'N 1 'D 1 'B 7 4 0 26 0
18 1 'L 1 'I 1 'B 1 'R 1 'A 1 'R 1 'Y 3 6 1 'L 1
'B 7 5 0 32 0 24 1 'S 1 'Y 1 'N 1 'T 1 'A 1 'X 1
'O 1 'N 1 'L 1 'Y 3 6 1 'S 1 'O 7 6 0 34 0 24 1
'N 1 'O 1 'A 1 'R 1 'G 1 'C 1 'H 1 'E 1 'C 1 'K 3
8 1 'N 1 'A 1 'C 7 7 0 26 0 18 1 'O 1 'N 1 'S 1
'T 1 'A 1 'C 1 'K 3 6 1 'O 1 'S 7 8 0 14 1 'N 1
'O 1 'C 1 'L 1 'I 7 9 0 10 1 'C 1 'L 1 'I 7 10 0
20 0 12 1 'L 1 'I 1 'S 1 'T 3 6 1 'L 1 'S 7 11 0
26 0 16 1 'N 1 'O 1 'L 1 'I 1 'S 1 'T 3 8 1 'N 1
'L 1 'S 7 12 0 36 0 28 1 'S 1 'H 1 'O 1 'R 1 'T 1
'I 1 'N 1 'T 1 'E 1 'G 1 'E 1 'R 3 6 1 'S 1 'I 7
13 0 34 0 26 1 'L 1 'O 1 'N 1 'G 1 'I 1 'N 1 'T 1
'E 1 'G 1 'E 1 'R 3 6 1 'L 1 'I 7 14 0 46 0 26 1
'O 1 'P 1 'E 1 'N 1 'D 1 'E 1 'F 1 'A 1 'U 1 'L 1
'T 3 6 1 'O 1 'D 0 10 1 'I 1 'O 9 12 3 4 9 0 7
15 0 30 0 22 1 'L 1 'O 1 'N 1 'G 1 'N 1 'A 1 'M 1
'E 1 'S 3 6 1 'L 1 'N 7 16 0 18 1 'N 1 'O 1 'T 1
'L 1 'E 1 'N 1 'D 7 17 0 12 1 'N 1 'O 1 'T 1 'L 7
18 0 32 0 24 1 'H 1 'O 1 'L 1 'L 1 'E 1 'R 1 'I 1
'T 1 'H 1 'S 3 6 1 'H 1 'O 7 19 0 36 0 28 1 'O 1
'L 1 'D 1 'P 1 'A 1 'R 1 'A 1 'M 1 'E 1 'T 1 'E 1
'R 3 6 1 'O 1 'P 7 20 0 22 0 14 1 'A 1 'L 1 'T 1
'D 1 'A 3 6 1 'A 1 'D 7 21 0 38 0 30 1 'E 1 'N 1
'C 1 'O 1 'D 1 'E 1 '/ 1 'D 1 'E 1 'C 1 'O 1 'D 1
'E 3 6 1 'E 1 'D 7 22 0 30 0 22 1 'H 1 'E 1 'X 1
'/ 1 'O 1 'C 1 'T 1 'A 1 'L 3 6 1 'X 1 'O 7 23 0
30 0 22 1 'R 1 'E 1 'C 1 'U 1 'R 1 'S 1 'I 1 'O 1
'N 3 6 1 'R 1 'C 7 24 0 26 0 16 1 'L 1 'O 1 'O 1
'P 1 '7 1 '7 3 8 1 'L 1 '7 1 '7 7 25 0 26 0 16 1
'L 1 'O 1 'O 1 'P 1 '6 1 '6 3 8 1 'L 1 '6 1 '6 7
26 0 32 0 24 1 'E 1 'X 1 'T 1 'R 1 'A 1 'C 1 'H 1
'A 1 'R 1 'S 3 6 1 'E 1 'C 7 27 0 32 0 24 1 'E 1
'X 1 'T 1 'R 1 'A 1 'T 1 'Y 1 'P 1 'E 1 'S 3 6 1
'E 1 'T 7 28 0 8 1 'C 1 'V 7 29 0 20 1 'N 1 'O 1
'N 1 '- 1 'A 1 'N 1 'S 1 'I 7 30 0 28 0 20 1 'E 1
'X 1 '- 1 'R 1 'A 1 'N 1 'G 1 'E 3 6 1 'X 1 'R 7
31 0 34 0 26 1 'C 1 'O 1 'M 1 'M 1 'O 1 'N 1 '- 1
'S 1 'I 1 'Z 1 'E 3 6 1 'C 1 'Z 7 32 0 28 0 20 1
'M 1 'I 1 'X 1 '- 1 'C 1 'H 1 'A 1 'R 3 6 1 'M 1
'C 7 33 0 30 0 22 1 'I 1 'N 1 'I 1 'T 1 '- 1 'D 1
'E 1 'C 1 'L 3 6 1 'I 1 'D 7 34 0 34 0 26 1 'I 1
'N 1 'I 1 'T 1 '- 1 'C 1 'O 1 'M 1 'M 1 'O 1 'N 3
6 1 'I 1 'C 7 35 0 32 0 24 1 'Q 1 'U 1 'O 1 'T 1
'E 1 '- 1 'H 1 'O 1 'L 1 'L 3 6 1 'Q 1 'H 7 36 0
35 0 24 1 'E 1 'R 1 'R 1 'O 1 'R 1 'L 1 'I 1 'M 1
'I 1 'T 3 6 1 'E 1 'L 2 13 84 7 37 31 0 7 38
END;

-> PASSWITCH;
LOOP2:
SWITCH SYNTAX [SY] \
BRANCH,
SYMBOL,
SYNE,
MERGE,
UP,
ENDFALSE,
ENDTRUE,
VAL,
NOVAL,
IN,
NLS,
INTEGA,
SINTEGER,
HEX,
NAME,
EXPR,
REPICOMMA,
REPICOMMALETTER,
INLETTER,
OPT,
NEGIN,
SETLISTCNT,
CONSTANT,
REPEATIFNOTDOVAR,
CHARCONST,
COPY,
SETUP,
CHECKNOSPEC,
FORMATSPEC,
SLASHSLASH,
DIGITSTRING,
SKIPTOCOMMA;
PASSWITCH:;
@END
@TITLE FTN04.1.2(1,6)
@COL 3R-4F
@COL 1S-2R
@ROW 2-3
@FLOW 1-2-3-4
@BOX 1.0
SCAN
@BOX 2.0
SCAN CODE
INBUILT COSYNES
TRUE
FALSE
VAL
IN
UP
@BOX 3.0
SCAN COSYNES
4.1.3: INTEGER
4.1.4: CONST
4.1.5: REP.I.COMMA
4.1.6: NLS
4.1.7:  SET.LIST.CNT
4.1.8: EXPR
4.1.9: FORMAT SPEC
4.1.10: REPEAT.IF.NOT.DO.VAR
4.1.11: SET.UP
4.1.12: COPY
4.1.13: OPT
4.1.14: NEG.IN
4.1.15: CHAR.CONST
4.1.16: IN LETTER
4.1.17: REP IF COMMA OR LETTER
4.1.18: CHECK NO SPEC
4.1.19: SLASH.SLASH
4.1.20: DIGIT.STRING
4.1.22: NAME
4.1.23: S.INTEGER
4.1.24: HEX
4.1.25: SKIP.TO.COMMA
@BOX 4.0
END
@BOX 1.1
@BOX 2.1
;PART(^SYNTAX,1,SIZE(^SYNTAX)) => SYNTAX1
;1 => S[0] => S[2]
;0 => S[1] => S[3] => S[5] => AS[1]
;-1 => S[4]
;9 => AP
;1 => WP
;6 => TOS
;-> LOOP2
;FALSE:
;S[TOS-1] => SY
;IF S[2->TOS] => WP < 0, -> FALSE
;IF SS > FSS THEN
   ;SS => FSS
;FI
;S[TOS-1] => SS
;S[2->TOS] => AP
;MERGE:
;SYNTAX1^[SY] +> SY
;-> LOOP2
;SYNE:
;0-WP => S[TOS]
;SY => S[TOS+1]
;2 +> TOS
;SYNTAX1^[SY] <<- 8 ! SYNTAX1^[SY+1] => SY
;->LOOP2
;BRANCH:
;AP => S[TOS]
;SS => S[TOS+1]
;WP => S[TOS+2]
;SY => S[TOS+3]
;4 +> TOS
;-> LOOP
;UPLP: 2->TOS
;UP: 2->TOS
;IF S[TOS] >=0, -> UPLP
;S[TOS+1] +3 => SY
;-> LOOP2
;IN:
;SYNTAX1^[SY] => WS[WP]
;1+>WP
;-> LOOP
;VAL:
;SYNTAX1^[SY] => AS[AP]
;AP+1 => TAP
;->ALL.VAL
;NOVAL: AP => TAP
;->ALL.VAL
;VLP: 2->TOS
;ALL.VAL: 2->TOS
;IF 0-S[TOS] => TEMPWP < 0,->VLP
;WP-TEMPWP => COUNT
;IF COUNT=0,->COPIED
;-1 => I
;WHILE 1+>I < COUNT DO
;WS[TEMPWP+I] => AS[TAP+I]
;OD
;COPIED : AP=>WS[TEMPWP]
;TEMP.WP+1 => WP
;TAP+ COUNT => AP
;S[TOS+1]+3 => SY
;->LOOP2
;END.FALSE:
;-1 => WS[0]
;->END.SCAN
;END.TRUE:
;SS+1 => END.SS.G
;WS[WP-1] + 1 => STAT.AP.G
;1=>WS[0]
;AP  => END.AP.G
;->END.SCAN
;SYMBOL:
;IF SYNTAX1^[SY]/= LINE.G[1+>SS], -> FALSE
;NULL:
;TRUE:
;LOOP:
;2 +> SY
;->LOOP2
@BOX 3.1
#FTN04.1.3
#FTN04.1.4
#FTN04.1.5
#FTN04.1.6
#FTN04.1.7
#FTN04.1.8
#FTN04.1.9
#FTN04.1.10
#FTN04.1.11
#FTN04.1.12
#FTN04.1.13
#FTN04.1.14
#FTN04.1.15
#FTN04.1.16
#FTN04.1.17
#FTN04.1.18
#FTN04.1.19
#FTN04.1.20
#FTN04.1.22
#FTN04.1.23
#FTN04.1.24
#FTN04.1.25
@BOX 4.1
;END.SCAN:
@END
@TITLE FTN04.1.3(1,10)
@COL 2S-3T-4R-5C
@COL 6C
@ROW 5-6
@FLOW 2-3NO-4-5
@FLOW 3YES-6
@BOX 2.0
INTEGER
@BOX 3.0
NEXT CH NOT A DIGIT
@BOX 4.0
READ INTEGER[FTN04.6]
STORE ON WS
INCR WP
@BOX 5.0
TRUE[FTN04.1.1]
@BOX 6.0
FALSE[FTN04.1.1]
@BOX 2.1
;INTEGA:
@BOX 3.1
;IF ST.CH[LINE.G[SS+1]] => CH < %1A OR CH > %23
@BOX 4.1
:: @@@ BCT 30-DEC-82
;READ.I(^SS,1) => INT OF PROPS.T[1 +> PROPS.I]
;PROPS.I => WS[WP]
;1+>WP
@BOX 5.1
;->TRUE
@BOX 6.1
;->FALSE
@END
@TITLE FTN04.1.4(1,6)
@COL 1S-2T-3T-5C
@COL 6R-7T-8R-9C
@ROW 3-6
@ROW 5-9
@FLOW 1-2NO-3NO-5
@FLOW 2YES-6-7NO-8-5
@FLOW 3YES-9
@FLOW 7YES-9
@BOX 1.0
CONST
@BOX 2.0
NEXT CH A (?
@BOX 3.0
INVALID RECOGNITION OF
A NON COMPLEX CONSTANT
     [FTN04.4]
@BOX 5.0
TRUE[FTN04.1.1]
@BOX 6.0
GET CHAR
@BOX 7.0
INVALID COMPLEX
CONSTANT[FTN04.4]
@BOX 8.0
GET CHAR
@BOX 9.0
FALSE[FTN04.1.1]
@BOX 1.1
;CONSTANT:
@BOX 2.1
;IF LINE.G[SS+1] = '(
@BOX 3.1
;IF REC.CONST(2) < 0
@BOX 5.1
;-> TRUE
@BOX 6.1
;1+>SS
@BOX 7.1
;IF REC.CONST(1) < 0
@BOX 8.1
;1+>SS
@BOX 9.1
;->FALSE
@END
@TITLE FTN04.1.5(1,6)
@COL 2S-3T-4R-5R-6C
@COL 7R-8C
@ROW 4-7
@FLOW 2-3NO-4-5-6
@FLOW 3YES-7-8
@BOX 2.0
REP I COMMA (P1)
@BOX 3.0
IF NEXT CH NOT ","?
@BOX 4.0
INCR LINE PTR
@BOX 5.0
SET SYNTAX TABLE PTR
@BOX 6.0
LOOP2[FTN04.1.1]
@BOX 7.0
STORE -1 ON WS
INCR WP
@BOX 8.0
TRUE[FTN04.1.1]
@BOX 2.1
;REP.I.COMMA:
@BOX 3.1
;IF LINE.G[SS+1] /= ',
@BOX 4.1
;1 +> SS
@BOX 5.1
;SY - SYNTAX1^[SY] => SY
@BOX 6.1
;-> LOOP2
@BOX 7.1
;-1 => WS[WP]
;1 +> WP
@BOX 8.1
;-> TRUE
@END
@TITLE FTN04.1.6(1,6)
@COL 2S-3T-4C
@COL 5C
@ROW 4-5
@FLOW 2-3NO-4
@FLOW 3YES-5
@BOX 2.0
NLS
@BOX 3.0
NEXT CH NOT A NL?
@BOX 4.0
VAL[FTN04.1.1]
@BOX 5.0
FALSE[FTN04.1.1]
@BOX 2.1
;NLS:
@BOX 3.1
;IF LINE.G[SS+1] /= NLL
@BOX 4.1
;-> VAL
@BOX 5.1
;-> FALSE
@END
@TITLE FTN04.1.7(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SET.LIST.CNT
@BOX 2.0
COUNT NO OF ITEMS IN LIST
AND SAVE AT START OF LIST
@BOX 3.0
TRUE[FTN04.1.1]
@BOX 1.1
;SET.LIST.CNT:
@BOX 2.1
;-1 => T
;WHILE WS[1+>T-:WP-2] >= 0 DO OD
;T => WS[T-:WP-2]
@BOX 3.1
;->TRUE
@END
@TITLE FTN04.1.8(1,6)
@COL 2S-3T-4R-5C
@COL 6C
@ROW 5-6
@FLOW 2-3NO-4-5
@FLOW 3YES-6


@BOX 2.0
EXPRESSION(P1)
@BOX 3.0
EXPRESSION(P1) NOT RECOGNISED[FTN04.2]
@BOX 5.0
TRUE[FTN04.1.1]
@BOX 4.0
PUSH EXPR PTR TO WS
@BOX 6.0
FALSE[FTN04.1.1]
@BOX 2.1
;EXPR:
@BOX 3.1
;IF REC.EXPR(SYNTAX1^[SY]) => WS[WP] < 0
@BOX 4.1
;1 +> WP
@BOX 5.1
;-> TRUE
@BOX 6.1
;-> FALSE
@END
@TITLE FTN04.1.9(1,11)

@COL 2S-5T-10T-11R-6R-7C
@COL 1A-9R-8C
@ROW 6-9
@FLOW 2-5NO-10NO-11-6-7
@FLOW 5YES-9-8
@FLOW 10YES-6

@BOX 2.0
FORMAT SPEC
@BOX 5.0
ANALYZE FORMAT SPEC
FORMAT FAULTY?
@BOX 6.0
ADD FORMAT LENGTH TO WS
INCR WP
@BOX 7.0
TRUE[FTN04.1.1]
@BOX 8.0
FALSE[FTN04.1.1]
@BOX 9.0
UPDATE SS FOR FAIL POINT
@BOX 10.0
ANSI STANDARD FORMAT?
@BOX 11.0
ISSUE WARNING
@BOX 2.1
;FORMAT.SPEC:
@BOX 5.1
;IF FIO.C.FORMAT(PART(^LINE.G,SS+1,LINE.SZ.L-1)
   ,^FMT.TABLE,^FMT.STRINGS)=> FMT.TBL.SZ.G => WS[WP] < 0
@BOX 6.1
;1 +> WP
@BOX 7.1
;-> TRUE
@BOX 8.1
;-> FALSE
@BOX 9.1
;FMT.TBL.SZ.G->SS
@BOX 10.1
;0 => T
;WHILE FMT.TBL.SZ.G > MAX.FMT.TABLE.L DO 1+> T
    ; MAX.FMT.TABLE.L -> FMT.TBL.SZ.G => WS[WP] OD
;IF T = 0
@BOX 11.1
;FAULT(175,6)
@END
@TITLE FTN04.1.10(1,6)
@COL 1S-2R-3R-4T-5R-6C
@COL 7R-8C
@ROW 5-7
@FLOW 1-2-3-4NO-5-6
@FLOW 4YES-7-8
@BOX 1.0
REPEAT.IF.NOT.DO.VAR(P1)
@BOX 2.0
NOTE LINE POSITION
@BOX 3.0
SKIP ALPHANUMERIC
CHARS
@BOX 4.0
NEXT CH "="
@BOX 5.0
RESET LINE POSITION
DECR SYNTAX PTR
BY P1
@BOX 6.0
LOOP2[FTN04.1.1]
@BOX 7.0
PUT -1 ON WS
RESET LINE POSITION
@BOX 8.0
TRUE[FTN04.1.1]
@BOX 1.1
;REPEAT.IF.NOT.DO.VAR:
@BOX 2.1
;SS => SSS
@BOX 3.1
;WHILE ST.CH[LINE.G[1+>SS]] < 36 DO
   ::NOTHING
;OD
@BOX 4.1
;IF LINE.G[SS] = '=
@BOX 5.1
;SSS => SS
;SY - SYNTAX1^[SY] => SY
@BOX 6.1
;-> LOOP2
@BOX 7.1
;-1 => WS[WP]
;1 +> WP
;SSS => SS
@BOX 8.1
;-> TRUE
@END
@TITLE FTN04.1.11(1,6)
@COL 1S-2R-3C
@FLOW 1-2-3
@BOX 1.0
SET.UP(P1)
@BOX 2.0
INCR WP BY P1
AND SET EACH
NEW WORD TO -1
@BOX 3.0
TRUE[FTN04.1.1]
@BOX 1.1
;SET.UP:
@BOX 2.1
;SYNTAX1^[SY] + WP => I
;WHILE WP < I DO
   ;-1 => WS[WP]
   ;1 +> WP
;OD
@BOX 3.1
;-> TRUE
@END
@TITLE FTN04.1.12(1,6)
@COL 1S-2R-3T-4R-5C
@COL 6C
@ROW 5-6
@FLOW 1-2-3NO-4-5
@FLOW 3YES-6
@BOX 1.0
COPY(P1)
@BOX 2.0
DECR WP
@BOX 3.0
IS WS[WP-P1]
/ -1
@BOX 4.0
COPY WS[WP]
TO WS[WP-P1]
@BOX 5.0
TRUE[FTN04.1.1]
@BOX 6.0
FALSE[FTN04.1.1]
@BOX 1.1
;COPY:
@BOX 2.1
;1 -> WP
@BOX 3.1
;IF WS[WP-SYNTAX1^[SY] => T] /= -1
@BOX 4.1
;WS[WP] => WS[T]
@BOX 5.1
;-> TRUE
@BOX 6.1
;->FALSE
@END
@TITLE FTN04.1.13(1,6)
@COL 1S-2T-3R-4C
@FLOW 1-2NO-3-4
@FLOW 2YES-4
@BOX 1.0
OPT(P1)
@BOX 2.0
NEXT CH /= P1
@BOX 3.0
INCR SS
@BOX 4.0
TRUE[FTN04.1.1]
@BOX 1.1
;OPT:
@BOX 2.1
;IF LINE.G[SS+1] /= SYNTAX.1^[SY]
@BOX 3.1
;1+>SS
@BOX 4.1
;->TRUE
@END
@TITLE FTN04.1.14(1,6)
@COL 1S-2R-3C
@FLOW 1-2-3
@BOX 1.0
NEG.IN
@BOX 2.0
PUT -1 ON
WS
@BOX 3.0
TRUE[FTN04.1.1]
@BOX 1.1
;NEG.IN:
@BOX 2.1
;-1 => WS[WP]
;1 +> WP
@BOX 3.1
;-> TRUE
@END
@TITLE FTN04.1.15(1,10)
@COL 1S-2T-3R-4C
@COL 5C
@ROW 4-5
@FLOW 1-2NO-3-4
@FLOW 2YES-5
@BOX 1.0
CHAR.CONST
@BOX 2.0
IS NEXT ITEM IN LINE
NOT A CHAR CONST
@BOX 3.0
PUT CONST PTR ON WS
INCR SS
@BOX 4.0
TRUE[FTN04.1.1]
@BOX 5.0
FALSE[FTN04.1.1]
@BOX 1.1
;CHAR.CONST:
@BOX 2.1
;IF LINE.G[SS+1] /= MARK.CH.L
@BOX 3.1
;BYTE(^LINE.G[SS+1]) => ADDRESS OF PROPS.T[1+>PROPS.I]
;PROPS.I => WS[WP]
;1+>WP
;WHILE LINE.G[1+>SS] /= 0 DO OD
@BOX 4.1
;->TRUE
@BOX 5.1
;-> FALSE
@END
@TITLE FTN04.1.16(1,6)
@COL 1S-2T-3R-4C
@COL 5C
@ROW 4-5
@FLOW 1-2N-3-4
@FLOW 2Y-5
@BOX 1.0
IN LETTER
@BOX 2.0
NEXT ITEM A LETTER?
@BOX 3.0
PUSH TO WS
INCR SS
@BOX 4.0
TRUE[FTN04.1.1]
@BOX 5.0
FALSE[FTN04.1.1]
@BOX 1.1
;IN.LETTER:
@BOX 2.1
;IF ST.CH[LINE.G[SS+1]=>CH] >= 26
@BOX 3.1
;1 +> SS
;CH => WS[WP]
;1 +> WP
@BOX 4.1
;-> TRUE
@BOX 5.1
;-> FALSE
@END

@TITLE FTN04.1.17(1,6)
@COL 1S-2T-3T-4R-5R-6R
@COL 7R-8C
@ROW 4-7
@FLOW 1-2N-3N-4-5-6
@FLOW 2Y-7
@FLOW 3Y-7-8
@BOX 3.0
NEXT CH NOT A LETTER?
@BOX 2.0
NEXT CH NOT A ","?
@BOX 4.0
INCR LINE PTR
@BOX 5.0
SET SYNTAX TABLE PTR
@BOX 6.0
LOOP2[FTN04.1.1]
@BOX 7.0
PUSH -1 TO WS
@BOX 8.0
TRUE[FTN04.1.1]
@BOX 1.0
REP IF COMMA THEN LETTER
@BOX 1.1
;REP.I.COMMA.LETTER:
@BOX 2.1
;IF LINE.G[SS+1] /= ',
@BOX 3.1
;IF ST.CH[LINE.G[SS+2]] >= 26
@BOX 4.1
;1 +> SS
@BOX 5.1
;SY - SYNTAX1^[SY] => SY
@BOX 6.1
;-> LOOP.2
@BOX 7.1
;-1 => WS[WP]
;1 +> WP
@BOX 8.1
;-> TRUE
@END

@TITLE FTN04.1.18(1,6)
@COL 1S-2T-3C
@COL 4C
@ROW 3-4
@FLOW 1-2N-3
@FLOW 2Y-4
@BOX 2.0
IS THERE AN "="
BEFORE NEXT ",", ")" or NEWLINE
@BOX 4.0
TRUE[FTN04.1.1]
@BOX 3.0
FALSE[FTN04.1.1]
@BOX 1.0
CHECK NO SPEC
@BOX 1.1
;CHECK.NO.SPEC:
@BOX 2.1
;SS => TSS
;WHILE LINE.G[1+>TSS] /= NL.L /= '= /= ', /= ') DO OD
;IF CH /= '=
@BOX 4.1
;-> TRUE
@BOX 3.1
;-> FALSE
@END
@TITLE FTN04.1.19(1,6)
@COL 1S-2T-3R-4C
@COL 5C
@ROW 4-5
@FLOW 1-2N-3-4
@FLOW 2Y-5
@BOX 1.0
SLASH SLASH
@BOX 2.0
NEXT CHAR AN ITEMISED //
@BOX 3.0
INCR LINE PTR
@BOX 4.0
TRUE[FTN04.1.1]
@BOX 5.0
FALSE[FTN04.1.1]
@BOX 1.1
;SLASH.SLASH:
@BOX 2.1
;IF LINE.G[SS+1] /= CONCAT.CH.L
@BOX 3.1
;1+>SS
@BOX 4.1
;->TRUE
@BOX 5.1
;->FALSE
@END

@TITLE FTN04.1.20(1,10)
@COL 1S-2T-4R-5T-8R-9C
@COL 10C
@ROW 9-10
@FLOW 1-2N-4-5N-8-9
@FLOW 2Y-10
@FLOW 5Y-10
@BOX 1.0
DIGIT.STRING
@BOX 2.0
NEXT.CH NOT A DIGIT
@BOX 4.0
COPY DIGIT STRING
@BOX 5.0
NEXT CH NOT A NEWLINE
@BOX 8.0
PUSH DIGIT STRING ADDR TO WS
@BOX 9.0
TRUE[FTN04.1.1]
@BOX 10.0
FALSE[FTN04.1.1]
@BOX 1.1
;DIGIT.STRING:
@BOX 2.1
;IF ST.CH[LINE.G[SS+1] => CH] => T < %1A OR T > %23
@BOX 4.1
;-1=>I
;WHILE 1+>I < 5 AND T >= %1A AND T =< %23 DO
   ;CH=>DIGIT.STR[I]
   ;ST.CH[LINE.G[1+>SS+1]=>CH]=>T
;OD
;0=>DIGIT.STR[I]
@BOX 5.1
;IF CH /= NL.L
@BOX 8.1
;BYTE(^DIGIT.STR)=> ADDRESS OF PROPS.T[1 +> PROPS.I]
;PROPS.I => WS[WP]
;1+>WP
@BOX 9.1
;->TRUE
@BOX 10.1
;->FALSE
@END

@TITLE FTN04.1.22(1,10)
@COL 2S-3T-4R-5R-6C
@COL 7C
@ROW 6-7
@FLOW 2-3NO-4-5-6
@FLOW 3YES-7
@BOX 2.0
NAME(P1)
@BOX 3.0
NOT A LETTER?
@BOX 4.0
RECOGNISE NAME[FTN04.3]
ADD TO APPR NL[FTN12]
0 - GLOBAL
1 - LOCAL
2 - COMMON
STORE PROP PTR ON WS
@BOX 5.0
INCR WP
@BOX 6.0
TRUE
:4.1.1
@BOX 7.0
FALSE
:4.1.1
@BOX 2.1
;NAME:
@BOX 3.1
;IF ST.CH[LINE.G[SS+1]] > 25
@BOX 4.1
;REC.NAME()
;1 +> PROPS.I => WS[WP]
;IF SYNTAX1^[SY] => T = 1 THEN
   ;ADD.L.NAME(^CUR.NAME) => LOC OF PROPS.T[PROPS.I]
;ELSE IF T = 0 THEN
   ;ADD.G.NAME(^CUR.NAME) => GLOB OF PROPS.T[PROPS.I]
;ELSE
   ;ADD.C.NAME(^CUR.NAME,0) => COM OF PROPS.T[PROPS.I]
;FI FI
@BOX 5.1
;1+>WP
@BOX 6.1
;->TRUE
@BOX 7.1
;->FALSE
@END
@TITLE FTN04.1.23(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
S.INTEGER
:: A NEW CHART AT CV FOR *COMMON
@BOX 2.0
HANDLE THE POSSIBLY SIGNED VALUE
@BOX 3.0
END
@BOX 1.1
;S.INTEGER:
;1 => T
;IF LINE.G[1+SS]=>CH = '- THEN
    -1 => T
   ;1 +> SS
 ELSE IF CH = '+ THEN 1+> SS
 FI FI
;IF ST.CH[LINE.G[SS+1]] => CH < %1A OR CH > %23, -> FALSE
   ;READ.I(^SS,T) => INT OF PROPS.T[1 +> PROPS.I] :: ??? JM 22-DEC-82
   ;PROPS.I => WS[WP]                            :: ??? JM 22-DEC-82
;1+>WP
@BOX 3.1
;-> TRUE
@END
@TITLE FTN04.1.24(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
HEX
:: A NEW CHART AT CV FOR *COMMON
@BOX 2.0
DECODE THE HEX VALUE
@BOX 3.0
END
@BOX 1.1
;HEX:
@BOX 2.1
;IF LINE.G[1+>SS] /= '%, -> FALSE
;0 => COUNT => T => I
;WHILE I = 0 DO
  ;IF ST.CH[LINE.G[1+>SS]] => CH >= %1A =< %23 THEN
      CH - %1A => CH
   ELSE IF CH >= 0 =< 5 THEN
      CH + 10 => CH
   ELSE
      -1 => I
     ;1 -> SS
   FI FI
  ;IF I = 0 THEN
      T <<- 4 ! CH => T
     ;1 +> COUNT
   FI
 OD
;IF COUNT = 0 , -> FALSE
   ;T => INT OF PROPS.T[1 +> PROPS.I] :: ??? JM 22-DEC-82
:: ;T => WS[WP]                       :: ??? JM 22-DEC-82
   ;PROPS.I => WS[WP]                 :: ??? JM 22-DEC-82
;1 +> WP
@BOX 3.1
; -> TRUE
@END
@TITLE FTN04.1.25(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SKIP TO COMMA
@BOX 2.0
SKIP OPTIONS ITEM
@BOX 3.0
TRUE
@BOX 1.1
;SKIP.TO.COMMA:
@BOX 2.1
;BYTE(^LINE.G[SS+1]) => ADDRESS OF PROPS.T[1+>PROPS.I=>WS[WP]]
; 1+>WP
; WHILE LINE.G[1+>SS] /= ', /= NL.L DO OD
; 1->SS
@BOX 3.1
; -> TRUE
@END
@TITLE FTN04.2(1,6)
@COL 9C-10R-11R-12R
@COL 1S-2R-3R-4T-5T-6T-7T-8R
@COL 13C-14R-15F
@ROW 9-2
@ROW 5-13
@ROW 10-6
@FLOW 1-2-3-4NO-5NO-6NO-7NO-8
@FLOW 9-3
@FLOW 5YES-10-11
@FLOW 4YES-14-15
@FLOW 6YES-14-15
@FLOW 7YES-12
@FLOW 13-14
@BOX 1.0
REC.EXPR(TYPE)EXPR.PTR
A RESULT OF Y INDICATES EXPR FAULT
TYPE
BIT 0 = 1 ASSIGNMENT EXPR
IE = PERMITTED
BIT 1 = 1 NL A VALID TERM
BIT 2 = 1 ) A VALID TERM
BIT 3 = 1 , A VALID TERM
BIT 4 = 1 : or ' A VALID TERM
BIT 5 = 1 BRACKETED SUBEXPRESSION
BIT 6 = 1 SIMPLE EXPRESSION
BIT 7 = 1 LABEL ARGUMENTS ALLOWED
@BOX 2.0
PUT INITIAL ([) OPERATOR ENTRY
ON WS
NOTE LAST ITEM PROCESS AN
OPERATOR
@BOX 3.0
SAVE POSITION OF ITEM
GET TYPE OF NEXT
CHAR
@BOX 4.0
ILLEGAL TYPE?
@BOX 5.0
CHAR AN OPERATOR?
@BOX 6.0
LAST ITEM PROCESSED
AN OPERAND?
@BOX 7.0
TYPE OF NEXT CHAR
ALPHABETIC?
@BOX 8.0
PROCESS A
CONSTANT[FTN04.2.7]
@BOX 9.0
PROCESS
NEXT
ITEM
@BOX 10.0
GET CHAR
@BOX 11.0
PROCESS
OPERATOR
[FTN04.2.1]
@BOX 12.0
PROCESS A
NAME[FTN04.2.5]
@BOX 13.0
EXPR
FAULT
@BOX 14.0
UPDATE MAX LINE
POSITION REACHED
@BOX 15.0
END-
FAULTY
@BOX 1.1
;PROC REC.EXPR(TY)
;$IN NAP
;$IN F,ISS,L.I,ITEM,CH,I.K,T,SV,OP,C,I,L.T,E.L
::L.I = 0 LAST ITEM AN OPERATOR
::L.I=1   LAST ITEM AN OPERAND
;ADDR CONST.PROP  CP
;DATAVEC PREC($LO8)
 8   3   3   2   2   6   7   10
10   4   4   4   4   4   4   1
11   0  12   5   9  13  14  16
 8  15  17  17
END :: @@@ BCT 13-DEC-82
;DATAVEC OPT($LO8)
9  0  0  5  5 10  5  5  5  6 5 6 9 5 5 6 7 5
9  0  5  5  5 10  5  5  5  6 5 6 9 5 5 6 7 5
9  0  5  5  5 10  5  5  5  6 5 6 9 5 5 6 7 5
9  0  0  5  5 10  5  5  5  6 5 6 9 5 5 6 7 5
0  0  0  0  6 10  5  5  5  6 5 0 0 5 5 6 7 5
0  0  0  0  0 10  5  5  5  6 5 0 0 5 5 6 7 5
0  0  0  0  0  0  5  5  5  6 5 0 0 5 5 6 7 5
0  0  0  0  0  0  0  5  5  6 5 0 0 5 5 6 7 5
0  0  0  0  0  0  0  0  1  0 0 0 0 3 2 6 7 4
0  0  0  0  0  0  0  0  8  6 0 0 0 6 6 6 7 6
0  0  0  0  0  0  0  0  5  6 5 0 0 5 5 6 7 5
6  6  6  6  5 10  5  5  5  6 5 5 6 5 5 6 7 5
9 11 11 11 11 10 11 11 11  6 11 6 9 11 11 6 7 11
END
;DATAVEC MUTLFN($LO16)
%16   8   9   11   12   4   5   3
14  %AF %8F %6F %CF %2F %4F %6
%1    9   8    3    0
END
@BOX 2.1
;0=> WS[WP] => L.I
;-1 => WS[WP+1]
;2 +> WP
@BOX 3.1
;ST.CH[LINE.G[SS+1=>ISS] => CH] => I.K
@BOX 4.1
;IF I.K & %80 /=0
@BOX 5.1
;IF I.K >= %60
@BOX 6.1
;IF LI = 1
@BOX 7.1
;IF I.K < 26
@BOX 8.1
#FTN04.2.7
@BOX 9.1
;F4.2B9:
@BOX 10.1
;1+>SS
@BOX 11.1
#FTN04.2.1
@BOX 12.1
#FTN04.2.5
@BOX 13.1
;F4.2B13:
@BOX 14.1
;IF SS>FSS THEN
   ;SS => FSS
;FI
@BOX 15.1
;-1 => REC.EXPR
;END
@END
@TITLE FTN04.2.1(1,6)
@COL 7R-8F
@COL 1S-2T-3T-4T-5R-6C
@COL 9C-10R
@ROW 2-9
@ROW 7-4-10
@FLOW 1-2NO-3NO-4NO-5-6
@FLOW 3YES-7
@FLOW 4YES-8
@FLOW 2YES-10
@FLOW 9-10
@BOX 1.0
PROCESS OPERATOR
@BOX 2.0
LAST ITEM AN
OPERAND?
@BOX 3.0
OPERATOR /= (?
@BOX 4.0
INVALID BRACKETED
EXPRESSION
[FTN04.2]
@BOX 5.0
INCR LINE PTR
PUSH EXPR PTR
ONTO WS
NOTE LAST ITEM
PROCESSED
AN OPERAND
@BOX 6.0
PROCESS NEXT
ITEM
[FTN04.2]
@BOX 7.0
PROCESS UNARY
OPERATORS AND
LABEL ARGUMENTS
[FTN04.2.4]
@BOX 8.0
EXPR FAULT
[FTN04.2]
@BOX 9.0
OPERATOR
SWITCH
@BOX 10.0
SWITCH DEPENDING ON
OPERATOR AND PREVIOUS
OPERATOR ON WS
REMOVE    [FTN04.2.2]
STACK OPERATOR [FTN04.2.3]
ILLEGAL USE OF SYMBOL [FTN04.2.3]
MISPLACED (   [FTN04.2.3]
CHECK TERMINATOR [FTN04.2.3]
CHECK = [FTN04.2.3]
REMOVE UNARY PLUS [FTN04.2.2]
ILLEGAL UNARY +, - [FTN04.2.3]
ILLEGAL UNARY NOT [FTN04.2.3]
@BOX 1.1
@BOX 2.1
;IF L.I=1
@BOX 3.1
;IF CH /= '(
@BOX 4.1
;IF REC.EXPR(%24) => T < 0
@BOX 5.1
;1+>SS
;T => WS[WP]
;1=>LI
;1 +> WP
@BOX 6.1
;->F4.2B9
@BOX 7.1
#FTN04.2.4
@BOX 8.1
;->F4.2B13
@BOX 9.1
;F4.2.1B9:
@BOX 10.1
;SWITCH OP.T[PREC[WS[WP-3]]*18+PREC[I.K-%60]] => SV \
  S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11
#FTN04.2.2
#FTN04.2.3
@END
@TITLE FTN04.2.2(1,6)
@COL 1S-5R-6R-7C-8C-10R-11C
@FLOW 1-5-6-7
@FLOW 8-10-11
@BOX 1.0
REMOVE
@BOX 5.0
POP OPERAND/OPERATOR/
OPERAND FROM WS AND
CREATE AN OPERATOR NODE ON AS
@BOX 6.0
PUSH OPERATOR NODE PTR TO WS
@BOX 7.0
OPERATOR
SWITCH
[FTN04.2.1]
@BOX 8.0
REMOVE UNARY PLUS
@BOX 10.0
REDUCE TRIPLE ON TOP OF
WS TO A SINGLE OPERAND
@BOX 11.0
OPERATOR
SWITCH
[FTN04.2.1]
@BOX 1.1
;S5:
@BOX 5.1
;MUTL.FN[WS[WP-3]] => AS[AP]
;WS[WP-4] => AS[AP+1]
;WS[WP-1] => AS[AP+2]
;WS[WP-2] => AS[AP+3]
@BOX 6.1
;AP => WS[WP-4]
;4 +> AP
;3 -> WP
@BOX 7.1
;-> F4.2.1B9
@BOX 8.1
;S11:
@BOX 10.1
;WS[WP-1] => WS[WP-4]
;3->WP
@BOX 11.1
;->F4.2.1B9
@END
@TITLE FTN04.2.3(1,6)
@COL 1S-2T-4F-5C-6C-8C
@COL 9C-10R-11C-12C-13T-14R-15C-16C-18C
@COL 19C-21C-23C-24C-26C
@ROW 1-9-19
@ROW 6-12
@ROW 16-24
@ROW 15-23
@FLOW 1-2NO-4
@FLOW 2YES-5
@FLOW 6-8
@FLOW 9-10-11
@FLOW 12-13NO-14-15
@FLOW 16-18
@FLOW 13YES-23
@FLOW 24-26
@FLOW 19-21
@BOX 1.0
CHECK
=
@BOX 2.0
AN ASSIGNMENT
EXPRESSION?
@BOX 4.0
EXPR FLT
[FTN04.2]
@BOX 5.0
REMOVE
[FTN04.2.2]
@BOX 6.0
MISPLACED
@BOX 8.0
EXPR FLT
[FTN04.2]
@BOX 9.0
STACK
OPERATOR
@BOX 10.0
PUSH OPERATOR ENTRY TO WS
NOTE LAST ITEM PROCESSED
AN OPERATOR
@BOX 11.0
PROCESS NEXT
ITEM
[FTN04.2]
@BOX 12.0
CHECK TERMINATOR
@BOX 13.0
INVALID USE OF
TERMINATOR?
@BOX 14.0
REMOVE INITIAL OPERATOR([)
FROM WS
DECR LINE PTR
@BOX 15.0
END - OK
@BOX 16.0
ILLEGAL USE OF
UNARY +, -
@BOX 18.0
EXPR FAULT
[FTN04.2]
@BOX 19.0
ILLEGAL USE
OF
SYMBOL
@BOX 21.0
EXPR FAULT
[FTN04.2]
@BOX 23.0
EXPR FAULT
[FTN04.2]
@BOX 24.0
ILLEGAL USE OF
UNARY NOT
@BOX 26.0
EXPR.FAULT
[FTN04.2]
@BOX 1.1
;S8:
@BOX 2.1
;IF TY & 1 /= 0
@BOX 4.1
;-> F4.2B13
@BOX 5.1
;->S5
@BOX 6.1
;S7:
@BOX 8.1
;->F4.2B13
@BOX 9.1
;S0:
@BOX 10.1
;IK -%60 => WS[WP]
;ISS => WS[WP+1]
;2 +> WP
;0 => L.I
@BOX 11.1
;->F4.2B9
@BOX 12.1
;S1:
;S2:
;S3:
;S4:
@BOX 13.1
;IF 1 <<- SV & TY = 0
@BOX 14.1
;1->SS
;3 -> WP
;WS[WP+2] => REC.EXPR
@BOX 15.1
;EXIT
@BOX 16.1
;S9:
@BOX 18.1
;->F4.2B13
@BOX 19.1
;S6:
@BOX 21.1
;->F4.2B13
@BOX 23.1
;->F4.2B13
@BOX 24.1
;S10:
@BOX 26.1
;->F4.2B13
@END
@TITLE FTN04.2.4(1,10)
@COL 11T-12T-13T-14T-15R-16T-17R-18F
@COL 1S-2T-3T-4R-5R-8R-6C-7C
@COL 21T-19R-20R-22R-23C
@ROW 3-21
@ROW 11-4
@FLOW 1-2NO-3NO-4-5-8-6
@FLOW 2YES-21N-19-20-8
@FLOW 21YES-22-23
@FLOW 3YES-11NO-12NO-13NO-14NO-15-16NO-17-18
@FLOW 11YES-7
@FLOW 12YES-7
@FLOW 13YES-7
@FLOW 14YES-7
@FLOW 16YES-7
@BOX 1.0
PROCESS UNARY OPERATOR
AND LABEL ARGUMENTS
@BOX 2.0
OPERATOR A '+' OR '-'?
@BOX 3.0
OPERATOR NOT 'NOT'
@BOX 4.0
SET OPERAND REQUIRED
TO TRUE
@BOX 5.0
SET OPERATOR TO
HIGH PRECEDENCE
NEQ
@BOX 6.0
OPERATOR
SWITCH
[FTN04.2.1]
@BOX 8.0
MAKE CONSTANT IN
LINESPACE
PUSH CONSTANT TERMINAL
NODE TO AS
PUCH NODE PTR TO WS
@BOX 7.0
EXPR
FAULT
[FTN04.2]
@BOX 11.0
OPERATOR NOT *
@BOX 12.0
*LABEL NOT
PERMITTED
@BOX 13.0
PREVIOUS OPERATOR
NOT [
@BOX 14.0
NEXT CHAR NOT
A DIGIT
@BOX 15.0
READ.INT
[FTN04.6]
@BOX 16.0
NEXT CHAR NOT
A , NOR)
@BOX 17.0
RESET WORKSTACK PTR
PUT A LABEL
OPERAND ON AS
@BOX 18.0
END-
OK
@BOX 19.0
SET OPERAND REQUIRED
TO ZERO
@BOX 20.0
SET OPERATOR TO
HIGH PRECEDENCE
'+' OR '-'
@BOX 21.0
NEXT CHAR START OF
A CONSTANT?
@BOX 22.0
GET '+' '-' CHAR BACK
@BOX 23.0
PROCESS
CONSTANT
[FTN04.2.7]
@BOX 1.1
@BOX 2.1
;IF CH = '+ OR CH = '-
@BOX 3.1
;IF IK /= %79
@BOX 4.1
;1=>C
@BOX 5.1
;%73 => IK
@BOX 8.1
;MAKE.CONST.PROP(LINE.SPACE) => C.P
;IF C=1 THEN
   ;1=>LOG.CONST OF C.P^; %4010 => AS[AP]
;ELSE
   ;0=>INT.CONST OF C.P^; %3010 => AS[AP]
;FI
;0 => AS[AP+1]
;C.P => CONST OF PROPS.T[1+>PROPS.I]
;PROPS.I => AS[AP+2]
;ISS => AS[AP+3]
;AP => WS[WP] + 4 => AP
;1 +> WP
@BOX 6.1
;->F4.2.1B9
@BOX 7.1
;->F4.2B13
@BOX 11.1
;IF CH /= '*
@BOX 12.1
;IF TY & %80 = 0
@BOX 13.1
;IF WS[WP-2] /= 0
@BOX 14.1
;IF ST.CH[LINE.G[SS+1]] => T < %1A OR T > %23
@BOX 15.1
;READ.I(^SS,1) => I ::CV
@BOX 16.1
;IF LINE.G[SS+1] /= ', /= ')
@BOX 17.1
;2->WP
;%601A => AS[AP]
;0 => AS[AP+1]
;I => AS[AP+2]
;ISS => AS[AP+3]
@BOX 18.1
;AP => REC.EXPR+4 => AP
;EXIT
@BOX 19.1
;0 => C
@BOX 20.1
;IF CH = '- THEN
   ; %71 => I.K ::CV
;ELSE
   ; %72 => I.K ::CV
;FI
@BOX 21.1
; IF ST.CH[LINE.G[SS+1]] > 25 < %60
@BOX 22.1
; 1 -> SS
@BOX 23.1
; -> F4.2.7B1
@END
@TITLE FTN04.2.5(1,10)
@COL 1S-2R-3R-4T-5R-6R-7T-8T-9R-11F
@COL 12C-13T-14R-15C
@ROW 5-12
@ROW 8-13
@FLOW 1-2-3-4NO-5-6-7NO-8NO-9-4
@FLOW 4YES-12
@FLOW 7YES-13NO-14-15
@FLOW 13YES-11
@FLOW 8YES-11
@BOX 1.0
PROCESS A NAME
@BOX 2.0
RECOGNISE A NAME [FTN04.3]
ADD NAME TO LOCAL NL [FTN12]
@BOX 3.0
CREATE A TERMINAL NODE ON AS
PUSH NODE^ TO WS
NOTE LAST ITEM PROCESSED AN
OPERAND
@BOX 4.0
NEXT CHAR /= (
OR REC A SIMPLE
EXPRESSION
@BOX 5.0
GET CHAR
@BOX 6.0
PROCESS AN
EXPR LIST [FTN04.2.6]
@BOX 7.0
UPDATE NODE INFO FOR
LIST TYPE
SUBSTRING EXPR LIST
@BOX 8.0
SUBSCRIPTS/ARGUMENTS
ALREADY INPUT?
@BOX 9.0
COPY EXPR CNT AND
EXPR A/R PTRS TO AS
@BOX 11.0
EXPR.FAULT
[FTN04.2]
@BOX 12.0
PROCESS
NEXT ITEM
[FTN04.2]
@BOX 13.0
EXPR CNT /= 2?
@BOX 14.0
COPY BOTH
EXPR PTRS TO AS
@BOX 15.0
PROCESS
NEXT ITEM
[FTN04.2]
@BOX 1.1
@BOX 2.1
;REC.NAME()
;ADD.L.NAME(^CUR.NAME) => LOC OF PROPS.T[1+>PROPS.I]
;PROPS.I => AS[AP+2]
@BOX 3.1
;%601F => AS[AP]
;0 => AS[AP+1]
;ISS => AS[AP+3]
;AP => NAP => WS[WP] +6 => AP
;1 +> WP
;1 => L.I
@BOX 4.1
;IF LINE.G[SS+1] /= '( OR TY & %40 = 1
@BOX 5.1
;1 +> SS
@BOX 6.1
#FTN04.2.6
@BOX 7.1
;AS[NAP] => T ! LT => AS[NAP]
;IF LT = %800
@BOX 8.1
;IF T & %400 /= 0
@BOX 9.1
;AP=>AS[NAP+4]
;EL=>AS[AP]
;1+>AP=>T+EL=>AP
;WP - E.L => W.P
;WHILE 1 -> E.L > = 0 DO
   ;WS[WP+E.L] => AS[T+E.L]
;OD
@BOX 11.1
;->F4.2B13
@BOX 12.1
;->F4.2B9
@BOX 13.1
;IF EL /= 2
@BOX 14.1
;WS[WP-2] => AS[AP]
;WS[WP-1] => AS[AP+1]
;IF T & %400 /= 0 THEN
   ;AP => AS[NAP+5]
;ELSE
   ;AP => AS[NAP+4]
;FI
;2+>AP
;2 -> WP
@BOX 15.1
;->F4.2B9
@END
@TITLE FTN04.2.6(1,6)
@COL 15R
@COL 1S-2R-3T-4R-5T-6T-7R-8T-9T-10R-11T-12R-13R-14F
@COL 16R-17R-18C
@ROW 15-6-16
@ROW 11-18
@FLOW 1-2-3NO-4-5NO-6NO-7-8NO-9NO-10-11NO-12-13-14
@FLOW 3YES-15-14
@FLOW 5YES-16-17-10
@FLOW 6YES-18
@FLOW 8YES-4
@FLOW 9YES-14
@FLOW 11YES-4
@BOX 1.0
PROCESS AN EXPR
LIST
@BOX 2.0
NOTE LIST TYPE AS
SUBSCRIPT/ARGUMENT
SET EXPR CNT = ZERO
@BOX 3.0
NEXT CHAR =)
@BOX 4.0
INCR EXPR CNT
@BOX 5.0
NEXT CHAR =:
@BOX 6.0
INVALID EXPR
[FTN04.2]
@BOX 7.0
SAVE EXPR PTR ON WS
@BOX 8.0
LAST CHAR = ,?
@BOX 9.0
LAST CHAR = )?
@BOX 10.0
NOTE LIST TYPE AS
SUBSTRING
@BOX 11.0
NEXT CHAR /=)
@BOX 12.0
GET CHAR
@BOX 13.0
INCR EXPR CNT
PUT A ZERO PTR ON WS
@BOX 14.0
END
@BOX 15.0
GET
CHAR
@BOX 16.0
GET CHAR
@BOX 17.0
PUT ZERO PTR FOR
EXPR ON WS
@BOX 18.0
EXPR FAULT
[FTN04.2]
@BOX 1.1
@BOX 2.1
;%400 => L.T
;0 => E.L
@BOX 3.1
;IF LINE.G[SS+1] = ')
@BOX 4.1
;1 +> E.L
@BOX 5.1
;IF LINE.G[SS+1] = ':
@BOX 6.1
;IF REC.EXPR(TY & %80 ! %1C) => WS[WP] < 0
@BOX 7.1
;1 +> WP
@BOX 8.1
;IF LINE.G[1+>SS] => CH =  ',
@BOX 9.1
;IF CH = ')
@BOX 10.1
;%800 => L.T
@BOX 11.1
;IF LINE.G[SS+1] /= ')
@BOX 12.1
;1 +> SS
@BOX 13.1
;1 +> E.L
;0 => WS[WP]
;1 +> WP
@BOX 14.1
@BOX 15.1
;1 +> SS
@BOX 16.1
;1 +> SS
@BOX 17.1
;0 => WS[WP]
;1 +> WP
@BOX 18.1
;->F4.2B13
@END
@TITLE FTN04.2.7(1,6)
@COL 1S-2R-3T-4R-5R-6C
@COL 8F
@ROW 4-8
@FLOW 1-2-3NO-4-5-6
@FLOW 3YES-8
@BOX 1.0
PROCESS A CONSTANT
@BOX 2.0
DETERMINE IF COMPLEX CONSTANT
PERMITTED
IE. BRACKETED SUBEXPRESSION
AND LAST ITEM A TERMINATOR
OPERATOR
@BOX 3.0
INVALID CONSTANT?
[FTN04.4]
@BOX 4.0
PUSH TERMINAL NODE TO AS
PUSH NODE PTR TO WS
@BOX 5.0
NOTE LAST ITEM PROCESSED
AN OPERAND
@BOX 6.0
PROCESS NEXT
ITEM
[FTN04.2]
@BOX 8.0
EXPR
FAULT
[FTN04.2]
@BOX 1.1
; F4.2.7B1:
@BOX 2.1
;IF TY & %20 /=0 AND L.I = 0 AND WS[WP-2] = 0 THEN
   ;0=> T
;ELSE
   ;2 => T
;FI
@BOX 3.1
;IF REC.CONST(T) < 0
@BOX 4.1
;WS[WP-2] <<- 12 ! %10 => AS[AP]
;0 => AS[AP+1]
;WS[WP-1] => AS[AP+2]
;ISS => AS[AP+3]
;AP => WS[WP-2]
;4 +> AP
;1 -> WP
@BOX 5.1
;1 => L.I
@BOX 6.1
;-> F4.2B9
@BOX 8.1
;->F4.2B13
@END
@TITLE FTN04.3(1,11)
@COL 1S-2R-3T-5R-8N-6R-7F
@FLOW 1-2-3NO-5-3
@FLOW 3YES-6-7
@BOX 1.0
REC.NAME()
@BOX 2.0
SET CNT = 0
record start of name
@BOX 3.0
NEXT CHAR FROM ITEMISED
LINE
NEITHER DIGIT NOR LETTER?
@BOX 5.0
increment character count
@BOX 6.0
make a bounded pointer to
the name
@BOX 7.0
END
@BOX 1.1
;PROC REC.NAME
;$LO8 CH :: ??? JM 29-DEC-82
;$IN CHAR.COUNT, FIRST.CHAR.POS
@BOX 2.1
;0 => CHAR.COUNT
;SS + 1 => FIRST.CHAR.POS
@BOX 3.1
 :: ??? JM 29-DEC-82
;IF LINE.G[1+>SS] => CH /= '$$ /= '_
 AND ST.CH[CH] > 35
@BOX 5.1
;1 +> CHAR.COUNT
@BOX 6.1
;PART (^LINE.G, FIRST.CHAR.POS, 1->SS)
       => NAME OF CURNAME
@BOX 7.1
;END
@END
@TITLE FTN04.4(1,11)
@COL 13T-14R-15R-16C-17T-18R-19R-20C-21C
@COL 1S-2T-22T-4T-5T-6T-23T-7R-8T-9T-10R-11R-12F
@ROW 13-5
@ROW 21-12
@FLOW 23NO-7
@FLOW 2NO-22NO-23YES-21
@FLOW 1-2YES-4NO-5NO-6NO-7-8NO-9NO-10-11-12
@FLOW 22YES-21
@FLOW 4YES-13NO-14-15-16
@FLOW 13YES-17NO-18-19-20
@FLOW 17YES-21
@FLOW 5YES-12
@FLOW 6YES-12
@FLOW 8YES-21
@FLOW 9YES-21
@BOX 1.0
REC.CONST(TYPE)STATUS
TYPE 0 - ANY
     1 - COMPLEX ONLY
     2 - ANY BUT COMPLEX
@BOX 2.0
NOT COMPLEX ONLY?
@BOX 4.0
INVALID ARITH CONST
[FTN04.5]
@BOX 5.0
NEXT CHAR NOT ,
@BOX 6.0
COMPLEX NOT ALLOWED
OR CONSTANT DP
@BOX 7.0
GET CHAR
@BOX 8.0
INVALID ARITH CONST
[FTN04.5]
@BOX 9.0
NEXT CHAR NOT )?
@BOX 10.0
ALLOCATE AND
INITIALISE COMPLEX
CONVERT COMPLEX COMPONENTS
TO REAL IF NECESSARY
@BOX 11.0
PUSH COMPLEX ENTRY
TO WS
@BOX 12.0
END
- OK
@BOX 13.0
NOT LOGICAL
CONSTANT
@BOX 14.0
GET LOGICAL
CONSTANT FROM
ITEMISED LINE
@BOX 15.0
PUSH LOGICAL
CONSTANT ENTRY
TO WS
@BOX 16.0
END - OK
@BOX 17.0
NOT CHARACTER
CONSTANT
@BOX 18.0
GET CHARACTER
CONSTANT INFO FROM
ITEMISED LINE
@BOX 19.0
PUSH CHARACTER
CONSTANT ENTRY TO
WS
@BOX 20.0
END - OK
@BOX 21.0
END -
FAIL
@BOX 22.0
INVALID ARITH
CONST [FTN04.5]
OR DP CONST
@BOX 23.0
NEXTCHAR NOT ","
@BOX 1.1
;PROC REC.CONST(TY)
;$IN CH
;ADDR CONST.PROP CP, CPR
;0 => REC.CONST
@BOX 2.1
;IF TY /= 1
@BOX 13.1
;IF CH /= L.TRUE.L /= L.FALSE.L
@BOX 14.1
;1+>SS
;MAKE.CONST.PROP(LINE.SPACE) => C.P
;IF CH = L.TRUE.L THEN
   ;TRUE.CONST.L => LOG.CONST OF C.P^
;ELSE
   ;FALSE.CONST.L => LOG.CONST OF C.P^
;FI
@BOX 15.1
;4 => WS[WP]
;C.P => CONST OF PROPS.T[1 +> PROPS.I]
;PROPS.I => WS[WP+1]
;2+>WP
@BOX 16.1
;EXIT
@BOX 17.1
;IF CH /= MARK.HOL.L /= MARK.CH.L
@BOX 18.1
;1+>SS
;BYTE(^LINE.G[SS+1]) => ADDRESS OF PROPS.T[1+>PROPS.I]
;PROPS.I => WS[WP+1]
;WHILE LINE.G[1+>SS] /= 0 DO
   ::NOTHING
;OD
@BOX 19.1
:: @@@ BCT 30-DEC-82
;IF CH = MARK.HOL.L THEN
    7 => WS[WP]
   ;FAULT(154,6)
 ELSE 5=>WS[WP] FI
:: @@@ BCT 30-DEC-82
;2+>WP
@BOX 20.1
;EXIT
@BOX 21.1
;-1 => REC.CONST
;EXIT
@BOX 4.1
;LINE.G[1+SS] => CH :: @@@ BCT 29-DEC-82
;IF REC.ARITH.CONST() < 0
@BOX 5.1
;IF LINE.G[SS+1] /= ',
@BOX 6.1
;IF TY = 2 OR WS[WP-2]=1
@BOX 7.1
;1 +> SS
@BOX 8.1
;IF REC.ARITH.CONST() < 0 OR WS[WP-2] = 1
@BOX 9.1
;IF LINE.G[SS+1] /= ')
@BOX 10.1
;CHANGE.CONST.TYPE(CONST OF PROPS.T[WS[WP-3]],WS[WP-4],2)
;IF WS[WP-2] /= 0 THEN
   ;CHANGE.CONST.TYPE(CONST OF PROPS.T[WS[WP-1]],WS[WP-2],0)
;FI
;2=>WS[WP-4]
;CONST OF PROPS.T[WS[WP-3]] => CP;
;CONST OF PROPS.T[WS[WP-1]] => CPR
;REAL.CONST OF CPR^ => I.COMP.CONST OF CP^
;2 -> WP
@BOX 11.1
::DONE IN BOX 10
@BOX 12.1
;END
@BOX 22.1
;IF REC.ARITH.CONST() < 0 OR WS[WP-2] = 1
@BOX 23.1
;IF LINE.G[SS+1] /= ',
@END
@TITLE FTN04.5(1,11)
@COL 18R-26R-19T-20R
@COL 1S-5T-2T-4T-8T-3R-6T-7R-10T-11T-27T-25R-12R-13T-14R-22T-16R-24R-17F
@COL 9R-33R-36R-15T-34T-29R-28R-32R-21C-23R-35N
@ROW 4-9
@ROW 16-23
@ROW 18-7
@ROW 26-27
@ROW 19-14-21
@FLOW 1-2N-4N-5N-8N-3-6NO-7-10NO-11NO-27NO-25-12-13NO-14-22NO-16-24-17
@FLOW 22YES-23-35-24
@FLOW 2Y-9-36-35
@FLOW 4Y-33-36
@FLOW 5Y-15N-34N-29-32-35
@FLOW 34Y-21
@FLOW 15Y-28-32
@FLOW 8Y-21
@FLOW 6YES-18-11YES-26-12-13YES-21
@FLOW 27YES-19NO-20-24
@FLOW 19YES-16
@FLOW 10YES-21
@BOX 1.0
REC.ARITH.CONST()STATUS
@BOX 2.0
SET SIGN EXPSIGN = 1
NOTE NO EXPONENT
SET CONSTANT SIGN[FTN04.5.1]
IS CH = " FOR OCTAL CONSTANT
@BOX 4.0
IS CH = % FOR HEX CONSTAT
@BOX 5.0
IS A STRING (POSSIBLY A TYPELESS CONSTANT)
@BOX 8.0
IS IS OBVIOUSLY AN ILLEGAL NUMBER
@BOX 3.0
NOTE LINE PTR TO INTEGER
PART OF N0
MAKE A CONSTANT ENTRY
SKIP DIGITS
@BOX 6.0
NOTE LINE PTR TO
FRACTIONAL PART OF NUMBER
IS NEXT CH NOT '.'
@BOX 7.0
SET TYPE AS REAL
SKIP DIGITS
@BOX 10.0
NO FRAC PART AND NO
INT PART?
@BOX 11.0
NEXT CH ="D"?
@BOX 12.0
GET CH
SET EXPONENT SIGN [FTN04.5.2]
@BOX 13.0
NO EXPONENT
(NEXT CH NOT DIGIT)?
@BOX 14.0
READ UNSIGNED EXPONENT [FTN04.6]
ADD ITS SIGN
@BOX 22.0
DP CONSTANT?
@BOX 17.0
END
@BOX 16.0
CREATE FL PT NUMBER
ASSIGN TO
CONSTANT ENTRY
@BOX 18.0
SET TYPE AS INTEGER
@BOX 19.0
TYPE NOT INTEGER
@BOX 20.0
CREATE INTEGER
ADD ITS SIGN
ASSIGN TO CONSTANT ENTRY
@BOX 27.0
CH/= 'E'
@BOX 25.0
SET TYPE REAL
@BOX 26.0
SETTYPE DP
@BOX 24.0
PUSH CONSTANT TYPE
AND VALUE PTR TO WS
@BOX 9.0
RECOGNISE OCTAL CONSTANT:FTN04.5.3:
@BOX 36.0
ISSUE WARNING
MAKE INTEGER CONSTANT NODE
@BOX 33.0
RECOGNISE HEX CONSTANT:FTN04.5.4:
@BOX 15.0
IS IT A TYPELESS OCTAL CONSTANT
@BOX 34.0
IS IT A TYPELESS HEX CONSTANT
@BOX 28.0
RECOGNISE OCTAL CONSTANT:FTN04.5.3:
@BOX 29.0
RECOGNISE HEX CONSTANT:FTN04.5.4:
@BOX 32.0
ISSUE WARNING
MAKE TYPELESS CONSTANT NODE
@BOX 21.0
END-
FAIL
@BOX 23.0
CREATE DP FL PT NUMBER
ASSIGN TO CONSTANT
ENTRY
@BOX 1.1
;PROC REC.ARITH.CONST
;$IN S,T1,E.S,TY,CH,EX,FEX
;$IN INT.ST,FRAC.ST
;$IN32 V
;ADDR CONST.PROP CP
:: @@@ BCT 29-DEC-82 start of new code
;$LO64 TYPELESS
;P.SPEC REC.OCT.CONST(LABEL,$LO64)/$LO64
;P.SPEC REC.HEX.CONST(LABEL,$LO64)/$LO64
#FTN04.5.3
#FTN04.5.4
;->SKIP;BOX21:->B21;SKIP:
@BOX 2.1
;1 => S => E.S
;0 => EX
#FTN04.5.1
;IF LINE.G[SS+1] => CH = '"
@BOX 4.1
;IF CH = '%
@BOX 5.1
;IF LINE.G[SS+1] = MARK.CH.L
@BOX 8.1
;IF [ST.CH[CH] < %1A OR ST.CH[CH] > %23]
     AND CH /= '. /= '+ /= '-
@BOX 3.1
:: @@@ BCT 29-DEC-82 end of new code
;MAKE.CONST.PROP(LINE.SPACE) => CP
;SS+1 => INT.ST
;WHILE ST.CH[LINE.G[SS+1]] >= %1A =< %23 DO
           1+> SS OD
@BOX 6.1
;IF LINE.G[SS+1 => FRAC.ST] /= '.
@BOX 7.1
;0=>TY
;1+>FRAC.ST
;WHILE ST.CH[LINE.G[1+>SS+1]] >= %1A =< %23 DO OD
@BOX 10.1
;IF INT.ST = SS
@BOX 11.1
;IF LINE.G[SS+1] => CH = 'D
@BOX 27.1
;IF CH /= 'E
@BOX 25.1
;0 => TY
@BOX 12.1
;1+>SS
#FTN04.5.2
@BOX 13.1
;IF ST.CH[LINE.G[SS+1]] => CH < %1A OR CH > %23
@BOX 14.1
;READ.I(^SS,E.S) => EX :: @@@ BCT 29-DEC-82
@BOX 22.1
;IF TY = 1
@BOX 18.1
;3 => TY
@BOX 26.1
;1 => TY
@BOX 19.1
;IF TY /= 3
@BOX 20.1
:: @@@ BCT 29-DEC-82 Start of new code
; 1 -> INT.ST
; READ.I (^INT.ST,S) => INT.CONST OF C.P^
:: @@@ BCT 29-DEC-82 End of new code
@BOX 24.1
;TY => WS[WP]
;CP => CONST OF PROPS.T[1+>PROPS.I]
;PROPS.I => WS[WP+1]
;2 +> WP
@BOX 17.1
;0 => REC.ARITH.CONST
;END
@BOX 16.1
:: @@@ BCT 29-DEC-82
;READ.REAL(INT.ST,FRAC.ST,S,EX,MIN.R.EXPONENT,MIN.R.MANTISSA,
         MAX.R.EXPONENT,MAX.R.MANTISSA,MAX.R.RESOLUTION)
;E.DP.G=>REAL.CONST OF C.P^
@BOX 9.1
:: @@@ BCT 29-DEC-82 Start of new code
;REC.OCT.CONST(BOX21,MAX.INT.OCT.MASK.L) => INT.ST
@BOX 33.1
;REC.HEX.CONST(BOX21,MAX.INT.HEX.MASK.L) => INT.ST
@BOX 36.1
;MAKE.CONST.PROP (LINE.SPACE) => CP
;INT.ST*S => INT.CONST OF CP^
;3 => TY
;FAULT(155,6)
@BOX 15.1
;SS => INT.ST
;WHILE LINE.G[1+>INT.ST] /= 0 DO OD
;IF LINE.G[1+>INT.ST] => CH = 'O
@BOX 34.1
;IF CH /= 'X
@BOX 29.1
;REC.HEX.CONST(BOX21,MAX.LO64.HEX.MASK.L) => TYPELESS
@BOX 28.1
;REC.OCT.CONST(BOX21,MAX.LO64.OCT.MASK.L) => TYPELESS
@BOX 32.1
;INT.ST => SS
;MAKE.CONST.PROP(LINE.SPACE) => CP
;TYPELESS => T.CONST OF CP^
;8 => TY
;FAULT(156,6)
@BOX 21.1
;B21: -1 =>
 REC.ARITH.CONST
:: @@@ BCT 29-DEC-82 End of new code
;EXIT
@BOX 23.1
:: @@@ BCT 29-DEC-82
;READ.REAL(INT.ST,FRAC.ST,S,EX,MIN.DP.EXPONENT,MIN.DP.MANTISSA,
        MAX.DP.EXPONENT,MAX.DP.MANTISSA,MAX.DP.RESOLUTION)
;E.DP.G => DP.CONST OF CP^
@END
@TITLE FTN04.5.1(1,6)
@COL 2S-3T-4R-5R-6F
@COL 7T-8N
@ROW 4-7
@FLOW 2-3NO-4-5-6
@FLOW 3YES-7NO-8-6
@FLOW 7YES-5
@BOX 2.0
SET SIGN
@BOX 3.0
IS CH NOT "-"?
@BOX 4.0
SET SIGN NEG
@BOX 5.0
GET CHAR
@BOX 6.0
END
@BOX 7.0
CH = "+"?
@BOX 2.1
@BOX 3.1
;IF LINE.G[SS+1] => CH /= '-
@BOX 4.1
;-1 => S
@BOX 5.1
;1 +> SS
@BOX 6.1
@BOX 7.1
;IF CH = '+
@END
@TITLE FTN04.5.2(1,6)
@COL 2S-3T-4R-5R-6F
@COL 7T-8N
@ROW 4-7
@FLOW 2-3NO-4-5-6
@FLOW 3YES-7NO-8-6
@FLOW 7YES-5
@BOX 2.0
SET EXP SIGN
@BOX 3.0
IS CH NOT "-"?
@BOX 4.0
SET EXPSIGN NEG
@BOX 5.0
GET CHAR
@BOX 6.0
END
@BOX 7.0
CH = "+"?
@BOX 2.1
@BOX 3.1
;IF LINE.G[SS+1] => CH /= '-
@BOX 4.1
;-1 => ES
@BOX 5.1
;1 +> SS
@BOX 6.1
@BOX 7.1
;IF CH = '+
@END
@TITLE FTN04.5.3(1,11)
@COL 1S-2T-7R-3T-4R-6F
@COL 5C
@ROW 5-6
@FLOW 1-2N-7-3N-4-3Y-6
@FLOW 2Y-5
@BOX 1.0
REC.OCT.CONST
@BOX 2.0
IS FIRST CHARACTER A VALID DIGIT
@BOX 7.0
ADVANCE LINE PTR
@BOX 3.0
IS NEXT CHARACTER A DIGIT
@BOX 4.0
ACCUMULATE NUMBER
@BOX 5.0
ABORT
@BOX 6.0
END
@BOX 1.1
:: @@@ BCT 29-DEC-82 Start of new code
;PROC REC.OCT.CONST(ABORT,MASK)
;$LO64 RESULT,MONITOR
;$LO8 CH
@BOX 2.1
; ST.CH[LINE.G[1+>SS+1]] - %1A => CH
;IF CH < 0 OR CH > 7
@BOX 7.1
; 0 => MONITOR
; CH => RESULT
; 1 +> SS
@BOX 3.1
; IF ST.CH[LINE.G[1+SS]] - %1A => CH < 0 OR CH > 7
@BOX 4.1
; 1+> SS
; RESULT !> MONITOR
; RESULT <<- 3 ! CH => RESULT
@BOX 5.1
; -> ABORT
@BOX 6.1
; IF MONITOR & MASK /= 0 THEN
      FAULT(159,6) FI
; RESULT => REC.OCT.CONST
 END
@END
@TITLE FTN04.5.4(1,11)
@COL 1S-2T-7R-3T-4R-6F
@COL 5C
@RWO 5-6
@FLOW 1-2N-7-3N-4-3Y-6
@FLOW 2Y-5
@BOX 1.0
REC.HEX.CONST
@BOX 2.0
IS FIRST CHARACTER A VALID DIGIT
@BOX 7.0
ADVANCE LINE PTR
@BOX 3.0
IS NEXT CHARACTER A DIGIT
@BOX 4.0
ACCUMULATE NUMBER
@BOX 5.0
ABORT
@BOX 6.0
END
@BOX 1.1
;PROC REC.HEX.CONST(ABORT,MASK)
;$LO64 RESULT,MONITOR
;$LO8 CH
@BOX 2.1
;IF ST.CH[LINE.G[1+>SS+1]] => CH >= %1A =< %23 THEN
    %1A -> CH
 ELSE IF CH >= 0 =< 5 THEN
    10 +> CH
 ELSE 16 => CH
 FI FI
;IF CH > 15
@BOX 7.1
;CH => RESULT
; 1+> SS
; 0 => MONITOR
@BOX 3.1
; IF ST.CH[LINE.G[1+SS]] => CH >= %1A =< %23 THEN
     %1A -> CH
  ELSE IF CH >= 0 =< 5 THEN
     10 +> CH
  ELSE 16 => CH
  FI FI
; IF CH > 15
@BOX 4.1
; 1+>SS
; RESULT !> MONITOR
; RESULT <<- 4 ! CH => RESULT
@BOX 5.1
; -> ABORT
@BOX 6.1
; IF MONITOR & MASK /= 0 THEN
     FAULT(159,6) FI
; RESULT => REC.HEX.CONST
 END
@END
@TITLE FTN04.6(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
READ.I()INT
@BOX 2.0
READ INTEGER
FROM
ITEMISED LINE
@BOX 3.0
END
@BOX 1.1
;PROC READ.I(SS,SIGN)
;$IN I, CH, LAST.DIG
@BOX 2.1
;0 => READ.I
;(IF SIGN = 1 THEN MAX.INT.M.TEN ELSE MAX.INT.M.TEN+1) => LAST.DIG
;WHILE ST.CH[LINE.G[SS^+1]] - %1A => CH >= 0 =< 9 DO
  ;IF READ.I < MIN.INT.D.TEN OR [READ.I = MIN.INT.D.TEN AND CH > LAST.DIG] THEN
       MIN.INT.D.TEN * 10 - LAST.DIG * (0 - 1) * SIGN => F.I.G => READ.I
       ; FAULT (158,8)
       ;-> ABORT FI
   ;READ.I * 10 - CH => READ.I
   ;1+>SS^
;OD
; 0 - 1 * SIGN *> READ.I
@BOX 3.1
;ABORT:
;END
@END
@TITLE FTN04.7(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
READ REAL(INT PTR, FRAC PTR, SIGN, EXP)
@BOX 2.0
CALCULATE CONSTANT
IN PRECISION TO ENSURE MAX ACCURACY
@BOX 3.0
END
@BOX 1.1
;PROC READ.REAL(I.P,F.P,S,EX,MIN.EX,MIN.MAN,MAX.EX,MAX.MAN,RES)
;$IN CH,T
@BOX 2.1
;0.=>E.DP.G
;0 => T
;WHILE ST.CH[LINE.G[IP]] - %1A =>CH >= 0 =< 9 DO
  ;IF CH = 0 THEN
    ;IF T /= 0 THEN
        1 +> T
       ;1 +> EX
     FI
   ELSE
    ;CH * N.POWER(1+>T,RES) +> E.DP.G
    ; 1+> EX
   FI
  ;1+>IP
;OD
;WHILE ST.CH[LINE.G[FP]] - %1A => CH >= 0 =< 9 DO
   IF CH = 0 THEN
      IF T /= 0 THEN
         1 +> T
      ELSE
        ;1 -> EX
      FI
   ELSE
     ;CH * N.POWER(1+>T,RES) +> E.DP.G
   FI
  ;1+>F.P
;OD
;IF EX > MAX.EX OR [EX = MAX.EX AND E.DP.G > MAX.MAN] OR
    EX < MIN.EX OR [EX = MIN.EX AND E.DP.G < MIN.MAN] THEN
    ;IF EX > 0 THEN MAX.MAN/N.POWER(MAX.EX,MIN.EX)=>E.DP.G
               ELSE MIN.MAN*N.POWER(0-MIN.EX,MIN.EX)=>E.DP.G FI
    ;(IF EX<0 THEN MIN.EX ELSE MAX.EX) => F.I.G
    ;FAULT(157,8)
 ELSE IF EX < 0 THEN
     N.POWER(0-EX,MIN.EX) *> E.DP.G
 ELSE IF EX > 0 THEN
     N.POWER(MIN.EX+MAX.EX-:EX,MIN.EX) /> E.DP.G
    ;N.POWER(MAX.EX+MIN.EX,MIN.EX) /> E.DP.G
 FI FI
FI
;IF S< 0 THEN
  ;0. - 1. *> E.DP.G
;FI
@BOX 3.1
;END
@END

@TITLE FTN04.8(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
N.POWER(I)
@BOX 2.0
GENERATE NEGATIVE POWER OF TEN
@BOX 3.0
END
@BOX 1.1
;PROC N.POWER(T,RESOLUTION)
;$IN I
@BOX 2.1
;IF T > 0-RESOLUTION THEN 0. => N.POWER; EXIT FI :: ??? JM 10-JAN-83
;1. => N.POWER
;10. => E.DP.1.G
;0 => I
;LOOP : IF T & 1 /= 0 THEN
           E.DP.1.G /> N.POWER FI
        ; IF T ->> 1 => T = 0 THEN EXIT FI
        ; E.DP.1.G *> E.DP.1.G
        ; -> LOOP
@BOX 3.1
END
:: @@@ BCT 30-DEC-82 End of new code
@END


