@X @~
~V7 56 2 -5
~D 10
~H                    MUSS
~
~
~D 10
~H             MTL031
~D 10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YMTL031
~S1~M~OMUTL IMPLEMENTATION DESCRIPTION~
~S1~M~OSection 3  Version 1~
~S1~OSection 3.1 Storage Declarations~
~S1~O1. General Description~
~BThis module implements the TL procedures concerned with
allocating storage for data structures.~
~S1~O2. Interfaces~
~
Other modules used:~
   Section  1 :   (Type Definitions)~
   Section  2 :   (Storage Control)~
   Section  4 :   (Literal Declarations)~
   Section  5 :   (Program Structure Declarations)~
   Section  6 :   (Label Declarations)~
   Section  7 :   (Code Planting)~
   Section 18 :   (Symbol Management)~
   Section 19 :   (Fault Monitoring)~
   Section 23 :   (Storage Allocation)~
   Section 27 :   (Computational Code Generation)~
   Section 28 :   (Control Code Generation)~
~
MUTL Procedures:~
   TL.SPACE~
   TL.MAKE~
   TL.S.DECL~
   TL.V.DECL~
   TL.SELECT.VAR~
   TL.SELECT.FIELD~
   TL.SET.TYPE~
   TL.ASS~
   TL.ASS.VALUE~
   TL.ASS.END~
   TL.ASS.ADV~
~
Interface Procedures:~
   GET.DIM(DIMENSION)DIMENSION~
   S.DECL(MUTL.TYPE,DIMENSION)ADDR.VAR.E~
   ALLOC.VAR(ADDR.VAR.E,ADDR.STORE.E,KIND)~
~
Interface Data Structures:~
   PARAM~
~
Interface Types:~
   VAR.E~
   VAR.ADDR.TY~
   V.STORE.E~
   V.E~
   SEL.B.E~
   SEL.E~
~
Configuration Parameters:~
   SP.VAR.TYPE~
   B.TYPE~
   ASS.Z~
   SP.UNITS~
   C.DFF~
~S1~O2.1 Hardware Interface~
~BAny machine.
~S1~O2.2 Software Interface~
~S11) GET.DIM(DIMENSION)DIMENSION.
~BThis procedure has as a parameter the DIMENSION parameter of TL.S.DECL,
TL.TYPE.COMP or TL.PROC.PARAM, and it yields the value of the dimension required
.~
~S12) S.DECL(MUTL.TYPE,DIMENSION)ADDR.VAR.E~
~BThis procedure allocates a local variable
on the stack frame,
if there is no stack a variable is allocated in the
current global area.
The procedure returns
a pointer to the variables property entry. The parameters are as
specified in TL.S.DECL.
~S13) ALLOC.VAR(ADDR.VAR.E,ADDR.STORE.E,KIND)
~BThis is the procedure that actually allocates store for a
variable.  P1 specifies the variable, P2 the storage area for
allocation, and P3 the storage area kind.  The final parameter
is encoded as the KIND parameter of TYPE.SIZE of MTL23.
~S14) PARAM~
~BParameters of procedures are allocated storage by TL.PROC of Section 5 calling
TL.S.DECL. A value of one in PARAM indicates parameter declarations.~
~S15) VAR.E~
~G6) VAR.ADDR.TY~G~
~BVAR.E is the MUSL type of a data variable property entry. It
contains the following fields.~
~T# 4 20
~
#:VAR.TYP~IMUTL type of variable. For variables of basic types
this contains the MUTL type encoding. For non basic
types it holds only the least significant two bits of
the MUTL type encoding.~
~
#:VAR.TYP.P~IFor variables of non basic types it contains a pointer
to a type property entry, for basic types it contains a nil
pointer.~
~
#:VAR.DIM~IDimension of variable.~
~
#:VAR.F~IA value of one in bit 0 means the variable has been
allocated storage. A value of one in bit 1, which is set by
Section 27, means there are references to the variable.
A value of one in bit 2 means the allocation of the variable
held back (i.e. where the TL.I.PARAM have been defined but not
referenced), storage is allocated only when the variables are
referenced.  In this case VAR.STORE.P of VAR.ADDR contains the
storage area pointer for the allocation.~
~
#:VAR.ADDR~IThis field is of type VAR.ADDR.TY and there are two
alternatives in it. For an allocated variable
there are two fields: VAR.STORE.P gives the storage area pointer,
and VAR.OFF the offset of the
variable within this area. For an unallocated variable
the field VAR.UNDEF is of VAR.UNDEF.TY type and holds information for handling
forward references in Section 27.~
~S17) V.STORE.E~
~G8) V.E~G~
~BV.STORE.E is the MUSL type of a V-store variable property entry. It
contains the following fields.~
~
#:V.READ.P~IPointer to procedure property entry of V-store read subroutine.~
~
#:V.WRITE.P~IPointer to procedure property entry of V-store write subroutine.~
~
#:V.KIND~IZero means that an absolute address and a 'one' means a
data variable is the V-store variable.~
~
#:V.STORE.DIM~IDimension of V-store variable.~
~
#:V.STORE.TYPE~IType of V-store encoded as a MUTL type.~
~
#:V~IThis specifies the whereabouts of the V-store variable.
It is of type V.E and contains a union of two fields.~
~T# 4 20 34
##:STORE.ADDR~IAbsolute address of machine V-store line.~
##:VAR.P~IPointer to property entry for variable.~
~T# 4 20
~S19) SEL.E~
~BThis is the MUSL type of a select variable property entry. It
contains the following fields.~
~
#:SEL.V.TYP~
#:SEL.V.TYP.P~
#:SEL.V.DIM~IThe above three fields specify the type of the data item pointed at
by the select variable. See VAR.E for description of these fields.~
~
#:SEL.V.F~IBit 0 set to one means that the item addressed by the select
variable is an element of a vector. A value of one in bit 1, set
by Section 27, means the select variable has previously been
referenced.~
~
#:SEL.ADDR~IThis is of type SEL.ADDR.TY, imported from Section 27, and it
contains fields for code generation purposes of select variables.~
~Q 6
~
#:SEL.V.MODE~
#:SEL.V.BASE.ST~
#:SEL.V.BASE.N~
#:SEL.V.OFFSET~
#:SEL.V.BASE.P~IIf the address of the item selected does not
contain any dynamic indexing or a load of the actual
D register then it is sufficient to save the status
of the addressing information, and re-instate it when
D is loaded from a select variable. Thus those fields
are merely copies of the variables D.MODE, D.BASE.ST,
D.BASE.V, D.OFFSET and D.BASE.P. See Section 7 for
details of these.~
~S110) SEL.B.E~
~BThis is the MUSL type of a select base property entry. It
contains the following fields.~
~
#:SEL.BASE~IMUTL name of select base.~
~
#:SEL.ALT~IAlternative selected.~
~
#:SEL.FIELD~IField selected.~
~S111) SP.VAR.TYPE~
~BThis is a literal that specifies the MUTL type of the variable allocated by
TL.SPACE for controlling a 'space'.
E.g. ~X%|%4C if address length is 32 bits,
%44 if address length is 16 bits.
~X%%
~S112) B.TYPE~
~BThis is a literal that specifies the mode required for the MUTL A register for
handling B register values.
Mode is specified as a MUTL type.
~X%`
E.g. %4C for 32 bit B register.
~X%%
~S113) ASS.Z~
~BThe TL.ASS, TL.ASS.VALUE, TL.ASS.END and TL.ASS.ADV utilise a
stack for recording the current assignment position with a data
structure. ASS.Z is a literal that specifies the number of entries in this stack
.~
~S114) SP.UNITS
~BThis literal specifies the number of MUTL storage
units (determined by storage allocator in MTL23)
per address unit.~
~S115) C.OFF
~BThis is a vector of 66 byte elements containing the offsets
within a variable of 'C' type
~X%\
(%34)
~X%%
of values of basic scalar type and data pointer type.  The first
64 entries cover the basic scalar types, and is indexed by MUTL
type ->> 2.
Entry 64 is for unbonded data pointers and entry 65 for bonded
pointers.
~S1~O3. Implementation.~
~S1~O3.1 Outline of Operation~
~BTL.SPACE creates space dynamically and
allocates a control variable to maintain the space. TL.MAKE
allocates storage within a space created by TL.SPACE. Note
that TL.SPACE at present does not check
for overflow into another segment.~
~S1~O3.2 Data Structures~
~BA stack called ASS.S maintains information to control
static initialisation of data structures. An entry is put on
the stack for each level in the data structure hierarchy as it is initialised.
ASS.I is the index to the entry on the top of the stack.
The entry type is ASS.S.E and it has the following fields.~
~T# 4 25
~
#:ASS.S.F~IPointer to a field entry.~
#:ASS.S.POS~IPosition of field within MUTL segment.~
#:ASS.S.COMP~IComponent number of field.~
#:ASS.S.Z~ISize of component, unless field is a vector
in which case it gives the size of element.~
#:ASS.SEL.COMP.CNT Number of components in element.~
~
ASS.P points to a variable entry of the variable being
initialised. ASS.STORE.P points to the MUTL segment
containing the variable. ASS.EL.Z is the size of an
element of the variable. ASS.POS is the current assignment
position within the segment, and ASS.ST.POS is the assignment positionof the dat
a structure.
ASS.COMP is the number of
the component currently being assigned to, ASS.COMP.Z is its size.
ASS.FLD is a field entry containing the type information of the
initialised item.~
~Y
~V9 -1
~P
~D 15
~HFLOWCHARTS
~
~
~H                MTL031
~V9 -1
~F
@TITLE MTL03(1,11)
@COL 1S-3R-2R-4R-5R-6R-7F
@FLOW 1-3-2-4-5-6-7
@BOX 1.0
SECTION 3
STATIC DATA STORAGE DECLARATIONS
@BOX 2.0
EXPORTED TYPES
@BOX 3.0
EXTERNAL ENVIRONMENT
AND MODULE HEADING
@BOX 4.0
VARIABLE AND LITERAL
DECLARATIONS
@BOX 5.0
PROCEDURE DECLARATIONS
TL PROCEDURES
3.1 : TL.SPACE
3.2 : TL.S.DECL
3.3 : TL.V.DECL
3.4 : TL.SELECT.VAR
3.5 : TL.SELECT.FIELD
3.6 : TL.SET.TYPE
3.7 : TL.MAKE
3.8 : TL.ASS
3.9 : TL.ASS.VALUE
3.10: TL.ASS.END
3.11: TL.ASS.ADV
OTHER PROCESSING PROCEDURES
3.20: GET.DIM
3.21: S.DECL
3.22: ALLOC.VAR
@BOX 6.0
INITIALISATION
@BOX 7.0
END
@BOX 1.1
@BOX 2.1
;TYPE VAR.ADDR.TY IS
   ADDR STORE.E VAR.STORE.P
   ADDR VAR.OFF OR
   VAR.UNDEF.TY VAR.UNDEF
;TYPE VAR.E IS
   $LO16 VAR.TYP ADDR VAR.DIM $LO16 VAR.F
   ADDR TYPE.E  VAR.TYP.P
   VAR.ADDR.TY VAR.ADDR
;TYPE V.E IS
   $LO32 STORE.ADDR OR
   ADDR VAR.E VAR.P
;TYPE V.STORE.E IS
   ADDR PROC.E V.READ.P,V.WRITE.P
   ADDR V.STORE.DIM $LO16 V.STORE.TYPE
   $LO8 V.KIND
   V.E V
;TYPE SEL.E IS
   $LO8 SEL.V.MODE, SEL.V.BASE.ST
   $LO16 SEL.V.BASE.N
   ADDR SEL.V.OFFSET
   ADDR VAR.E SEL.V.BASE.P
   $LO16 SEL.V.TYP
   ADDR TYPE.E SEL.V.TYP.P
   ADDR SEL.V.DIM
   $LO8 SEL.V.F
   SEL.ADDR.TY SEL.ADDR
;TYPE SEL.B.E IS
   $LO16 SEL.BASE,SEL.ALT,SEL.FIELD
@BOX 3.1
;::PDP*CODE 6;
#MTL03/1
;MODULE(TL.SPACE,TL.MAKE,TL.S.DECL,TL.V.DECL,
        TL.SELECT.VAR,TL.SELECT.FIELD,
        TL.SET.TYPE,TL.ASS,TL.ASS.VALUE,TL.ASS.END,
        TL.ASS.ADV,GET.DIM,S.DECL,ALLOC.VAR,PARAM,
        VAR.E, SEL.E, V.E, V.STORE.E, SEL.B.E, VAR.ADDR.TY);
@BOX 4.1
;$LI/ADDR VAR.E NIL.VAR.P =
;$LI/ADDR[$LO8] NIL.S =
;$LI/ADDR PROC.E NIL.PROC.P =
;*GLOBAL 9
;$IN PARAM
;ADDR STORE.E    ASS.STORE.P
;ADDR VAR.E      ASS.P
;FIELD.E    ASS.FLD
;ADDR ASS.POS,L.ASS.POS,ASS.ST.POS;
$IN  ASS.COMP.Z,ASS.COMP,ASS.I,ASS.EL.Z
;$IN ASS.AREA
;TYPE ASS.E IS
   ADDR FIELD.E  ASS.S.F
   ADDR  ASS.S.POS
   $IN  ASS.S.Z,ASS.S.EL.COMP.CNT,ASS.S.COMP
;ASS.E[ASS.Z]  ASS.S
;*GLOBAL 0
@BOX 5.1
;PSPEC GET.DIM(ADDR)/ADDR
;PSPEC S.DECL($IN,ADDR)/ADDR VAR.E
;PSPEC ALLOC.VAR(ADDR VAR.E,ADDR STORE.E,$IN)
;LSPEC TL.SPACE(ADDR)
;LSPEC TL.S.DECL(ADDR[$LO8],$IN,ADDR)
;LSPEC TL.V.DECL(ADDR[$LO8],$LO32,$IN,$IN,$IN,ADDR)
;LSPEC TL.MAKE($IN,$IN,ADDR)
;LSPEC TL.SELECT.VAR()
;LSPEC TL.SELECT.FIELD($IN,$IN,$IN)
;LSPEC TL.SET.TYPE($IN,$IN)
;LSPEC TL.ASS($IN,$IN)
;LSPEC TL.ASS.VALUE($IN,$IN)
;LSPEC TL.ASS.END()
;LSPEC TL.ASS.ADV($IN)
;::PDP*CODE 4;
#MTL03.1
::PDP*CODE 1;
#MTL03.2
;::PDP*CODE 6;
#MTL03.3
#MTL03.4
#MTL03.5
#MTL03.6
#MTL03.7
#MTL03.8
#MTL03.9
#MTL03.10
#MTL03.11
;::PDP*CODE 1;
#MTL03.20
;::PDP*CODE 6;
#MTL03.21
#MTL03.22
@BOX 6.1
@BOX 7.1
*END
@END
@TITLE MTL03/1(1,11)
@COL 1S-2R-3R
@COL 4R-5F
@ROW 2-4
@FLOW 1-2-3-4-5
@BOX 1.0
EXTERNAL
ENVIRONMENT
@BOX 2.0
TYPES
@BOX 3.0
VARIABLES &
LITERALS
@BOX 4.0
PROCEDURES
@BOX 5.0
END
@BOX 1.1
::EXTERNAL
::ENVIRONMENT
@BOX 2.1
;IMPORT TYPE VAR.UNDEF.TY,SEL.ADDR.TY,LAB.ADDR.TY,PROC.ADDR.TY,STORE.ADDR.TY
;TYPE VAR.E;
;TYPE SEL.E;
;TYPE SEL.B.E;
;TYPE V.STORE.E;
;TYPE FIELD.E;
;TYPE TYPE.E IS
   ADDR FIELD.E TYPE.FIELD.P
   $LO8 TYPE.AL, TYPE.FL
   $LO16 TYPE.Z, TYPE.LIB, TYPE.NAME
;TYPE LAB.E IS
   $LO8 LAB.USE,LAB.TX
   LAB.ADDR.TY LAB.ADDR
;TYPE PAR.E IS
   ADDR PAR.E N.PAR.P
   $LO8 PAR.TYP
   ADDR PAR.DIM
   ADDR TYPE.E PAR.TYP.P
   ADDR VAR.E PAR.REF.V.P,PAR.VAL.V.P
;TYPE PROC.ENTRY.TY IS
   PROC.ADDR.TY PROC.ADDR
   OR $LO32 PROC.FIND.N
;TYPE PROC.E IS
   $LO8 PROC.NAT
   $LO8 PROC.RES.TYP
   $LO8 PROC.INFO
   ADDR PAR.E PROC.PAR.P
   ADDR TYPE.E PROC.RES.TYP.P
   PROC.ENTRY.TY ENTRY
;TYPE STORE.E IS
   ADDR STORE.I,STORE.Z,STORE.EQ.Z
   $LO8 STORE.KIND,SEG.NO
   STORE.ADDR.TY STORE.ADDR
   $LO8 STORE.TY
   ADDR STORE.C.ADDR
   $LO32 STORE.R.ADDR
   $LO8 STORE.BASE, STORE.ACCESS
;TYPE FIELD.E IS
   ADDR FIELD.E NEXT.FIELD.P
   $LO16 FIELD.POS,FIELD.TYPE
   ADDR TYPE.E FIELD.TYPE.P
   $IN FIELD.TAG
   ADDR  FIELD.DIM
@BOX 3.1
;IMPORT LITERAL Z64, SP.UNITS, ADDR.OFF
;ADDR C.TYPE.Z
;$IN DATA.AREA,CODE.AREA,LAST.NAME,C.TYPE.BOUNDARY,C.TYPE.OFFSET
;$IN TL.M, TX.I, COM.DATA, CMP.MODE, CHK.IN
;ADDR [$LO64] USE.LIT.P
;ADDR [STORE.E] CUR.FRAME, PREV.FRAME
;ADDR STORE.E CUR.COM.STORE.P
;ADDR TYPE.E PARAM.TYP.P
;ADDR VAR.E CUR.VAR.P
;ADDR SEL.E CUR.SEL.P
;ADDR V.STORE.E CUR.VSTORE.P
;ADDR SEL.B.E CUR.SELB.P
;ADDR PROC.E CUR.PROC.P
;ADDR LAB.E CUR.LAB.P
;IMPORT LITERAL SP.VAR.TYPE,B.TYPE,AREA.T.Z,ASS.Z,SEG.Z
;$IN CUR.L.REP
;ADDR [$LO8] CUR.L.P
;$LO8[4]STK.T
;$LO8[AREA.T.Z] AREA.T
;STORE.E[SEG.Z] SEG.T
;$IN8[66] C.OFF;
@BOX 4.1
::SYS MUTL ;PSPEC B.TL.SPACE(ADDR)
::SYS MUTL ;PSPEC B.TL.S.DECL(ADDR[$LO8],$IN,ADDR)
::SYS MUTL ;PSPEC B.TL.V.DECL(ADDR[$LO8],$LO32,$IN,$IN,$IN,ADDR)
::SYS MUTL ;PSPEC B.TL.MAKE($IN,$IN,ADDR)
::SYS MUTL ;PSPEC B.TL.SELECT.VAR()
::SYS MUTL ;PSPEC B.TL.SELECT.FIELD($IN,$IN,$IN)
::SYS MUTL ;PSPEC B.TL.SET.TYPE($IN,$IN)
::SYS MUTL ;PSPEC B.TL.ASS($IN,$IN)
::SYS MUTL ;PSPEC B.TL.ASS.VALUE($IN,$IN)
::SYS MUTL ;PSPEC B.TL.ASS.END()
::SYS MUTL ;PSPEC B.TL.ASS.ADV($IN)
::SYS MUTL ;PSPEC C.TL.SPACE(ADDR)
::SYS MUTL ;PSPEC C.TL.S.DECL(ADDR[$LO8],$IN,ADDR)
::SYS MUTL ;PSPEC C.TL.V.DECL(ADDR[$LO8],$LO32,$IN,$IN,$IN,ADDR)
::SYS MUTL ;PSPEC C.TL.MAKE($IN,$IN,ADDR)
::SYS MUTL ;PSPEC C.TL.SELECT.VAR()
::SYS MUTL ;PSPEC C.TL.SELECT.FIELD($IN,$IN,$IN)
::SYS MUTL ;PSPEC C.TL.SET.TYPE($IN,$IN)
::SYS MUTL ;PSPEC C.TL.ASS($IN,$IN)
::SYS MUTL ;PSPEC C.TL.ASS.VALUE($IN,$IN)
::SYS MUTL ;PSPEC C.TL.ASS.END()
::SYS MUTL ;PSPEC C.TL.ASS.ADV($IN)
;LSPEC NEWLINES($IN)
;LSPEC ENTER.TRAP($IN, $IN)
;LSPEC CAPTION(ADDR[$LO8])
;LSPEC OUTI($IN32,$IN)
;PSPEC CHECK.TYPE(ADDR TYPE.E,ADDR TYPE.E)/$IN
;PSPEC ALLOCATE.STK($IN32,$IN32,$IN)
;PSPEC TYPE.SIZE($IN,ADDR TYPE.E,ADDR,$IN)
;PSPEC CHECK.ENT($IN,ADDR [$LO8])/$IN
;PSPEC TL.REG($IN)
;PSPEC TL.PL($IN,$IN)
;PSPEC TL.D.TYPE($IN,ADDR)
;PSPEC TL.C.LIT.16($IN,$IN16)
;PSPEC TL.C.LIT.32($IN,$IN32)
;PSPEC CODE()
;PSPEC TYPE.PTR(ADDR $IN)/ADDR TYPE.E
;PSPEC TL.DATA.AREA($IN)
;PSPEC GET.LIT($IN)/$IN
;PSPEC CHECK.JUMP.RND()
;PSPEC JUMP.RND()
;PSPEC RESET.KIND($IN,$IN)
;PSPEC GET.KIND($IN)/$IN
;PSPEC ALLOCATE($IN,$IN)
;PSPEC ADD.MUTL.NAME($IN,ADDR[$LO8])/$IN
;PSPEC FAULT($IN,ADDR[$LO8])
;PSPEC PR.VAR.REFS(ADDR VAR.E,ADDR STORE.E,ADDR)
;PSPEC PROP.PTR($IN,$IN)
;PSPEC ASS.LIT64($LO64,$IN,ADDR STORE.E,ADDR)
;PSPEC ASS.LIT.128($LO64,$LO64,$IN,ADDR STORE.E,ADDR)
;PSPEC ASS.REF.VAR(ADDR VAR.E,ADDR STORE.E,ADDR)
;PSPEC ASS.LABEL(ADDR LAB.E,ADDR STORE.E,ADDR)
;PSPEC ASS.PROC(ADDR PROC.E,ADDR STORE.E,ADDR)
;PSPEC ASS()
;PSPEC ASS.END()
@BOX 5.1
::END 03/1
@END


@TITLE MTL03.1(1,6)
@COL 1S-12R-6R-4R-5R-7R-9F
@FLOW 1-12-6-4-5-7-9
@BOX 1.0
TL.SPACE(SIZE)
@BOX 12.0
CHECK IF LABEL REQUIRED
AFTER EMBEDDED PROCS OR
VARIABLE[MTL07]
@BOX 6.0
ALLOCATE CONTROL
VARIABLE FOR SPACE
@BOX 4.0
ALLOCATE SPACE BY
DECLARING IT AS A
BYTE VECTOR[MTL03]
@BOX 5.0
PLANT[MTL03]
A = REF OF SPACE
A CONV INT
A => SPACE VAR
@BOX 7.0
REMOVE MUTL NAME
OF VECTOR
@BOX 9.0
END
@BOX 1.1
;PROC TL.SPACE(Z)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.SPACE(Z)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.SPACE(Z)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;1 +> CHK.IN
;$IN T
@BOX 12.1
;CHECK.JUMP.RND()
@BOX 6.1
;TL.S.DECL(NIL.S,SP.VAR.TYPE,0)
;LAST.NAME => T
@BOX 4.1
;TL.S.DECL(NIL.S,%80,Z)
@BOX 5.1
;TL.PL(%46,%83)
;TL.PL(%21,LAST.NAME)
;TL.PL(%45,SP.VAR.TYPE)
;TL.PL(%20,T)
@BOX 7.1
;1 -> LAST.NAME
@BOX 9.1
;1 -> CHK.IN
;END
@END
@TITLE MTL03.2(1,11)
@COL 16R
@COL 1S-2R-17R-20T-21R-3T-4R-5T-6T-8T-9T-18T-10R-13R-23T-14R-15F
@COL 22R
@ROW 4-22
@ROW 16-10
@FLOW 1-2-17-20N-21-3N-4-5N-6N-8N-9N-18N-10-13-23N-14-15
@FLOW 20Y-22-18
@FLOW 3Y-5
@FLOW 23Y-15
@FLOW 5Y-18
@FLOW 6Y-9
@FLOW 8Y-16-4
@FLOW 9Y-14
@FLOW 18Y-23
@BOX 1.0
TL.S.DECL(SYMB.NAME,TYPE,DIM)
@BOX 2.0
CHECK USE OF ENTITY
AND SELECT SPACE FOR
ITS PROPERTIES[MTL18]
@BOX 3.0
PROPERTY ENTRY
ALREADY EXISTS?
@BOX 4.0
ALLOCATE PROPERTY ENTRY
INIT PROPERTY ENTRY
@BOX 5.0
INTERNAL?
@BOX 6.0
FIRST REFN TO INT.ENTITY
@BOX 8.0
TYPE SPECS DIFFER?
@BOX 9.0
IMPORT?
@BOX 10.0
GET STORAGE AREA
[MTL03.2.1]
@BOX 13.0
ALLOCATE STORAGE FOR VARIABLE
[MTL03.22]
@BOX 14.0
ADD MUTL NAME
@BOX 15.0
END
@BOX 16.0
FAULT
MAKE INTERNAL
@BOX 17.0
GET DIMENSION[MTL03.20]
@BOX 21.0
GET TYPE INFO[MTL01]
@BOX 18.0
STORAGE TO BE ALLOCATED
AT TL.ASS TIME?
@BOX 20.0
MUTL NAME ALREADY DECLARED
@BOX 22.0
GET PROPERTY ENTRY
UPDATE KIND
@BOX 23.0
MUTL NAME ALREADY EXISTS
@BOX 1.1
;PROC TL.S.DECL(NAME,TYP,DIM)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.S.DECL(NAME,TYP,DIM)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.S.DECL(NAME,TYP,DIM)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;$IN N,MN,F,T,K,SEG,S
;ADDR TYPE.E TP
;ADDR V.OFF,D
;ADDR STORE.E V.ST.P
;0 => F
@BOX 2.1
;CHECK.ENT(TYP & %C000 ! 4,NAME) => N
@BOX 3.1
;IF N & %FFF /= 0
@BOX 4.1
;ALLOCATE(4,-1)
;T.P => VAR.TYP.P OF CUR.VAR.P^
;0 => VAR.F OF CUR.VAR.P^
;T => VAR.TYP OF CUR.VAR.P^
;DIM=>VAR.DIM OF CUR.VAR.P^
@BOX 17.1
;GET.DIM(DIM) => D => DIM
;IF DIM = -4096 THEN 0=> DIM FI
@BOX 21.1
;TYP & %3FFF => T
;IF PARAM = 0 THEN
   ;TYPE.PTR(^T) => T.P
;ELSE
    ;PARAM.TYP.P=>T.P
;FI
@BOX 5.1
;IF TYP & %C000 = 0
@BOX 6.1
;IF N & %FFF = 0
@BOX 8.1
;SELECT CUR.VAR.P^
;IF [VAR.DIM /= DIM AND DIM /= -1 AND VAR.DIM /= -1] OR
   [T > 3 AND CHECK.TYPE(T.P,VAR.TYP.P) = 0] OR
   T /= VAR.TYP
@BOX 9.1
;IF TYP & %8000 /= 0
@BOX 10.1
#MTL03.2.1
@BOX 13.1
;ALLOC.VAR(CUR.VAR.P,V.ST.P,SEG)
@BOX 14.1
;ADD.MUTL.NAME(N & %E000 ! 4,NAME)
@BOX 15.1
;END
@BOX 16.1
;FAULT(2 => F,NAME)
;%3FFF &> TYP
;0 => N
@BOX 18.1
;IF D < 0
@BOX 20.1
;IF TYP & %C000 = %C000
@BOX 22.1
;PROP.PTR(TYP & %FFF => MN, 4)
;DIM => VAR.DIM OF CUR.VAR.P^
;RESET.KIND(MN, GET.KIND(MN) ! %C0)
@BOX 23.1
;IF TYP & %C000 = %C000
@END


@TITLE MTL03.2.1(1,11)
@COL 1S-12T-2T-8T-9R-3R-4F
@COL 13R-7R
@ROW 2-13
@ROW 3-7
@FLOW 1-12N-2N-8N-9-3-4
@FLOW 12Y-13-4
@FLOW 2Y-7-4
@FLOW 8Y-3
@BOX 1.0
SELECT STORAGE AREA
@BOX 2.0
OFFSTACK DECLARATION?
@BOX 3.0
SELECT APPROPRIATE
STORAGE ENTRY
@BOX 4.0
END
@BOX 7.0
GET STORE ENTRY
@BOX 8.0
NOT A LIBRARY GLOBAL
@BOX 9.0
FAULT
@BOX 12.0
COMMON AREA CURRENTLY SELECTED
@BOX 13.0
GET STORE ENTRY FOR CURRENT COMMON
@BOX 1.1
@BOX 2.1
;IF DATA.AREA > 0
@BOX 3.1
;2=>K
;PARAM + 2 => SEG
;IF DIM /= 0 OR TYP & %3FFF > 255 THEN
   ;3 => K
;FI
;STK.T[K-PARAM-PARAM]=>S
;IF DATA.AREA = 0 THEN
   ;^CUR.FRAME^[S]=>V.ST.P
;ELSE
   ;^PREV.FRAME^[S] => V.ST.P
;FI
@BOX 4.1
::END
@BOX 7.1
;AREA.T[DATA.AREA]=>S
;^SEG.T[S] => V.ST.P
@BOX 9.1
;FAULT(21,NAME)
@BOX 8.1
;IF TL.M & 4 = 0 OR TX.I /= 0 OR F /= 0
@BOX 12.1
;1 => SEG
;IF COM.DATA /= 0
@BOX 13.1
;CUR.COM.STORE.P => V.ST.P
@END


@TITLE MTL03.3(1,9)
@COL 10R-11R-12R
@COL 1S-2R-3T-5T-6T-8R-9F
@COL 14R
@ROW 10-6-14
@FLOW 1-2-3N-5N-6N-8-9
@FLOW 3Y-14-8
@FLOW 5Y-10-12-9
@FLOW 6Y-11-12
@BOX 1.0
TL.V.DECL(SYMB.NAME,STORE.ADDR,READ.SUBR,WRITE.SUBR,TYPE,DIM)
@BOX 2.0
CHECK USE OF ENTITY
AND SELECT SPACE
FOR ITS PROPERTIES
[MTL18]
@BOX 3.0
EXPORT OR INTERNAL
ENTITY?
@BOX 5.0
NO PREVIOUS EXPORT?
@BOX 6.0
TYPE & DIM INCONSISTANT?
@BOX 8.0
ALLOCATE MUTL NAME[MTL18]
@BOX 9.0
END
@BOX 10.0
FAULT
@BOX 11.0
FAULT
@BOX 12.0
DECLARE IT AS A
NORMAL VARIABLE
[MTL03.2]
@BOX 14.0
GET DIMENSION[MTL13.20]
ALLOCATE PROPERTY
ENTRY [MTL18]
AND INITIALISE
COPY PROPS IF VSTORE
MAPS TO A LOCAL DATA VARIABLE
@BOX 1.1
;PROC TL.V.DECL(NAME,ST.ADDR,R.PROC,W.PROC,TYP,DIM)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.V.DECL(NAME,ST.ADDR,R.PROC,W.PROC,TYP,DIM)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.V.DECL(NAME,ST.ADDR,R.PROC,W.PROC,TYP,DIM)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;ADDR [$LO64] T.USE.LIT.P
;ADDR VAR.E L.VAR.P
;$IN N
@BOX 2.1
;CHECK.ENT(TYP & %C000 ! 8,NAME) => N
@BOX 3.1
;IF TYP & %8000 = 0
@BOX 5.1
;IF N & %FFF = 0
@BOX 6.1
;IF V.STORE.TYPE OF CUR.VSTORE.P^ /= TYP & %3FFF
   OR[DIM = 0 AND V.STORE.DIM OF CUR.VSTORE.P^ /= 0]
   OR[DIM /= 0 AND V.STORE.DIM OF CUR.VSTORE.P^ = 0]
@BOX 8.1
;ADD.MUTL.NAME(N & %E000 ! 8,NAME)
@BOX 9.1
;END
@BOX 10.1
;FAULT(3,NAME)
@BOX 11.1
;FAULT(2,NAME)
@BOX 12.1
;1 +> CHK.IN
;TL.S.DECL(NAME,TYP & %3FFF,DIM & 1)
;1 -> CHK.IN
@BOX 14.1
;ALLOCATE(8,-1)
;IF R.PROC = 0 THEN
   ;NIL.PROC.P=>CUR.PROC.P
;ELSE
   ;PROP.PTR(R.PROC,6)
;FI
;CUR.PROC.P => V.READ.P OF CUR.VSTORE.P^
;IF W.PROC = 0 THEN
   ;NIL.PROC.P=>CUR.PROC.P
;ELSE
   ;PROP.PTR(W.PROC,6)
;FI
;CUR.PROC.P => V.WRITE.P OF CUR.VSTORE.P^
;GET.DIM(DIM) => V.STORE.DIM OF CUR.VSTORE.P^
;TYP & %3FFF => V.STORE.TYPE OF CUR.VSTORE.P^
;IF ST.ADDR = 0 THEN
   ;0=>V.KIND OF CUR.V.STOREP^
   ;GET.LIT(0)
;USE.LIT.P => T.USE.LIT.P
   ;TUSE.LIT.P^[0]=>STORE.ADDR OF V OF CUR.V.STOREP^
;ELSE
   ;1=>V.KIND OF CUR.V.STOREP^
   ;PROP.PTR(ST.ADDR,4)
   ;IF GET.KIND(ST.ADDR) & %C0 = 0 THEN
      ;CUR.VAR.P => L.VAR.P
      ;ALLOCATE(4,0)
      ;L.VAR.P^ => CUR.VAR.P^
   ;FI
   ;CUR.VAR.P => VAR.P OF V OF CUR.V.STOREP^
;FI
@END
@TITLE MTL03.4(1,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
TL.SELECT.VAR()
@BOX 2.0
ALLOCATE SELECT ENTRY IN MODULE SPACE[MTL18]
@BOX 3.0
ALLOCATE MUTL NAME[MTL18]
@BOX 4.0
END
@BOX 1.1
;PROC TL.SELECT.VAR
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.SELECT.VAR()
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.SELECT.VAR()
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
;ALLOCATE(%7,1)
;0=>SEL.V.F OF CUR.SEL.P^
@BOX 3.1
;ADD.MUTL.NAME(7,NIL.S)
@BOX 4.1
;END
@END
@TITLE MTL03.5(1,6)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
TL.SELECT.FIELD(BASE,ALT,FIELD)
@BOX 2.0
ALLOCATE SELECT BASE
ENTRY IN MODULE SPACE[MTL18]
@BOX 3.0
ALLOCATE MUTL NAME[MTL18]
@BOX 4.0
INIT PROPERTY ENTRY
@BOX 5.0
END
@BOX 1.1
;PROC TL.SELECT.FIELD(BASE,ALT,FLD)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.SELECT.FIELD(BASE,ALT,FLD)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.SELECT.FIELD(BASE,ALT,FLD)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
@BOX 2.1
;ALLOCATE(12,1)
@BOX 3.1
;ADD.MUTL.NAME(%C,NIL.S)
@BOX 4.1
;BASE => SEL.BASE OF CUR.SELB.P^
;ALT => SEL.ALT OF CUR.SELB.P^
;FLD => SEL.FIELD OF CUR.SELB.P^
@BOX 5.1
;END
@END
@TITLE MTL03.6(1,11)
@COL 1S-4R-5T-6R-2R-3F
@COL 7R
@ROW 6-7
@FLOW 1-4-5N-6-2-3
@FLOW 5Y-7-2
@BOX 1.0
TL.SET.TYPE(NAME,TYPE)
@BOX 2.0
SET TYPE INFORMATION[MTL01]
@BOX 3.0
END
@BOX 4.0
GET PROPERTY PTR [MTL18]
@BOX 5.0
RESET OF LOGICAL 64 DATA TYPE
@BOX 6.0
IF TYPE CHANGED FROM BOUNDED
TO UNBOUNDED PTR ADJUST OFFSET
@BOX 7.0
ADJUST OFFSET
@BOX 1.1
;PROC TL.SET.TYPE(N,T)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.SET.TYPE(N,T)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.SET.TYPE(N,T)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;$IN I,J
@BOX 4.1
;PROP.PTR(N,4)
@BOX 6.1
;IF [T & 3 = 1 OR T = %24] AND VAR.TYP OF CUR.VAR.P^ & 3 = 3 THEN
    ;ADDR.OFF +> VAR.OFF OF VAR.ADDR OF CUR.VAR.P^
;FI
@BOX 2.1
;TYPE.PTR(^T) => VAR.TYP.P OF CUR.VAR.P^
; T => VAR.TYP OF CUR.VAR.P^
@BOX 3.1
;END
@BOX 5.1
;IF VAR.TYP OF CUR.VAR.P^ = %9C
@BOX 7.1
;IF T & 3 => J = 3 THEN
   ;64 => I
;ELSE IF J = 1 OR T = %24 THEN
   ;65 => I
;ELSE
   ;T ->> 2 & %3F => I
;FI FI
;C.OFF[I] +> VAR.OFF OF VAR.ADDR OF CUR.VAR.P^
@END
@TITLE MTL03.7(1,11)
@COL 13R
@COL 1S-2R-3R-4R-5T-6R-7T-8R-9R-10T-11R-16T-17R-12F
@COL 14R
@ROW 13-11-14
@FLOW 1-2-3-4-5N-6-7N-8-9-10N-11-16N-17-12
@FLOW 5Y-13-12
@FLOW 7Y-9
@FLOW 10Y-14-12
@FLOW 16Y-12
@BOX 1.0
TL.MAKE(SPACE,TYPE,DIM)
@BOX 2.0
CHECK IF LABEL REQUIRED
AROUND EMBEDDED PROC
OR CODE DATA[MTL07]
@BOX 3.0
CODE ANY OUTSTANDING
SEQUENCES
@BOX 4.0
GET DIMENSION[MTL03.20]
DETERMINE TYPE ALLOCATION
INFORMATION[MTL23]
@BOX 5.0
ONSTACK DECLARATION?
@BOX 6.0
PLANT[MTL07]
AMODE = SPACE VAR TYPE
A = SPACE VAR
@BOX 7.0
BYTE ALLIGNMENT?
@BOX 8.0
PLANT[MTL07]
A + (BOUNDARY-1)
A & BOUNDARY MASK
A => SPACE.VAR
@BOX 9.0
SAVE A
STACK A
@BOX 10.0
UNKNOWN DIM?
@BOX 11.0
PLANT[MTL07]
A + SIZE
A => SPACE VAR
A=STACK
A CONV PTR.TYPE
PLANT TLPL CALLS
TO SET LIMIT
IF DIM NONZERO
@BOX 12.0
END
@BOX 13.0
ALLOCATE ON
STACK[MTL23]
@BOX 14.0
PLANT[MTL07]
AMODE = B.TYPE
A = B
A * EL.SIZE
ACONV SPACE VAR TYPE
A +> SPACE
B - 1
A = STACK
A CONV PTR.TYPE
LIMIT
@BOX 16.0
SCALAR MAKE
@BOX 17.0
PLANT LIMIT[MTL07]
@BOX 1.1
;PROC TL.MAKE(SP,TYP,DIM)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.MAKE(SP,TYP,DIM)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.MAKE(SP,TYP,DIM)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;1 +> CHK.IN
;$IN S,T,Z,B
;ADDR TYPE.E TP
;ADDR D
@BOX 2.1
;CHECK.JUMP.RND()
@BOX 3.1
;CODE()
@BOX 4.1
;IF DIM => D < -1 THEN
   ;GET.DIM(DIM) => DIM => D
;ELSE IF DIM < 0 THEN
   ;1 => D
;FI FI
;TYP => T
;TYPE.PTR(^T)=>T.P
;TYPE.SIZE(T,T.P,D,1)
;C.TYPE.BOUNDARY + SP.UNITS - 1 / SP.UNITS => B
;C.TYPE.Z + SP.UNITS -1 / SP.UNITS => Z
@BOX 5.1
;IF SP = 0
@BOX 6.1
;TL.PL(%46,SP.VAR.TYPE)
;TL.PL(%22,SP)
@BOX 7.1
;IF B = 1
@BOX 8.1
;TL.C.LIT.16(%84,B-1)
;TL.PL(%28,0)
;TL.C.LIT.16(%44,%FFFF -= (B-1))
;TL.PL(%24,0)
;TL.REG(2)
;TL.PL(%20,SP)
@BOX 9.1
;TL.REG(2)
;TL.PL(%47,%3000)
@BOX 10.1
;TL.C.LIT.32(B.TYPE,Z)
;IF DIM = -1
@BOX 11.1
;TL.PL(%28,0)
;TL.PL(%20,SP)
;TL.PL(%22,%4000)
;TL.PL(%45,(IF DIM = 0 THEN
1 ELSE 3) ! TYP)
@BOX 16.1
;IF DIM = 0
@BOX 17.1
;TL.C.LIT.32(%4C,DIM - 1)
;TL.PL(%02,0)
;TL.PL(%27,0)
@BOX 12.1
;1 -> CHK.IN
;END
@BOX 13.1
;TL.PL(%46, (IF DIM = 0 THEN 1 ELSE 3) ! TYP)
;ALLOCATE.STK(C.TYPE.Z,DIM,B)
@BOX 14.1
;TL.PL(%46,B.TYPE)
;TL.PL(%22,%2000)
;TL.PL(%2B,0)
;TL.PL(%45,SP.VAR.TYPE)
;TL.PL(%38,SP)
;TL.C.LIT.16(%80,1)
;TL.PL(%22,%4000)
;TL.PL(%45, TYP ! 3)
;TL.PL(%9,0)
;TL.PL(%27,0)
@END
@TITLE MTL03.8(1,11)
@COL 1S-2T-3T-4R-10R-5R-6R-7R-8F
@COL 9R
@ROW 4-9
@FLOW 1-2N-3N-4-10-5-6-7-8
@FLOW 2Y-9-7
@FLOW 3Y-5
@BOX 1.0
TL.ASS(NAME,AREA.NUMBER)
@BOX 2.0
GET PROPERTY POINTER[MTL18]
VARIABLE ALREADY ALLOCATED?
@BOX 3.0
NOT IN CODE AREA
@BOX 4.0
PLANT JUMP ROUND[MTL07]
@BOX 5.0
GET TYPE AND SAVE INFORMATION[MTL23]
@BOX 6.0
GET SEGMENT POINTER
GET POSITION OF VARIABLE
@BOX 7.0
SET UP FIELD FOR VARIABLE
INITIALISE ASSIGNMENT[MTL03.11]
NOTE MUTL SEGMENT CONTAINS
INITIALIZED DATA.
@BOX 8.0
END
@BOX 9.0
GET SEGMENT POINTER
OBTAIN POSITION WITHIN MUTL SEG
@BOX 10.0
INFORM LOW LEVEL MUTL
OF INCODE DATAVEC START [MTL27]
@BOX 1.1
;PROC TL.ASS(N,AREA)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.ASS(N,AREA)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.ASS(N,AREA)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;ADDR T
@BOX 2.1
;PROP.PTR(N,4)
;CUR.VAR.P => ASS.P
;IF VAR.F OF ASS.P^ & 1 /= 0
@BOX 3.1
;IF AREA => ASS.AREA /= -1
@BOX 4.1
;JUMP.RND()
@BOX 5.1
;IF VAR.DIM OF ASS.P^ =>T /= 0 THEN
  ;1=>T
;FI
;TYPE.SIZE(VAR.TYP OF ASS.P^,VAR.TYP.P OF ASS.P^,
           T,1)
;C.TYPE.Z => ASS.EL.Z
@BOX 6.1
;IF AREA = -2 THEN
   ;DATA.AREA => AREA
;ELSE IF AREA = -1 THEN
   ;CODE.AREA => AREA
;FI FI
;^ SEG.T[AREA.T[AREA]] => ASS.STORE.P
;STORE.I OF ASS.STORE.P^ + C.TYPE.BOUNDARY
 -1 & (0-C.TYPE.BOUNDARY) => ASS.POS => ASS.ST.POS
@BOX 7.1
;0 => ASS.COMP
;0=>FIELD.POS OF ASS.FLD => FIELD.TAG OF ASS.FLD
;VAR.TYP OF ASS.P^ => FIELD.TYPE OF ASS.FLD
;VAR.TYP.P OF ASS.P^ => FIELD.TYPE.P OF ASS.FLD
;VAR.DIM OF ASS.P^ => FIELD.DIM OF ASS.FLD
;1 +> CHK.IN
;TL.ASS.ADV(0)
;1 -> CHK.IN
;%10 !> STORE.KIND OF ASS.STORE.P^
@BOX 8.1
;END
@BOX 9.1
;VAR.STORE.P OF VAR.ADDR OF ASS.P^ => ASS.STORE.P
;VAR.OFF OF VAR.ADDR OF ASS.P^ => ASS.POS
@BOX 10.1
;ASS()
@END
@TITLE MTL03.9(1,9)
@COL 12T-13R
@COL 1S-2R-3T-4R-5R-6C-7R-8R-9R-10T-11F
@COL 14C-16R-17C-19R-20C-22R
@ROW 12-5
@ROW 6-14
@FLOW 1-2-3N-4-5
@FLOW 3Y-12N-13-10N-11
@FLOW 6-7-8-9-10Y-3
@FLOW 14-16-9
@FLOW 17-19-9
@FLOW 20-22-9
@FLOW 12Y-7
@BOX 1.0
TL.ASS.VALUE(NAME,CNT)
@BOX 2.0
SET REPETITION COUNT
[MTL03.10]
@BOX 3.0
CURRENT LITERAL
@BOX 4.0
GET KIND AND PROP PTR
OF NAME[MTL18]
@BOX 5.0
SWITCH ON KIND
@BOX 6.0
LITERAL
@BOX 7.0
GET VALUE[MTL04]
@BOX 8.0
ASSIGN LITERAL[MTL27]
@BOX 9.0
ADVANCE TO NEXT COMPONENT
[MTL03.11]
@BOX 10.0
DECR REPEAT COUNT
COUNT NOT EXPIRED?
@BOX 11.0
END
@BOX 12.0
REPEAT COUNT
SINGLE VALUED LITERAL?
@BOX 13.0
ASSIGN VALUES
[MTL27]
[MTL03.11]
@BOX 14.0
LABEL
@BOX 16.0
ASSIGN LABEL[MTL28]
@BOX 17.0
PROC
@BOX 19.0
ASSIGN PROC[MTL29]
@BOX 20.0
VARIABLE
@BOX 22.0
ASSIGN REFN OF VARIABLE
[MTL27]
@BOX 1.1
;PROC TL.ASS.VALUE(N,CNT)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.ASS.VALUE(N,CNT)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.ASS.VALUE(N,CNT)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;1 +> CHK.IN
;$IN K,J,T
@BOX 2.1
;GET.DIM(CNT) => CNT
@BOX 3.1
;IF N = 0
@BOX 4.1
;GET.KIND(N) & %F => K
;PROP.PTR(N,K)
@BOX 5.1
;SWITCH K-2 \
B6,B6,B20,B14,B17
@BOX 6.1
;B6:
@BOX 7.1
;GET.LIT(N)
@BOX 8.1
;IF ASS.COMP.Z =< Z64 THEN
   ;ASS.LIT64(USE.LIT.P^[0],ASS.COMP.Z,
             ASS.STORE.P,ASS.POS)
;ELSE
   ;ASS.LIT128(USE.LIT.P^[1],USE.LIT.P^[0],
              ASS.COMP.Z,ASS.STORE.P,ASS.POS)
;FI
@BOX 9.1
;TL.ASS.ADV(1)
@BOX 10.1
;IF 1 -> CNT > 0
@BOX 11.1
;B11:
;1 -> CHK.IN
;END
@BOX 12.1
;IF CUR.L.REP =< 1
@BOX 13.1
;-1 => J
;WHILE 1 +> J < CUR.L.REP DO
      ;CUR.L.P^[J] => T
   ;ASS.LIT.64(T,1,ASS.STORE.P,ASS.POS)
   ;TL.ASS.ADV(1)
;OD
@BOX 14.1
;B14:
@BOX 16.1
;ASS.LABEL(CUR.LAB.P,ASS.STORE.P,ASS.POS)
@BOX 17.1
;B17:
@BOX 19.1
;ASS.PROC(CUR.PROC.P,ASS.STORE.P,ASS.POS)
@BOX 20.1
;B20:
@BOX 22.1
;ASS.REF.VAR(CUR.VAR.P,ASS.STORE.P,ASS.POS)
@BOX 23.1
;IF ASS.COMP.Z /= 0
@BOX 24.1
;ASS.BIT(USE.LIT.P^[0],ASS.STORE.P,ASS.POS,ASS.BIT.POS)
@END
@TITLE MTL03.10(1,11)
@COL 1S-2T-3R-4R-5T-6R-7R-9T-10R-8F
@FLOW 1-2N-3-4-5N-6-7-9N-10-8
@FLOW 2Y-8
@FLOW 5Y-7
@FLOW 9Y-8
@BOX 1.0
TL.ASS.END()
@BOX 2.0
VAR ALREADY ALLOCATED?
@BOX 3.0
CALCULATE DIM
@BOX 4.0
ALLOCATE STORAGE
@BOX 5.0
ANY OUTSTANDING FORWARD
REFNS?
@BOX 6.0
PROCESS FORWARD REFNS[MTL27]
@BOX 7.0
COMPLETE PROPS
@BOX 8.0
END
@BOX 9.0
NOT AN INCODE DATAVEC
@BOX 10.0
INFORM LOW LEVEL MUTL
OF DATAVEC END [MTL27]
@BOX 1.1
;PROC TL.ASS.END
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.ASS.END()
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.ASS.END()
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;$IN F
;ADDR Z
@BOX 2.1
;IF VAR.F OF ASS.P^ => F & 1 /= 0
@BOX 3.1
;IF VAR.DIM OF ASS.P^ = 0 THEN
   ;1 => Z
;ELSE
   ;ASS.POS - ASS.ST.POS + ASS.EL.Z - 1
    /ASS.EL.Z => Z => VAR.DIM OF ASS.P^
;FI
@BOX 4.1
;Z * ASS.EL.Z + ASS.ST.POS => STORE.I OF ASS.STORE.P^
@BOX 5.1
;IF F & 2 = 0
@BOX 6.1
;PR.VAR.REFS(ASS.P,ASS.STORE.P,ASS.ST.POS)
@BOX 7.1
;1 => VAR.F OF ASS.P^
;ASS.ST.POS => VAR.OFF OF VAR.ADDR OF ASS.P^
;ASS.STORE.P => VAR.STORE.P OF VAR.ADDR OF ASS.P^
@BOX 8.1
;END
@BOX 9.1
;IF ASS.AREA /= -1
@BOX 10.1
;ASS.END()
@END
@TITLE MTL03.11(1,10)
@COL 15R-16R-28R-17T-18R-19R-20T-21R-23T-22R-24R
@COL 1S-2R-3T-26T-27R-4T-29T-5R-6T-7T-8R-9R-10T-11R-12R-13T-14F
@ROW 15-26
@ROW 21-9
@FLOW 1-2-3NO-26NO-27-4NO-29NO-5-6NO-7NO-8-9-10NO-11-4YES-16-28-17NO-18-19-28
@FLOW 3YES-15-28
@FLOW 17YES-20NO-21-10YES-12-13NO-14
@FLOW 26YES-9
@FLOW 6YES-4
@FLOW 7YES-9
@FLOW 13YES-19
@FLOW 20YES-23NO-22-16
@FLOW 23YES-24-14
@FLOW 29Y-14
@BOX 1.0
TL.ASS.ADV(NO)
@BOX 2.0
SET REQ COMP NO
SAVE POS OF LAST ASSIGNMENT
@BOX 3.0
INITIALISATION?
@BOX 26.0
CURRENT FIELD A VECTOR?
@BOX 4.0
NOT LAST FIELD OF TYPE?
@BOX 5.0
POP STACKED FIELD ENTRY
@BOX 6.0
CURRENT FIELD SCALAR?
@BOX 7.0
NO OF COMP IN ELEMENT
ALREADY KNOWN?
@BOX 8.0
SET COMP CNT FOR ELEMENT
@BOX 9.0
RESET CUR COMP NO TO
START OF VECTOR
@BOX 10.0
REQ COMP IN
VECTOR?
@BOX 11.0
SET CUR COMP CNT
@BOX 12.0
CALCULATE POSITION OF
REQUIRED ELEMENT
SET COMP SIZE
@BOX 13.0
NON BASIC TYPE?
@BOX 14.0
END
@BOX 15.0
RE-SET STACK PTR
GET FIRST FIELD
@BOX 16.0
GET NEXT FIELD
@BOX 28.0
TYPE.STORE CURRENT
FIELD INFO ON STACK
@BOX 17.0
CURRENT FIELD OF
BASIC TYPE?
@BOX 18.0
NOTE TYPE DISPL
@BOX 19.0
PUSH A FIELD
ENTRY TO STACK
SELECT FIRST FLD
OF TYPE
@BOX 20.0
SCALAR?
@BOX 21.0
SET EL COMP
CNT = 1
@BOX 22.0
INCR CUR COMP NO
@BOX 23.0
IS THIS THE
REQUIRED COMP NO
@BOX 24.0
CALCULATE ASSIGNMENT
ADDRESS
SET COMP SIZE
@BOX 27.0
INCR CUR COMP NO
@BOX 29.0
END OF TYPE
@BOX 1.1
;PROC TL.ASS.ADV(N)
::SYS MUTL ;IF CMP.MODE /= 0 THEN
::SYS MUTL    ;IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        ;B.TL.ASS.ADV(N)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        ;C.TL.ASS.ADV(N)
::SYS MUTL    ;FI
::SYS MUTL    ;IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL ;FI
;$IN REQ.COMP,CC,D,AD
;ADDR FIELD.E F
;ADDR T
@BOX 2.1
;ASS.COMP + N => REQ.COMP
;ASS.POS=>L.ASS.POS
@BOX 3.1
;IF N = 0
@BOX 15.1
;^ASS.FLD => F
;ASS.POS => ASS.S.POS OF ASS.S[0=>ASS.I]
@BOX 28.1
;BEGIN
;SELECT ASS.S[ASS.I]
;F => ASS.S.F
;IF FIELD.DIM OF F^ => T /= 0 THEN
   ;1 => T
;FI
;0-T=> ASS.S.EL.COMP.CNT
;TYPE.SIZE(FIELD.TYPE OF F^,FIELD.TYPE.P OF F^,T,0)
;C.TYPE.Z => ASS.S.Z
;ASS.COMP => ASS.S.COMP
;END
@BOX 17.1
;IF FIELD.TYPE OF F^ > 3
@BOX 18.1
;FIELD.POS OF F^ + ASS.S.POS OF ASS.S[ASS.I] => ASS.POS
@BOX 19.1
;ASS.POS => ASS.S.POS OF ASS.S[1+>ASS.I]
;TYPE.FIELD.P OF FIELD.TYPE.P^ OF F^ => F
@BOX 20.1
;IF FIELD.DIM OF F^ = 0
@BOX 21.1
;1 => ASS.S.EL.COMP.CNT OF ASS.S[ASS.I]
@BOX 23.1
;IF REQ.COMP = ASS.COMP
@BOX 22.1
;1 +> ASS.COMP
@BOX 16.1
;NEXT.FIELD.P OF F^ => F
@BOX 24.1
;FIELD.POS OF F^ + ASS.S.POS OF ASS.S[ASS.I] => ASS.POS
;ASS.S.Z OF ASS.S[ASS.I] => ASS.COMP.Z
@BOX 26.1
;ASS.S.F OF ASS.S[ASS.I] => F
;IF ASS.S.EL.COMP.CNT OF ASS.S[ASS.I] /= 0
@BOX 27.1
;1 +> ASS.COMP
@BOX 4.1
;IF FIELD.TAG OF F^ /= 0
@BOX 29.1
;IF ASS.I = 0
@BOX 5.1
;ASS.S.F OF ASS.S[1->ASS.I] => F
@BOX 6.1
;IF ASS.S.EL.COMP.CNT OF ASS.S[ASS.I] => C.C = 0
@BOX 7.1
;IF C.C > 0
@BOX 8.1
;ASS.COMP - ASS.S.COMP OF ASS.S[ASS.I]
    => ASS.S.EL.COMP.CNT OF ASS.S[ASS.I]
@BOX 9.1
;ASS.S.COMP OF ASS.S[ASS.I] => ASS.COMP
@BOX 10.1
;IF REQ.COMP - ASS.COMP/(ASS.S.EL.COMP.CNT OF ASS.S[ASS.I] => CC) => D
    < FIELD.DIM OF F^ OR FIELD.DIM OF F^ = -1
@BOX 11.1
;D * CC +> ASS.COMP
@BOX 12.1
;REQ.COMP => ASS.COMP
;ASS.S.Z OF ASS.S[ASS.I] => ASS.COMP.Z * D
    + FIELD.POS OF F^ + ASS.S.POS OF ASS.S[ASS.I]
     => ASS.POS
@BOX 13.1
;IF CC /= 1
@BOX 14.1
;END
@END
@TITLE MTL03.20(1,11)
@COL 1S-2T-3R-4F
@COL 5T-6R
@ROW 5-3
@FLOW 1-2N-3-4
@FLOW 2Y-5N-6-3
@FLOW 5Y-4
@BOX 1.0
GET.DIM(DIMENSION)DIMENSION
@BOX 2.0
DIMENSION NOT GIVEN BY MANIFEST
LITERAL
@BOX 3.0
SET DIMENSION TO LITERAL VALUE[MTL04]
@BOX 4.0
END
@BOX 5.0
DIMENSION NOT GIVEN BY
CURRENT LITERAL
@BOX 6.0
NOTE CURRENT LITERAL REQUIRED
@BOX 1.1
;PROC GET.DIM(D)
@BOX 2.1
;IF D => GET.DIM >= -1 OR D < -2047
@BOX 3.1
;GET.LIT(0-D)
;USE.LIT.P^[0] => GET.DIM
@BOX 4.1
;END
@BOX 5.1
IF D /= -2048
@BOX 6.1
;0 => D
@END
@TITLE MTL03.21(1,11)
@COL 1S-2R-7T-8R-3R-4R-5R-6F
@FLOW 1-2-7N-8-3-4-5-6
@FLOW 7Y-3
@BOX 1.0
S.DECL(TYPE,DIM)ADDR VAR.E
@BOX 2.0
SAVE CURRENT DATA AREA
@BOX 7.0
ONSTACK DECLARATIONS NOT PERMITTED?
@BOX 8.0
SELECT STACK
@BOX 3.0
DECLARE VARIABLE[MTL03.2]
@BOX 4.0
GET PROPERTY PTR
REMOVE MUTL NAME
@BOX 5.0
RESELECT ORIGINAL DATA AREA
@BOX 6.0
END
@BOX 1.1
;PROC S.DECL(T,D)
;$IN S.D.A
@BOX 2.1
;DATA.AREA=>S.D.A
@BOX 7.1
;IF TL.M & 2 /= 0 AND TX.I =< 0
@BOX 8.1
;0=>DATA.AREA
@BOX 3.1
;1 +> CHK.IN
;TL.S.DECL(NIL.S,T,D)
;1 -> CHK.IN
@BOX 4.1
;1->LAST.NAME
;CUR.VAR.P=>S.DECL
@BOX 5.1
;S.D.A=>DATA.AREA
@BOX 6.1
;END
@END
@TITLE MTL03.22(1,11)
@COL 1S-2R-3R-4T-5R-6R-7F
@FLOW 1-2-3-4N-5-6-7
@FLOW 4Y-6
@BOX 1.0
ALLOCATE VARIABLE(VAR.P,STORE.P,KIND)
@BOX 2.0
GET ALLOCATION INFORMATION
[MTL23]
@BOX 3.0
ALLOCATE STORAGE FOR VARIABLE
@BOX 4.0
NO FORWARD REFERENCES?
@BOX 5.0
PROCESS FORWARD REFERENCES TO
VARIABLE [MTL27]
@BOX 6.0
COMPLETE PROPERTY ENTRY
@BOX 7.0
END
@BOX 1.1
;PROC ALLOC.VAR(V.P, ST.P, K)
;ADDR V.OFF
;SELECT V.P^
@BOX 2.1
;TYPE.SIZE(VAR.TYP, VAR.TYP.P, VAR.DIM, K)
@BOX 3.1
;STORE.I OF ST.P^ + C.TYPE.BOUNDARY - 1 & (0 - C.TYPE.BOUNDARY) => V.OFF
   + C.TYPE.Z => STORE.I OF ST.P^
;C.TYPE.OFFSET +> V.OFF
@BOX 4.1
;IF VAR.F & 2 = 0
@BOX 5.1
;PR.VAR.REFS(V.P, ST.P, V.OFF)
@BOX 6.1
;V.OFF => VAR.OFF OF VAR.ADDR
;ST.P => VAR.STORE.P OF VAR.ADDR
;1 => VAR.F
@BOX 7.1
;END
@END

