-- RCMap.mesa
  -- Last Modified By Paul Rovner On 22-Jul-81  9:43:28

RCMap: DEFINITIONS
= BEGIN 


-- TYPES

  Base: TYPE = LONG BASE POINTER;
  Limit: CARDINAL = 40000B;  -- plenty

  Object: TYPE = RECORD
    [ map: SELECT type: * FROM
             null => [],  -- NOTE assumed one word
             ref => [],  -- NOTE assumed one word
             controlLink => [],  -- NOTE assumed one word
             oneRef =>  -- NOTE assumed one word
               [ offset: [0..componentLength) ← 0],
             simple =>  -- NOTE assumed one word
               [ length: [0..simpleLength] ← 0,
                 refs: PACKED ARRAY [0..simpleLength) OF BOOLEAN ← ALL[FALSE]],
             nonVariant =>
               [ complete: BOOLEAN ← FALSE,
                 nComponents: [0..componentLength/2) ← 0,
                 components: ARRAY [0..0) OF RCField],
             variant =>  -- NOTE the specified RCMap for each variant includes all common parts
               [ complete: BOOLEAN ← FALSE,
                 nVariants: [0..componentLength/2) ← 0,
                 fdTag: FieldDescriptor ← [],
                 variants: ARRAY [0..0) OF Index -- indexed by tag value
               ],
             array =>
               [ wordsPerElement: [0..componentLength) ← 0,
                 nElements: CARDINAL ← 0,
                 rcmi: Index ← nullIndex
               ],
             sequence =>
               [ wordsPerElement: [0..componentLength) ← 0,
                 fdLength: FieldDescriptor ← [],  -- actual number of elements is stored here
                 commonPart: Index ← nullIndex,
                 dataOffset: CARDINAL ← 0,  -- actual data begins here
                 rcmi: Index ← nullIndex
               ],
             ENDCASE
    ];

  RCField: TYPE = RECORD  -- describes an RC field in a record
    [ wordOffset: CARDINAL ← 0|NULL,
      rcmi: Index ← nullIndex|NULL
    ];

  FieldDescriptor: TYPE = RECORD  -- "fd"
    [ wordOffset: INTEGER ← 0,
      bitFirst: [0..15] ← 0,  -- 4 bits
      bitCount: [1..32] ← 1,  -- 5 bits
      fill: [0..177B] ← 0  -- 7 bits
    ];


  Index: TYPE = Base RELATIVE POINTER [0..Limit) TO Object;
  VIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO variant Object;
  NVIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO nonVariant Object;
  AIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO array Object;
  SeqIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO sequence Object;
  SimpIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO simple Object;
  OneRefIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO oneRef Object;
  NullIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO null Object;
  RefIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO ref Object;
  ControlLinkIndex: TYPE = Base RELATIVE POINTER [0..Limit) TO controlLink Object;


-- CONSTANTS

  componentMaxIndex: CARDINAL = LAST[CARDINAL]/16;  -- leave room for Object.type in length word
    componentLength: CARDINAL = componentMaxIndex+1;
  simpleMaxIndex: CARDINAL = 7;  -- 4 bits for Object.type, 4 for length, 8 BOOLEANs
    simpleLength: CARDINAL = simpleMaxIndex+1;

  invalidIndex: Index = LAST[Index]; -- guaranteed to be an invalid Index
  nullIndex: NullIndex = LOOPHOLE[0]; -- always at index 0 in the Base
  refIndex: RefIndex = LOOPHOLE[1]; -- always at index 1 in the Base
  controlLinkIndex: ControlLinkIndex = LOOPHOLE[2]; -- always at index 2 in the Base

END.