@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                   MUSS
~
~
~HVOLUME        14
~D5
~M~OCOMPILERS WRITERS UTILITIES MANUAL~
~BThis volume contains the implementation of utilities used in
compiler writing for MUSS. The utilities include SYNTAB for parser
generation, and an OUTPROG procedure to decode compiled binary.~
~D12
~MUNIVERSITY OF MANCHESTER
~V9 -1
~P
~D10
~MVolume 14 CONTENTS~
~
~
~MCWU011   -   SYNTAB           ~
~
~NCWU023   -   Disassembler for VAX11~
~
~NCWU025   -   Disassembler for MC68000~
~
~NCWU027   -~
~V9 -1
~P
~D10
~H                    MUSS
~
~
~D10
~H            CWU011
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                           ISSUE 11~
~V9 -1
~P
~V9 1
~YCWU011
~S1~M~OCOMPILER WRITERS UTILITIES
~S1~M~OSection 1
~S1~OSection 1. SYNTAB
~S1~O1.1 General Description
~S1~O1.1.1 Introduction
~BSYNTAB is a Syntax Processing Package which allows a translator
written largely in MUSL to have its syntax phase defined by a
notation similar to that of BNF. First the package translates the
syntax specification into MUSL then sends the resulting code to a
file for compilation by the MUSL compiler. This MUSL code needs
a SCAN procedure which may be called within the compiler. When
entered this procedure attempts to match some text supplied in a
vector parameter with the automatically generated vector containing
the encoded form of the specified syntax. The SCAN procedure uses
a top-down fastback technique.
~S1~O1.1.2 The Notation for Describing Syntax
~BThe syntax specifications must appear at the beginning of the
translator and be delimited by:-~
~
         BEGIN SYNTAX SPEC~
   and   END~
~
Thus a translator has the form:-~
~
         BEGIN SYNTAX SPEC~
         <SYNTAX SPEC>~
         END~
         <AUTOCODE PROGRAM>~
~
There are five components in the SYNTAX SPEC the main two of
which define the synes and cosynes.~
~
      <SYNTAX SPEC> =~
         <DELIMITER LIST>~
         <PROCEDURE LIST>~
         <COSYNE LIST>~
         <SYNE DEFINITIONS>~
         <COSYNE DEFINITIONS>~
~BSyne definitions are syntactic rules of the languages written
as in BNF except for these differences:-~
~T# 9
~
   1.~IStylistic differences. The word SYNE must precede each
definition and ::= is replaced by =.~
   2.~IDifferences in ordering. The order of alternatives and
of elements within alternatives are both different. Syne formulae
are used by a left to right scanning algorithm which requires that:-~
~T# 13
         (a)~IAny alternative which is a stem of another comes after it.~
         (b)~IIf one alternative is a special case of another it
must come first.~
         (c)~IIn recursive definitions there must be at least
one leftmost element not recursive.~
~T# 9
   3.~IMetalinguistic Bracketing. Several alternatives may be
specified as an element of another by enclosing them in square
brackets.~
   4.~IThose syne definitions which are to be referenced by the autocode
part of the compiler, (e.g., as parameters of the scan routine) must be
preceded by a *. The result of this will be that a CONST declaration
is generated to associate the syne name with the position allotted to
it in a DATA VEC 'SYNES'.~
   5.~IAlternatives within syne definitions must be less than 128
elements long.~
~
~IFor example, a definition of <STATEMENTS> might take the form:-~
~
~ISYNE <STATEMENTS> = <STATEMENT> [<STATEMENTS>|<NULL>]~
~
~Iwhere <NULL> indicates an empty string.~
~BFor both semantic and syntactic reasons it is convenient to be
able to interrupt the scanning algorithm at defined points and execute
code provided by the user. This is achieved by inserting an element
into the syntax which is referred to as if it were a syne but is in
fact defined as the name of a section of code (COSYNE) to be executed
when the scanning algorithm reaches that point.
~BTo make this facility more flexible the cosyne routine may have
one numeric parameter the value of which is defined explicitly
wherever the cosyne is used thus:-~
~
~M<cosyne name (numeric parameter)>
~BCosynes are defined as labelled sequences of Autocode instructions
which operate within the SCAN procedure. Each sequence is labelled with
the name of the cosyne it represents. Cosynes may use the variables and
labels in the scan of which the following are the most useful:-~
~S1AS, WS, LINE, SYNTAX
~BDescriptors mapping the analysis record area, the working stack,
the current statement and the syntax tables, respectively.
~S1AP, WP, SS, SY
~BPointers to the current position in AS, WS, LINE and SYNTAX, respectively.
~S1TRUE, FALSE
~BLabels to which the cosynes may jump on completion.
~BIn a translator it is usual to itemise the input string before
applying the scan. This pre-scan pass may reduce delimiters to single
pseudo symbols. A similar transformation has to be applied to
delimiters appearing in the syntax. These delimiters and the value of
the code to be assigned to them must be listed thus:-~
~
      <DELIMITER LIST> =~
         DELIMITERS<NL>~
         <DELIMITER SPEC>~
         END<NL>~
~
where  <DELIMITER SPEC> = <INTEGER>/<STRING><NL>[<DELIMITER SPEC>|<NIL>]~
~T# 12
~
<INTEGER>~Iis any integer in the range 0 - 255 and is the
code to be assigned to the delimiter specified by,~
<STRING>~Iwhich is any character string but all strings must
begin with the same symbol, (e.g., 'for delimiters in quotes),~
<NL>~Irepresents a newline.~
~BEach procedure name used as the parameter of a cosyne will be
replaced by the integer which indexes its entry in the procedure list.
~S1Formally:-~
~
        <PROCEDURE LIST> = PROCEDURE NAMES<NAME LIST><NL>~
 where  <NAME LIST> = <NAME>[,<NAME LIST>|<NIL>]~
~BThe COSYNE LIST contains the names of all the cosynes used in
the syntax. Its form is:-~
~
        COSYNE NAMES<NAME LIST><NL>~
~S1~O1.1.3 Basic operation.
~BSYNTAB operates on a line-by-line basis. Its action may be
divided into eight phases. In each of these phases some
specification may be input, additions may be made to internal tables
and some program statements may be generated and output. Blank
lines are always ignored where a specification line is expected.
Alternatively, the input text is copied directly to the output
stream where no specification is expected.~
~BThe eight phases are:~
~T# 6
~
1)
~ISYNTAB sets up and initialises its variables and
tables. Information from the call is used to determine the
language of the program statements to be generated.~
~
2)
~IEach line is copied to the output stream until one
reading BEGIN SYNTAX SPEC is encountered.~
~
3)~IOnly one line reading DELIMITERS is accepted.~
~
4)~IDelimiter specifications or a line reading END are
accepted. In the former case an addition is made to the
internal name list. The latter case terminates this
phase.~
~
5)~IOnly one line of the form~
~
~I    PROCEDURE NAMES name, name, .......~
~
~Iis accepted. Each of the names (with a sequence number
associated with it) is added to the internal name list.~
~
6)~IOnly one line of the form~
~
~I    COSYNE NAMES name, name, .......~
~
~Iis accepted. Again each of the names is added to the list
and a sequence number is associated with it.~
~
7)~IOnly syne definitions or a line reading COSYNES is
accepted. The latter case terminates this phase. In the
former case the syne name is added to the name list and
any previous references to it are dealt with. If the
definition is preceded by a * symbol a literal statement
is generated where the number assigned is an index in an
eight bit vector called SYNTAX (see below). It gives the
position in this vector of the encoding for that syne. An
internal coding of each syne definition is added to the
syntax tables. A DATAVEC called SYNTAX is generated from
the internal syntax tables.
A SWITCH called COSYNES is generated.
~
8)~IThe remainder of the input stream is copied directly
to the output stream until a line reading END SYNTAX SPEC
is encountered.~
~P
~S1~MFIGURE 1~
~S1~MSchematic Form of Input~
~
BEGIN SYNTAX SPEC~
DELIMITERS~
128/'BEGIN'~
.~
.~
END~
~
PROCEDURE NAMES name, name, .....~
COSYNE NAMES name, name, .....~
SYNE<name>=---~
*SYNE<name>=---~
.~
.~
COSYNES~
.~
.~
END SYNTAX SPEC~
~S1~MFIGURE 2
~S1~MSchematic Form of Output
~Mfor a MUSL Compiler~
~
LITERAL synename=index;~
.~
.~
DATAVEC SYNTAX($LO8)~
.~
.~
END;~
PSPEC SCAN(ADDR[$LO8],ADDR[$IN],ADDR[$IN],ADDR[$IN],$IN);~
PROCEDURE SCAN(SYNTAX,LINE,AS,WS,START);~
~
->PASSWITCH;~
LOOP2:~
SWITCH SYNTAX[SY]\~
cosyne name,~
.~
.~
cosyne name;~
.~
PASSWITCH:;~
.~
**IN -1~
~S1~O2. Interfaces
~S1~O2.1 Section Interfaces Used
~BNone.
~S1~O2.2 Section Interface
~BLibrary Procedures :   SYNTAB~
~S1~O3. Implementation
~S1~O3.1 Outline of Operation
~S1~ODelimiters
~BThe syntax for delimiter specs is:~
~
   SYNE<DELIMITERS> = DELIMITERS <NL>~
                      <SPECS>~
                      END <NL>~
   SYNE<SPECS> = <SPEC>[<SPECS>!<NIL>]~
   SYNE<SPEC> = <NUMBER>/<BRACKET><STRING><BRACKET><NL>~
~BWhere <NUMBER> is a decimal number which is taken to be modulo
256. And <STRING> is any character string. The string <BRACKET> is
any character but must be the same for all delimiters and different
from any other character in the syntax spec.~
~BWhen processing SYNE statements, SYNTAB will convert any
occurence of any of the delimiter strings specified to the
corresponding 8 bit number.~
~BThe delimiter specs are stored in the name list with TYPE = 4 and
VALUE = <NUMBER>. The string bracket is stored as the last character
of the name. This serves to distinguish the delimiter from any other
name type.~
~BThe analysis record for a delimiter spec is of the form:~
~T% 10
~3
~
%&                                  ~
%|~
%\\\\\ value &~
%            |~
%            hash value  no.  chars of name~
~0
~S1~OProcedure Names
~BThe numeric parameter to a cosyne in SYNTAB syntax specifications
may be given as a procedure name.~
~BThe names of all such procedures must be specified in a procedure
list whose syntax is:~
~
~MSYNE<PROC.LIST> = PROCEDURE NAMES <NAME.LIST><NL>~
~NSYNE<NAME.LIST> = <NAME><REPEAT.IF((,))>~
~BContinuation of the list onto the next line is achieved by ending
the line with a # symbol.~
~BThe procedure names are allocated numbers according to their
position in this list (starting at 0).~
~BEach procedure name is added to the SYNTAB name list with TYPE =
2 and VALUE = sequential number.~
~BThe analysis record for a procedure list is of the form:~
~3
~
%&                              ~
%|~
%\\\\\ count &  &  ..  &~
%            ~O|  |      |~
%            |~
%            hashvalue  no.  chars of name~
~0
~S1~OCosynes~
~BThe name of all cosynes used in syne definitions are specified
by a statement whose syntax is~
~
~MSYNE<COSYNE.LIST>=COSYNE NAMES<NAME.LIST><NL>~
~BContinuation of the list onto the next line is achieved by ending
the line with a # symbol.~
~BThe cosyne names specified in a <COSYNE LIST> are added to the
name list. Only these cosynes may be referred to in the following
syne definitions. An index table is also filled with pointers to
the relevant namelist positions (see figure 3). The first ten
positions are reserved.~
~BIf after processing all of the syne definitions, any names have
been referred to but not defined, SYNTAB produces a relevant fault
message. At this time, cosyne names are output as part of a DATAVEC
called COSYNES. The above mentioned index table is used to order
the calls.~
~BThe analysis record for a cosyne list has the form:~
~3
~
%&                                 ~
%|~
%\\\\\ count & FL & FL & FL . . .~
%            ~O|    |    |~
%            |~
%            hashvalue  no.  chars of name~
~
~
%FL = 0    8 bit parameter~
%FL = 1    16 bit parameter~
~0
~P
~S1~MFIGURE 3~
~
~3
%Cosyne Index Table~
~
~
~
~
~%   |     ~O       ~O                                  ~
%   |     |     |~
%   |     |     |~
%cosyne   |     |~
%sequence |     |~
%number   |     |~
%   |     ~O|     |~
%         ~O|  .--|~O------------------~
%         |     |                  |~
%         |     |                  |~
%         |     |                  |~
%         |     |                  |~
%         ~O|     |~O                  |~
%                                  |~
%COSYNE.INDEX.TABLE                |~
%                                  |~
%                             ptr to name list~
%                             entry for this cosyne~
~0
~P
~S1~OSyntax of SYNE Definitions~
~BEach syne definition is recognised according to the syntax:~
~
~MSYNE<SYNE.DEF> =     <MAYBE.STAR> SYNE <<><NAME><>> =~
~N                     <CONVERT.DELIMS><ALTERNATIVES>~
~N                     <VALNL(FORM.SYNE.DEFN)>~
~
~NSYNE<ALTERNATIVES> = <ALTERNATIVE><REPEAT.IF.BAR>~
~
~NSYNE<ALTERNATIVE>  = <ELEMENT><REPEAT.IF.NOT.NL>~
~
~NSYNE<ELEMENT>      = <SYNE.OR.COSYNE>        <VAL(0)> !~
~N                     <<><SPECIAL.SYMBOL><>>  <VAL(1)> !~
~N                     <ORDINARY.SYMBOL>       <VAL(1)> !~
~N                     <[><ALTERNATIVES><]>    <VAL(2)>~
~
~NSYNE<SYNE.OR.COSYNE> =    <<>NAME>[(<NAME><CHECK.PROC>)!~
~N                     (<CONSTANT.STRING)!<IN(0)>]<>><UP>~
~NSYNE<MAYBE.STAR> = [*<IN(1)> ! <IN(0)>] <UP>~
~T# 20
~
~
<CONVERT.DELIMS>
~Iis a cosyne whose action is to convert
any delimiter strings in the syne definition to their
corresponding eight bit codes. This eight bit code
replaces the first bracket of the string and a space
filler is used.~
~
<CONSTANT.STRING>
~Iis a cosyne which recognises any
sequence of symbols up to the matching closing round
bracket.~
~
<CHECK.PROC>
~Iis a cosyne which checks that the previously
recognised name is a procedure name and substitutes its
sequence number in the analysis record.~
~
<SPECIAL.SYMBOL>
~Iis a cosyne which recognises the symbols
<>![]!.~
~
<ORDINARY.SYMBOL>
~Irecognises any one symbol other than a
special symbol or newline.~
~BContinuation of the syne onto the next line may be achieved by
~T& 2
ending the line with a # symbol.~
~T# 20
~BThe analysis record form for a syne definition is shown in figure
4 and the internal form of syntax table generated is shown in figure
5.~
~P
~S1~MFIGURE 4~
~3
~
~MAnalysis Record for a Syne Definition~
~
~
~
~
&~
|~
|~
star       &    &~
           |    |~
           |    |~
           name & & & . . . -1~
                ~O| | |~
                |~
                & & & . . . -1~
                | | |~
             ~O   | | |~
             |~
             |~
syne or      |~
cosyne       |-0 &       &        or  --------  0 & 0~
             |   |       |                        |~
             |   name   {0 symbol string 0        name~
             |          {1 proc.seq.no~
             |~
             |~
symbol       |-1 symbol~
             |~
             |~
             |~
bracketed    |~
alternatives |-2 &~
                 |~
                 |~
                 & & . . . -1~
                 ~O| |~
                 |~
                 & & . . . -1~
                 ~O| |~
                 |~
~0
~P
~S1~MFIGURE 5~
~
~MForm of Internal Syntax Table in Syntab~
~
~
Element Type            Content of Internal Syntax Tables~
~
BRANCH-----------------{0~
                       {Relative distance from first word of~
                       {next alternative~
~
SYMBOL-----------------{1~
                       {Internal code of symbol (negated)~
~
SYNE-------------------{2~
                       {Index in tale of encoding for this~
                       {syne (two locations)~
~
MERGE------------------{3~
                       {Relative distance from first word of~
                       {merge point~
~
UP---------------------{4~
~
ENDFALSE---------------{5~
~
ENDTRUE----------------{6~
~
COSYNE           }-----{Sequence number~
with no parameter}     {0~
~
COSYNE          }------{Sequence number~
with a parameter}      {number 0-255 stored if param is number~
                       {or pointer - 10000 stored if symbol string~
                       {appearing within brackets ()~
~S1Notes
~T# 6
~
1)
~ICosyne sequence numbers are allocated from 7 upwards
but the first three of these are preallocated as
VAL-7, NOVAL-8 and IN-9.~
~
2)
~IIn order to facilitate the termination algorithm of
the SCAN procedure the first four elements of the syntax
table are loaded as:~
~
~M  ~O   ~
~N| ~O|0|~O(BRANCH)~
~N|-~O|2|~
~N| ~O|5|~O(END FALSE)~
~N| ~O|6|~O(END TRUE)~
~N  | |~
~S1~OThe Syntactic Scan Procedure
~BThe scan procedure has the specification:-~
~
~MPROC SPEC SCAN (S, S, S, S, I32)
~
The parameters are:-~
~T# 8
~
  (i)~IThe string SYNTAX which contains the complete syntax to be
used in the scan and which is set up by the syntax processing phase.
The scan maintains a modifier SY (I32 variable) at the current position
in the syntax tables.~
~
 (ii)~IThe vector LINE with 8-bit or 32-bit elements containing the
text to be recognised. Each element is compared with a byte in the
syntax tables. SS is maintains pointing to the last symbol recognised.
On entry SS = 0.~
~
(iii)~ITwo vectors AS and WS with 8-bit or 32-bit elements as the~
 (iv)~Iuser requires. The modifiers within these vectors are AP
and WP respectively, zeroed on entry to the scan. AS and WS are for
use by the cosynes in generating an analysis record. AS or analysis
space is conventionally the area in which the final analysis record
is built up. WS or work space is the area used as temporary storage
for intermediate levels of the analysis record. These areas are used
for this purpose by the built-in cosynes VAL, NOVAL and IN. WS is
used for output information as follows:-~
~
~IWS[0] = -1 if the scan fails, WS[0] = 1 if it passes.~
~
~IConsistent use of VAL will ensure that WS[1] is a modifier in AS
pointing to the first element of the analysis record. The first free
space in WS, usually WS[2] is the value of the modifier in LINE (SS)
for the last symbol recognised. The analysis record created by the
user starts as WS[1]. AS[0] contains the number of elements in the
complete analysis record (i.e., if the last element is AS[4],
AS[0] = 5).~
~
  (v)~IThe address of the start of the SYNE to be scanned for. This
is the I32 literal constant given by the name of a starred SYNE.~
~S1~OOperation of the Scan Procedure
~S1~OAnalysis Records
~BObviously in BNF no record is kept of the way in which the
source string fits the syne definitions. Also there is no specific
way of recognising the end of an alternative. Both these functions
are performed by cosynes. A terminal cosyne is required at the end
of every alternative in a syne definition. This should generate the
required record and end by transferring control to a specified point
in the scanning routine, where the stack will be adjusted and the
scan continued in the syne definition one level up. Two terminal
cosynes are built into the system, they may be used as models for
others. The first is UP which causes the scan to continue at the
syne definition one level up and generates no analysis record. The
other, VAL, generates an analysis record which as a tree structure
form. The parameter of the reference to the VAL cosyne is entered
as the first element of the current level of tree structure.
~BOn some occasions it may be necessary to record information in
the analysis record without creating a new level of tree structure.
This is achieved by use of the cosyne IN, which inserts its parameter
into the analysis record. Thus analysis records may be produced as
in Figure 3. The pointers are stored as indices in the vector
containing the analysis record.~
~
SYNTAX:~
       SYNE <SENTENCE> = THE[CAT<IN(1)>|DOG<IN(2)>]<VERB>THE WALL<VAL(0)>~
       SYNE <VERB>     = SAT<PREP><VAL(1)>|RAN FROM <VAL(0)>~
       SYNE <PREP>     = [ON<IN(0)>|UPON<IN(1)>]<UP>~
~
INPUT:~
       THE DOG SAT ON THE WALL~
~
~3
ANALYSIS RECORD:~
              |~
             ~O|    ~
            |~O0|2|.~O|~
                  |~
                 ~O|  ~
                |~O1|0~O|~
~
         ~OFigure 3. Analysis Records~
~S1~OCosynes
~BThese are labelled sections of code usually delimited by BEGIN and
END. Several are built into the scan procedures and these are:-~
~
~MBRANCH, SYMBOL, SYNE, MERGE, UP, ENDFALSE, ENDTRUE, VAL, NOVAL, IN
~BThe VAL, UP and IN cosynes have already been discussed. The
cosyne NOVAL acts as VAL but has no parameter and does not precede the
analysis record level with a number. The other built in cosynes are
of less interest to the user.
~BA reference to the UP cosyne occupies one 8-bit element of the
internal encoding of the syntax; a syne reference occupies 3 elements
and all other cosyne references occupy 2 elements.
~BThe second of the 2 elements occupied by a cosyne holds the
parameter and this may be accessed within the cosyne as:-~
~
~MSYNTAX1[SY]
~BCosynes may insert information onto the current level of analysis
record by storing to:-~
~
~MWS[WP]
and advancing the index WP. They may also access the next symbol to be
recognised as:-~
~
~MLINE[SS + 1]
~
If a symbol is recognised thus, then the index SS should be advanced.
~BCosynes should normally exit to one of the two built in labels
TRUE or FALSE - according to whether recognition is to proceed or to
backtrack in the syntax.
~S1~O3.2 Data Structures
~
~OStorage of Names~
~BSyntactic recognition of names in SYNTAB results in an analysis
record of the form:-~
~
~M&                                ~
~N|~
~Nhashvalue  no.  chars of name....~
~
They are stored on a namelist with the form shown in figure 6.~
~BThe type number and value for each name have the following
interpretation~
~
~MTYPE-    TYPE                   VALUE                      ~
~N-NUMBER~
~N0        FORWARD REFCE.         POINTER TO A REFERENCE LIST~
~N1        SYNE                   POINTER TO STORE POSN.~
~N2        PROCEDURE              SEQUENTIAL NUMBER~
~N3        COSYNE 8bit parameter  SEQUENTIAL NUMBER~
~N4        DELIMITER              DELIMITER VALUE~
~N5        COSYNE 16bit parameter SEQUENTIAL NUMBER~
~
The reference list takes the form given in figure 7.~
~V2 -10
~Q 38
~S1~MFIGURE 6~
~3
~
~MStorage of Names~
~
~
 ------~
|      |   |~
|      |   |~
|      | hash value~
|      | of name~
|      |   |~
|      |   |~
|------|~
|   ---|---------       ------------------------------------------~
|------|        |                 | | |        |       ~
|      |        |       ------------------------------------------~
|      |        |       NAMES       |~
|      |        |                   |~
 ------         |                   |~
hash list: first|                   |~
64 entries      |                   |~
of NAME.LIST    |                   |~
table           |                   |~
                |                   |NAME.SPACE-----------~
                |                   |points to next      |~
                |                   |available position  |~
                |                   |                    |~
      ----------------------------------------------------~
              |   |type|value|count|  |  |0|t|v|c|chars|  ~
      ----------------------------------------------------~
 NAME.LIST      |                         |~
                 -------------------------~
                   ptr to next name~
                   with same hash~
                   value (0 indicates~
                   last such name)~
~P
~V2 -15
~S1~MFIGURE 7~
~
~MReference Chain Mechanism~
~
~
~
                                  Syne entry in NAME.LIST table~
                                  -----------------------------------------~
                                      |ptr|type|value|count|ptr to name|~
                                  -----------------------------------------~
                             NAME.LIST              |~
                                                    |~
            -------------------                     |~
           |                   |                    |~
     ------------------------------------------------------------------~
          | |table posn |     | |table posn |      | |table posn |       ~
          | |of syne ref|     | |of syne ref|      | |of syne ref|~
     ------------------------------------------------------------------~
REF.LIST                       |                    |             |~
                                --------------------              |~
        0 indicates                                               |~
        last reference      ptr to next reference                 |~
        to this syne        to syne in reference                  |~
                            chain                                 |~
                                                                  |~
                                               REF.SPACE points---~
                                               to next~
                                               available~
                                               position~
~V2 0
~0
~S1~O4. Compile Jobs
~S1~O4.1 Compile CWU for paged machines.
::BEGIN CWU FOR PAGED MACHINES~
DO 0 CWU\?LOG %200~
LIB MSLX~
LIB MTLX\~
LIB L2X\~
OPENDIR MUSMS~
LIB DIR7\?~
MUSL %0 BCWU\? %605  *FOR MC7*~
MUSL %0 BCWU\? %705          *FOR MC5*~
MUSL %0 BCWU\? %705        *FOR MC5G*~
MUSL %0 BCWU\? %405              *FOR MC3*~
**DI 5 MU6C:CWU011~
**FLIP STR5* 1 0 LB: ->LB; ->LB;~
CWU01~
**ED~
(FD/::MU6G/)E  *FOR MC7*~
(F D/::PTV/)E          *FOR MC5*~
(F D/::PTV/)E        *FOR MC5G*~
(FD/::VAX/)E              *FOR MC3*~
**TLSEG 0 %10000 %2780000 -1 6  *FOR MC7*~
**TLSEG 0 %10000 %00A80000 -1 6         *FOR MC5*~
**TLSEG 0 %10000 %00A80000 -1 6         *FOR MC5G*~
**TLSEG 0 %10000 %7FDD0000 -1 6              *FOR MC3*~
**TLSEG 1 %100 %0 -3 6~
**TLSEG 2 %10000 %1EC0000 -3 6  *FOR MC7*~
**TLSEG 2 %10000 %006C0000 -3 6               *FOR MC5*~
**TLSEG 2 %10000 %001B0000 -1 6               *FOR MC5G*~
**TLSEG 2 %10000 %3B0000 -3 6                   *FOR MC3*~
**TLSEG 4 %100 0 -3 0~
**TLLOAD 1 2~
**TLLOAD 4 6~
**TLLOAD 2 3~
*INFORM %2400;~
**DI 5~
**SI 5~
**EI 5~
DELETE~
MUSL %0 0 %E00  *FOR MC7*~
MUSL %0 0 %F00          *FOR MC5*~
MUSL %0 0 %F00          *FOR MC5G*~
MUSL %0 0 %C00              *FOR MC3*~
**FLIP MU6C:CWU02\ 1 0 LB: ->LB; ->LB; *FOR MC7*~
**FLIP MU6C:CWU02\ 1 0 ;LB: ;->LB!0A! !2C!->LB!0A! *FOR MC5G*~
**FLIP MU6C:CWU02\ 1 0 ;LB: ;->LB!0A! !2C!->LB!0A! *FOR MC5*~
**FLIP MU6C:CWU02\ 1 0 LB: ->LB; ->LB; *FOR MC3*~
CWU02~
**ED           *FOR MC7*~
**ED          *FOR MC5*~
**ED          *FOR MC5G*~
(FD/::MU6/)E         *FOR MC7*~
(F D/::PTV/)E          *FOR MC5*~
(F D/::GEM/)E    *FOR MC5G*~
**DI 5~
**SI 5~
**EI 5~
DELETE~
MUSL %0 %0 %C00~
**FLIP MU6C:MTL111 1 0 LB: ->LB; !2C!->LB;~
MTL11~
**ED~
(F D!::MU6!)E~
**DI 5~
**SI 5~
**EI 5~
DELETE~
::END CWU FOR PAGED MACHINES~
~Y
~V9 -1
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H               CWU011
~V9 -1
~F
@TITLE CWU01(1,6)
@COL 1S-2R-7R-9F
@FLOW 1-2-7-9
@BOX 1.0
COMPILER WRITER UTILITIES
SECTION 1
@BOX 2.0
[IMPORTS CWU01/1]
MODULE HEADING
@BOX 7.0
PROCEDURES IN MODULE
  CWU01.0: SYNTAB
@BOX 9.0
END
@BOX 2.1
#CWU01/1
MODULE(SYNTAB);
@BOX 7.1
LSPEC SYNTAB(ADDR[$LO8],$LO64,$IN);
#CWU01.0
@BOX 9.1
*END
@END
@TITLE CWU01/1(1,11)
@COL 1S
@BOX 1.0
SYNTAB IMPORTS
@BOX 1.1
LSPEC BREAK.OUTPUT($IN);
LSPEC DEFINE.INPUT($IN, ADDR[$LO8],$IN32)/$IN
LSPEC DEFINE.OUTPUT($IN,ADDR[$LO8],$IN32,$IN32)/$IN;
LSPEC CURRENT.OUTPUT()/$IN;
LSPEC IN.CH()/$IN;
LSPEC SPACES($IN);
LSPEC OUT.I($IN32,$IN);
LSPEC CAPTION(ADDR[$LO8]);
LSPEC NEWLINES($IN);
LSPEC OUT.CH($IN);
LSPEC OUT.HEX($LO32,$IN);
LSPEC CURRENT.INPUT()/$IN;
LSPEC SELECT.INPUT($IN);
LSPEC SELECT.OUTPUT($IN);
LSPEC CREATESEGMENT($IN,ADDR);
LSPEC RELEASESEGMENT($IN);
@END
@TITLE CWU01.0(1,10)
@COL 1S-4R-5R-6R-7R-8T-9R-10F
@COL 11R
@ROW 9-11
@FLOW 1-4-5-6-7-8YES-9-6
@FLOW 8NO-11-6
@BOX 1.0
PROC SYNTAB
@BOX 4.0
CWU01.1     DECLARATIONS
CWU01.2     INITIALISATION
CWU01.3     READLINE
CWU01.4     SYNTAX ANALYSIS
@BOX 5.0
SELECT INPUT FROM STREAM
OUTPUT TO CURRENT FILE
@BOX 6.0
READ A LINE
@BOX 7.0
CHECK SYNTAX AND
FORM ANALYSIS RECORD
PRINT LINE AND AS IF MODE SET
@BOX 8.0
RECOGNISED?
@BOX 9.0
SEMANTICS
@BOX 10.0
CWU01.5     SEMANTICS
CWU01.6     SYNTAX TABLE ROUTINES
CWU01.7     NAME LIST ROUTINES
CWU01.8     PRINTLINE AND MONITORFAULT
END
@BOX 11.0
FAULT-LINE
NOT RECOGNISED
@BOX 1.1
PROC SYNTAB( STREAM,COMP,MODE);
PSPEC SCAN(ADDR[$LO8],ADDR[$IN],ADDR[$IN],ADDR[$IN],$IN);
PSPEC FORM.SYNTAX.TABLE($IN,$IN);
PSPEC FORM.SYNTAX.ELEMENT($IN);
PSPEC LOOK.UP.NAME(ADDR[$IN])/$IN;
PSPEC ADD.NAME(ADDR[$IN])/$IN;
PSPEC TIDY.UP.NAMES();
PSPEC PRINT.LINE();
PSPEC MONITOR.FAULT($IN,$IN);
PSPEC READ.LINE();
LITERAL/ADDR[$LO8] NIL=;
$IN SPEC;
MODE & 4 => SPEC;
MODE & 3 => MODE;
@BOX 2.1
#CWU01.1
@BOX 3.1
#CWU01.2
@BOX 4.1
#CWU01.1
#CWU01.2
#CWU01.3
#CWU01.4
STAGE2 => SYNTAX.SWITCH;
@BOX 5.1
CURRENT.INPUT() => SAVEDINPUT;
CURRENT.OUTPUT() => OSTREAM0;
SELECTINPUT(DEFINE.INPUT(-1,STREAM,0));
SELECTOUTPUT(DEFINE.OUTPUT(-1,NIL,0,0)=>OSTREAM);
@BOX 6.1
1 +> LINE.NO;
READ.LINE();
IF MODE = 1 OR MODE = 2 THEN;
SELECTOUTPUT(OSTREAM0);
NEWLINES(0);
PRINT.LINE();
NEWLINES(1);
SELECTOUTPUT(OSTREAM);
FI;
@BOX 7.1
SCAN(^SYNTAX,^LINE,^AS,^WS,SYNTAX.SWITCH);
IF MODE = 2 THEN;
SELECTOUTPUT(OSTREAM0);
NEWLINES(2);
-1 => I;
0 => J;
WHILE 1 +> I < MAXSS DO
OUTHEX(LINE[I],8);
SPACES(1);
1 +> J;
IF J = 13 THEN;
NEWLINES(1);
0 => J;
FI;
OD;
NEWLINES(2);
-1 => I;
0 => J;
WHILE 1 +> I < AS[0] DO
OUTHEX(AS[I],8);
SPACES(1);
1 +> J;
IF J = 13 THEN;
NEWLINES(1);
0 => J;
FI;
OD;
CAPTION(%"AP");
OUTI(WS[1],5);
NEWLINES(2);
SELECTOUTPUT(OSTREAM);
FI;
@BOX 8.1
IF WS[0] < 0,
@BOX 9.1
WS[1] => T + 1 => AP;
SWITCH AS[T]\
END.STAGE2, END.STAGE3, END.STAGE4,
END.STAGE7, END.STAGE8, COPY,
DELIMITER, FAULTY.DELIM, NO.PROCS,
COSNE.NAMES, FORM.SYNE.DEFN, FAULTY.SYNE,
GIVE.UP, PROCEDURE.NAMES, NO.DELIMS,
IGNORE, NO.COSYNES;
PROCESS.RETURN:
@BOX 10.1
#CWU01.5
#CWU01.6
#CWU01.7
#CWU01.8
END;
@BOX 11.1
MONITOR.FAULT(0,0);
@END
@TITLE CWU01.1(1,6)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
DECLARATIONS
@BOX 2.0
VARIABLES
@BOX 3.0
LITERALS
@BOX 4.0
DATAVECS
@BOX 5.0
DATAVEC PROCEDURES
@BOX 6.0
END
@BOX 1.1
@BOX 2.1
$IN I,J,T,T1,T2,THE.FIRST.SYMBOL,SYNTAX.SWITCH;
$IN LINE.NO,COSYNE.SEQ.NO,TABLE.POSN;
$IN FAULT.COUNT,NAME.SPACE,OLD.LINE.NO;
$IN PARAM.AREA,COMPILER,SAVED.INPUT,AP,MAXSS;
$IN REF.SPACE,O.STREAM,O.STREAM0;
ADDR[$IN] S;
$IN DATA.SEG;
@BOX 3.1
LITERAL/$LO8 NL=%A;
LITERAL NP=%C;
LITERAL/$LO8 SPACEL=%20;
LITERAL/$LO8 SHRIEKL=%21;
LITERAL/$LO8 VERTBARL=%7C;
LITERAL SQL=%27;
LITERAL DQL=%22;
LITERAL TABL=%9;
LITERAL ETXL=%3;
LITERAL EOTL=%4;
@BOX 4.1
:: SHOULD BE $LO1
DATAVEC LETTER($LO8)
0[%41]
1[%1A]
0[6]
1[%1A]
0[5]
END;
@BOX 5.1
@BOX 6.1
@END
@TITLE CWU01.2(1,6)
@COL 1S-2R-3R-4R-5R-6R-7R-8F
@FLOW 1-2-3-4-5-6-7-8
@BOX 1.0
INITIALISATION
@BOX 2.0
TABLES
@BOX 3.0
VECTORS
@BOX 4.0
INITIAL NAMES
@BOX 5.0
COMPILER DATAVECS
@BOX 6.0
INITIALISE VECTORS
AND TABLES
@BOX 7.0
SET COMPILER
@BOX 8.0
END
@BOX 1.1
@BOX 2.1
TYPE NAMELISTENTRY IS
$LO16 NEXT.NAME
$LO8 NAME.TYPE
$IN NAME.TYPE.VALUE
$LO8 NAME.COUNT
$IN NAME.BASE;
TYPE REFLISTENTRY IS
$LO16 NEXT.REF
$IN REF.PTR;
$IN NEXT.N;
0 => NEXT.N;
@BOX 3.1
*GLOBAL 3;
NAME.LIST.ENTRY [%300] NAMELIST;
$LO8 [%1300] NAMES;
REF.LIST.ENTRY [%180] REFLIST;
$IN [%800] LINE;
$IN [%800] AS;
$IN [%800] WS;
$IN [%200] COSYNE.INDEX.TABLE;
$IN [%1000] TABLE;
$LO8 [%400] COS.PARAMETERS;
*GLOBAL 0;
@BOX 4.1
DATAVEC NAMEPTRS($IN)
%5C 6 'B 'R 'A 'N 'C 'H
%14 6 'S 'Y 'M 'B 'O 'L
%3A 4 'S 'Y 'N 'E
%26 5 'M 'E 'R 'G 'E
%74 2 'U 'P
%6 8 'E 'N 'D 'F 'A 'L 'S 'E
%2E 7 'E 'N 'D 'T 'R 'U 'E
%4C 3 'V 'A 'L
%7C 5 'N 'O 'V 'A 'L
%40 2 'I 'N
END;
@BOX 5.1
LITERAL NOCOMPS=1;
DATAVEC COMPCOMP($LO64)
"MUSL"
END;
DATAVEC COMPDSEP($LO8)
SPACEL
END;
DATAVEC COMPLS($LO8)
'=
END;
@BOX 6.1
RELEASESEGMENT(59);
::MU6G CREATESEGMENT(123,%10000);
::VAX CREATESEGMENT(59,%10000);
::PTV CREATESEGMENT(27,%10000);
-1 => I;
WHILE 1 +> I < 64 DO
0 => NEXT.NAME OF NAMELIST[I];
OD;
128 => NAME.SPACE;
^NAMEPTRS => S;
-1 => I;
WHILE 1 +> I < 10 DO
ADDNAME(S) => T;
3 => NAME.TYPE OF NAMELIST[T];
I => NAME.TYPE.VALUE OF NAMELIST[T];
T => COSYNE.INDEX.TABLE[I];
S^[1] + 2 => T1;
PART(S,T1,SIZE(S)) => S;
OD;
0 => TABLE[0];
2 => TABLE[1];
5 => TABLE[2];
6 => TABLE[3];
4 => TABLE.POSN;
-1 => OLD.LINE.NO;
0 => FAULT.COUNT => THE.FIRST.SYMBOL => LINE.NO => PARAM.AREA;
4 => REF.SPACE;
@BOX 7.1
-1 => COMPILER;
WHILE 1 +> COMPILER < NOCOMPS DO
IF COMP = COMPCOMP[COMPILER], -> SKIP;
OD;
0 => COMPILER;
SKIP:
@BOX 8.1
@END
@TITLE CWU01.3(1,6)
@COL 1S-2R-3T-4T-5R
@COL 6R-7T-8R-12T-13R-9T-10R-11F
@ROW 3-6
@FLOW 1-2-3NO-4NO-5-2
@FLOW 3YES-6-2
@FLOW 4YES-7NO-8-12NO-13-9NO-10-2
@FLOW 7YES-2
@FLOW 12YES-9YES-11
@BOX 1.0
PROC READLINE
@BOX 2.0
READ A CHAR
@BOX 3.0
TAB?
@BOX 4.0
NEWLINE OR NEWPAGE?
@BOX 5.0
PLANT CHAR IN
LINE
@BOX 6.0
REPLACE TAB
WITH SPACE
@BOX 7.0
NULL LINE?
@BOX 8.0
CYCLE BACK
OVER SPACES
@BOX 12.0
NOT SPACE?
@BOX 13.0
REPEAT
@BOX 9.0
NO CONTINUATION?
@BOX 10.0
RESET PTR
@BOX 11.0
PLANT NL
AND EXIT
@BOX 1.1
PROC READLINE;
$IN CHR,T,I;
-1 => I;
@BOX 2.1
IN.CH() => CHR;
@BOX 3.1
IF CHR = TABL,
@BOX 4.1
IF CHR = NL OR CHR = NP,
@BOX 5.1
CHR => LINE[1+>I];
@BOX 6.1
SPACEL => LINE[1+>I];
@BOX 7.1
IF I < 0,
@BOX 8.1
1 +> I;
LAB1:
@BOX 12.1
IF LINE[1->I] /= SPACEL,
@BOX 13.1
IF I > 0, -> LAB1;
@BOX 9.1
IF LINE[I] /= "#",
@BOX 10.1
1 -> I;
@BOX 11.1
NL => LINE[I+1];
END;
@END
@TITLE CWU01.4(1,6)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
SYNTAX ANALYSIS
@BOX 2.0
SCAN AND
SYNTAX TABLE
@BOX 3.0
COSYNES
@BOX 4.0
END
@BOX 1.1
LITERAL STAGE2=4;
LITERAL STAGE3=40;
LITERAL STAGE4=70;
LITERAL STAGE5=96;
LITERAL STAGE6=137;
LITERAL STAGE7=172;
LITERAL STAGE8=234;
DATAVEC SYNTAX($LO8)
0 2 5 6 0 34 1 'B 1 'E 1 'G 1 'I 1 'N 1 'S 1 'Y
1 'N 1 'T 1 'A 1 'X 1 'S 1 'P 1 'E 1 'C 10 0 7 5
0 24 1 'D 1 'E 1 'L 1 'I 1 'M 1 'I 1 'T 1 'E 1 'R
1 'S 10 1 0 4 10 15 7 14 0 10 1 'E 1 'N 1 'D 10 2
0 10 12 0 1 '/ 13 0 10 6 0 4 10 15 7 7 0 35 1 'P
1 'R 1 'O 1 'C 1 'E 1 'D 1 'U 1 'R 1 'E 1 'N 1 'A
1 'M 1 'E 1 'S 2 1 126 10 13 0 4 10 15 7 8 0 29 1
'C 1 'O 1 'S 1 'Y 1 'N 1 'E 1 'N 1 'A 1 'M 1 'E 1
'S 2 1 132 10 9 0 4 10 15 10 16 0 38 1 'C 1 'O 1 'S
1 'Y 1 'N 1 'E 1 'S 0 18 1 'N 1 'O 1 'T 1 'E 1 'X
1 'T 9 1 3 4 9 0 10 3 0 18 2 1 22 1 'S 0 9 2
1 33 10 10 3 4 10 11 0 4 10 15 10 12 0 42 0 30 1 'E
1 'N 1 'D 1 'S 1 'Y 1 'N 1 'T 1 'A 1 'X 1 'S 1 'P
1 'E 1 'C 3 10 1 '* 1 'E 1 'O 1 'S 10 4 7 5 0 8
1 '* 9 1 3 4 9 0 4 1 'Y 1 'N 1 'E 1 '< 11 0 1
'> 1 '= 22 0 2 1 53 4 2 1 58 20 0 2 1 63 21 0 0
7 2 1 95 7 0 0 10 1 '< 18 0 1 '> 7 1 0 6 19 0
7 1 1 '[ 2 1 53 1 '] 7 2 1 '< 11 0 0 12 1 '( 11
0 17 0 1 ') 3 14 0 10 1 '( 16 0 1 ') 3 4 9 0 1
'> 4 14 0 11 0 15 4 14 0 11 0 2 1 22 15 7
END;
PROC SCAN(SYNTAX,LINE,AS,WS,START);
@BOX 2.1
#CWU01.4.1
@BOX 3.1
#CWU01.4.2
@BOX 4.1
END;
@END
@TITLE CWU01.4.1(1,6)
@COL 27R-28C-29R-30T-31R-32R-5C-54R-33C-34R-35C
@COL 23C-24R-25R-26R-6C-7R-8R-40N-36C-37R
@COL 9C-55T-56R-10T-11R-12C-13R-14R
@COL 1S-2R-3R-4C-15C-16R-17R-18T-19R-20C-21R-22R
@ROW 5-6-9-15
@ROW 33-36-12
@FLOW 1-2-3-4
@FLOW 5-54-40-12
@FLOW 6-7-8-40-12
@FLOW 9-55YES-10YES-11-12-13-14
@FLOW 55NO-56-55
@FLOW 10NO-15-16-17-18YES-19-20-21-22
@FLOW 18NO-15
@FLOW 23-24-25-26
@FLOW 27-28-29-30YES-31-32
@FLOW 30NO-27
@FLOW 33-34-35
@FLOW 36-37-35
@BOX 1.0
SCAN
DECLARATIONS
@BOX 2.0
INITIALISATION
@BOX 3.0
SYNTAX LOOP
PRINT INFO
@BOX 4.0
COSYNE SWITCH
@BOX 5.0
BRANCH
@BOX 54.0
STACK BRANCH
PTR
@BOX 6.0
IN
@BOX 7.0
PLANT PARAM VALUE
@BOX 8.0
INCR PTR
@BOX 9.0
SYMBOL
@BOX 55.0
CHAR /= SPACE?
@BOX 56.0
MOVE TO NEXT CHAR
@BOX 10.0
CHAR=SYMBOL?
@BOX 11.0
MOVE TO NEXT CHAR
@BOX 12.0
TRUE
@BOX 13.0
MOVE TO NEXT COSYNE
@BOX 14.0
->SYNTAX LOOP
@BOX 15.0
FALSE
@BOX 16.0
SET MAX SS
@BOX 17.0
UNSTACK WP TO SEARCH
FOR LAST SYNE
@BOX 18.0
SYNE FOUND?
@BOX 19.0
UNSTACK AP AND SS
@BOX 20.0
MERGE
@BOX 21.0
MERGE TO GET NEW SY
@BOX 22.0
->SYNTAX LOOP
@BOX 23.0
SYNE
@BOX 24.0
STACK -WP AND SY
TO MARK START OF SYNE
@BOX 25.0
GET SYNE ADDRESS
@BOX 26.0
->SYNTAX LOOP
@BOX 27.0
UNSTACK AP
@BOX 28.0
UP
@BOX 29.0
UNSTACK WP TO SEARCH
FOR NEXT SYNE UP
@BOX 30.0
SYNE FOUND?
@BOX 31.0
MOVE TO NEXT SYNE
@BOX 32.0
->SYNTAX LOOP
@BOX 33.0
ENDTRUE
@BOX 34.0
SET FLAG OK
SET LENGTH OF AS
@BOX 35.0
EXIT FROM SCAN
@BOX 36.0
ENDFALSE
@BOX 37.0
SET FLAG FAULTY
@BOX 1.1
PSPEC NLREC(ADDR[$IN],ADDR $IN)/$IN;
$IN AP,SS,WP,SY,TEMPWP,TEMPSY;
$IN TAP,COUNT,I,J,CHR,HASHVALUE,T,T1,T2;
$IN PRINTCOUNT;
ADDR[$LO8] SYNTAX1;
ADDR[$IN] S;
$IN [512] ST;
$IN TOS;
@BOX 2.1
-2 => TOS;
0 => PRINT.COUNT => MAXSS;
PART(SYNTAX,1,SIZE(SYNTAX)-1)
    => SYNTAX1;
1 => AP => ST[2+>TOS];
0 => SS => ST[TOS+1];
AP => ST[2+>TOS];
SS => ST[TOS+1];
-1 => AP => ST[2 +>TOS];
SS => ST[TOS+1];
1 => AP => WP;
0 => SS;
START => SY;
@BOX 3.1
SYNTAX.LOOP:
IF MODE = 2 THEN;
SELECTOUTPUT(OSTREAM0);
OUTI(SS,4);
OUTI(SY,4);
OUTI(SYNTAX^[SY],4);
SPACES(2);
1 +> PRINTCOUNT;
IF PRINTCOUNT = 7 THEN;
NEWLINES(1);
0 => PRINTCOUNT;
FI;
SELECTOUTPUT(OSTREAM);
FI;
@BOX 4.1
SWITCH SYNTAX^[SY]\
BRANCH,SYMBOL,SYNE,MERGE,
UP,ENDFALSE,ENDTRUE,
VAL,NOVAL,IN,VALNL,NAME,
DECNO,SPECSTRING,
RCOUNT,RIFCOMMA,
CONSTANTSTRING,CHECKPROC,
SPECIALSYMBOL,
ORDINARYSYMBOL,RIFBAR,
RIFNOTNL,CONVERTDELIMS;
#CWU01.4.1.1
@BOX 5.1
BRANCH:
@BOX 54.1
AP => ST[2+>TOS];
SS => ST[TOS+1];
WP => ST[2+>TOS];
SY => ST[TOS+1];
@BOX 6.1
IN:
@BOX 7.1
SYNTAX1^[SY] => WS^[WP];
@BOX 8.1
1 +> WP;
@BOX 9.1
SYMBOL:
@BOX 55.1
IF LINE^[SS] /= SPACEL,
@BOX 56.1
1 +> SS;
@BOX 10.1
IF SYNTAX1^[SY] /= LINE^[SS],
@BOX 11.1
1 +> SS;
@BOX 12.1
TRUE:
@BOX 13.1
2 +> SY;
@BOX 14.1
->SYNTAX.LOOP;
@BOX 15.1
FALSE:
@BOX 16.1
IF SS>MAXSS THEN;
SS => MAXSS;
FI;
@BOX 17.1
ST[TOS+1] => SY;
ST[TOS] => WP;
2 -> TOS;
@BOX 18.1
IF WP < 0,
@BOX 19.1
ST[TOS+1] => SS;
ST[TOS] => AP;
2 -> TOS;
@BOX 20.1
MERGE:
@BOX 21.1
SYNTAX1^[SY] +> SY;
@BOX 22.1
->SYNTAX.LOOP;
@BOX 23.1
SYNE:
@BOX 24.1
0 - WP => TEMPWP;
SY => TEMPSY;
TEMPWP => ST[2+>TOS];
TEMPSY => ST[TOS+1];
@BOX 25.1
SYNTAX1^[SY]<<-8 !
    SYNTAX1^[SY+1] => SY;
@BOX 26.1
->SYNTAX.LOOP;
@BOX 27.1
ST[TOS+1] => TEMPSY;
ST[TOS] => TEMPWP;
2 -> TOS;
@BOX 28.1
UP:
@BOX 29.1
ST[TOS+1] => TEMPSY;
ST[TOS] => TEMPWP;
2 -> TOS;
@BOX 30.1
IF TEMPWP >= 0,
@BOX 31.1
TEMPSY + 3 => SY;
@BOX 32.1
->SYNTAX.LOOP;
@BOX 33.1
ENDTRUE:
@BOX 34.1
SS => WS^[WP] => MAXSS;
1 => WS^[0];
AP => AS^[0];
@BOX 35.1
EXIT;
@BOX 36.1
ENDFALSE:
@BOX 37.1
-1 => WS^[0];
SS => MAXSS;
@END
@TITLE CWU01.4.1.1(1,6)
@COL 38C-39R-40R-41R-42R-43R-44T-45R-46T-47R-50R-51R-52R
@COL 53C
@ROW 38-53
@FLOW 38-39-40-42-43-44YES-45-46NO-47-50-51-52
@FLOW 44NO-41-42
@FLOW 46YES-50
@FLOW 53-42
@BOX 38.0
VAL
@BOX 39.0
PLANT PARAM VALUE
@BOX 40.0
SAVE AP+1
@BOX 41.0
UNSTACK AP
@BOX 42.0
UNSTACK WP TO SEARCH
 FOR LAST SYNE
@BOX 43.0
NEGATE WP
@BOX 44.0
SYNE FOUND?
@BOX 45.0
SET COUNT
@BOX 46.0
COUNT=0?
@BOX 47.0
CYCLE THROUGH WS
COPYING TO AS
@BOX 50.0
PLANT PTR IN WS
@BOX 51.0
INCR WP,AP
AND SY
@BOX 52.0
->SYNTAX LOOP
@BOX 53.0
NOVAL
@BOX 38.1
VAL:
@BOX 39.1
SYNTAX1^[SY] => AS^[AP];
@BOX 40.1
1 + AP => TAP;
@BOX 41.1
ST[TOS+1] => TEMPSY;
ST[TOS] => TEMPWP;
2 -> TOS;
@BOX 42.1
ST[TOS+1] => TEMPSY;
ST[TOS] => TEMPWP;
2 -> TOS;
@BOX 43.1
0 - TEMPWP => TEMPWP;
@BOX 44.1
IF TEMPWP < 0,
@BOX 45.1
WP - TEMPWP => COUNT;
@BOX 46.1
IF COUNT = 0,
@BOX 47.1
-1 => I;
WHILE 1 +> I < COUNT DO
WS^[TEMPWP + I] => AS^[TAP + I];
OD;
@BOX 50.1
AP => WS^[TEMPWP];
@BOX 51.1
TEMPWP + 1 => WP;
TAP + COUNT => AP;
TEMPSY + 3 => SY;
@BOX 52.1
->SYNTAX.LOOP;
@BOX 53.1
NOVAL:
AP => TAP;
@END
@TITLE CWU01.4.2(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
COSYNES
@BOX 2.0
CWU01.4.2.1    VALNL
CWU01.4.2.2    NAME
CWU01.4.2.3    DECIMAL NUMBER
CWU01.4.2.4    SPEC STRING
CWU01.4.2.5    RCOUNT
CWU01.4.2.6    REPEAT IF COMMA
CWU01.4.2.7    CONSTANT STRING
CWU01.4.2.8    CHECK PROCEDURE NAME
CWU01.4.2.9    SPECIAL SYMBOL
CWU01.4.2.10    ORDINARY SYMBOL
CWU01.4.2.11    REPEAT IF BAR
CWU01.4.2.12    REPEAT IF NOT NEWLINE
CWU01.4.2.13    CONVERT DELIMITERS
CWU01.4.2.14    PROCEDURE NLREC
@BOX 3.0
END
@BOX 1.1
@BOX 2.1
#CWU01.4.2.1
#CWU01.4.2.2
#CWU01.4.2.3
#CWU01.4.2.4
#CWU01.4.2.5
#CWU01.4.2.6
#CWU01.4.2.7
#CWU01.4.2.8
#CWU01.4.2.9
#CWU01.4.2.10
#CWU01.4.2.11
#CWU01.4.2.12
#CWU01.4.2.13
#CWU01.4.2.14
@BOX 3.1
@END
@TITLE CWU01.4.2.1(1,6)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
VALNL
@BOX 2.0
CHECK FOR NL
@BOX 3.0
JUMP TO VAL
@BOX 4.0
END
@BOX 1.1
VALNL:
@BOX 2.1
IF NLREC(LINE,^SS)=>T = 1,->FALSE;
@BOX 3.1
->VAL;
@BOX 4.1
@END
@TITLE CWU01.4.2.2(1,6)
@COL 1S-2R-3R-4T-5R-6R-12R-7T-8T-9T-10F
@COL 11R
@ROW 5-11
@FLOW 1-2-3-4YES-5-6-12-7NO-8NO-9NO-10
@FLOW 4NO-11
@FLOW 7YES-5
@FLOW 8YES-12
@FLOW 9YES-5
@BOX 1.0
NAME
@BOX 2.0
SKIP SPACES
@BOX 3.0
CLEAR HASH & COUNT
@BOX 4.0
FIRST CHAR UPPER
CASE LETTER?
@BOX 5.0
ADD TO HASHVALUE
@BOX 6.0
PLANT CHAR IN
AS & INCR COUNT
@BOX 12.0
GET NEXT CHAR
@BOX 7.0
LETTER?
@BOX 8.0
FULL STOP?
@BOX 9.0
NUMBER?
@BOX 10.0
PLANT HASH VALUE
AND COUNT IN AS
@BOX 11.0
FALSE
@BOX 1.1
NAME:
@BOX 2.1
1 -> SS;
WHILE LINE^[1+>SS] => CHR = SPACEL DO OD;
@BOX 3.1
0 => HASH.VALUE;
0 => COUNT;
AP => WS^[WP] => T1;
2 +> AP;
@BOX 4.1
IF LETTER[CHR] = 0,
@BOX 5.1
CHR + HASHVALUE <<- 1 => HASHVALUE;
@BOX 6.1
CHR => AS^[AP];
1 +> COUNT;
1 +> AP;
@BOX 12.1
1 +> SS;
LINE^[SS] => CHR;
@BOX 7.1
IF LETTER[CHR] /= 0,
@BOX 8.1
IF CHR = ".",
@BOX 9.1
IF CHR >= "0" AND CHR =< "9",
@BOX 10.1
HASHVALUE & %7F => AS^[T1];
COUNT => AS^[T1+1];
1 +> WP;
->TRUE;
@BOX 11.1
->FALSE;
@END
@TITLE CWU01.4.2.3(1,6)
@COL 1S-2T-3R-4R-5T-6R-7F
@COL 8R
@ROW 3-8
@FLOW 1-2YES-3-4-5NO-6-7
@FLOW 2NO-7
@FLOW 5YES-7
@BOX 1.0
DECIMAL NUMBER
@BOX 2.0
FIRST CHAR
DECIMAL DIGIT?
@BOX 3.0
CYCLE THROUGH
DIGITS
@BOX 4.0
ADD TO TOTAL
@BOX 5.0
NON DECIMAL DIGIT?
@BOX 6.0
REPEAT
@BOX 7.0
PLANT VALUE
INCR POINTERS
TRUE
@BOX 8.0
FALSE
@BOX 1.0
DECIMAL NUMBER
@BOX 2.0
FIRST CHAR
DECIMAL DIGIT?
@BOX 3.0
CYCLE THROUGH
DIGITS
@BOX 4.0
ADD TO TOTAL
@BOX 5.0
NON DECIMAL DIGIT?
@BOX 6.0
REPEAT
@BOX 7.0
PLANT VALUE
INCR POINTERS
TRUE
@BOX 8.0
FALSE
@BOX 1.1
DEC.NO:
@BOX 2.1
IF LINE^[SS] => CHR < "0" OR CHR > "9",
@BOX 3.1
0 => T;
LAB2:
@BOX 4.1
T*10 + CHR - "0" => T;
@BOX 5.1
IF LINE^[1+>SS] => CHR < "0" OR CHR > "9",
@BOX 6.1
-> LAB2;
@BOX 7.1
T => WS^[WP];
1 +> WP;
->TRUE;
@BOX 8.1
->FALSE;
@END
@TITLE CWU01.4.2.4(1,6)
@COL 1S-2R-3R-4T-5R-6T-7T-8R-9R
@COL 10T-11R-12T-13T-14R-15R
@ROW 5-10
@ROW 7-12
@FLOW 1-2-3-4NO-5-6NO-7NO-8-9-6YES-12NO-13NO-14
@FLOW 4YES-10YES-6
@FLOW 10NO-11-15
@FLOW 7YES-6
@FLOW 12YES-11
@FLOW 13YES-15
@BOX 1.0
SPEC STRING
@BOX 2.0
SKIP SPACES
@BOX 3.0
CLEAR HASH
AND COUNT
@BOX 4.0
FIRST SYM /= 0?
@BOX 5.0
SET FIRST SYM
= CHR
@BOX 6.0
NEXT SYM
NOT A CHR
@BOX 7.0
CHR = SPACE ?
@BOX 8.0
ADD TO HASH VALUE
@BOX 9.0
PLANT CHAR IN AS
INCR COUNT
@BOX 10.0
CHR = FIRST SYMBOL?
@BOX 11.0
MONITOR FAULTY
DELIM SPEC
@BOX 12.0
LAST CHAR /=
FIRST SYM?
@BOX 13.0
< 1 CHAR?
@BOX 14.0
SET AS & WS
PLANT HASH VALUE
AND COUNT
->TRUE
@BOX 15.0
RESET PTRS
->FALSE
@BOX 1.1
SPEC.STRING:
@BOX 2.1
SS => T1;
1 -> SS;
WHILE LINE^[1+>SS] = SPACEL DO OD;
@BOX 3.1
0 => HASH.VALUE => COUNT;
AP => WS^[WP] => T2;
2 +> AP;
@BOX 4.1
LINE^[SS] => CHR;
IF THE.FIRST.SYMBOL /= 0,
@BOX 5.1
CHR => THE.FIRST.SYMBOL;
@BOX 6.1
IF LINE^[1+>SS] => CHR < SPACEL,
@BOX 7.1
IF CHR=SPACEL,
@BOX 8.1
CHR + HASH.VALUE <<- 1 => HASH.VALUE;
@BOX 9.1
CHR => AS^[AP];
1 +> COUNT;
1 +> AP;
@BOX 10.1
IF CHR = THE.FIRST.SYMBOL,
@BOX 11.1
MONITOR.FAULT(5,0);
@BOX 12.1
IF LINE^[SS-1] /= THE.FIRST.SYMBOL,
@BOX 13.1
IF COUNT < 2,
@BOX 14.1
HASH.VALUE & %7F => AS^[T2];
COUNT => AS^[T2+1];
1 +> WP;
->TRUE;
@BOX 15.1
COUNT + 2 -> AP;
T1 => SS;
-> FALSE;
@END
@TITLE CWU01.4.2.5(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
COUNT
@BOX 2.0
PLANT WS
@BOX 3.0
TRUE
@BOX 1.1
RCOUNT:
@BOX 2.1
1 => WS^[WP];
WP => T + 1 => WP;
@BOX 3.1
->TRUE;
@END
@TITLE CWU01.4.2.6(1,6)
@COL 1S-2R-3T-4F
@COL 5R
@ROW 4-5
@FLOW 1-2-3YES-4
@FLOW 3NO-5
@BOX 1.0
REPEAT IF COMMA
@BOX 2.0
SKIP SPACES
@BOX 3.0
COMMA?
@BOX 4.0
SET WS
INCR PTRS
@BOX 5.0
UP
@BOX 1.1
R.IF.COMMA:
@BOX 2.1
1 -> SS;
WHILE LINE^[1+>SS] => CHR = SPACEL DO OD;
@BOX 3.1
IF CHR /= ",",
@BOX 4.1
1 +> SS;
1 +> WS^[T];
SYNTAX^[SY+1] -> SY;
->TRUE;
@BOX 5.1
->UP;
@END
@TITLE CWU01.4.2.7(1,6)
@COL 8R
@COL 1S-2R-3T-4T-5R-6T-7R
@COL 9T-10R-11R
@ROW 8-5
@ROW 4-9
@ROW 7-11
@FLOW 1-2-3NO-4YES-8
@FLOW 4NO-5-6NO-7-3
@FLOW 3YES-9NO-10-6YES-11
@FLOW 9YES-6
@BOX 1.0
CONSTANT STRING
@BOX 2.0
SET WS,AR
AND PTRS
@BOX 3.0
CHR /= ")"?
@BOX 4.0
COUNT = 0?
@BOX 5.0
DECR COUNT
@BOX 6.0
CHR = NL?
@BOX 7.0
COPY CHR TO AS
@BOX 8.0
SET AS
INCR AP
TRUE
@BOX 9.0
CHR /= "("?
@BOX 10.0
INCR COUNT
@BOX 11.0
RESET SS
FALSE
@BOX 1.1
CONSTANT.STRING:
@BOX 2.1
0 => I;
AP => WS^[WP];
1 +> WP;
0 => AS^[AP];
1 +> AP;
SS => T;
@BOX 3.1
IF LINE^[SS] => CHR /= ")",
@BOX 4.1
IF I = 0,
@BOX 5.1
1 -> I;
@BOX 6.1
IF CHR = NL,
@BOX 7.1
CHR => AS^[AP];
1 +> AP;
1 +> SS;
@BOX 8.1
0 => AS^[AP];
1 +> AP;
->TRUE;
@BOX 9.1
IF CHR /= "(",
@BOX 10.1
1 +> I;
@BOX 11.1
T => SS;
->FALSE;
@END
@TITLE CWU01.4.2.8(1,6)
@COL 1S-2T-3T-4R
@COL 5R
@ROW 4-5
@FLOW 1-2YES-3YES-4
@FLOW 2NO-5
@FLOW 3NO-5
@BOX 1.0
CHECK PROCEDURE NAME
@BOX 2.0
NAME IN LIST?
@BOX 3.0
PROCEDURE TYPE?
@BOX 4.0
SET AS-
TRUE
@BOX 5.0
FALSE
@BOX 1.1
CHECK.PROC:
@BOX 2.1
WS^[WP - 1] => T;
IF LOOK.UP.NAME(PART(AS,T,SIZE(AS)-1) => S) => T = 0,
@BOX 3.1
IF NAME.TYPE OF NAMELIST[T] /= 2,
@BOX 4.1
WS^[WP-1] => AP;
1 => AS^[AP];
NAME.TYPE.VALUE OF NAMELIST[T] => AS^[AP+1];
2 +> AP;
->TRUE;
@BOX 5.1
->FALSE;
@END
@TITLE CWU01.4.2.9(1,6)
@COL 1S-2R-3T-4R-5R
@COL 6R
@ROW 4-6
@FLOW 1-2-3NO-4-5
@FLOW 3YES-6
@BOX 1.0
SPECIAL SYMBOL
@BOX 2.0
CYCLE THROUGH
SPECIAL SYMBOLS
@BOX 3.0
CHR = SPECIAL SYMBOL?
@BOX 4.0
REPEAT
@BOX 5.0
FALSE
@BOX 6.0
TRUE
@BOX 1.1
DATAVEC SPECIAL.SYMBOL.TABLE($LO8)
'< '> '[ '] SHRIEKL VERTBARL NL
END;
SPECIAL.SYMBOL:
@BOX 2.1
LINE^[SS] => CHR;
0 => I;
LAB3:
@BOX 3.1
IF CHR = SPECIAL.SYMBOL.TABLE[I],
@BOX 4.1
1 +> I;
IF I < 6, -> LAB3;
@BOX 5.1
->FALSE;
@BOX 6.1
CHR => WS^[WP];
1 +> SS;
1 +> WP;
->TRUE;
@END
@TITLE CWU01.4.2.10(1,6)
@COL 1S-2R-3R-4T-5R-6R
@COL 7R
@ROW 5-7
@FLOW 1-2NO-3-4NO-5-6
@FLOW 4YES-7
@BOX 1.0
ORDINARY SYMBOL
@BOX 2.0
SKIP SPACES
@BOX 3.0
CYCLE THROUGH
SPECIAL SYMBOLS
@BOX 4.0
CHR = SPECIAL.SYMBOL?
@BOX 5.0
REPEAT
@BOX 6.0
TRUE
@BOX 7.0
FALSE
@BOX 1.1
ORDINARY.SYMBOL:
@BOX 2.1
1 -> SS;
WHILE LINE^[1+>SS] => CHR = SPACEL DO OD;
@BOX 3.1
0 => I;
LAB4:
@BOX 4.1
IF CHR = SPECIAL.SYMBOL.TABLE[I],
@BOX 5.1
1 +> I;
IF I < 7, -> LAB4;
@BOX 6.1
CHR => WS^[WP];
1 +> WP;
1 +> SS;
->TRUE;
@BOX 7.1
->FALSE;
@END
@TITLE CWU01.4.2.11(1,6)
@COL 1S-2R-3T-4R
@COL 5R
@ROW 4-5
@FLOW 1-2-3NO-4
@FLOW 3YES-5
@BOX 1.0
REPEAT IF BAR
@BOX 2.0
SKIP SPACES
@BOX 3.0
CHR = BAR?
@BOX 4.0
NO REPEAT
NOVAL
@BOX 5.0
REPEAT
TRUE
@BOX 1.1
R.IF.BAR:
@BOX 2.1
1->SS;
WHILE LINE^[1+>SS] => CHR = SPACEL DO OD;
@BOX 3.1
IF CHR = SHRIEKL OR CHR = VERTBARL,
@BOX 4.1
-1 => WS^[WP];
1 +> WP;
->NOVAL;
@BOX 5.1
1 +> SS;
5->SY;
->TRUE;
@END

@TITLE CWU01.4.2.12(1,6)
@COL 1S-2R-3T-4R
@COL 5R
@ROW 4-5
@FLOW 1-2-3NO-4
@FLOW 3YES-5
@BOX 1.0
REPEAT IF NOT NEWLINE
@BOX 2.0
SKIP SPACES
@BOX 3.0
CHR= NL,!,VERTBAR OR ]?
@BOX 4.0
NO REPEAT
NOVAL
@BOX 5.0
REPEAT
TRUE
@BOX 1.1
R.IF.NOT.NL:
@BOX 2.1
1->SS;
WHILE LINE^[1+>SS]=>CHR = SPACEL DO OD;
@BOX 3.1
IF CHR=NL OR CHR=SHRIEKL OR CHR=VERTBARL OR CHR="]",
@BOX 4.1
5 -> SY;
->TRUE;
@BOX 5.1
-1=>WS^[WP];
1+>WP;
->NOVAL;
@END
@TITLE CWU01.4.2.13(1,6)
@COL 15T-16R-17F-18R-19R-20R
@COL 1S-2R-3R-4T-5T-6R-7R-8R-9T-10T-11T-12R-13T-14R
@COL 21T
@ROW 4-21
@ROW 15-6
@ROW 16-10
@ROW 18-12
@ROW 19-14
@FLOW 1-2-3-4NO-5NO-6-7-8-9NO-10NO-11NO-12-13NO-14-4
@FLOW 4YES-21YES-21NO-5
@FLOW 5YES-15NO-17
@FLOW 15YES-4
@FLOW 9YES-16-17
@FLOW 10YES-7
@FLOW 11YES-18-4
@FLOW 13YES-19-20-14
@BOX 1.0
CONVERT DELIMS
@BOX 2.0
SKIP SPACES
@BOX 3.0
SAVE SS
@BOX 4.0
NEXT CHAR = "<"?
@BOX 5.0
CHR /= THE FIRST SYM?
@BOX 6.0
CLEAR COUNT & HASH
SAVE PTR TO CHR
BEFORE DELIM
@BOX 7.0
GET NEXT CHAR
@BOX 8.0
INCR COUNT & HASH
@BOX 9.0
CHR = NL OR NP?
@BOX 10.0
CHR /= THE FIRST SYM?
@BOX 11.0
NO CHARS IN DELIM?
@BOX 12.0
SAVE CHAR BEFORE DELIM
PLANT COUNT & HASH IN LINE
@BOX 13.0
NAME NOT ON NAME LIST?
@BOX 14.0
FOUND
REPLANT CHAR BEFORE DELIM
PLANT VALUE & FILL NAME
WITH RELEVANT NO OF SPACES
@BOX 15.0
CHR /= NL OR NP?
@BOX 16.0
MONITOR FAULTY DELIM
@BOX 17.0
RESET SS
-> TRUE
@BOX 18.0
MONITOR FAULTY DELIM
@BOX 19.0
MONITOR FAULTY DELIM
@BOX 20.0
ADD NAME TO LIST
@BOX 21.0
NEXT SYM /= ">"?
@BOX 1.1
CONVERT.DELIMS:
@BOX 2.1
1 -> SS;
WHILE LINE^[1+>SS] = SPACEL DO OD;
@BOX 3.1
SS => T;
1 -> SS;
@BOX 4.1
IF LINE^[1+>SS] => CHR = "<",
@BOX 5.1
IF CHR /= THE.FIRST.SYMBOL,
@BOX 6.1
0 => COUNT => HASH.VALUE;
SS - 1 => T1;
@BOX 7.1
LINE^[1+>SS] => CHR;
@BOX 8.1
1 +> COUNT;
CHR + HASH.VALUE <<- 1 => HASH.VALUE;
@BOX 9.1
IF CHR = NL OR CHR = NP,
@BOX 10.1
IF CHR /= THE.FIRST.SYMBOL,
@BOX 11.1
IF COUNT < 2,
@BOX 12.1
LINE^[T1] => CHR;
HASH.VALUE & %7F => LINE^[T1];
COUNT => LINE^[T1+1];
@BOX 13.1
IF LOOK.UP.NAME(PART(LINE,T1,SIZE(LINE)-1) => S) => T2 = 0,
@BOX 14.1
CHR => LINE^[T1];
0 - NAME.TYPE.VALUE OF NAMELIST[T2] => LINE^[T1+1];
-1 => I;
WHILE 1 +> I < COUNT DO
SPACEL => LINE^[T1+2+I];
OD;
@BOX 15.1
IF CHR /= NL AND CHR /= NP,
@BOX 16.1
MONITOR.FAULT(5,0);
@BOX 17.1
T => SS;
-> TRUE;
@BOX 18.1
MONITOR.FAULT(5,0);
@BOX 19.1
MONITOR.FAULT(5,0);
MONITOR.FAULT(2,0);
@BOX 20.1
ADD.NAME(S) => T2;
@BOX 21.1
IF LINE^[1+>SS] /= ">",
@END
@TITLE CWU01.4.2.14(1,6)
@COL 1S-2T-3T-4T-5R-6T-7R
@COL 8R-9T-10F
@ROW 3-8
@FLOW 1-2NO-3NO-4NO-5-6NO-7
@FLOW 2YES-8
@FLOW 3YES-9NO-10
@FLOW 9YES-8
@FLOW 4YES-8
@FLOW 6YES-10
@BOX 1.0
PROC NLREC
@BOX 2.0
CHR=SPACE?
@BOX 3.0
NOT COMMENT?
@BOX 4.0
CERTAINLY NOT
COMMENT?
@BOX 5.0
CYCLE THROUGH LINE
FOR NEXT NL OR NP
@BOX 6.0
CHR = NL OR NP?
@BOX 7.0
REPEAT
@BOX 8.0
SET FALSE
EXIT
@BOX 9.0
CHR /= NL NOR NP?
@BOX 10.0
INCR SS
SET TRUE
EXIT
@BOX 1.1
PROC NLREC(LINE,SS);
$IN CHR;
@BOX 2.1
IF LINE^[SS^] => CHR = SPACEL,
@BOX 3.1
IF CHR /= ":",
@BOX 4.1
IF LINE^[SS^+1] /= ":",
@BOX 5.1
1 +> SS^;
LAB5:
@BOX 6.1
IF LINE^[1+>SS^] => CHR = NL OR CHR = NP,
@BOX 7.1
-> LAB5;
@BOX 8.1
1 => NLREC;
EXIT;
@BOX 9.1
IF CHR /= NL AND CHR /= NP,
@BOX 10.1
1 +> SS^;
0 => NLREC;
END;
@END
@TITLE CWU01.5(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SEMANTICS
@BOX 2.0
CWU01.5.1     END STAGES 2 TO 4
CWU01.5.2     END STAGE 7
CWU01.5.3     COPY
CWU01.5.4     DELIMITER
CWU01.5.5     FAULTY DELIMITER
CWU01.5.6     NO PROCEDURES
CWU01.5.7     COSYNE NAMES
CWU01.5.8     FORM SYNE DEFINITION
CWU01.5.9     FAULTY SYNE
CWU01.5.10    GIVE UP
CWU01.5.11    PROCEDURE NAMES
CWU01.5.12    NO DELIMITERS
CWU01.5.13    IGNORE
CWU01.5.14    NO COSYNES
CWU01.5.15    END.STAGE 8
@BOX 3.0
END
@BOX 1.1
@BOX 2.1
#CWU01.5.1
#CWU01.5.2
#CWU01.5.3
#CWU01.5.4
#CWU01.5.5
#CWU01.5.6
#CWU01.5.7
#CWU01.5.8
#CWU01.5.9
#CWU01.5.10
#CWU01.5.11
#CWU01.5.12
#CWU01.5.13
#CWU01.5.14
#CWU01.5.15
@BOX 3.1
@END
@TITLE CWU01.5.1(1,6)
@COL 1S-2R-3R-4R
@BOX 1.0
END STAGES 2 TO 4
@BOX 2.0
END STAGE 2
@BOX 3.0
END STAGE 3
@BOX 4.0
END STAGE 4
@BOX 1.1
@BOX 2.1
END.STAGE2:
STAGE3 => SYNTAX.SWITCH;
->PROCESS.RETURN;
@BOX 3.1
END.STAGE3:
STAGE4 => SYNTAX.SWITCH;
->PROCESS.RETURN;
@BOX 4.1
END.STAGE4:
STAGE5 => SYNTAX.SWITCH;
->PROCESS.RETURN;
@END
@TITLE CWU01.5.2(1,12)
@COL  14R
@COL 1S-2R-3R-4T-5T-6R-7T-8R-9R-10T-11T-12R-13N
@COL 15R-16R-23R-17R-18F
@ROW 14-5-15
@ROW 11-16
@FLOW 1-2-3-4NO-5NO-6-7NO-8-9-10NO-11NO-12-13-4
@FLOW 4YES-15-7
@FLOW 5YES-14-7
@FLOW 7YES-9
@FLOW 10YES-16-23-17-18
@FLOW 11YES-4
@BOX 1.0
END STAGE 7
@BOX 2.0
OUTPUT DATAVEC SYNTAX HEADER
@BOX 3.0
INITIALISE TABLE COUNT
AND LINE COUNT
@BOX 4.0
STRING?
@BOX 5.0
SYMBOL?
@BOX 6.0
OUTPUT ELEMENT
@BOX 7.0
NOT END OF LINE?
@BOX 8.0
OUTPUT NEWLINE
RESET LINE PTR
@BOX 9.0
INCR COUNT
@BOX 10.0
END OF TABLE?
@BOX 11.0
END OF LINE?
@BOX 12.0
OUTPUT SEPARATOR
@BOX 14.0
OUTPUT SYMBOL IN QUOTES
@BOX 15.0
OUTPUT STRING
@BOX 16.0
OUTPUT END OF DATAVEC
@BOX 23.0
OUTPUT SCAN
PROC HEADER
@BOX 17.0
TIDY UP NAMES
@BOX 18.0
RETURN TO
STAGE 8
@BOX 1.1
END.STAGE7:
@BOX 2.1
SELECTOUTPUT(OSTREAM);
ALTERNATIVE COMPILER FROM
CAPTION(%"DATAVEC SYNTAX($$LO8)")
END;
NEWLINES(1);
@BOX 3.1
0 => I;
20 => J;
@BOX 4.1
IF TABLE[I] => T +256 < 0 ,
@BOX 5.1
IF T < 0,
@BOX 6.1
OUTI(T,0);
@BOX 7.1
IF 1 -> J /= 0,
@BOX 8.1
20 => J;
NEWLINES(1);
@BOX 9.1
1 +> I;
@BOX 10.1
IF I = TABLE.POSN,
@BOX 11.1
IF J = 20,
@BOX 12.1
OUT.CH(COMPDSEP[COMPILER]);
@BOX 14.1
IF COMPILER = 0 THEN
OUT.CH(SQL);
OUT.CH(0-T);
IF 0-T = '$$ THEN
   OUT.CH('$$);
FI
FI;
@BOX 15.1
10000 + T => T;
WHILE COS.PARAMETERS[T]/=0 DO
     OUT.CH(COS.PARAMETERS[T]);
     1 +> T;
OD;
@BOX 16.1
NEWLINES(1);
ALTERNATIVE COMPILER FROM
CAPTION(%"END;")
END;
NEWLINES(2);
@BOX 23.1
IF SPEC /= 0 THEN
   IF COMPILER = 0 THEN
    CAPTION(%"PSPEC SCAN(ADDR[$$LO8],ADDR[$$IN],ADDR[$$IN],ADDR[$$IN],$$IN);");
    NEWLINES(0);
    CAPTION(%"PROC SCAN(SYNTAX,LINE,AS,WS,START);");
FI;
NEWLINES(2);
FI;
@BOX 17.1
TIDY.UP.NAMES();
@BOX 18.1
STAGE8 => SYNTAX.SWITCH;
->PROCESS.RETURN;
@END
@TITLE CWU01.5.3(1,6)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
COPY
@BOX 2.0
CYCLE
@BOX 3.0
COPY CHAR TO
OUTPUT STREAM
@BOX 4.0
REPEAT UNITL NL OR NP
@BOX 5.0
RETURN
@BOX 1.1
COPY:
@BOX 2.1
-1 => I;
LAB6:
@BOX 3.1
OUT.CH(LINE[1+>I] => T);
@BOX 4.1
IF T = NL OR T = NP THEN;
NL => T;
FI;
IF T /= NL, -> LAB6;
@BOX 5.1
->PROCESS.RETURN;
@END
@TITLE CWU01.5.4(1,6)
@COL 1S-2R-3T-4R-5R-6R-7F
@FLOW 1-2-3NO-4-5-6-7
@FLOW 3YES-5
@BOX 1.0
DELIMITER
@BOX 2.0
PICK UP VALUE AND
STRING PTR FROM AS
@BOX 3.0
NAME IN NAMELIST?
@BOX 4.0
MONITOR FAULT -
NAME ALREADY EXISTS
@BOX 5.0
ADD NAME TO
NAME LIST
@BOX 6.0
FILL NAMELIST TABLE
@BOX 7.0
RETURN
@BOX 1.1
DELIMITER:
BEGIN;
$IN VALUE,LIST;
@BOX 2.1
AS[AP] => VALUE;
AP + 1 => LIST;
@BOX 3.1
AS[LIST] => T;
IF LOOK.UP.NAME(PART(^AS,T,SIZE(^AS)-1) => S) => T1 = 0,
@BOX 4.1
MONITOR.FAULT(1,T1);
@BOX 5.1
ADD.NAME(S) => T1;
@BOX 6.1
4 => NAME.TYPE OF NAMELIST[T1];
VALUE => NAME.TYPE.VALUE OF NAMELIST[T1];
@BOX 7.1
END;
->PROCESS.RETURN;
@END
@TITLE CWU01.5.5(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
FAULTY DELIMITER
@BOX 2.0
MONITOR FAULTY DELIM
@BOX 3.0
RETURN
@BOX 1.1
FAULTY.DELIM:
@BOX 2.1
MONITOR.FAULT(5,0);
@BOX 3.1
->PROCESS.RETURN;
@END

@TITLE CWU01.5.6(1,6)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
NO PROCEDURES
@BOX 2.0
MONITOR FAULT IN
PROC NAMES SPEC
@BOX 3.0
SET SWITCH TO STAGE 6
@BOX 4.0
RETURN
@BOX 1.1
NO.PROCS:
@BOX 2.1
MONITOR.FAULT(6,0);
@BOX 3.1
STAGE6 => SYNTAX.SWITCH;
@BOX 4.1
->PROCESS.RETURN;
@END
@TITLE CWU01.5.7(1,6)
@COL 1S-2R-3R-4R-5T-6R-7R-8R-9R-10R-11R-12R-13F
@FLOW 1-2-3-4-5NO-6-7-8-9-10-11-12-13
@FLOW 5YES-7
@BOX 1.0
COSYNE NAMES
@BOX 2.0
SET LIST AND COUNT
FROM AS
@BOX 3.0
INIT COSYNE SEQ NO
@BOX 4.0
CYCLE TROUGH
COSYNE LIST
@BOX 5.0
NAME NOT ON
NAME LIST?
@BOX 6.0
MONITOR FAULT-
NAME ALREADY EXISTS
@BOX 7.0
ADD NAME TO LIST
@BOX 8.0
FILL NAMELIST TABLE
@BOX 9.0
ADD PTR TO COSYNE
INDEX TABLE
@BOX 10.0
INCR COSYNE SEQ
NO AND LIST
@BOX 11.0
REPEAT
@BOX 12.0
SET SWITCH
TO STAGE 7
@BOX 13.0
RETURN
@BOX 1.1
COSNE.NAMES:
BEGIN;
$IN LIST,COUNT;
@BOX 2.1
AS[AP] => COUNT;
AP+1 => LIST;
@BOX 3.1
10 => COSYNE.SEQ.NO;
@BOX 4.1
0 => I;
LAB7:
@BOX 5.1
AS[LIST] => T;
IF LOOK.UP.NAME(PART(^AS,T,SIZE(^AS)-1) => S) => T1 = 0,
@BOX 6.1
MONITOR.FAULT(1,T1);
@BOX 7.1
ADD.NAME(S) => T;
@BOX 8.1
IF AS[LIST+1]=0 THEN;
3 => NAME.TYPE OF NAMELIST[T];
ELSE;
5=>NAME.TYPE OF NAMELIST[T];
FI;
COSYNE.SEQ.NO => NAME.TYPE.VALUE OF NAMELIST[T];
@BOX 9.1
T => COSYNE.INDEX.TABLE[COSYNE.SEQ.NO];
@BOX 10.1
1 +> COSYNE.SEQ.NO;
2 +> LIST;
@BOX 11.1
1 +> I;
IF I < COUNT, -> LAB7;
@BOX 12.1
STAGE7 => SYNTAX.SWITCH;
@BOX 13.1
END;
->PROCESS.RETURN;
@END
@TITLE CWU01.5.8(1,6)
@COL 1S-2R-3T-4T-5R-6R-7R-8T-9R-10R-11F
@COL 12T-13R-14T
@ROW 5-12
@FLOW 1-2-3YES-4NO-5-6-7-8YES-9-10-11
@FLOW 3NO-6
@FLOW 4YES-12NO-13-14NO-13
@FLOW 12YES-7
@FLOW 14YES-7
@FLOW 8NO-10
@BOX 1.0
FORM SYNE DEFINITION
@BOX 2.0
SET STAR,NAME AND
ALTERNATIVES FROM AS
@BOX 3.0
NAME ALREADY EXISTS?
@BOX 4.0
TYPE FR?
@BOX 5.0
MONITOR FAULT -
NAME ALREADY EXISTS
@BOX 6.0
ADD NAME TO LIST
@BOX 7.0
FILL NAME LIST TABLE
@BOX 8.0
* PRESENT
@BOX 9.0
OUTPUT LITERAL
STATEMENT
@BOX 10.0
FORM SYNTAX TABLE
WITHOUT MERGES
@BOX 11.0
RETURN
@BOX 12.0
NO REFS?
@BOX 13.0
FILL REFS TO NAME
@BOX 14.0
NO FURTHER REFS?
@BOX 1.1
FORM.SYNE.DEFN:
BEGIN;
$IN STAR,NAME,ALTERNATIFS;
@BOX 2.1
AS[AP]=> STAR;
AP+1 => NAME;
AS[AP+2] => ALTERNATIFS;
@BOX 3.1
AS[NAME] => T;
IF LOOK.UP.NAME(PART(^AS,T,SIZE(^AS)-1) => S) => T = 0,
@BOX 4.1
IF NAME.TYPE OF NAMELIST[T] = 0,
@BOX 5.1
MONITOR.FAULT(1,T);
@BOX 6.1
ADD.NAME(S) => T;
@BOX 7.1
1 => NAME.TYPE OF NAMELIST[T];
TABLE.POSN => NAME.TYPE.VALUE OF NAMELIST[T];
@BOX 8.1
IF STAR = 0,
@BOX 9.1
SELECTOUTPUT(OSTREAM);
ALTERNATIVE COMPILER FROM
CAPTION(%"LITERAL ")
END;
NAME.COUNT OF NAMELIST[T] => T1;
SELECT NAMELIST[T];
CAPTION(PART(^NAMES,NAME.BASE,NAME.BASE+NAME.COUNT-1));
OUT.CH(COMPLS[COMPILER]);
OUTI(TABLE.POSN,0);
IF COMPILER = 0 THEN
OUT.CH(";") FI;
NEWLINES(1);
SELECTOUTPUT(OSTREAM0);
@BOX 10.1
FORM.SYNTAX.TABLE(ALTERNATIFS,0);
@BOX 11.1
END;
->PROCESS.RETURN;
@BOX 12.1
IF NAME.TYPE.VALUE OF NAMELIST[T] => T2 = 0,
@BOX 13.1
2 => TABLE[REF.PTR OF REFLIST[T2]=>T1];
TABLE.POSN & %FF00 ->>8 => TABLE[T1+1];
TABLE.POSN & %FF => TABLE[T1+2];
@BOX 14.1
IF NEXT.REF OF REFLIST[T2] => T2 = 0,
@END
@TITLE CWU01.5.9(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
FAULTY SYNE
@BOX 2.0
MONITOR FAULT-
SYNE DEFN FAULTY
@BOX 3.0
RETURN
@BOX 1.1
FAULTY.SYNE:
@BOX 2.1
MONITOR.FAULT(8,0);
@BOX 3.1
->PROCESS.RETURN;
@END

@TITLE CWU01.5.10(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
GIVE UP
@BOX 2.0
MONITOR FAULT-
SYNTAB CANNOT CONTINUE
@BOX 3.0
EXIT FROM SYNTAB
@BOX 1.1
GIVE.UP:
@BOX 2.1
MONITOR.FAULT(9,0);
SELECTOUTPUT(OSTREAM0);
@BOX 3.1
BREAK.OUTPUT(OSTREAM);
SELECTINPUT(SAVEDINPUT);
EXIT;
@END
@TITLE CWU01.5.11(1,6)
@COL 1S-2R-3R-4T-5R-6R-7R-8R-9F
@COL 10R-11R
@ROW 5-10
@FLOW 1-2-3-4YES-5-6-7-8-9
@FLOW 4NO-10-11-6
@BOX 1.0
PROCEDURE NAMES
@BOX 2.0
GET CONST AND
LIST FROM AS
@BOX 3.0
CYCLE THROUGH
PROC NAMES
@BOX 4.0
NAME IN NAMELIST?
@BOX 5.0
FAULT-
NAME ALREADY EXISTS
@BOX 6.0
INCR LIST
@BOX 7.0
REPEAT
@BOX 8.0
SET SWITCH
TO STAGE 6
@BOX 9.0
RETURN
@BOX 10.0
ADD NAME TO NAME LIST
@BOX 11.0
FILL NAME LIST
TABLE
@BOX 1.1
PROCEDURE.NAMES:
BEGIN;
$IN COUNT,LIST,SEQ.NO;
@BOX 2.1
AS[AP] => COUNT;
AP+1 => LIST;
@BOX 3.1
0 => SEQ.NO;
LAB14:
@BOX 4.1
AS[LIST] => T;
IF LOOK.UP.NAME(PART(^AS,T,SIZE(^AS)-1) => S) => T = 0,
@BOX 5.1
MONITOR.FAULT(1,T);
@BOX 6.1
1 +> LIST;
@BOX 7.1
1 +> SEQ.NO;
IF SEQ.NO < COUNT, -> LAB14;
@BOX 8.1
STAGE6 => SYNTAX.SWITCH;
@BOX 9.1
END;
->PROCESS.RETURN;
@BOX 10.1
ADD.NAME(S) => T;
@BOX 11.1
2 => NAME.TYPE OF NAMELIST[T];
SEQ.NO => NAME.TYPE.VALUE OF NAMELIST[T];
@END
@TITLE CWU01.5.12(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
NO DELIMITERS
@BOX 2.0
MONITOR FAULT-
DELIM HEADER FAULTY
@BOX 3.0
RETURN TO STAGE 3
@BOX 1.1
NO.DELIMS:
@BOX 2.1
MONITOR.FAULT(4,0);
@BOX 3.1
->END.STAGE3;
@END

@TITLE CWU01.5.13(1,6)
@COL 1S-2F
@FLOW 1-2
@BOX 1.0
IGNORE
@BOX 2.0
RETURN
@BOX 1.1
IGNORE:
@BOX 2.1
->PROCESS.RETURN;
@END

@TITLE CWU01.5.14(1,6)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
NO COSYNES
@BOX 2.0
MONITOR FAULT-
COSYNE NAMES SPEC FAULTY
@BOX 3.0
SET SWITCH TO STAGE 7
@BOX 4.0
RETURN
@BOX 1.1
NO.COSYNES:
@BOX 2.1
MONITOR.FAULT(7,0);
@BOX 3.1
STAGE7 => SYNTAX.SWITCH;
@BOX 4.1
->PROCESS.RETURN;
@END
@TITLE CWU01.5.15(1,6)
@COL 1S-2T-3R-4R-5R-6F
@COL 7R
@ROW 3-7
@FLOW 1-2NO-3-4-5-6
@FLOW 2YES-7-4
@BOX 1.0
END STAGE 8
@BOX 2.0
PROCESSED OK?
@BOX 3.0
PRINT FAULTY MESS
@BOX 4.0
RELEASE OUTPUT
RESET INPUT
@BOX 5.0
RELEASE DATA SEG
@BOX 6.0
RETURN TO PPC
@BOX 7.0
PRINT OK MESS
@BOX 1.1
END.STAGE.8:
@BOX 2.1
SELECTOUTPUT(OSTREAM0);
IF FAULT.COUNT = 0,
@BOX 3.1
CAPTION(%"**SYNTAX PROCESSING FAULTY");
@BOX 4.1
BREAKOUTPUT(OSTREAM);
SELECTINPUT(SAVEDINPUT);
@BOX 5.1
RELEASESEGMENT(59);
@BOX 6.1
EXIT;
@BOX 7.1
CAPTION(%"--SYNTAX PROCESSED OK");
@END
@TITLE CWU01.6(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SYNTAX TABLE ROUTINES
@BOX 2.0
CWU01.6.1     FORM SYNTAX TABLE
CWU01.6.2     FORM SYNTAX ELEMENT
@BOX 3.0
END
@BOX 1.1
@BOX 2.1
#CWU01.6.1
#CWU01.6.2
@BOX 3.1
@END
@TITLE CWU01.6.1(1,6)
@COL 1S-2R-3T-4R-5R-6R-7T-8R-9T-10T-11R-12R
@COL 13T-14R-15F
@ROW 10-13
@FLOW 1-2-3NO-4-5-6-7YES-8-9NO-10YES-11-12-3
@FLOW 3YES-5
@FLOW 7NO-5
@FLOW 9YES-13YES-14-15
@FLOW 13NO-15
@FLOW 10NO-12
@BOX 1.0
FORM SYNTAX TABLE
@BOX 2.0
INITIALISE MERGE CHAIN
@BOX 3.0
LAST ALTERNATIVE?
@BOX 4.0
LEAVE TWO LOCATIONS
 FOR BRANCH ENTRY
@BOX 5.0
FORM SYNTAX ELEMENT
@BOX 6.0
MOVE TO NEXT ELEMENT
@BOX 7.0
LAST ELEMENT?
@BOX 8.0
MOVE TO NEXT
ALTERNATIVE
@BOX 9.0
LAST ALTERNATIVE?
@BOX 10.0
MERGE REQUIRED?
@BOX 11.0
CHAIN IN NEXT TWO
TABLE POSITIONS
@BOX 12.0
FILL IN BRANCH ENTRY
@BOX 13.0
MERGE REQUIRED?
@BOX 14.0
POINT ALL CHAINED
ELEMENTS TO TABLE POSN
@BOX 15.0
EXIT
@BOX 1.1
PROC FORM.SYNTAX.TABLE(ALTERNATIFS,MERGES);
$IN ALTERNATIF,MERGE,BRANCH,T;
@BOX 2.1
0 => MERGE;
@BOX 3.1
AS[ALTERNATIFS] => ALTERNATIF;
IF AS[ALTERNATIFS+1] < 0,
@BOX 4.1
TABLE.POSN => BRANCH;
2 +> TABLE.POSN;
@BOX 5.1
FORM.SYNTAX.ELEMENT(AS[ALTERNATIF]);
@BOX 6.1
1 +> ALTERNATIF;
@BOX 7.1
IF AS[ALTERNATIF] >= 0,
@BOX 8.1
1 +> ALTERNATIFS;
@BOX 9.1
IF AS[ALTERNATIFS] < 0,
@BOX 10.1
IF MERGES = 0,
@BOX 11.1
MERGE => TABLE[TABLE.POSN];
TABLE.POSN => MERGE;
2 +> TABLE.POSN;
@BOX 12.1
0 => TABLE[BRANCH];
IF TABLE.POSN - BRANCH => TABLE[BRANCH+1] >= 256 THEN;
MONITOR.FAULT(10,0);
FI;
@BOX 13.1
IF MERGE = 0,
@BOX 14.1
WHILE MERGE /= 0 DO
TABLE[MERGE=>T] => MERGE;
3 => TABLE[T];
IF TABLE.POSN - T => TABLE[T+1] >= 256 THEN;
MONITOR.FAULT(11,0);
FI;
OD;
@BOX 15.1
END;
@END
@TITLE CWU01.6.2(1,6)
@COL 1S-18C-19R-20R-21C-22R-23R
@COL 24C-25R-26R-27C-28R-29T-30T-31T-32R-33R-34R-35R
@COL 36R-37R-38R-39F
@ROW 30-36
@ROW 33-38
@FLOW 18-19-20
@FLOW 21-22-23
@FLOW 24-25-26
@FLOW 27-28-29NO-30YES-31NO-32-34-35
@FLOW 29YES-36-37
@FLOW 30NO-38-34
@FLOW 31YES-33-34
@BOX 1.0
FORM SYNTAX ELEMENT
@BOX 18.0
[ ]
@BOX 19.0
FORM SYNTAX TABLE
WITH MERGES
@BOX 20.0
RETURN
@BOX 21.0
PROC
@BOX 22.0
MONITOR FAULT-
NAME REF INCONSISTENT
WITH DECL
@BOX 23.0
RETURN
@BOX 24.0
SYMBOL
@BOX 25.0
PLANT SYMBOL
IN TABLE
@BOX 26.0
RETURN
@BOX 27.0
COSYNE
@BOX 28.0
PLANT COSYNE PTR
IN TABLE
@BOX 29.0
UP?
@BOX 30.0
PARAM GIVEN?
@BOX 31.0
CONSTANT OR STRING
PARAM?
@BOX 32.0
PLANT PROCEDURE
INDEX IN TABLE
@BOX 33.0
ADD CONSTANT TO
TABLE OR
COPY STRING INTO
PARAM AREA
@BOX 34.0
INCR TABLE POSN
@BOX 35.0
RETURN
@BOX 36.0
INCR TABLE POSN
@BOX 37.0
RETURN
@BOX 38.0
SET TABLE ELEMENT
TO ZERO
@BOX 39.0
END
@BOX 1.1
PROC FORM.SYNTAX.ELEMENT(TREE);
$IN T,I,T1,T2,FLAG,CTYPE;
ADDR[$IN] S;
SWITCH AS[TREE]\
SYN.COS,SYMB,BRACKETS;
#CWU01.6.3
@BOX 18.1
BRACKETS:
@BOX 19.1
FORM.SYNTAX.TABLE(AS[TREE+1],1);
@BOX 20.1
EXIT;
@BOX 21.1
PROC1:
@BOX 22.1
MONITOR.FAULT(3,T);
@BOX 23.1
EXIT;
@BOX 24.1
SYMB:
@BOX 25.1
1 => TABLE[TABLE.POSN];
0 - AS[TREE+1] => TABLE[TABLE.POSN+1];
2 +> TABLE.POSN;
@BOX 26.1
EXIT;
@BOX 27.1
COS:
@BOX 28.1
NAME.TYPE OF NAMELIST[T]=>CTYPE;
NAME.TYPE.VALUE OF NAMELIST[T] => T1 => TABLE[TABLE.POSN];
@BOX 29.1
IF T1=4,
@BOX 30.1
IF AS[TREE+2] => T = 0,
@BOX 31.1
IF AS[T] = 0,
@BOX 32.1
IF CTYPE = 3 THEN;
AS[T+1] => TABLE[TABLE.POSN+1];
ELSE;
AS[T+1]->>8 =>TABLE[TABLE.POSN+1];
AS[T+1] & %FF =>TABLE[TABLE.POSN+2];
FI;
@BOX 33.1
0 => FLAG;
0 => T2;
0 => I;
LAB13:
IF AS[T+1+I] => T1 = 0,->ROUND;
IF I=0 THEN;
IF T1 < "0" OR T1 > "9" THEN;
1 => FLAG;
FI;
FI;
IF FLAG=0 THEN;
T2 * 10 + T1 - "0" => T2;
FI;
1 +> I;
->LAB13;
ROUND:
IF FLAG = 1 THEN;
PARAM.AREA - 10000 => T2;
LAB8:
     AS[1 +> T] => T1  => COS.PARAMETERS[PARAM.AREA];
     1 +> PARAM.AREA;
IF T1 /= 0,-> LAB8;
FI;
IF CTYPE=3 THEN;
IF T2 >= 256 THEN;
MONITOR.FAULT(12,0);
ELSE;
T2=>TABLE[TABLE.POSN+1];
FI;
ELSE;
IF T2 >= %10000 THEN;
MONITOR.FAULT(13,0);
ELSE;
T2->>8=>TABLE[TABLE.POSN+1];
T2 & %FF =>TABLE[TABLE.POSN+2];
FI;
FI;
@BOX 34.1
2 +> TABLE.POSN;
IF C.TYPE= 5 THEN;
1+>TABLE.POSN;
FI;
@BOX 35.1
EXIT;
@BOX 36.1
1 +> TABLE.POSN;
@BOX 37.1
EXIT;
@BOX 38.1
0 => TABLE[TABLE.POSN+1]=>TABLE[TABLE.POSN+2];
@BOX 39.1
END;
@END
@TITLE CWU01.6.3(1,6)
@COL 6R-7C-8T-9R-10R-11R-12R
@COL 2C-3R-4T-5C-13C-14T-15R-16R-17R
@ROW 6-13
@FLOW 2-3-4YES-5
@FLOW 4NO-6-7-8YES-9-10-11-12
@FLOW 8NO-10
@FLOW 13-14YES-15-16-17
@FLOW 14NO-16
@BOX 2.0
NAME
@BOX 3.0
LOOK UP NAME
@BOX 4.0
FOUND?
@BOX 5.0
TYPE?
@BOX 6.0
ADD NAME
AND FILL NAMELIST
TABLE
@BOX 7.0
REFERENCE
@BOX 8.0
PARAM GIVEN?
@BOX 9.0
MONITOR FAULT-
NAME NOT
DEFINED
@BOX 10.0
ADD REF
@BOX 11.0
INCR TABLE POSN
@BOX 12.0
RETURN
@BOX 13.0
SYNE
@BOX 14.0
PARAM GIVEN?
@BOX 15.0
MONITOR FAULT-
NAME REF INCONSISTENT
WITH DECL
@BOX 16.0
PLANT SYNE PTR
IN TABLE
@BOX 17.0
RETURN
@BOX 2.1
SYN.COS:
@BOX 3.1
AS[TREE+1] => T;
@BOX 4.1
IF LOOK.UP.NAME(PART(^AS,T,SIZE(^AS)-1) => S) => T = 0,
@BOX 5.1
SWITCH NAME.TYPE OF NAMELIST[T]\
REFCE,SYN,PROC1,COS,COS,COS;
@BOX 6.1
ADD.NAME(S) => T;
0 => NAME.TYPE OF NAMELIST[T];
0 => NAME.TYPE.VALUE OF NAMELIST[T];
@BOX 7.1
REFCE:
@BOX 8.1
IF AS[TREE+2] = 0,
@BOX 9.1
MONITOR.FAULT(2,T);
@BOX 10.1
NAME.TYPE.VALUE OF NAMELIST[T] => NEXT.REF OF REFLIST[REF.SPACE];
REF.SPACE => NAME.TYPE.VALUE OF NAMELIST[T];
TABLE.POSN => REF.PTR OF REFLIST[REF.SPACE];
1 +> REF.SPACE;
@BOX 11.1
3 +> TABLE.POSN;
@BOX 12.1
EXIT;
@BOX 13.1
SYN:
@BOX 14.1
IF AS[TREE+2] = 0,
@BOX 15.1
MONITOR.FAULT(3,T);
@BOX 16.1
2 => TABLE[TABLE.POSN];
NAME.TYPE.VALUE OF NAMELIST[T] => T;
T & %FF00 ->>8 => TABLE[TABLE.POSN+1];
T & %FF => TABLE[TABLE.POSN+2];
3 +> TABLE.POSN;
@BOX 17.1
EXIT;
@END
@TITLE CWU01.7(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
NAME LIST PROCEDURES
@BOX 2.0
CWU01.7.1     LOOK.UP.NAME
CWU01.7.2     ADD NAME
CWU01.7.3     TIDY UP NAMES
@BOX 3.0
END
@BOX 1.1
@BOX 2.1
#CWU01.7.1
#CWU01.7.2
#CWU01.7.3
@BOX 3.1
@END
@TITLE CWU01.7.1(1,6)
@COL 1S-2R-3T-4R-5T-6R-7T-8R-9F
@FLOW 1-2-3YES-4-5NO-6-7YES-8-9
@FLOW 3NO-9
@FLOW 5YES-3
@FLOW 7NO-3
@BOX 1.0
LOOK UP NAME
@BOX 2.0
GET HASHVALUE
AND COUNT
@BOX 3.0
ANY MORE NAMES?
@BOX 4.0
SET PTR TO NEXT
NAME IN CHAIN
@BOX 5.0
NOT SAME NUMBER
OF CHARS?
@BOX 6.0
CYCLE THROUGH
CHARS OF NAME
@BOX 7.0
CHAR EQUAL?
@BOX 8.0
REPEAT
@BOX 9.0
EXIT
@BOX 1.1
PROC LOOK.UP.NAME(NAME);
$IN T,HASHVALUE,I,COUNT;
@BOX 2.1
NAME^[0] => HASHVALUE;
NAME^[1] => COUNT;
@BOX 3.1
IF NEXT.NAME OF NAMELIST[HASHVALUE] => T = 0,
@BOX 4.1
T => HASHVALUE;
@BOX 5.1
IF COUNT /= NAME.COUNT OF NAMELIST[T],
@BOX 6.1
0 => I;
LAB9:
@BOX 7.1
IF NAME^[2+I] /= NAMES[NAME.BASE OF NAMELIST[T]+I],
@BOX 8.1
1 +> I;
IF I < COUNT, -> LAB9;
@BOX 9.1
T => LOOK.UP.NAME;
END;
@END
@TITLE CWU01.7.2(1,6)
@COL 1S-2R-3T-10R-4R-5R-8R-9F
@COL 11R
@ROW 3-11
@FLOW 1-2-3YES-10-4-5-8-9
@FLOW 3YES-11-3
@BOX 1.0
ADD NAME
@BOX 2.0
GET HASHVALUE
@BOX 3.0
NAME ENTRY?
@BOX 10.0
PLANT PTR
TO NEW NAME
@BOX 4.0
GET COUNT
@BOX 5.0
CYCLE THROUGH
NAME CHARS
PLANT CHAR
@BOX 8.0
ADVANCE PTR
@BOX 9.0
EXIT
@BOX 11.0
SET NAME PTR TO
NEXT NAME IN CHAIN
@BOX 1.1
PROC ADD.NAME(NAME);
$IN HASHVALUE,I,T,COUNT;
@BOX 2.1
NAME^[0] => HASHVALUE;
@BOX 3.1
IF NEXT.NAME OF NAMELIST[HASHVALUE] => T /= 0,
@BOX 10.1
NAME.SPACE => NEXT.NAME OF NAMELIST[HASHVALUE];
0 => NEXT.NAME OF NAMELIST[NAME.SPACE];
@BOX 4.1
NAME^[1] => NAME.COUNT OF NAMELIST[NAME.SPACE] => COUNT;
@BOX 5.1
-1 => I;
NEXT.N => NAME.BASE OF NAMELIST[NAME.SPACE];
WHILE 1 +> I < COUNT DO
NAME^[2+I] => NAMES[NEXT.N+I]
OD;
COUNT +> NEXT.N;
@BOX 8.1
NAME.SPACE => T;
1 +> NAME.SPACE;
@BOX 9.1
T => ADD.NAME;
END;
@BOX 11.1
T => HASHVALUE;
@END
@TITLE CWU01.7.3(1,6)
@COL 1S-2R-3R-4T-5T-6R-7R-8R-9R-10R-13R-14F
@FLOW 1-2-3-4NO-5NO-6-7-4
@FLOW 4YES-8-9-10-13-14
@FLOW 5YES-7
@BOX 1.0
TIDY UP NAMES
@BOX 2.0
CYCLE THROUGH HASH LIST
@BOX 3.0
GET NAME PTR
@BOX 4.0
NO ENTRY?
@BOX 5.0
NOT FORWARD REF?
@BOX 6.0
MONITOR FAULT-
NAME NOT DEFINED
@BOX 7.0
GET NEXT NAME PTR
IN CHAIN
@BOX 8.0
REPEAT
@BOX 9.0
OUTPUT DATAVEC
COSYNES HEADER
@BOX 10.0
CYCLE THROUGH
COSYNE NAMES
OUTPUT COSYNE NAME
@BOX 13.0
OUTPUT END
DATAVEC
@BOX 14.0
EXIT
@BOX 1.1
PROC TIDY.UP.NAMES;
$IN I,T,T1;
@BOX 2.1
0 => I;
LAB10:
@BOX 3.1
NEXT.NAME OF NAMELIST[I] => T;
@BOX 4.1
IF T = 0,
@BOX 5.1
IF NAME.TYPE OF NAMELIST[T] /= 0,
@BOX 6.1
MONITOR.FAULT(2,T);
@BOX 7.1
NEXT.NAME OF NAMELIST[T] => T;
@BOX 8.1
2 +> I;
IF I < 128, -> LAB10;
@BOX 9.1
ALTERNATIVE COMPILER FROM
CAPTION(%"-> PASSWITCH;");
END;
IF COMPILER = 0 THEN
NEWLINES(0);
CAPTION(%"LOOP2:");
NEWLINES(0);
CAPTION(%"SWITCH SYNTAX [SY] \")
FI;
NEWLINES(1);
@BOX 10.1
-1 => I;
WHILE 1 +> I < COSYNE.SEQ.NO DO
NAME.COUNT OF NAMELIST[COSYNE.INDEX.TABLE[I]=>T] => T1;
SELECT NAMELIST[T];
CAPTION(PART(^NAMES,NAME.BASE,NAME.BASE+NAME.COUNT-1));
IF COMPILER = 0 THEN
IF I+1 /= COSYNE.SEQ.NO THEN
OUT.CH(",");
ELSE
OUT.CH(";")  FI FI;
NEWLINES(1);
OD;
@BOX 13.1
ALTERNATIVE COMPILER FROM
CAPTION(%"PASSWITCH:;")
END;
NEWLINES(1);
CAPTION(%"**IN -1");
NEWLINES(1);
@BOX 14.1
END;
@END
@TITLE CWU01.8(1,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PRINTLINE AND MONITORFAULT
@BOX 2.0
CWU01.8.1     PRINT LINE
CWU01.8.2     MONITOR FAULT
@BOX 3.0
END
@BOX 1.1
@BOX 2.1
#CWU01.8.1
#CWU01.8.2
@BOX 3.1
@END
@TITLE CWU01.8.1(1,6)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
PROC PRINT LINE
@BOX 2.0
CYCLE THROUGH CHARS
@BOX 3.0
PRINT CHAR
@BOX 4.0
IF LINE FILLED
START NEW ONE
@BOX 5.0
REPEAT UNTIL NL OR NP
@BOX 6.0
END
@BOX 1.1
PROC PRINTLINE;
$IN I,CHR;
@BOX 2.1
-1 => I;
LAB11:
@BOX 3.1
OUT.CH(LINE[1+>I] => CHR);
@BOX 4.1
IF I & %7F = %73 THEN;
NEWLINES(1);
FI;
@BOX 5.1
IF CHR = NL OR CHR = NP THEN;
NL => CHR;
FI;
IF CHR /= NL, -> LAB11;
@BOX 6.1
END;
@END
@TITLE CWU01.8.2(1,6)
@COL 1S-2R-3T-4R-5R-6R-7R-8T-9R-10F
@FLOW 1-2-3NO-4-5-6-7-8YES-9-10
@FLOW 3YES-5
@FLOW 8NO-10
@BOX 1.0
PROC MONITOR FAULT
@BOX 2.0
SELECT OUTPUT CHANNEL
PRINT NEWLINE
@BOX 3.0
SAME LINE?
@BOX 4.0
SET OLDLINENO
AND PRINT LINE
@BOX 5.0
INCR FAULT COUNT
@BOX 6.0
PRINT LINE NUMBER
@BOX 7.0
PRINT MONITOR
@BOX 8.0
PRINT NAME?
@BOX 9.0
PRINT NAME
@BOX 10.0
END
@BOX 1.1
PROC MONITOR.FAULT(NO,NAME);
$IN T;
@BOX 2.1
SELECTOUTPUT(OSTREAM0);
NEWLINES(1);
@BOX 3.1
IF LINENO = OLDLINENO,
@BOX 4.1
LINENO => OLDLINENO;
SPACES(5);
PRINTLINE();
@BOX 5.1
1 +> FAULT.COUNT;
@BOX 6.1
OUT.CH("*");
SPACES(6);
OUTI(LINE.NO,4);
SPACES(4);
@BOX 8.1
IF NAME = 0,
@BOX 9.1
SPACES(1);
NAME.COUNT OF NAMELIST[NAME] => T;
SELECT NAMELIST[NAME];
CAPTION(PART(^NAMES,NAME.BASE,NAME.BASE+NAME.COUNT-1));
@BOX 10.1
SELECTOUTPUT(OSTREAM);
END;
@BOX 7.1
ALTERNATIVE NO FROM
CAPTION(%"STATEMENT NOT RECOGNISED");
CAPTION(%"NAME ALREADY DEFINED");
CAPTION(%"NAME NOT DEFINED");
CAPTION(%"NAME REFCE AND DECL INCONSISTENT");
CAPTION(%"DELIMITER HEADING FAULTY");
CAPTION(%"DELIMITER FAULTY");
CAPTION(%"PROC NAMES SPEC FAULTY");
CAPTION(%"COSYNE NAMES SPEC FAULTY");
CAPTION(%"SYNE DEFINITION FAULTY");
CAPTION(%"SYNE STATEMENT EXPECTED - SYNTAB CANNOT CONTINUE - GOODBYE");
CAPTION(%"RELATIVE DISTANCE FROM NEXT ALTERNATIF >= 256");
CAPTION(%"RELATIVE DISTANCE FROM MERGE POINT >= 256");
CAPTION(%"COSYNE PARAMETER CONSTANT >= 256");
CAPTION(%"COSYNE PARAMETER CONSTANT >= 65536")
END;
@END
