Index: 
PUBLIC 
PROC [node: Tree.Index] 
RETURNS [Lexeme] =
BEGIN -- generates code for array indexing
arrayType: CSEIndex = P5U.OperandType[tb[node].son[1]];
grain, tBits: BitCount;
packed: BOOL;
elementWords: OpWordCount;
indexRange: LONG CARDINAL;
owd: CARDINAL;
delta: INTEGER;
t2: Tree.Link;
base, index, offset: VarComponent;
er: IndVarIndex;
bar: BoVarIndex ← P5L.MakeBo[P5L.VarForLex[P5.Exp[tb[node].son[1]]]];
IF bar = VarNull 
THEN
SIGNAL CPtr.CodeNotImplemented; -- no packed arrays of arrays
 
base ← cb[bar].base; offset ← cb[bar].offset;
WITH a: seb[arrayType] 
SELECT 
FROM
array =>
BEGIN
grain ← SymbolOps.BitsPerElement[a.componentType, a.packed];
packed ← grain < wordLength;
elementWords ← IF packed THEN 1 ELSE OpWordCount[grain/wordLength];
indexRange ← SymbolOps.Cardinality[a.indexType];
END;
 
ENDCASE => ERROR;
 
IF packed 
AND (tBits ← indexRange*grain) 
IN (0..wordLength) 
THEN
BEGIN
fieldSize: CARDINAL = offset.wSize*wordLength + offset.bSize;
IF tBits < fieldSize 
THEN
P5L.ModComponent[var: @offset, wd: 0, bd: fieldSize-tBits];
 
END;
 
WITH oo: offset 
SELECT 
FROM
frame =>
BEGIN
IF oo.level # Symbols.lZ THEN ERROR;
IF packed 
THEN
BEGIN
ScaleComponent[@offset, PackedBitCount[grain]];
offset.wSize ← 0;  offset.bSize ← grain;
END
 
ELSE
BEGIN
IF oo.bd # 0 
OR offset.bSize # 0 
THEN 
ERROR; -- arrays start on word boundaries and are words long
 
offset.wSize ← elementWords;
END;
 
owd ← oo.wd;
END;
 
code =>
BEGIN -- this gets cross jumped
IF packed 
THEN
BEGIN
ScaleComponent[@offset, PackedBitCount[grain]];
offset.wSize ← 0;  offset.bSize ← grain;
END
 
ELSE
BEGIN
IF oo.bd # 0 
OR offset.bSize # 0 
THEN 
ERROR; -- arrays start on word boundaries and are words long
 
offset.wSize ← elementWords;
END;
 
owd ← oo.wd;
END;
 
ENDCASE => ERROR;
 
[t2, delta] ← CheckAdditivity[tb[node].son[2], elementWords, owd];
P5L.ModComponent[var: @offset, wd: INTEGER[elementWords] * delta];
index ← P5L.ComponentForLex[P5.Exp[t2]];
WITH ii: index 
SELECT 
FROM
const =>
BEGIN
co: LONG CARDINAL = LongMult[elementWords, ii.d1];
IF co + owd.LONG > OpWordCount.LAST THEN GO TO tooBig;
P5L.ModComponent[var: @offset, wd: co];
IF packed THEN UnscaleComponent[@offset, PackedBitCount[grain]];
cb[bar].offset ← offset;
RETURN [[bdo[bar]]]
END;
 
ENDCASE;
 
P5L.ReleaseVarItem[bar];
er ← LOOPHOLE[P5L.GenVarItem[ind]];
cb[er] ← [body: ind[base: base, index: index, offset: offset,
simple: TRASH, packinfo: TRASH]];
 
IF packed 
THEN
BEGIN
cb[er].simple ← indexRange # 0 AND grain*(owd+indexRange) <= 4096;
cb[er].packinfo ← packed[grain: PackedBitCount[grain]];
END
 
ELSE
BEGIN
cb[er].simple ← 
(P5L.Words[base.wSize, base.bSize] = 1) 
OR
(indexRange # 0 AND elementWords*indexRange <= OpWordCount.LAST.LONG+1);
 
 
cb[er].packinfo ← notPacked[elementWords];
END;
 
RETURN [[bdo[er]]]
END;
 
DIndex: 
PUBLIC 
PROC [node: Tree.Index] 
RETURNS [Lexeme] =
BEGIN -- generates code for indexing from an array descriptor
arrayDType: CSEIndex = SymbolOps.NormalType[P5U.OperandType[tb[node].son[1]]];
arrayType: CSEIndex = 
WITH seb[arrayDType] 
SELECT 
FROM
arraydesc => SymbolOps.UnderType[describedType],
ENDCASE => ERROR;
 
grain: BitCount;
packed: BOOL;
elementWords: OpWordCount;
nilck: BOOL = tb[node].attr1;
long: BOOL = tb[node].attr2;
pLength: CARDINAL = IF long THEN 2 ELSE 1;
bndck: BOOL = tb[node].attr3;
owd: CARDINAL;
delta: CARDINAL ← 0;
t2: Tree.Link;
rBase, rBound: VarIndex;
base, bound, index: VarComponent;
offset: frame VarComponent;
er: IndVarIndex;
WITH a:seb[arrayType] 
SELECT 
FROM
array =>
BEGIN
grain ← SymbolOps.BitsPerElement[a.componentType, a.packed];
packed ← grain < wordLength;
elementWords ← IF packed THEN 1 ELSE OpWordCount[grain/wordLength];
END
 
ENDCASE => ERROR;
 
IF packed THEN offset ← [bSize: grain, space: frame[wd: 0]]
ELSE offset ← [wSize: elementWords, space: frame[wd: 0]];
rBase ← P5L.VarForLex[P5.Exp[tb[node].son[1]]];
IF bndck 
THEN
BEGIN
IF nilck THEN [first: rBase, next: rBound] ← P5L.ReusableCopies[rBase, load, TRUE]
ELSE [first: rBound, next: rBase] ← P5L.ReusableCopies[rBase, load, TRUE];
P5L.FieldOfVar[r: rBound, wd: pLength, wSize: 1];
P5L.FieldOfVar[r: rBase, wSize: pLength];
END
 
ELSE P5L.FieldOfVarOnly[r: rBase, wSize: pLength];
base ← P5L.MakeComponent[rBase];
IF nilck 
THEN
BEGIN
P5L.LoadComponent[base];
P5U.Out0[IF long THEN FOpCodes.qNILCKL ELSE FOpCodes.qNILCK];
base ← P5L.TOSComponent[pLength];
END;
 
IF bndck THEN t2 ← tb[node].son[2]
ELSE [t2, delta] ← CheckAdditivity[tb[node].son[2], elementWords, 0];
offset.wd ← owd ← elementWords*delta; -- elementWords = 1 if packed
index ← P5L.ComponentForLex[P5.Exp[t2]];
IF bndck 
THEN
BEGIN
bound ← P5L.MakeComponent[rBound];
P5L.LoadBoth[@index, @bound, FALSE];
P5U.Out0[FOpCodes.qBNDCK];
index ← P5L.TOSComponent[1];
END
 
ELSE 
WITH ii: index 
SELECT 
FROM
const =>
BEGIN
bar: VarIndex;
co: LONG CARDINAL = LongMult[elementWords, ii.d1];
IF co + owd.LONG > OpWordCount.LAST THEN GO TO tooBig;
P5L.ModComponent[var: @offset, wd: co];
IF packed THEN UnscaleComponent[@offset, PackedBitCount[grain]];
bar ← P5L.GenVarItem[bo];
cb[bar] ← [body: bo[base: base, offset: offset]];
RETURN [[bdo[bar]]]
END;
 
ENDCASE;
 
er ← LOOPHOLE[P5L.GenVarItem[ind]];
cb[er] ← [body: ind[base: base, index: index, offset: offset,
simple: TRASH, packinfo: TRASH]];
 
IF packed
THEN {cb[er].simple ← FALSE; cb[er].packinfo ← packed[grain: PackedBitCount[grain]]}
ELSE {cb[er].simple ← ~long; cb[er].packinfo ← notPacked[elementWords]};
 
RETURN [[bdo[er]]]
END;
 
SeqIndex: 
PUBLIC 
PROC [node: Tree.Index] 
RETURNS [Lexeme] =
BEGIN
seqType: CSEIndex = P5U.OperandType[tb[node].son[1]];
isString: BOOL ← FALSE;
grain: BitCount;
packed: BOOL;
elementWords: OpWordCount;
indexRange: LONG CARDINAL;
long: BOOL = tb[node].attr2;
bndck: BOOL = tb[node].attr3;
owd: CARDINAL;
rBound, bor: BoVarIndex;
base, offset, index: VarComponent;
er: IndVarIndex;
WITH ss: seb[seqType] 
SELECT 
FROM
array =>
BEGIN
isString ← packed ← TRUE;  grain ← Symbols.ByteLength;
elementWords ← 1;
indexRange ← SymbolOps.Cardinality[ss.indexType];
END;
 
sequence =>
BEGIN
grain ← SymbolOps.BitsPerElement[ss.componentType, ss.packed];
packed ← grain < wordLength;
elementWords ← IF packed THEN 1 ELSE OpWordCount[grain/wordLength];
indexRange ← SymbolOps.Cardinality[seb[ss.tagSei].idType];
IF bndck THEN P5.AdjustNilCheck[tb[node].son[1], WordOffset[ss.tagSei]];
END;
 
ENDCASE => ERROR;
 
bor ← P5L.MakeBo[P5L.VarForLex[P5.Exp[tb[node].son[1]]]];
IF bor = VarNull 
THEN 
SIGNAL CPtr.CodeNotImplemented; -- no packed arrays of sequences
 
IF bndck 
THEN
BEGIN
[first: 
LOOPHOLE[bor, VarIndex], next: 
LOOPHOLE[rBound, VarIndex]] ←
P5L.ReusableCopies[bor, load, FALSE];
 
P5L.LoadComponent[cb[bor].base];
cb[bor].base ← P5L.TOSComponent[IF long THEN 2 ELSE 1];
END;
 
IF isString 
THEN
BEGIN
IF bndck 
THEN 
WITH vv: cb[rBound].offset 
SELECT 
FROM
frame => {vv.wd ← vv.wd - 1; vv.wSize ← 1}; -- maxlength precedes text
ENDCASE => ERROR;
 
END
 
ELSE P5L.FieldOfVar[
r: bor, wd: cb[bor].offset.wSize, bd: cb[bor].offset.bSize]; -- skip tag
 
base ← cb[bor].base; offset ← cb[bor].offset;
IF packed THEN {offset.bSize ← grain; offset.wSize ← 0}
ELSE {offset.wSize ← elementWords; offset.bSize ← 0};
WITH vv: offset 
SELECT 
FROM
frame =>
BEGIN
IF packed THEN ScaleComponent[@offset, PackedBitCount[grain]];
owd ← vv.wd;
END;
 
ENDCASE => ERROR;
 
IF bndck 
THEN
BEGIN
P5.PushRhs[tb[node].son[2]];
P5L.LoadVar[rBound];
P5U.Out0[FOpCodes.qBNDCK];
index ← P5L.TOSComponent[1];
END
 
ELSE
BEGIN
t2: Tree.Link;
delta: INTEGER;
[t2, delta] ← CheckAdditivity[tb[node].son[2], elementWords, owd];
P5L.ModComponent[var: @offset, wd: INTEGER[elementWords] * delta];
index ← P5L.ComponentForLex[P5.Exp[t2]];
END;
 
WITH ii: index 
SELECT 
FROM
const =>
BEGIN
co: LONG CARDINAL = LongMult[elementWords, ii.d1];
IF co + owd.LONG > OpWordCount.LAST THEN GO TO tooBig;
P5L.ModComponent[var: @offset, wd: co];
IF packed THEN UnscaleComponent[@offset, PackedBitCount[grain]];
cb[bor].offset ← offset;
RETURN [[bdo[bor]]]
END;
 
ENDCASE;
 
P5L.ReleaseVarItem[bor];
er ← LOOPHOLE[P5L.GenVarItem[ind]];
cb[er] ← [body: ind[base: base, index: index, offset: offset,
simple: TRASH, packinfo: TRASH]];
 
IF packed 
THEN
BEGIN
cb[er].simple ← indexRange # 0 AND grain*(owd+indexRange) <= 4096;
cb[er].packinfo ← packed[grain: PackedBitCount[grain]];
END
 
ELSE
BEGIN
cb[er].simple ← 
(P5L.Words[base.wSize, base.bSize] = 1) 
OR
(indexRange # 0 AND elementWords*indexRange <= OpWordCount.LAST.LONG+1);
 
 
cb[er].packinfo ← notPacked[elementWords];
END;
 
RETURN [[bdo[er]]]
END;