@X @~
~V7 56 2 -5
~L3 COUK1247
80
~D10
~H                    MUSS
~
~
~D10
~H             MTL092
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YMTL092
~S1~M~OMUTL IMPLEMENTATION DESCRIPTION
~S1~M~OSection 9 Version 2
~S1~OSection 9.2 Diagnostics
~S1~O1. General Description
~BThis module is concerned with the implementation of procedures
which accumulate information to support the runtime diagnostics.
~S1~OInterfaces~
~
Other modules used:~
   Section 18:   (Symbol Management)~
~
MUTL Procedures:~
   TL.LINE~
   TL.PRINT~
   TL.BOUNDS~
~
Interface Procedures:~
   SAVE.PROPS~
   SAVE.TYPE~
   SAVE.LT~
   INIT.9~
~
Interface Data Structures:~
   TL.PR.M~
   C.P.L~
   NAME.MASK~
~S1~O2.1 Hardware Interface~
~BAny machine.~
~S1~O2.2 Software Interface~
~S11) SAVEPROPS(FIRST.MUTL.NAME,LAST.MUTL.NAME,PROC.MUTL.NAME)~
~BThis procedure is called at the end of a procedure or module
to save the procedure and local variable properties in the property
vector, provided the least significant bit of TL.M is clear. For
a block or module PROC.MUTL.NAME is zero and for the
external block containing the exports of all modules it is one.~
~S12) SAVE.TYPE(TYPE.MUTL.NAME,FIELD.NAMES)~
~BThis procedure is called to store information about an aggregate
type in the property vector, provided that the least significant bit of
TL.M is clear. P1 is the MUTL name of the type and P2 a vector
of symbol table index values for the field names, the symbolic names
of which are generated by calling SYMB.NAME (Section 18).~
~S13) SAVE.LT(TYPE)~
~BThis procedure is called to save an entry in the linetable,
the type of which is specified by TYPE-~
   0 - line~
   1 - procedure/block begin~
   2 - procedure/block end~
   3 - end of table~
~BEntries for new pages and segments are put in as required,
marked by a change of page in C.P.L and a change of segment in
the current code position.~
~S14) INIT.9()~
~BThis procedure is used to initialise the data structures used by
this section.~
~S15) TL.PR.M
~BThis contains the MODE parameter of the last call to TL.PRINT.
~S16) NAME.MASK
~BThis indicates the kinds of MUTL entities whose symbolic names
need not be maintained.
~BThe following bits when set indicate which names are not required.~
~
   Bit 2   64 bit literals~
   Bit 3   128 bit literals~
   Bit 4   Variables~
   Bit 5   Labels~
   Bit 7   Vstore~
   Bit 9   Types~
~S1~O3. Implementation~
~S1~O3.1 Outline of Operation~
~S11) SAVE.NAME(NAME,P2)~
~BThis procedure saves the symbolic name corresponding to NAME
in the symbol vector, and stores the index into it in the next free
location of the property vector. P2=0 indicates that NAME is a
MUTL name, P2=1 indicates it is an index into a symbol table.
~S12) PROPERTIES()
~BThis procedure is called by SAVE.LT at TL.END time. It puts the
linetable and symbol vector displacements into the first two locations
of the property vector. A list of segments used by the currently
compiled program is inserted at the end of the property vector or
linetable and this displacement is put into the third location of
the property vector.
~S1~O3.2 Data Structures~
~BThree data structures are created by this section to provide
information for the runtime diagnostics.For a non-zero FILE.NAME parameter to TL
, the propetries will be put
into a file called <FILENAME>RD.~
~BThe property vector contains information about the properties of procedures,
variables and aggregate types. The symbolic name of each entry is stored
in the symbol table. The line table contains information which
matches code addresses with lines of the source program and acts
as an index into the property vector for procedure entries.
~S11) PVLT (property vector)~
~S12) PTR.PV~
~BWhen PVLT is indexed by PTR.PV, it is being used as the property vector.
The entry for a procedure in the property vector consists
of an index into the symbol table for the name of the procedure,
followed by one or more variable entries of type redundant also in 247.. The
terminator for the procedure is a variable with an index
into the symbol table of -1. Each variable entry
has the following fields:-~
~
   NAME   index into symbol table~
   TYPE   Bits 0,1~
            0 - scalar~
            1 - pointer to a scalar instance of a type~
            3 - bounded pointer to a vector instance of a type~
          Bits 2-13~
            Either a MUTL basic type or pointer to an aggregate~
            type entry~
          Bit  14~
            0 - basic type~
            1 - aggregate type~
          Bit  15~
            0 - scalar~
            1 - vector~
~
~X%&
~X}|
SEGMENT } segment and offset within segment of the~
OFFSET  } location of the variable~
          Negative values of SEGMENT indicate the stack frame~
          %FFFE  -  parameter~
          %FFFD  -  local scalar or vector variable~
~
DIM     - optional field, only used when TYPE specifies a vector.~
~X%%
~X}}
~S13) SV(symbol vector)~
~BThe symbol vector is a byte vector and contains the names of
procedures, variables and types as follows:-~
~3
~Q 6
~T% 10
~
% ~O                                         ~O~
%|~O      |      |      |      | .. . |      ~O|~
%    |~
%  size  name ----------------------------->~
%   of~
%  name~
~0
~BThe pointer in the PROPERTY.VECTOR, NAME, points to the first
element of the sequence of bytes above.~
~S14) PVLT (line table)~
~S5) PTR.LT
~BWhen PVLT is indexed by PTR.LT, it is being used as the linetable.
The line table is a vector of 16-bit elements and consists
of seven types of entries, each containing two elements.~
~S1a) SEGMENT entry~
~T# 14
~
   Element 0~IFFFD~
   Element 1~ITop 16 bit of 32 bit address following entries until the next
segment entry is encountered.
Thus for the purposes of the line table only all segments
are regarded as containing 2{16} bytes.~
~S1b) PAGE entry~
~
   Element 0~IFFFF~
   Element 1~IPage number of following entries until the next page
entry is encountered.~
~S1c) PROCEDURE.BEGIN entry~
~
   Element 0~IFFFE~
   Element 1~IIndex in 16-bit words into the PROPERTY.VECTOR of a
procedure entry.~
~S1d) PROCEDURE.END entry~
~
   Element 0~IFFFC~
   Element 1~IIndex to associated PROCEDURE.BEGIN entry.~
~S1e) LINE entry~
~
   Element 0~I16 bit pointer to code address in bytes.~
   Element 1~ILine number.~
~S1f) Start of line table entry~
~
   Element 0~IFFFB~
   Element 1~I0~
~S1g) End of line table entry~
~
   Element 0~IFFFA~
   Element 1~I0~
~S16) TYPE.PTRS~
~S7) TPTR~
~BTYPE.PTRS is a vector with entries of type TPTR, containing descriptions
of all the aggregate types that are currently held in the property vector,
so that aggregate type variables can be matched to their type as they are
put into the property vector. Each entry contains the following fields:-~
~
  :TYPE.PTR~Ipointer to a MUTL type.~
  :PVNAME~Iproperty vector name corresponding to this type.~
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                MTL092
~V9 -1
~F
@TITLE MTL09(2,11)
@COL 1S-2R-3R-4R-5R-6R-7F
@FLOW 1-2-3-4-5-6-7
@BOX 1.0
SECTION 9
DIAGNOSTIC INFORMATION
@BOX 2.0
EXTERNAL ENVIRONMENT
AND MODULE HEADING
@BOX 3.0
TYPE DECLARATIONS
@BOX 4.0
VARIABLE AND LITERAL
DECLARATIONS
@BOX 5.0
PROCEDURE DECLARATIONS
TL PROCEDURES
9.1 : TL.LINE
9.2 : TL.BOUNDS
9.3 : TL.PRINT
9.4 : INIT.9
9.6 : SAVE PROPS
9.7 : SAVE.TYPE
9.8 : SAVE.LT
INTERNAL PROCEDURE
9.5 : SAVE.NAME1
9.9 : PROPERTIES
@BOX 6.0
INITIALISATION
@BOX 7.0
END
@BOX 1.1
*CODE 3;
@BOX 2.1
#MTL09/1
MODULE(SAVE.PROPS,SAVE.LT,SAVE.TYPE,INIT.9,TL.PR.M,TL.LINE,TL.BOUNDS,TL.PRINT,C.
P.L,NAME.MASK);
@BOX 3.1
@BOX 4.1
*GLOBALS 9;
$LO8[32] FNAME;
ADDR [$LO8] FNAMEP;
ADDR L.STAT.I;
$IN32 C.P.L;
$IN NAME.MASK,TL.PR.M;
ADDR STORE.E L.STAT.SEG.P;
LITERAL/ADDR [$LO8] NIL.PTR =;
LITERAL/ADDR STORE.E NIL.SEG=;
LITERAL/ADDR FIELD.E NIL.FIELD=;
TYPE TPTR IS ADDR TYPE.E TYPE.PTR $IN PVNAME;
LITERAL PPSIZE=8,LTSIZE=%2800,PVSIZE=%4000,SVSIZE=%3000,TTSIZE=%80;
LITERAL PVLTSIZE=PVSIZE+LTSIZE;
$IN PTR.PV,PTR.LT,PTR.SV,CUR.PROC.PV,CUR.LT.PAGE,PROPSEG,
LAST.LT.PROC,CUR.LT.SEG,PTR.TT,PTR.SEG.T,DPV;
ADDR DSV, DLT;
TPTR [TTSIZE] TYPE.PTRS;
LITERAL/ADDR TYPE.E NIL.E=;
LITERAL/ADDR PROC.E NIL.F=;
*GLOBALS 4;
$LO16[PVLTSIZE] PVLT;
$LO8 [SVSIZE] SV;
*GLOBALS 0;
@BOX 5.1
LSPEC TL.LINE($IN32)/$IN;
LSPEC TL.BOUNDS($IN,ADDR[$IN]);
LSPEC TL.PRINT($IN);
PSPEC SAVE.NAME($IN,$IN);
PSPEC SAVE.LT($IN);
PSPEC SAVE.TYPE( $IN, ADDR[$IN]);
PSPEC SAVE.PROPS($IN,$IN,$IN);
PSPEC PROPERTIES();
PSPEC INIT.9(ADDR[$LO8])
#MTL09.5
#MTL09.8
#MTL09.9
#MTL09.1
#MTL09.6
#MTL09.2
#MTL09.3
#MTL09.7
#MTL09.4
@BOX 6.1
@BOX 7.1
*END
**IN -1
@END

@TITLE MTL09/1(2,11)
@COL 1S-2R-3R-4R-5F
@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 LITERAL FRAME.AREAS,TX.Z,SEG.Z,VAR.ADDR.Z,SEGSHIFT,MURD.TABLE.SEG;
IMPORT TYPE STORE.ADDR.TY;
IMPORT TYPE VAR.UNDEF.TY;
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 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;
TYPE STORE.E IS
   ADDR STORE.I,STORE.Z,STORE.EQ.Z
   $LO8 STORE.KIND,SEG.NO
   STORE.ADDR.TY STORE.ADDR
   $LO8 STORE.TX
   ADDR STORE.C.ADDR
   $LO32 STORE.R.ADDR
   $LO8 STORE.BASE,STORE.ACCESS;
TYPE TX.E IS
$LO16 TX.PROC.N
$LO8 TX.STATUS, TX.BASE
STORE.E [FRAME.AREAS] TX.FRAME;
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;
@BOX 3.1
IMPORT TYPE PROC.E;
ADDR PW1;
$IN MONIT.STR,INT.CNT,TL.M,TX.I,CMP.MODE;
ADDR FIELD.E CUR.FLD.P;
ADDR TYPE.E CUR.TYPE.P;
ADDR PROC.E  CUR.PROC.P;
ADDR VAR.E  CUR.VAR.P;
ADDR STORE.E CODE.SEG.P;
STORE.E [SEG.Z] SEG.T;
TX.E [TX.Z] TX.S;
@BOX 4.1
::SYS MUTL ;PSPEC B.TL.LINE($IN32)/$IN;
::SYS MUTL ;PSPEC B.TL.BOUNDS($IN,ADDR[$IN]);
::SYS MUTL ;PSPEC B.TL.PRINT($IN);
::SYS MUTL ;PSPEC C.TL.LINE($IN32)/$IN;
::SYS MUTL ;PSPEC C.TL.BOUNDS($IN,ADDR[$IN]);
::SYS MUTL ;PSPEC C.TL.PRINT($IN);
PSPEC YIELD.SYMB.NAME($IN)/ADDR [$LO8];
PSPEC FAULT($IN, ADDR[$LO8]);
PSPEC PROP.PTR($IN,$IN);
PSPEC OUT.PROC.ADDR(ADDR PROC.E);
PSPEC OUT.CODE.ADDR();
PSPEC OUT.VAR.ADDR(ADDR VAR.E);
PSPEC SYMB.NAME( $IN)/ADDR[$LO8];
PSPEC GET.KIND($IN)/$IN;;
PSPEC OUT.CODE(ADDR,ADDR);
PSPEC CODE()
PSPEC TL.INSERT($IN);
LSPEC FILE(ADDR [$LO8],$LO64,$IN);
LSPEC RELEASE.SEGMENT($IN);
LSPEC CREATE.FILE.SEGMENT($IN,ADDR,ADDR [$LO8],$LO64);
LSPEC OUTI($IN32,$IN);
LSPEC OUTHEX($LO32,$IN);
LSPEC SELECT.OUTPUT($IN);
LSPEC NEWLINES($IN);
LSPEC CAPTION(ADDR [$LO8]);
LSPEC SPACES($IN);
LSPEC OUTCH($IN);
@BOX 5.1
::END 09/1
@END
@TITLE MTL09.1(2,6)
@COL 1S-2R-6T-7R-8R-4R-3F
@FLOW 1-2-6N-7-8-4-3
@FLOW 6Y-4
@BOX 1.0
TL.LINE(LINE.NO)
@BOX 2.0
SAVE LINE AND
UPDATE LINE TABLE
@BOX 4.0
MONITOR IN LOAD MAP
@BOX 3.0
END
@BOX 6.0
CODE PRINTING NOT REQUIRED
@BOX 7.0
CODE ANY HELD BACK INSTR[MTL07]
@BOX 8.0
PRINT CODE[MTL29]
@BOX 1.1
PROC TL.LINE(L);
::SYS MUTL IF CMP.MODE /= 0 THEN
::SYS MUTL    IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        B.TL.LINE(L);
::SYS MUTL    FI
::SYS MUTL    IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        C.TL.LINE(L);
::SYS MUTL    FI
::SYS MUTL    IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL FI
ADDR T;
@BOX 2.1
L => C.P.L;
IF TL.PR.M &%108 /=0 THEN CODE() FI;
@BOX 4.1
SAVE.LT(0) ;
IF TL.PR.M&%100 /=0 THEN
TL.INSERT(%FC) FI;
::T.B.C
@BOX 3.1
END
@BOX 6.1
IF TL.PR.M & %8 = 0,
@BOX 7.1
@BOX 8.1
IF STORE.I OF CODE.SEG.P^ => T > L.STAT.I
      AND L.STAT.SEG.P = CODE.SEG.P THEN
   ;OUT.CODE(L.STAT.I,T-1);
FI;
CODE.SEG.P=>L.STAT.SEG.P;
T=>L.STAT.I;
@END


@TITLE MTL09.2(2,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.BOUNDS(NAME,[BOUNDS])
@BOX 2.0
NO ACTION
@BOX 3.0
END
@BOX 1.1
PROC TL.BOUNDS(N,B);
::SYS MUTL IF CMP.MODE /= 0 THEN
::SYS MUTL    IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        B.TL.BOUNDS(N,B);
::SYS MUTL    FI
::SYS MUTL    IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        C.TL.BOUNDS(N,B);
::SYS MUTL    FI
::SYS MUTL    IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL FI
@BOX 2.1
@BOX 3.1
END
@END


@TITLE MTL09.3(2,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TL.PRINT(MODE)
@BOX 2.0
SAVE MODE
@BOX 3.0
END
@BOX 1.1
PROC TL.PRINT(M);
IF CMP.MODE & 9 = 0 THEN
   IF M & 1 = 0 THEN
      %FFFD &> CMP.MODE;
   ELSE
      2 !> CMP.MODE;
   FI
FI
::SYS MUTL IF CMP.MODE /= 0 THEN
::SYS MUTL    IF CMP.MODE & 1 /= 0 THEN
::SYS MUTL        B.TL.PRINT(M);
::SYS MUTL    FI
::SYS MUTL    IF CMP.MODE & 2 /= 0 THEN
::SYS MUTL        C.TL.PRINT(M);
::SYS MUTL    FI
::SYS MUTL    IF CMP.MODE & 8 /= 0 THEN EXIT FI
::SYS MUTL FI
@BOX 2.1
M=>TL.PR.M;
@BOX 3.1
END
@END

@TITLE MTL09.4(2,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROC INIT9(FN)
@BOX 2.0
INIIALIZE DATA STRUCTURES IN MODULE 9
@BOX 3.0
END
@BOX 1.1
PROC INIT9(FN);
$IN I,J;
@BOX 2.1
RELEASE.SEGMENT(MURD.TABLE.SEG);
CREATE.FILE.SEGMENT(MURD.TABLE.SEG,%10000,NIL.PTR,0);
0 =>DPV=>LAST.LT.PROC;
IF SIZE(FN)=>J >0 THEN
   -1 => I;
   WHILE 1 +> I < J AND I < 30 DO
      FN^[I] => FNAME[I];
   OD
   'R => FNAME[I];
   'D => FNAME[I + 1];
   PART(^FNAME, 0, I+1) => FNAME.P;
ELSE
      NIL.PTR => F.NAME.P;
FI
NIL.SEG => L.STAT.SEG.P;
2 =>PTR.SV;
3 =>PTR.PV;
PVSIZE =>PTR.LT *2 =>DLT +(LTSIZE*2) =>DSV;
%FFFB =>PVLT[PTR.LT];
-1 => CUR.LT.SEG => CUR.LT.PAGE;
FOR I < TTSIZE DO
NIL.E =>TYPE.PTR OF TYPE.PTRS[I] OD;
@BOX 3.1
END;
@END

@TITLE MTL09.5(2,7)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
PROC SAVENAME(MUTL.NAME);
@BOX 2.0
DECLARATIONS
@BOX 3.0
SAVE SYMBOLIC NAME IN SYMBOL VECTOR
@BOX 4.0
END
@BOX 1.1
PROC SAVE.NAME(MN,P2);
@BOX 2.1
$IN I,J;
ADDR [$LO8] NAME;
@BOX 3.1
IF PTR.PV>PVSIZE-%20 THEN
   FAULT(19, %"LPV");
ELSE IF PTR.SV>SVSIZE-%10 THEN
   FAULT(19, %"SV")
FI FI
ALTERNATIVE P2 FROM
YIELD.SYMB.NAME(MN) =>NAME;
SYMB.NAME(MN) =>NAME;
END;
SIZE(NAME) =>J =>SV[PTR.SV=>PVLT[PTR.PV]];
FOR I <J DO
NAME^[I] &%7F =>SV[PTR.SV+1+I] OD;
J+1 +>PTR.SV;
@BOX 4.1
END;
@END

@TITLE MTL09.6(2,8)
@COL 1S-2R-3R-12T-4R-5T-6T-7R-8R-9R-10R-11F
@FLOW 1-2-3-12N-4-5N-6N-7-8-9
@FLOW 12Y-11
@FLOW 5Y-10-11
@FLOW 6Y-9
@FLOW 9-5
@BOX 1.0
PROC SAVE.PROPS(FN,LN,BLK)
@BOX 2.0
DECLARATIONS
@BOX 3.0
PRODUCE COMPILE MAP
[MTL09.6.1]
@BOX 4.0
CREATE PROC ENTRY IN PV
@BOX 5.0
NO MORE MUTL NAMES?
@BOX 6.0
NOT A VARIABLE?
@BOX 7.0
CREATE VAR ENTRY
@BOX 8.0
INSERT FIELDS
@BOX 9.0
GET NEXT NAME
@BOX 10.0
CREATE PROC END
@BOX 11.0
END
@BOX 12.0
PROPERTIES NOT WANTED?
@BOX 1.1
PROC SAVEPROPS(FN,LN,BLK);
@BOX 2.1
$IN I,K,FIRST;
ADDR RADDR;
LITERAL/ADDR [$LO8] NONAME=;
FN => FIRST;
@BOX 3.1
#MTL09.6.1
@BOX 4.1
PTR.PV =>CUR.PROC.PV;
IF BLK >1 THEN
SAVE.NAME(BLK,0) ELSE
BLK => PVLT[PTR.PV] FI;
1 +>PTR.PV;
@BOX 5.1
IF FIRST > LN,
@BOX 6.1
IF [GET.KIND(FIRST)=>K &%EF /=4 AND BLK/=1]
OR [BLK=1 AND K &%4F /=%44]
OR YIELD.SYMB.NAME(FIRST) =NONAME,
@BOX 7.1
SAVE.NAME(FIRST,0);
PROP.PTR(FIRST,4);
SELECT CUR.VAR.P^;
@BOX 8.1
IF VAR.TYP =>PVLT[PTR.PV+3] ->>2 =0 THEN
-1 =>I;
WHILE 1+>I<TTSIZE AND TYPEPTR OF TYPEPTRS[I] /=VAR.TYP.P DO OD;
IF I = TTSIZE THEN 0 =>I FI;
PVNAME OF TYPEPTRS[I]<<-2 !%4000 !>PVLT[PTR.PV+3] FI;
SELECT VAR.ADDR;
VAR.OFF => K;
ALTERNATIVE STORE.KIND OF VAR.STORE.P^&3 FROM
%FFFD => I;
STORE.R.ADDR OF VAR.STORE.P^ ->>SEGSHIFT =>I;
BEGIN %FFFE =>I;
STORE.Z OF TX.FRAME[0] OF TXS[TXI] + 24 - VAR.OFF => K END;
END;
I <<- SEGSHIFT ! K => RADDR;
RADDR ->> 16 => PVLT[PTR.PV+1];
RADDR & %FFFF => PVLT[PTR.PV +2];
IF VARDIM =>PVLT[PTR.PV+4] >0 THEN
%8000 !>PVLT[PTR.PV+3];
5 +>PTR.PV ELSE
4 +>PTR.PV FI;
@BOX 9.1
1 +>FIRST;
@BOX 10.1
%FFFF => PVLT[PTR.PV];
1 +>PTR.PV;
@BOX 11.1
END;
@BOX 12.1
IF TL.M &1 =1,
@END

@TITLE MTL09.6.1(2,7)
@COL 1S-2T-3R-4T-5R-6T-7T-8T-13T-9R-10R-11R-12F
@FLOW 1-2N-3-4N-5-6N-7N-8N-13N-9-10-7Y-11-12
@FLOW 2Y-12
@FLOW 4Y-6Y-12
@FLOW 8Y-10
@FLOW 13Y-10
@BOX 1.0
PRODUCE COMPILE MAP
@BOX 2.0
NO MAP REQUIRED?
@BOX 3.0
SELECT OUTPUT MONITOR STREAM
@BOX 4.0
PROC MAP NOT REQUIRED?
@BOX 5.0
PRINT PROC/MODULE/BLOCK LINE
@BOX 6.0
DATA MAP NOT REQUIRED?
@BOX 7.0
NO MORE MUTL NAMES?
@BOX 8.0
NOT A VARIABLE?
@BOX 13.0
UNNAMED OR UNDEFINED?
@BOX 9.0
PRINT VARIABLE INFO
@BOX 10.0
GET NEXT NAME
@BOX 11.0
OUTPUT NEWLINE
@BOX 12.0
END
@BOX 1.1
BEGIN;
;$IN POS,Z,T
;ADDR[$LO8] NAME
@BOX 2.1
;IF TL.PR.M & %24 = 0 OR BLK = 1,
@BOX 3.1
;SELECT.OUTPUT(MONIT.STR)
@BOX 4.1
;IF TL.PR.M & 4 = 0,
@BOX 5.1
;NEWLINES(0)
;IF BLK /= 0 THEN
   ;CAPTION(%"PROC ")
   ;CAPTION(YIELD.SYMB.NAME(BLK))
   ;CAPTION(%" STARTS AT ")
   ;PROP.PTR(BLK,6)
   ;OUT.PROC.ADDR(CUR.PROC.P)
   ;CAPTION(%" ENDS AT ")
   ;OUT.CODE.ADDR()
   ;NEWLINES(1)
;FI
@BOX 6.1
;0 => POS
;IF TL.PR.M & %20 = 0,
@BOX 7.1
;IF F.N > L.N,
@BOX 8.1
;IF GET.KIND(FN) & %F /=4,
@BOX 13.1
;YIELD.SYMB.NAME(FN) => NAME
;PROP.PTR(FN,4)
;IF SIZE(NAME) => Z = 0 OR VAR.F OF CUR.VAR.P^ & 1 = 0,
@BOX 9.1
;IF POS + VAR.ADDR.Z + 3 + Z > 119 THEN
      ;NEWLINES(1); 0 => POS
;FI
;CAPTION(NAME)
;VAR.ADDR.Z+Z+3+>POS
;OUTCH('.)
;WHILE 1+>POS / 20 * 20 /= POS DO
   ;OUTCH('.)
;OD
;OUT.VAR.ADDR(CUR.VAR.P)
;SPACES(2);
@BOX 10.1
;1 +> F.N;
@BOX 11.1
;NEWLINES(0);
@BOX 12.1
;END
@END
@TITLE MTL09.7(2,9)
@COL 1S-2R-10R-11T-3R-4R-5R-6R-7R-8T-12R-9F
@FLOW 1-2-10-11N-3-4-5-6-7-8N-12-4
@FLOW 11Y-9
@FLOW 8Y-9
@BOX 1.0
PROC SAVE.TYPE(MUTL.NAME,FIELD.VECTOR)
@BOX 2.0
DECLARATIONS
@BOX 3.0
INSERT TYPE.NAME,SIZE
@BOX 4.0
SELECT FIELD LOCATIONS
@BOX 5.0
DISPLACEMENT,FLAG
@BOX 6.0
TYPE
@BOX 7.0
DIMENSION
@BOX 8.0
END OF TYPE?
@BOX 9.0
END
@BOX 10.0
PRODUCE TYPE MAP
[MTL09.7.1]
@BOX 11.0
PROPERTIES NOT WANTED?
@BOX 12.0
GET NEXT FIELD
@BOX 1.1
PROC SAVE.TYPE(MN,FLDS);
@BOX 2.1
$IN I,J,T;
ADDR FIELD.E FLD;
-1 =>I;
@BOX 3.1
PROP.PTR(MN,9);
IF 1+>PTR.TT = TTSIZE THEN
FAULT(19, %"TYPE.PTRS");
EXIT FI;
SELECT TYPE.PTRS[PTR.TT];
CUR.TYPE.P=>TYPE.PTR;
PTR.PV=>PVNAME;
SAVE.NAME(MN,0);
TYPE.Z OF CUR.TYPE.P^ =>PVLT[PTR.PV+1];
2 +>PTR.PV;
TYPE.FIELD.P OF CUR.TYPE.P^ => FLD;
@BOX 4.1
SAVE.NAME(FLDS^[1+>I],1);
SELECT FLD^;
@BOX 5.1
FIELD.POS =>PVLT[PTR.PV+2];
IF FIELD.TAG+1 =>PVLT[PTR.PV+1] >2 THEN 0 =>PVLT[PTR.PV+1] FI;
@BOX 6.1
IF FIELD.TYPE =>PVLT[PTR.PV+3] ->>2 =0 THEN
-1 =>J;
WHILE 1+>J < TTSIZE AND TYPE.PTR OF TYPE.PTRS[J] /=FIELD.TYPE.P DO OD;
IF J=TTSIZE THEN 0 =>J FI;
PVNAME OF TYPE.PTRS[J]<<-2 !%4000 !>PVLT[PTR.PV+3] FI;
@BOX 7.1
IF FIELD.DIM =>PVLT[PTR.PV+4]>0 THEN
%8000 !>PVLT[PTR.PV+3];
5 +>PTR.PV ELSE
4 +>PTR.PV FI;
@BOX 8.1
IF FIELD.TAG =0,
@BOX 9.1
END;
@BOX 10.1
#MTL09.7.1
@BOX 11.1
IF TL.M &1 =1,
@BOX 12.1
NEXT.FIELD.P => FLD;
@END

@TITLE MTL09.7.1(2,10)
@COL 1S-2T-3R-4R-5F
@FLOW 1-2N-3-4-5
@FLOW 2Y-5
@BOX 1.0
PRODUCE TYPE MAP
@BOX 2.0
DATA MAP NOT REQUIRED
@BOX 3.0
SELECT MONITORING STREAM
@BOX 4.0
PRINT TYPE AND FIELD INFO
@BOX 5.0
END
@BOX 1.1
BEGIN;
;ADDR FIELD.E F.P
;$IN I, Z, POS, I.POS, T, M
;ADDR [$LO8] NAME
@BOX 2.1
;IF TL.PR.M & %20 = 0,
@BOX 3.1
;SELECT.OUTPUT( MONIT.STR)
;NEWLINES(0)
@BOX 4.1
;CAPTION(%" TYPE   ")
;SIZE( YIELD.SYMB.NAME( MN) => NAME) + 31 => POS => I.POS
;CAPTION(NAME)
;PROP.PTR(MN, 9)
;CAPTION(%" SIZE  ")
;OUTHEX(TYPEZ OF CUR.TYPE.P^, 8)
;CAPTION(%" FIELDS:")
;IF TYPE.FIELD.P OF CUR.TYPE.P^ => F.P /= NIL.FIELD THEN
   ;-1 => M
   ;WHILE F.P /= NIL.FIELD DO
      ;SYMB.NAME( FLDS^[1 +> M]) => NAME
      ;IF SIZE( NAME) => Z + POS > 108 THEN
         ;NEWLINES(1)
         ;SPACES(IPOS => POS)
      ;FI
      ;12 + Z +> POS
      ;SPACES(3)
      ;CAPTION(NAME)
      ;OUTCH('/)
      ;OUTHEX( FIELD.POS OF F.P^,8)
      ;NEXT.FIELD.P OF F.P^ => F.P
   ;OD
;FI
@BOX 5.1
;END
@END


@TITLE MTL09.8(2,8)
@COL 1S-2R-3R-4R-5R-6R-7R-8R-9F
@FLOW 1-2-3-4-5-6-7-8-9
@BOX 1.0
PROC SAVE.LT(TYPE)
@BOX 2.0
DECLARATIONS
@BOX 3.0
SEGMENT ENTRY
@BOX 4.0
PAGE ENTRY
@BOX 5.0
LINE ENTRY
@BOX 6.0
PROC ENTRY
@BOX 7.0
END.PROC ENTRY
@BOX 8.0
END.TABLE ENTRY
@BOX 9.0
END
@BOX 11.0
BLOCK ENTRY
@BOX 12.0
ENDBLOCK ENTRY
@BOX 1.1
PROC SAVELT(P1);
IF TL.M &1 =1, ->E;
$IN S,T;
ADDR CODE.AD;
@BOX 2.1
IF PTR.LT+2=LTSIZE+PVSIZE THEN
   FAULT(19, %"LT");
EXIT FI;
@BOX 3.1
 STORE.R.ADDR OF CODE.SEG.P^ ! STORE.I OF CODE.SEG.P^ => CODE.AD;
IF CODE.AD ->>16 =>S /=CUR.LT.SEG THEN
%FFFD =>PVLT[2+>PTR.LT];
S =>PVLT[PTR.LT+1] => CUR.LT.SEG;
%FFFF =>PVLT[2+>PTR.LT];
CUR.LT.PAGE =>PVLT[PTR.LT+1] FI;
CODE.AD & %FFFF => T;
@BOX 4.1
IF C.P.L ->>16 =>S /=CUR.LT.PAGE THEN
%FFFF =>PVLT[2+>PTR.LT];
S =>PVLT[PTR.LT+1] => CUR.LT.PAGE FI;
@BOX 5.1
ALTERNATIVE P1 FROM
BEGIN
IF T /=PVLT[PTR.LT] THEN
T =>PVLT[2+>PTR.LT];
C.P.L  =>PVLT[PTR.LT+1];
FI;
END;
@BOX 6.1
BEGIN T =>PVLT[2+>PTR.LT];
C.P.L => PVLT[PTR.LT+1];
%FFFE =>PVLT[2+>PTR.LT];
LAST.LT.PROC =>PVLT[PTR.LT+1];
PTR.LT =>LAST.LT.PROC;
END;
@BOX 7.1
BEGIN T => PVLT[2+>PTR.LT];
C.P.L =>PVLT[PTR.LT+1];
%FFFC =>PVLT[2+>PTR.LT];
LAST.LT.PROC -PVSIZE =>PVLT[PTR.LT+1];
PVLT[LAST.LT.PROC+1] => LAST.LT.PROC;
CUR.PROC.PV  =>PVLT[PVLT[PTR.LT+1]+PVSIZE+1];
END;
@BOX 8.1
BEGIN %FFFA =>PVLT[2+>PTR.LT];
PROPERTIES() END;
END;
@BOX 9.1
E:END;
@END

@TITLE MTL09.9(2,11)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
PROC PROPERTIES
@BOX 2.0
DECLARATIONS
@BOX 3.0
COMPACT SEGMENT BY MOVING LT AND SV
@BOX 4.0
PUT PROPERTY DISPLACEMENTS AT
START OF SEGMENT
@BOX 5.0
INSERT SEGMENT NOS.
IN SEG TABLE AFTER SV
@BOX 6.0
FILE PROPERTIES
END
@BOX 1.1
PROC PROPERTIES;
@BOX 2.1
$LO8 [8] FILE.N;
ADDR [$LO8] NEW.SV;
ADDR I,J;
$IN K;
@BOX 3.1
DLT/2 => J;
FOR I < PTR.LT - J + 2 DO
   PVLT[J+I] => PVLT[PTR.PV + I]
OD;
PTR.PV * 2 => DLT;
I*2 + DLT +2 => DSV;
MAKE($LO8,PTR.SV+1,BYTE(^PVLT[0])+DSV)=> NEW.SV;
FOR I < PTR.SV +1 DO SV[I] => NEW.SV^[I] OD;
DSV +PTR.SV +2/2 =>PTR.SEG.T;
@BOX 4.1
DLT =>PVLT[0];
DSV =>PVLT[1];
PTR.SEG.T+1 *2 =>PVLT[2];
@BOX 5.1
FOR I < SEG.Z DO
IF STORE.KIND OF SEG.T[I] &1 =1 THEN
STORE.R.ADDR OF SEG.T[I] ->> SEGSHIFT => PVLT[1+>PTR.SEG.T]
FI OD;
%FFFF => PVLT[PTR.SEG.T+1];
@BOX 6.1
E:IF FNAME.P /= NIL.PTR THEN
CHANGE.SIZE(MURD.TABLE.SEG,PTR.SEG.T+2*2);
FILE(FNAME.P, 0,MURD.TABLE.SEG);
RELEASE.SEGMENT(MURD.TABLE.SEG) FI;
END;
@END


