Address.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Sweet, May 31, 1986 9:55:28 pm PDT
Satterthwaite, November 24, 1982 3:24 pm
Maxwell, August 11, 1983 9:01 am
Russ Atkinson (RRA) March 6, 1985 11:55:59 pm PST
DIRECTORY
Alloc,
Code,
CodeDefs,
ComData,
FOpCodes,
IntCodeDefs,
P5,
P5S,
P5U,
SymbolOps,
Symbols,
Tree;
Address: PROGRAM
IMPORTS MPtr: ComData, CPtr: Code, CodeDefs, P5U, P5, SymbolOps
EXPORTS CodeDefs, P5S =
BEGIN OPEN IntCodeDefs, CodeDefs;
imported definitions
BitCount: TYPE = INT; -- should it be Symbols.BitCount;
PackedBitCount: TYPE = Symbols.PackedBitCount;
WordCount: TYPE = Symbols.WordCount;
wordLength: CARDINAL = Symbols.WordLength;
CSEIndex: TYPE = Symbols.CSEIndex;
ISEIndex: TYPE = Symbols.ISEIndex;
tb: Tree.Base;  -- tree base (local copy)
seb: Symbols.Base;  -- semantic entry base (local copy)
cb: CodeDefs.Base;  -- code base (local copy)
AddressNotify: PUBLIC Alloc.Notifier =
BEGIN -- called by Code whenever table area is repacked
seb ← base[Symbols.seType];
tb ← base[Tree.treeType];
cb ← base[codeType];
END;
operations
Index: PUBLIC PROC [node: Tree.Index] RETURNS [v: Var] =
BEGIN -- generates code for array indexing
arrayType: CSEIndex = P5U.OperandType[tb[node].son[1]];
grain, tBits: BitCount;
packed: BOOL;
indexRange: INT;
ind: IndexedLocation;
an: Node ← P5.Exp[tb[node].son[1]];
WITH a: seb[arrayType] SELECT FROM
array =>
BEGIN
grain ← SymbolOps.BitsPerElement[a.componentType, a.packed];
packed ← grain < wordLength;
indexRange ← SymbolOps.Cardinality[a.indexType];
END;
ENDCASE => ERROR;
IF packed AND (tBits ← indexRange*grain) IN (0..wordLength) AND tBits < an.bits THEN
an ← P5U.TakeField[n: an, vl: [disp: an.bits-tBits, size: tBits]];
ind ← z.NEW[indexed LocationRep ← [indexed[base: an, index: P5.Exp[tb[node].son[2]]]]];
v ← P5U.MakeVar[bits: grain, id: NullVariableId, loc: ind];
END;
boundCheckOp: Node ← NIL; -- *** must NIL if z goes away
descSize: CARDINAL = PtrSize + WordSize;
DIndex: PUBLIC PROC [node: Tree.Index] RETURNS [l: Node] =
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;
nilck: BOOL = tb[node].attr1;
bndck: BOOL = tb[node].attr3;
t1: Tree.Link ← tb[node].son[1];
t2: Tree.Link ← tb[node].son[2];
desc, base, bound, index: Node;
ind: Location;
cl: CodeList ← P5U.NewCodeList[];
t1 ← P5U.ProcessSafens[cl, t1];
WITH a:seb[arrayType] SELECT FROM
array => grain ← SymbolOps.BitsPerElement[a.componentType, a.packed];
ENDCASE => ERROR;
desc ← P5.Exp[t1];
base ← P5U.TakeField[n: desc, vl: [disp: 0, size: PtrSize]];
IF nilck THEN
base ← P5U.ApplyOp[oper: P5U.MesaOpNode[nilck], args: P5U.MakeNodeList[base], bits: PtrSize];
index ← P5.Exp[t2];
IF bndck THEN
BEGIN
bound ← P5U.TakeField[n: desc, vl: [disp: PtrSize, size: WordSize]];
index ← P5U.BoundsCheck[index, bound];
END;
ind ← z.NEW[indexed LocationRep ← [indexed[base: P5U.Deref[base, 0], index: index]]];
l ← P5U.MakeVar[bits: grain, id: NullVariableId, loc: ind];
RETURN[P5U.MaybeBlock[cl, l]];
END;
StringBoundSize: CARDINAL = 16;
WordOffset: PROC [sei: ISEIndex] RETURNS [INT] =
BEGIN
bits: CARDINAL = seb[sei].idValue;
RETURN [P5U.WordsForBits[bits]]
END;
SeqIndex: PUBLIC PROC [node: Tree.Index] RETURNS [l: Node] =
BEGIN
seqType: CSEIndex = P5U.OperandType[tb[node].son[1]];
t1: Tree.Link ← tb[node].son[1];
t2: Tree.Link ← tb[node].son[2];
isString: BOOLFALSE;
grain: BitCount;
bndck: BOOL = tb[node].attr3;
index, elements, tag: Node;
ind: Location;
cl: CodeList ← P5U.NewCodeList[];
t1 ← P5U.ProcessSafens[cl, t1];
WITH ss: seb[seqType] SELECT FROM
array => {isString ← TRUE; grain ← Symbols.ByteLength};
sequence =>
BEGIN
grain ← SymbolOps.BitsPerElement[ss.componentType, ss.packed];
IF bndck THEN P5.AdjustNilCheck[tb[node].son[1], WordOffset[ss.tagSei]];
END;
ENDCASE => ERROR;
IF isString THEN {
elements ← P5.Exp[tb[node].son[1]];
tag ← P5U.TakeField[n: elements, vl: [disp: -StringBoundSize, size: StringBoundSize]]}
ELSE {
tag ← P5.Exp[tb[node].son[1]]; -- The symbol table entry for the sequence part points to the tag (if any). If there is not tag (i.e., a COMPUTED sequence), it still points ahead of the sequence part. If one adds the size of this node to its location, one gets a node pointing to the beginning of the sequence part
elements ← P5U.TakeField[n: tag, vl: [disp: tag.bits, size: 0]]};
index ← P5.Exp[t2];
IF bndck THEN index ← P5U.BoundsCheck[index, tag];
ind ← z.NEW[indexed LocationRep ← [indexed[base: elements, index: index]]];
l ← P5U.MakeVar[bits: grain, id: NullVariableId, loc: ind];
RETURN[P5U.MaybeBlock[cl, l]];
END;
END.