DIRECTORY
Alloc,
Basics,
Code,
CodeDefs,
ComData,
FOpCodes,
IntCodeDefs,
Literals,
P5,
P5U,
PrincOps,
PrincOpsUtils,
Symbols,
SymbolOps,
Tree,
TreeOps;

Constructor: PROGRAM
IMPORTS  MPtr: ComData, CPtr: Code, CodeDefs, P5, P5U, PrincOpsUtils, SymbolOps, TreeOps
EXPORTS CodeDefs, P5 = BEGIN OPEN CodeDefs, SymbolOps;


WordSize: CARDINAL = CodeDefs.WordSize;
charlength: CARDINAL = Basics.bitsPerChar;

ArraySEIndex: TYPE = Symbols.ArraySEIndex;
BitAddress: TYPE = Symbols.BitAddress;
BitCount: TYPE = Symbols.BitCount;
ContextLevel: TYPE = Symbols.ContextLevel;
CSEIndex: TYPE = Symbols.CSEIndex;
CTXIndex: TYPE = Symbols.CTXIndex;
ISEIndex: TYPE = Symbols.ISEIndex;
ISENull: ISEIndex = Symbols.ISENull;
lZ: ContextLevel = Symbols.lZ;
lG: ContextLevel = Symbols.lG;
RecordSEIndex: TYPE = Symbols.RecordSEIndex;
SEIndex: TYPE = Symbols.SEIndex;
typeANY: CSEIndex = Symbols.typeANY;	-- don't-care type for ConsAssign


tb: Tree.Base;                -- tree base (local copy)
seb: Symbols.Base;            -- semantic entry base (local copy)
cb: CodeDefs.Base;            -- code base (local copy)
stb: Literals.Base;           -- string base (local copy)

ConstructorNotify: PUBLIC Alloc.Notifier =
BEGIN  -- called by allocator whenever table area is repacked
seb _ base[Symbols.seType];
stb _ base[Literals.stType];
tb _ base[Tree.treeType];
cb _ base[codeType];
END;



ConstructionError: SIGNAL = CODE;

cd: PUBLIC ConsDestination;

SetConsDest: PROC [t: Tree.Link, cl: CodeList] =
BEGIN
n: Node;
tv: Var;
cd.cl _ cl;
WITH tt: t SELECT FROM
symbol => {
ctx: CTXIndex _ seb[tt.index].idCtx;
level: ContextLevel _ SymbolOps.CtxLevel[ctx];
SELECT level FROM
lG, CPtr.curctxlvl => {
cd.destNode _ P5.Exp[t];
RETURN};
ENDCASE => NULL;
};
ENDCASE => NULL;
n _ P5.Exp[t];
tv _ P5U.MakeTemp[cl: cl, bits: PtrSize, init: P5U.ApplyOp[oper: P5U.MesaOpNode[addr], args: P5U.MakeNodeList[n], bits: PtrSize]].var;
cd.destNode _ P5U.Deref[tv, n.bits];
END;

CountedAssign: PROC [type: CSEIndex, const: BOOL] RETURNS [BOOL] = INLINE
BEGIN
RETURN [cd.options.counted AND RCType[type]#none AND ~(const AND cd.options.init)]
END;


AssureSize: PROC [n: Node, size: IntCodeDefs.Count] RETURNS [Node] = {
SELECT size FROM
> n.bits => RETURN[P5U.ZeroExtend[n: n, to: size]];
< n.bits => RETURN[P5U.TakeField[n: n, vl: [disp: 0, size: size]]];
ENDCASE => RETURN[n]};

ConsAssign: PROC [type: CSEIndex, offset: VLoc, n: Node] =
BEGIN
field: Var _ P5U.TakeField[n: cd.destNode, vl: offset];
P5U.DoAssign[cl: cd.cl, lhs: field, rhs: AssureSize[n, offset.size]];
END;

VanillaCons: PROC [t: Tree.Link] RETURNS [vanilla: BOOL _ TRUE] =
BEGIN

CheckItem: Tree.Scan =
BEGIN
SELECT TreeOps.OpName[t] FROM
rowcons, construct, all, union => vanilla _ FALSE;
cast, pad => CheckItem[TreeOps.NthSon[t, 1]];
ENDCASE => NULL;
END;

TreeOps.ScanList[t, CheckItem];  RETURN
END;


MainConstruct: PROC [
maint: Tree.Link,
rSei: CSEIndex,
fa: PROC [ISEIndex] RETURNS [BitAddress, CARDINAL],
total: VLoc,
fieldSei: ISEIndex _ ISENull] =
BEGIN -- workhorse subroutine for construction in memory
tOffset: VLoc = total;
totalBits: CARDINAL = total.size;
rcSei: RecordSEIndex;

AssignField: PROC [root: Tree.Link] =
BEGIN
offset: VLoc;
rep: BitAddress;
res: BitCount;
fieldType: CSEIndex = UnderType[seb[fieldSei].idType];
IF root # Tree.Null THEN
BEGIN
[rep, res] _ fa[fieldSei];
offset _ P5U.TakeVField[vl: tOffset, disp: P5U.Bits[rep], size: res];
IF fa # FnField AND totalBits <= WordSize THEN
offset _ P5U.AdjustLoc[vl: offset, rSei: rcSei, fSei: fieldSei, tBits: totalBits];
DO -- until we get to something interesting
SELECT TreeOps.OpName[root] FROM
pad =>
BEGIN
root _ TreeOps.NthSon[root, 1];
offset.size _ P5U.WordsForOperand[root]*WordSize; 
END;
cast => root _ TreeOps.NthSon[root, 1];
ENDCASE => EXIT;
ENDLOOP;
SELECT TreeOps.OpName[root] FROM
construct =>
MainConstruct[TreeOps.NthSon[root, 2], P5U.OperandType[root], RecField, offset];
union => UnionConstruct[TreeOps.GetNode[root], rcSei, tOffset];
rowcons => Row[TreeOps.GetNode[root], offset];
all => [] _ AllConstruct[TreeOps.GetNode[root], offset];
ENDCASE => {ConsAssign[fieldType, offset, P5.Exp[root]]};
END; -- IF root # Tree.Null
fieldSei _ P5U.NextVar[NextSe[fieldSei]];
END; -- of AssignField

IF fieldSei = ISENull THEN
WITH seb[rSei] SELECT FROM
record =>
BEGIN
rcSei _ RecordRoot[LOOPHOLE[rSei]];
fieldSei _ P5U.NextVar[FirstCtxSe[seb[rcSei].fieldCtx]];
END;
ENDCASE => P5.P5Error[589]
ELSE rcSei _ LOOPHOLE[rSei];
TreeOps.ScanList[maint, AssignField];
END; -- of MainConstruct


Row: PROC [node: Tree.Index, total: VLoc] =
BEGIN  -- handles ARRAY construction
aSei: ArraySEIndex = LOOPHOLE[SymbolOps.UnderType[tb[node].info]];
offset: VLoc _ total;
eSize: BitCount;
cSei: CSEIndex = UnderType[seb[aSei].componentType];

AssignElement: PROC [t: Tree.Link] =
BEGIN
DO -- until we get to something interesting
SELECT TreeOps.OpName[t] FROM
pad =>
BEGIN
t _ TreeOps.NthSon[t, 1];
offset.size _ P5U.WordsForOperand[t]*WordSize;
END;
cast => t _ TreeOps.NthSon[t, 1];
ENDCASE => EXIT;
ENDLOOP;
SELECT TreeOps.OpName[t] FROM
rowcons => Row[TreeOps.GetNode[t], offset];
construct =>
MainConstruct[TreeOps.NthSon[t, 2], P5U.OperandType[t], RecField, offset];
all => -- convert this later
[] _ AllConstruct[TreeOps.GetNode[t], offset];
ENDCASE => IF t # Tree.Null THEN ConsAssign[cSei, offset, P5.Exp[t]];
offset _ P5U.TakeVField[vl: offset, disp: eSize, size: eSize];
END; -- of AssignElement

totalBits: BitCount = total.size;
grain: BitCount = BitsPerElement[seb[aSei].componentType, seb[aSei].packed];
packed: BOOL;
fillBits: CARDINAL;
IF seb[aSei].typeTag # array THEN P5.P5Error[580];
IF grain >= WordSize THEN
BEGIN
packed _ FALSE;  fillBits _ 0;
eSize _ BitsForType[seb[aSei].componentType];
END
ELSE
BEGIN
packed _ TRUE;
fillBits _ totalBits - Cardinality[UnderType[seb[aSei].indexType]]*grain;
eSize _ grain;
END;
IF fillBits # 0 AND totalBits <= WordSize THEN 
BEGIN
offset.size _ eSize + fillBits;
fillBits _ 0;
END
ELSE offset.size _ eSize;
TreeOps.ScanList[tb[node].son[2], AssignElement];
IF fillBits # 0 THEN
BEGIN
offset.size _ fillBits;
ConsAssign[typeANY, offset, CPtr.nC0];
END;
END;


UnionConstruct: PROC [node: Tree.Index, rootSei: RecordSEIndex, total: VLoc] =
BEGIN -- construct a union part, total is offset of beginning of record
tOffset: VLoc = total;
offset: VLoc _ total;
fieldSei: ISEIndex;
vCtx: CTXIndex;
uSei: CSEIndex = SymbolOps.UnderType[tb[node].info];
rcSei: RecordSEIndex;
tSei: ISEIndex;
tagged: BOOL;
tagValue: CARDINAL;
tBits: CARDINAL = tOffset.size;
WITH u: seb[uSei] SELECT FROM
union =>
BEGIN
tagged _ u.controlled;
IF tagged THEN
BEGIN
tagAddr: BitAddress = seb[u.tagSei].idValue;
tagSize: BitCount = LONG[LOOPHOLE[seb[u.tagSei].idInfo, CARDINAL]];
offset _ P5U.TakeVField[vl: offset, disp: P5U.Bits[tagAddr],  size: tagSize];
IF tBits <= WordSize THEN
offset _ P5U.AdjustLoc[vl: offset, rSei: rootSei, fSei: u.tagSei, tBits: tBits];
END;
END;
ENDCASE => ERROR;
tSei _ TreeOps.GetSe[tb[node].son[1]];
tagValue _ seb[tSei].idValue;
rcSei _ LOOPHOLE[UnderType[tSei], RecordSEIndex];
vCtx _ seb[rcSei].fieldCtx;
fieldSei _ P5U.NextVar[FirstCtxSe[vCtx]];
IF tagged THEN
BEGIN
IF fieldSei # ISENull AND seb[fieldSei].idCtx # vCtx THEN
BEGIN -- a dummy fill field
fillSize: CARDINAL = seb[fieldSei].idInfo;
tagValue _ PrincOpsUtils.BITSHIFT[tagValue, fillSize];
offset.size _ offset.size + fillSize;
fieldSei _ P5U.NextVar[NextSe[fieldSei]];
END;
ConsAssign[typeANY, offset, P5U.MakeNodeLiteral[tagValue]];
END
ELSE IF fieldSei # ISENull AND seb[fieldSei].idCtx # vCtx THEN
BEGIN -- no tag, but a fill field anyway
fillSize: [0..WordSize) = seb[fieldSei].idInfo;
fillAddr: BitAddress = seb[fieldSei].idValue; -- can't be full word
offset _ P5U.TakeVField[ vl: offset, disp: P5U.Bits[fillAddr], size: fillSize];
IF tBits <= WordSize THEN
offset _ P5U.AdjustLoc[vl: offset, rSei: rootSei, fSei: fieldSei, tBits: tBits];
ConsAssign[typeANY, offset, CPtr.nC0];
fieldSei _ P5U.NextVar[NextSe[fieldSei]];
END;
IF fieldSei # ISENull THEN MainConstruct[tb[node].son[2], rootSei, RecField, total, fieldSei];
END;


AllConstruct: PROC [node: Tree.Index, total: VLoc] =
BEGIN
aSei: ArraySEIndex = LOOPHOLE[SymbolOps.UnderType[tb[node].info]];
tOffset: VLoc = total;
offset: VLoc;
val: Node;
csei: CSEIndex = UnderType[seb[aSei].componentType];
eSize: BitCount;
t1: Tree.Link _ tb[node].son[1];
totalBits: BitCount = tOffset.size;
aBits: BitCount;
grain: BitCount = BitsPerElement[seb[aSei].componentType, seb[aSei].packed];
packed: BOOL;
fillBits, eCount: CARDINAL;
IF grain >= WordSize THEN
BEGIN
packed _ FALSE;  fillBits _ 0;
eSize _ BitsForType[seb[aSei].componentType];
aBits _ totalBits;
END
ELSE
BEGIN
packed _ TRUE;
eCount _ Cardinality[UnderType[seb[aSei].indexType]];
aBits _ eCount*CARDINAL[grain];
fillBits _ totalBits - aBits;
eSize _ grain;
END;
offset _ P5U.TakeVField[vl: tOffset, disp: 0, size: aBits];
IF fillBits # 0 AND totalBits <= WordSize THEN 
BEGIN
offset.size _ eSize + fillBits;
fillBits _ 0;
END;
val _ AssureSize[P5.Exp[t1], grain];
ConsAssign[aSei, offset, z.NEW [NodeRep.all _ [bits: aBits, details: all[count: P5U.MakeNodeLiteral[eCount], value: val]]]];
IF fillBits # 0 THEN {
offset _ P5U.TakeVField[vl: offset, disp: aBits, size: fillBits];
ConsAssign[typeANY, offset, CPtr.nC0]};
RETURN
END;



All: PUBLIC PROC [t: Tree.Link, node: Tree.Index, options: StoreOptions]
RETURNS [l: Node] =
BEGIN  -- generate code for constructor expression
aSei: Symbols.ArraySEIndex = LOOPHOLE[SymbolOps.UnderType[tb[node].info]];
cl: CodeList _ P5U.NewCodeList[];
aBits: BitCount = BitsForType[aSei];
saveCd: ConsDestination = cd;

IF t = Tree.Null THEN {
var: Var;
sei: ISEIndex;
[var: var, sei: sei] _ P5U.MakeTemp[cl: cl, bits: aBits];
t _ [symbol[sei]]; options.init _ TRUE; options.expr _ TRUE};
cd _ [options: options, ignoreSafen: t = Tree.Null OR t.tag = symbol]; -- + many defaults
tb[node].son[1] _ P5U.ProcessSafens[cl, tb[node].son[1], cd.ignoreSafen];
SetConsDest[t, cl];
AllConstruct[node, [disp: 0, size: cd.destNode.bits]];
IF options.expr THEN P5U.MoreCode[cl, cd.destNode];
l _ P5U.MakeBlock[cl];
IF options.expr THEN l.bits _ aBits;
cd _ saveCd;
END;


Construct: PUBLIC PROC [t: Tree.Link, node: Tree.Index, options: StoreOptions]
RETURNS [l: Node] =
BEGIN  -- generate code for constructor expression
tsei: RecordSEIndex = LOOPHOLE[SymbolOps.UnderType[tb[node].info]];
cl: CodeList _ P5U.NewCodeList[];
nbits: BitCount = BitsForType[tsei];
saveCd: ConsDestination = cd;

IF t = Tree.Null THEN {
var: Var;
sei: ISEIndex;
[var: var, sei: sei] _ P5U.MakeTemp[cl: cl, bits: nbits];
t _ [symbol[sei]]; options.init _ TRUE; options.expr _ TRUE};
cd _ [options: options, ignoreSafen: t = Tree.Null OR t.tag = symbol]; -- + many defaults
tb[node].son[2] _ P5U.ProcessSafens[cl, tb[node].son[2], cd.ignoreSafen];
SetConsDest[t, cl];

MainConstruct[
tb[node].son[2], tsei, IF seb[tsei].argument THEN FnField ELSE RecField, [disp: 0, size: cd.destNode.bits]];
IF options.expr THEN P5U.MoreCode[cl, cd.destNode];
l _ P5U.MakeBlock[cl];
IF options.expr THEN l.bits _ cd.destNode.bits;
cd _ saveCd;
END;


ListCons: PUBLIC PROC[node: Tree.Index] RETURNS[Node _ NIL] = {
};
RowCons: PUBLIC PROC [t: Tree.Link, node: Tree.Index, options: StoreOptions]
RETURNS [l: Node] =
BEGIN  -- array (expression) construction
aSei: Symbols.ArraySEIndex = LOOPHOLE[SymbolOps.UnderType[tb[node].info]];
cl: CodeList _ P5U.NewCodeList[];
aBits: BitCount = BitsForType[aSei];
saveCd: ConsDestination = cd;

IF t = Tree.Null THEN {
var: Var;
sei: ISEIndex;
[var: var, sei: sei] _ P5U.MakeTemp[cl: cl, bits: aBits];
t _ [symbol[sei]]; options.init _ TRUE; options.expr _ TRUE};
cd _ [options: options, ignoreSafen: t = Tree.Null OR t.tag = symbol]; -- + many defaults
tb[node].son[1] _ P5U.ProcessSafens[cl, tb[node].son[1], cd.ignoreSafen];
SetConsDest[t, cl];
Row[node, [disp: 0, size: cd.destNode.bits]];
IF options.expr THEN P5U.MoreCode[cl, cd.destNode];
l _ P5U.MakeBlock[cl];
IF options.expr THEN l.bits _ aBits;
cd _ saveCd;
END;


VariantConstruct: PUBLIC PROC [t1, t2: Tree.Link, options: StoreOptions]
RETURNS [l: Node] =
BEGIN  -- array (expression) construction
rootSei: RecordSEIndex;
cl: CodeList _ P5U.NewCodeList[];
saveCd: ConsDestination = cd;
offset: VLoc;

t1 _ TreeOps.NthSon[t1, 1];
SetConsDest[t1, cl];
cd _ [options: options, ignoreSafen: t1.tag = symbol]; -- + many defaults
t2 _ P5U.ProcessSafens[cl, t2, cd.ignoreSafen];
rootSei _ RecordRoot[LOOPHOLE[P5U.OperandType[t1]]];
offset _ [disp: 0, size: cd.destNode.bits];
UnionConstruct[TreeOps.GetNode[t2], rootSei, offset];
l _ P5U.MakeBlock[cl];
cd _ saveCd;
END;


New: PUBLIC PROC [node: Tree.Index] RETURNS [Node _ NIL] =
BEGIN
END;
END.

��\��Constructor.mesa
Copyright c 1985 by Xerox Corporation.  All rights reserved.
Sweet, May 30, 1986 3:50:06 pm PDT
Satterthwaite, March 27, 1986 9:15:18 am PST
Maxwell, August 11, 1983 9:19 am
Russ Atkinson (RRA) March 6, 1985 11:13:59 pm PST
imported definitions
state data and common code for construction
main drivers
public entries
pSei: CSEIndex = SymbolOps.UnderType[tb[node].info];
rSei: CSEIndex = SymbolOps.ReferentType[pSei];
long: BOOL = tb[node].attr2;
counted: BOOL = tb[node].attr3;
pLength: CARDINAL = WordsForType[pSei];
zoneTree: Tree.Link;
zoneVar: Lexeme.se;
nwords: CARDINAL = WordsForType[rSei];
k: CARDINAL _ TreeOps.ListLength[tb[node].son[2]];
destVar: Lexeme.se _ P5.GenTempLex[pLength];
restVar: Lexeme.se _ (IF k > 1 THEN P5.GenTempLex[pLength] ELSE NullLex);
rest: Tree.Link _ P5U.NilTree[pSei];

PushSize: PROC = {P5U.PushLitVal[nwords]};
ConsItem: Tree.Map = {
r: VarIndex;
saveCd: ConsDestination = cd;
saveTempList: TempStateRecord = P5.PushTempState[];
list: Tree.Link;
listNode: Tree.Index;
offset: VarComponent.frame;
cd _ [options: [init: TRUE, counted: counted], ignoreSafen: FALSE]; -- + many defaults
TreeOps.PushTree[t]; TreeOps.PushTree[rest]; 
list _ TreeOps.UpdateList[TreeOps.MakeList[2], CountDups];
listNode _ NARROW[list, Tree.Link.subtree].index;
IF counted THEN
Counting.Allocate[zone: zoneTree, type: rSei, catch: Tree.Null, pushSize: NIL]
ELSE {
P5.ZoneOp[zone: zoneTree, index: 0, pushArg: PushSize, catch: Tree.Null, long: long];
Stack.Incr[pLength]};
P5.SAssign[destVar.lexsei];
offset _ [wSize: nwords, space: frame[wd: 0]];
r _ P5L.GenVarItem[bo];
cb[r] _ [body: bo[base: P5L.ComponentForLex[destVar], offset: offset]];
[] _ SetConsDest[r, FALSE];
MainConstruct[list, rSei, RecField, @offset];
IF (k _ k-1) # 0 THEN {
sTemp: Lexeme.se = destVar;
rest _ [symbol[destVar.lexsei]];
destVar _ restVar;  restVar _ sTemp}; 
v _ tb[listNode].son[1];
tb[listNode].son[1] _ Tree.Null;  [] _ TreeOps.FreeTree[list];
cd _ saveCd;  P5.PopTempState[saveTempList]};

Stack.Dump[];
IF tb[node].son[1] = Tree.Null THEN {
zoneVar _ P5.GenTempLex[pLength];
Counting.LoadSystemZone[];  P5.SAssign[zoneVar.lexsei];
zoneTree _ [symbol[zoneVar.lexsei]]}
ELSE zoneTree _ tb[node].son[1];
tb[node].son[2] _ TreeOps.ReverseUpdateList[tb[node].son[2], ConsItem];
RETURN [destVar];

long: BOOL = tb[node].attr2;
counted: BOOL = tb[node].attr3;
pLength: CARDINAL = WordsForType[tb[node].info];
typeTree: Tree.Link = tb[node].son[2];
overType: SEIndex = P5U.TypeForTree[typeTree];
type: CSEIndex = UnderType[overType];
catchTree: Tree.Link = IF tb[node].nSons = 4 THEN tb[node].son[4] ELSE Tree.Null;
tag: ISEIndex _ ISENull;
seqLength: VarComponent;
computedType: BOOL = (TreeOps.OpName[typeTree] = apply);
sizePusher: PROC = IF computedType THEN PushNewSize ELSE NIL;

PushNewSize: PROC =
BEGIN
nw: CARDINAL = WordsForType[type];
IF computedType THEN
BEGIN
subNode: Tree.Index = TreeOps.GetNode[typeTree];
vSei: ISEIndex = VariantField[type];
bitsPerItem, n: CARDINAL;
IF vSei # ISENull THEN
BEGIN
vType: CSEIndex = UnderType[seb[vSei].idType];
WITH v: seb[vType] SELECT FROM
sequence =>
BEGIN
tag _ IF v.controlled THEN v.tagSei ELSE ISENull;
bitsPerItem _ BitsPerElement[v.componentType, v.packed];
END;
ENDCASE => ERROR;
END
ELSE
BEGIN  -- must be StringBody, fudge it
tag _ NextSe[FirstCtxSe[seb[LOOPHOLE[type, RecordSEIndex]].fieldCtx]];
bitsPerItem _ charlength;
END;
seqLength _ P5L.ComponentForLex[P5.Exp[tb[subNode].son[2]]];
IF tag # ISENull THEN seqLength _ P5L.EasilyLoadable[seqLength, load];
IF bitsPerItem >= wordlength THEN
BEGIN
n _ bitsPerItem/wordlength;
WITH s: seqLength SELECT FROM
const => P5U.PushLitVal[nw + n*s.d1];
ENDCASE =>
BEGIN
P5L.LoadComponent[seqLength];
IF n # 1 THEN {P5U.PushLitVal[n];  P5U.Out0[FOpCodes.qMUL]};
P5U.PushLitVal[nw];  P5U.Out0[FOpCodes.qADD];
END;
END
ELSE
BEGIN
n _ wordlength/bitsPerItem;
WITH s: seqLength SELECT FROM
const => P5U.PushLitVal[nw + ((s.d1+(n-1))/n)];
ENDCASE =>
BEGIN
P5L.LoadComponent[seqLength];
P5U.PushLitVal[n-1];  P5U.Out0[FOpCodes.qADD];
P5U.PushLitVal[SELECT n FROM 2 => -1, 4 => -2, 8 => -3, ENDCASE => -4];
P5U.Out0[FOpCodes.qSHIFT];
P5U.PushLitVal[nw];  P5U.Out0[FOpCodes.qADD];
END;
END;
END
ELSE P5U.PushLitVal[nw];
END;

zoneTree: Tree.Link = tb[node].son[1];
initTree: Tree.Link;

saveCd: ConsDestination = cd;
cd _ [options: [init: TRUE, counted: counted], ignoreSafen: FALSE];  -- + defaults
cd.remaining _ 1;
tb[node].son[3] _ CountDups[tb[node].son[3]];

IF counted THEN
Counting.Allocate[zone: zoneTree, type: overType, catch: catchTree, pushSize: sizePusher]
ELSE
BEGIN
P5.ZoneOp[zone: zoneTree, index: 0, pushArg: PushNewSize, catch: catchTree, long: long];
Stack.Incr[pLength];
END;
IF tag # ISENull OR tb[node].son[3] # Tree.Null THEN
BEGIN
ptrVar: VarIndex;
ptrVar _ P5L.TOSAddrLex[size: WordsForType[type], long: long].lexbdoi;
[] _ SetConsDest[ptrVar];
IF tag # ISENull THEN
BEGIN
offset:  VarComponent _ P5L.ComponentForSE[tag];
WITH o: offset SELECT FROM
frame => ConsAssign[typeANY, @o, Tree.Null, [bdo[P5L.OVarItem[seqLength]]]];
ENDCASE => ERROR;
END;
IF tb[node].son[3] # Tree.Null THEN
BEGIN
offset:  VarComponent.frame _ [wSize: cd.wSize, bSize: cd.bSize, space: frame[]];
initTree _ tb[node].son[3];
DO
SELECT TreeOps.OpName[initTree] FROM
pad =>
BEGIN
initTree _ TreeOps.NthSon[initTree, 1];
offset.wSize _ P5U.WordsForOperand[initTree];  offset.bSize _ 0;
END;
cast => initTree _ TreeOps.NthSon[initTree, 1];
ENDCASE => EXIT;
ENDLOOP;
SELECT TreeOps.OpName[initTree] FROM
construct =>
MainConstruct[TreeOps.NthSon[initTree, 2], P5U.OperandType[initTree], 
RecField, @offset];
rowcons => Row[TreeOps.GetNode[initTree], @offset];
all => [] _ AllConstruct[TreeOps.GetNode[initTree], @offset];
mwconst => ConstantFill[type, @offset, initTree];
ENDCASE => {ConstructCountDown[]; ConsAssign[type, @offset, initTree]};
END;
IF cd.remaining # 1 THEN SIGNAL ConstructionError;
[] _ LoadPointer[0];
END;
cd _ saveCd;
RETURN [P5L.TOSLex[pLength]]

�Ê��˜�codešœ™Kšœ
Ïmœ1™<Kšœ"™"Kšœ,™,K™ K™1—K˜�šÏk	˜	Kšœ˜Kšœ˜Kšœ˜Kšœ	˜	Kšœ˜Kšœ	˜	Kšœ˜Kšœ	˜	Kšœ˜Kšœ˜Kšœ	˜	Kšœ˜Kšœ˜Kšœ
˜
Kšœ˜šœ˜K˜�——šœ
ž˜KšžœQ˜XKšžœžœ˜6K˜�Kšœ™K˜�Kšœ
žœ˜'Kšœžœ˜*K˜�Kšœžœ˜*Kšœžœ˜&Kšœ
žœ˜"Kšœžœ˜*Kšœ
žœ˜"Kšœ
žœ˜"Kšœ
žœ˜"K˜$K˜K˜Kšœžœ˜,Kšœ	žœ˜ Kšœ%Ïc!˜FK˜�K˜�KšœŸ˜7KšœŸ#˜AKšœŸ˜7KšœŸ˜9K˜�šœžœ˜*KšžœŸ6˜=K˜K˜K˜K˜Kšžœ˜K˜�—Kšœ+™+K˜�K˜�Kšœžœžœ˜!K˜�Kšœžœ˜K˜�šÏnœžœ˜0Kšž˜K˜K˜K˜šžœžœž˜˜K˜$Kšœ.˜.šžœž˜šœ˜K˜Kšžœ˜—Kšžœžœ˜—K˜—Kšžœžœ˜—K˜K˜†K˜$Kšžœ˜K˜�—š 
œžœžœžœžœž˜IKšž˜Kšžœžœžœ	žœ˜RKšžœ˜K˜�K˜�—š 
œžœ$žœ˜Fšžœž˜Kšœžœ!˜3Kšœžœ1˜CKšžœžœ˜—K˜�—š 
œžœ*˜:Kšž˜K˜7K˜EKšžœ˜K˜�—š
 œžœžœžœžœ˜AKšž˜K˜�˜Kšž˜šžœž˜Kšœ,žœ˜2K˜-Kšžœžœ˜—Kšžœ˜K˜�—Kšœ!ž˜'Kšžœ˜K˜�—Kšœ™K˜�š 
œžœ˜K˜K˜Kšœžœžœžœ˜3K˜K˜KšžœŸ2˜8K˜Kšœžœ˜!K˜K˜�š œžœ˜%Kšž˜K˜
K˜Kšœ˜K˜6šžœž˜Kšž˜K˜KšœE˜Ešžœžœž˜.KšœR˜R—šžœŸ(˜+šžœž˜ ˜Kšž˜K˜K˜2Kšžœ˜—K˜'Kšžœžœ˜—Kšžœ˜—šžœž˜ ˜K˜P—K˜?K˜.K˜8Kšžœ2˜9—KšžœŸ˜—K˜)KšžœŸ˜K˜�—šžœž˜šžœžœž˜˜	Kšž˜Kšœžœ˜#K˜8Kšžœ˜—Kšžœ˜——Kšžœ	žœ˜K˜%KšžœŸ˜K˜�K˜�—š œžœ"˜+KšžœŸ˜$Kšœžœ%˜BK˜Kšœ˜K˜4K˜�š 
œžœ˜$Kšž˜šžœŸ(˜+šžœž˜˜Kšž˜K˜K˜.Kšžœ˜—K˜!Kšžœžœ˜—Kšžœ˜—šžœž˜K˜+˜K˜J—šœŸ˜K˜.—Kšžœžœžœ%˜E—K˜>KšžœŸ˜K˜�—Kšœ!˜!K˜LKšœžœ˜
Kšœ
žœ˜Kšžœžœ˜2šžœž˜Kšž˜Kšœ	žœ˜K˜-Kšž˜—šž˜Kšž˜Kšœ	žœ˜K˜IK˜Kšžœ˜—šžœžœžœ˜/Kšž˜Kšœ˜K˜
Kšž˜—Kšžœ˜K˜1šžœž˜Kšž˜K˜K˜&Kšžœ˜—Kšžœ˜K˜�K˜�—š œžœ:˜NKšžœŸA˜GK˜K˜K˜K˜K˜4K˜K˜Kšœžœ˜
Kšœ
žœ˜Kšœžœ˜šžœžœž˜˜Kšž˜K˜šžœž˜Kšž˜K˜,Kšœžœžœžœ˜CKšœM˜Mšžœž˜K˜P—Kšžœ˜—Kšžœ˜—Kšžœžœ˜—K˜&K˜Kšœžœ!˜1K˜K˜)šžœž˜Kšž˜šžœžœž˜9KšžœŸ˜Kšœ
žœ˜*Kšœžœ˜6Kšœ%˜%K˜)Kšžœ˜—K˜;Kšž˜—šžœžœžœž˜>KšžœŸ"˜(K˜/Kšœ.Ÿ˜CK˜Ošžœž˜K˜P—K˜&K˜)Kšžœ˜—KšžœžœD˜^Kšžœ˜K˜�K˜�—š œžœ"˜4šž˜Kšœžœ%˜BK˜K˜
K˜
K˜4Kšœ˜K˜ Kšœ#˜#K˜K˜LKšœžœ˜
Kšœžœ˜šžœž˜Kšž˜Kšœ	žœ˜K˜-K˜Kšž˜—šž˜Kšž˜Kšœ	žœ˜K˜5Kšœžœ˜Kšœ˜K˜Kšžœ˜—Kšœ;˜;šžœžœžœ˜/Kšž˜Kšœ˜K˜
Kšžœ˜—K˜$Kšœžœ^˜|šžœžœ˜KšœA˜AK˜'—Kšž˜Kšžœ˜K˜�K˜�——Kšœ™K˜�š œžœžœ8˜HKšžœ˜KšžœŸ+˜2Kšœžœ%˜JK˜!Kšœ$˜$K˜K˜�šžœžœ˜K˜	K˜Kšœ9˜9Kšœ"žœžœ˜=—Kšœ3žœŸ˜YKšœI˜IK˜Kšœ6˜6Kšžœžœ˜3K˜Kšžœžœ˜$K˜Kšžœ˜K˜�K˜�—š 	œžœžœ8˜NKšžœ˜KšžœŸ+˜2Kšœžœ%˜CK˜!Kšœ$˜$K˜K˜�šžœžœ˜K˜	K˜Kšœ9˜9Kšœ"žœžœ˜=—Kšœ3žœŸ˜YK˜IK˜K˜�˜Kšœžœžœ	žœ.˜l—Kšžœžœ˜3K˜Kšžœžœ˜/K˜Kšžœ˜K˜�K˜�—š
 œžœžœžœžœ˜?K™4K™.Kšœžœ™Kšœ	žœ™Kšœ	žœ™'K™Kšœ™Kšœžœ™&Kšœžœ'™2Kšœ,™,KšœI™IK™$K™�Kš œžœ™*š œ™K™K™K™3K™K™K™Kšœžœ"žœŸ™VK™-K™:Kšœžœ ™1šžœ	ž™KšœN™N—šž™KšœU™UKšœ™—Kšœ™K™.K™K™GKšœžœ™Kšœ-™-šžœžœ™K™K™ Kšœ&™&—Kšœ™Kšœ>™>Kšœ-™-—K™�Kšœ
™
šžœžœ™%Kšœ!™!Kšœ7™7Kšœ$™$—Kšžœ™ K™GKšžœ™Kšœ˜K™�—š œžœžœ8˜LKšžœ˜KšžœŸ"˜)Kšœžœ%˜JK˜!Kšœ$˜$K˜K˜�šžœžœ˜K˜	K˜Kšœ9˜9Kšœ"žœžœ˜=—Kšœ3žœŸ˜YKšœI˜IK˜Kšœ-˜-Kšžœžœ˜3K˜Kšžœžœ˜$K˜Kšžœ˜K˜�K˜�—š œžœžœ+˜HKšžœ˜KšžœŸ"˜)K˜K˜!K˜K˜
K˜�K˜K˜Kšœ7Ÿ˜IKšœ/˜/Kšœžœ˜4Kšœ+˜+Kšœ5˜5K˜K˜Kšžœ˜K˜�K˜�—š œžœžœžœ˜:Kšž˜Kšœžœ™Kšœ	žœ™Kšœ	žœ™0K™&K™.K™%Kšœžœžœžœ™QK™K™Kšœžœ&™8Kšœžœžœžœ
žœžœ™=K™�š œžœ™Kšž™Kšœžœ™"šžœž™Kšž™K™0K™$Kšœžœ™šžœž™Kšž™K™.šžœžœž™™Kšž™Kšœžœžœ
žœ	™1K™8Kšžœ™—Kšžœžœ™—Kšž™—šž™KšžœŸ™&Kšœžœ"™FK™Kšžœ™—K™<Kšžœžœ1™Fšžœž™!Kšž™K™šžœžœž™K™%šžœ™
Kšž™K™Kšžœžœ/™<K™-Kšžœ™——Kšž™—šž™Kšž™K™šžœžœž™K™/šžœ™
Kšž™K™K™.Kšœžœžœžœ™GK™K™-Kšžœ™——Kšžœ™—Kšž™—Kšžœ™Kšžœ™K™�—K™&K™K™�K™Kšœžœ"žœŸ
™RK™K™-K™�šžœ	ž™K™Y—šž™Kšž™K™XK™Kšžœ™—šžœžœž™4Kšž™K™K™FK™šžœž™Kšž™K™0šžœžœž™K™LKšžœžœ™—Kšžœ™—šžœž™#Kšž™K™QK™šž™šžœž™$™Kšž™K™'K™@Kšžœ™—K™/Kšžœžœ™—Kšžœ™—šžœž™$™™FK™——K™3K™=K™1Kšžœ@™G—Kšžœ™—Kšžœžœžœ™2K™Kšžœ™—K™Kšžœ™Kšžœ˜K™�—šžœ˜K˜�———�…—����1��Zý��