DIRECTORY A3: TYPE USING [ CanonicalType, LongPath, OperandLhs, OperandType, OrderedType, TargetType, TypeForTree], Alloc: TYPE USING [Notifier], ComData: TYPE USING [idCARDINAL, typeCHAR, typeINT, typeStringBody], Copier: TYPE USING [SEToken, nullSEToken, CtxFirst, CtxNext, CtxValue], Log: TYPE USING [Error, ErrorN, ErrorNode, ErrorTree], P3: TYPE USING [ Attr, fullAttr, NPUse, MergeNP, phraseNP, And, Exp, ForceType, Interval, MakeLongType, MakeRefType, RAttr, Rhs, RPop, RPush, RType, SequenceField, TypeExp, VoidExp], P3S: TYPE USING [safety], Symbols: TYPE USING [ Base, SERecord, SEIndex, ISEIndex, CSEIndex, CTXIndex, SENull, ISENull, typeANY, seType], SymbolOps: TYPE USING [ MakeNonCtxSe, NormalType, RCType, ReferentType, TypeForm, UnderType], Tree: TYPE USING [Base, Index, Link, Null, treeType], TreeOps: TYPE USING [ FreeNode, GetNode, IdentityMap, ListLength, NthSon, OpName, PopTree, PushSe, PushTree, PushNode, SetAttr, SetInfo, UpdateList]; Pass3Xc: PROGRAM IMPORTS A3, Copier, Log, P3, P3S, SymbolOps, TreeOps, dataPtr: ComData EXPORTS P3 = { OPEN SymbolOps, Symbols, TreeOps, A3, P3; tb: Tree.Base; -- tree base address (local copy) seb: Symbols.Base; -- se table base address (local copy) ExpCNotify: PUBLIC Alloc.Notifier = { seb _ base[seType]; tb _ base[Tree.treeType]}; Range: PUBLIC PROC [t: Tree.Link, type: CSEIndex] RETURNS [val: Tree.Link] = { subType: CSEIndex; SELECT OpName[t] FROM subrangeTC => { val _ RewriteSubrange[GetNode[t]]; Interval[val, IF type # typeANY THEN type ELSE dataPtr.typeINT, FALSE]}; IN [intOO .. intCC] => { val _ t; Interval[val, IF type # typeANY THEN type ELSE dataPtr.typeINT, FALSE]}; ENDCASE => IF TypeForm[type] # long THEN { val _ TypeExp[t]; RPush[TargetType[UnderType[TypeForTree[val]]], fullAttr]; phraseNP _ none} ELSE { val _ MakeEndPoints[t]; Interval[val, type, FALSE]}; subType _ RType[]; IF ~OrderedType[subType] AND subType # typeANY THEN Log.Error[nonOrderedType]; RETURN}; RewriteSubrange: PROC [node: Tree.Index] RETURNS [Tree.Link] = { subNode: Tree.Index = GetNode[tb[node].son[2]]; PushTree[tb[subNode].son[1]]; PushTree[IdentityMap[tb[node].son[1]]]; PushNode[apply, -2]; tb[subNode].son[1] _ PopTree[]; PushTree[tb[subNode].son[2]]; PushTree[tb[node].son[1]]; PushNode[apply, -2]; tb[subNode].son[2] _ PopTree[]; tb[node].son[1] _ tb[node].son[2] _ Tree.Null; FreeNode[node]; RETURN [[subtree[subNode]]]}; MakeEndPoints: PROC [t: Tree.Link] RETURNS [Tree.Link] = { PushTree[t]; PushNode[first, 1]; PushTree[IdentityMap[t]]; PushNode[last, 1]; PushNode[intCC, 2]; RETURN [PopTree[]]}; SEToken: TYPE = Copier.SEToken; Span: PUBLIC PROC [type: CSEIndex] RETURNS [first, last: SEToken] = { subType: CSEIndex = TargetType[type]; vCtx: CTXIndex = WITH seb[subType] SELECT FROM enumerated => valueCtx, ENDCASE => ERROR; WITH t: seb[type] SELECT FROM enumerated => {first _ CtxFirst[vCtx]; last _ CtxLast[vCtx]}; subrange => { IF t.mark4 THEN { first _ Copier.CtxValue[vCtx, t.origin]; last _ Copier.CtxValue[vCtx, t.origin + t.range]} ELSE { node: Tree.Index = LOOPHOLE[t.range]; subNode: Tree.Index = GetNode[tb[node].son[2]]; first _ EnumeratedValue[tb[subNode].son[1], vCtx]; last _ EnumeratedValue[tb[subNode].son[2], vCtx]; SELECT tb[subNode].name FROM intOO, intOC => first _ CtxSucc[vCtx, first]; ENDCASE; SELECT tb[subNode].name FROM intOO, intCO => last _ CtxPred[vCtx, last]; ENDCASE}}; ENDCASE => first _ last _ Copier.nullSEToken; RETURN}; EnumeratedValue: PROC [t: Tree.Link, vCtx: CTXIndex] RETURNS [SEToken] = { WITH t SELECT FROM symbol => { sei: ISEIndex = index; RETURN [SELECT TRUE FROM ~seb[sei].constant => Copier.nullSEToken, (seb[sei].idCtx = vCtx) OR seb[sei].mark4 => Copier.CtxValue[vCtx, seb[sei].idValue], ENDCASE => EnumeratedValue[InitTree[sei], vCtx]]}; subtree => { node: Tree.Index = index; RETURN [SELECT tb[node].name FROM first => Span[UnderType[TypeForTree[tb[node].son[1]]]].first, last => Span[UnderType[TypeForTree[tb[node].son[1]]]].last, pred => CtxPred[vCtx, EnumeratedValue[tb[node].son[1], vCtx]], succ => CtxSucc[vCtx, EnumeratedValue[tb[node].son[1], vCtx]], ENDCASE => Copier.nullSEToken]}; ENDCASE => RETURN [Copier.nullSEToken]}; CtxFirst: PROC [ctx: CTXIndex] RETURNS [SEToken] = Copier.CtxFirst; CtxLast: PROC [ctx: CTXIndex] RETURNS [last: SEToken] = { last _ Copier.nullSEToken; FOR t: SEToken _ Copier.CtxFirst[ctx], Copier.CtxNext[ctx, t] UNTIL t = Copier.nullSEToken DO last _ t ENDLOOP; RETURN}; CtxSucc: PROC [ctx: CTXIndex, t: SEToken] RETURNS [SEToken] = Copier.CtxNext; CtxPred: PROC [ctx: CTXIndex, t: SEToken] RETURNS [pred: SEToken] = { next: SEToken; pred _ Copier.nullSEToken; IF t # Copier.nullSEToken THEN { next _ Copier.CtxFirst[ctx]; UNTIL next = t OR next = Copier.nullSEToken DO pred _ next; next _ Copier.CtxNext[ctx, next] ENDLOOP}; RETURN}; InitTree: PROC [sei: ISEIndex] RETURNS [Tree.Link] = INLINE { RETURN [tb[LOOPHOLE[seb[sei].idValue, Tree.Index]].son[3]]}; AddrOp: PUBLIC PROC [node: Tree.Index, target: CSEIndex] = { SELECT tb[node].name FROM addr => Addr[node, target]; base => Base[node, target]; length => Length[node]; arraydesc => Desc[node, target]; ENDCASE => ERROR}; Addr: PROC [node: Tree.Index, target: CSEIndex] = { OPEN tb[node]; type: CSEIndex; attr: Attr; subType: CSEIndex = NormalType[target]; var: BOOL = WITH t: seb[subType] SELECT FROM ref => t.var, ENDCASE => FALSE; counted: BOOL _ FALSE; IF P3S.safety = checked AND ~var THEN Log.ErrorNode[unsafeOperation, node]; son[1] _ Exp[son[1], typeANY]; FOR t: Tree.Link _ son[1], NthSon[t, 1] DO SELECT OpName[t] FROM uparrow => { subType: CSEIndex = NormalType[OperandType[NthSon[t, 1]]]; WITH p: seb[subType] SELECT FROM ref => IF p.counted THEN counted _ TRUE; ENDCASE; EXIT}; cast, openx => NULL; ENDCASE => EXIT; ENDLOOP; SELECT OperandLhs[son[1]] FROM counted => IF var THEN { son[1] _ SafenRef[son[1]]; IF RCType[RType[]] # none THEN Log.ErrorTree[unimplemented, son[1]]}; none => Log.ErrorTree[nonAddressable, son[1]]; ENDCASE; type _ MakeRefType[ cType:RType[], hint:subType, counted:counted AND ~var, var:var]; IF var THEN {Log.ErrorNode[unimplemented, node]; attr2 _ FALSE} ELSE IF (attr2 _ LongPath[son[1]]) THEN type _ MakeLongType[type, target]; attr _ RAttr[]; RPop[]; RPush[type, attr]}; SafenRef: PROC [t: Tree.Link] RETURNS [v: Tree.Link] = { WITH t SELECT FROM subtree => { node: Tree.Index = index; SELECT tb[node].name FROM dot, uparrow, dindex, reloc => { PushTree[tb[node].son[1]]; PushNode[safen, 1]; SetInfo[OperandType[tb[node].son[1]]]; tb[node].son[1] _ PopTree[]; v _ t}; dollar, index, seqindex, loophole, cast, openx, pad, chop => { tb[node].son[1] _ SafenRef[tb[node].son[1]]; v _ t}; cdot => { tb[node].son[2] _ SafenRef[tb[node].son[2]]; v _ t}; apply, safen => v _ t; ENDCASE => ERROR}; ENDCASE => v _ t; RETURN}; StripRelative: PROC [rType: CSEIndex] RETURNS [type: CSEIndex, bType: SEIndex] = { WITH seb[rType] SELECT FROM relative => {type _ UnderType[offsetType]; bType _ baseType}; ENDCASE => {type _ rType; bType _ SENull}; RETURN}; MakeRelativeType: PROC [type: CSEIndex, bType: SEIndex, hint: CSEIndex] RETURNS [CSEIndex] = { rType, tType: CSEIndex; WITH seb[hint] SELECT FROM relative => IF offsetType = type AND UnderType[baseType] = UnderType[bType] THEN RETURN [hint]; ENDCASE; tType _ IF TypeForm[bType] = long OR TypeForm[type] = long THEN MakeLongType[NormalType[type], type] ELSE type; rType _ MakeNonCtxSe[SERecord.cons.relative.SIZE]; seb[rType].typeInfo _ relative[ baseType: bType, offsetType: type, resultType: tType]; seb[rType].mark3 _ seb[rType].mark4 _ TRUE; RETURN [rType]}; Base: PROC [node: Tree.Index, target: CSEIndex] = { OPEN tb[node]; type, aType, nType, subTarget: CSEIndex; bType: SEIndex; attr: Attr; long: BOOL; IF P3S.safety = checked THEN Log.ErrorNode[unsafeOperation, node]; IF ListLength[son[1]] = 1 THEN { son[1] _ Exp[son[1], typeANY]; [aType, bType] _ StripRelative[CanonicalType[RType[]]]; attr _ RAttr[]; RPop[]; nType _ NormalType[aType]; [subTarget, ] _ StripRelative[target]; WITH seb[nType] SELECT FROM array => { name _ addr; IF OperandLhs[son[1]] = none THEN Log.ErrorTree[nonAddressable, son[1]]; long _ LongPath[son[1]]}; arraydesc => {long _ seb[aType].typeTag = long; nType _ UnderType[describedType]}; ENDCASE => IF nType # typeANY THEN Log.ErrorTree[typeClash, son[1]]} ELSE { Log.ErrorN[listLong, ListLength[son[1]]-1]; son[1] _ UpdateList[son[1], VoidExp]; long _ FALSE}; type _ MakeRefType[nType, NormalType[subTarget]]; IF (attr2 _ long) THEN type _ MakeLongType[type, subTarget]; IF bType # SENull THEN type _ MakeRelativeType[type, bType, target]; attr.const _ FALSE; RPush[type, attr]; RETURN}; Length: PROC [node: Tree.Index] = { OPEN tb[node]; type, subType: CSEIndex; attr: Attr; IF ListLength[son[1]] = 1 THEN { son[1] _ Exp[son[1], typeANY]; type _ RType[]; attr _ RAttr[]; RPop[]; subType _ IF seb[type].mark3 THEN NormalType[StripRelative[CanonicalType[type]].type] ELSE typeANY; WITH seb[subType] SELECT FROM array => { IF subType # type THEN son[1] _ ForceType[son[1], subType]; attr.const _ TRUE}; arraydesc => attr.const _ FALSE; ENDCASE => { attr.const _ TRUE; IF type # typeANY THEN Log.ErrorTree[typeClash, son[1]]}} ELSE { attr.const _ TRUE; Log.ErrorN[listLong, ListLength[son[1]]-1]; son[1] _ UpdateList[son[1], VoidExp]}; RPush[dataPtr.typeINT, attr]; RETURN}; Desc: PROC [node: Tree.Index, target: CSEIndex] = { OPEN tb[node]; type, subType: CSEIndex; attr: Attr; saveNP: NPUse; aType, bType: SEIndex _ SENull; cType, iType: SEIndex; fixed: {none, range, both} _ none; packed: BOOL _ FALSE; long: BOOL; subTarget: CSEIndex = StripRelative[target].type; nTarget: CSEIndex = NormalType[subTarget]; IF P3S.safety = checked THEN Log.ErrorNode[unsafeOperation, node]; SELECT ListLength[son[1]] FROM 1 => { rType: SEIndex; nType: CSEIndex; nDerefs: CARDINAL _ 0; son[1] _ Exp[son[1], typeANY]; IF OperandLhs[son[1]] = none THEN Log.ErrorTree[nonAddressable, son[1]]; long _ LongPath[son[1]]; subType _ CanonicalType[RType[]]; attr _ RAttr[]; IF subType # RType[] THEN son[1] _ ForceType[son[1], subType]; RPop[]; nType _ NormalType[subType]; WHILE seb[nType].typeTag = ref AND (nDerefs _ nDerefs+1) < 64 DO long _ seb[subType].typeTag = long; subType _ CanonicalType[ReferentType[nType]]; PushTree[son[1]]; PushNode[uparrow, 1]; SetInfo[subType]; SetAttr[2, long]; SetAttr[3, FALSE]; son[1] _ PopTree[]; nType _ NormalType[subType]; ENDLOOP; PushTree[son[1]]; IF seb[subType].typeTag = record THEN { sei: ISEIndex = SequenceField[LOOPHOLE[subType]]; SELECT TRUE FROM (sei # ISENull) => { subType _ UnderType[seb[sei].idType]; WITH s: seb[subType] SELECT FROM sequence => { PushSe[sei]; PushNode[dollar, 2]; SetInfo[subType]; SetAttr[2, long]}; ENDCASE => ERROR}; (subType = dataPtr.typeStringBody) => NULL; -- fake sequence ENDCASE => {Log.ErrorTree[typeClash, son[1]]; subType _ typeANY}}; WITH t: seb[subType] SELECT FROM array => {rType _ aType _ OperandType[son[1]]; fixed _ both}; sequence => { rType _ cType _ t.componentType; packed _ t.packed; iType _ seb[t.tagSei].idType; fixed _ both; IF ~t.controlled THEN Log.ErrorTree[typeClash, son[1]]}; record => { -- StringBody rType _ cType _ dataPtr.typeCHAR; packed _ TRUE; iType _ dataPtr.idCARDINAL; fixed _ both}; ENDCASE => { rType _ cType _ typeANY; IF subType # typeANY THEN Log.ErrorTree[typeClash, son[1]]}; subType _ MakeRefType[rType, typeANY]; IF long THEN subType _ MakeLongType[subType, typeANY]; PushNode[addr, 1]; SetInfo[subType]; SetAttr[2, long]; son[1] _ PopTree[]}; 3 => { subNode: Tree.Index = GetNode[son[1]]; tb[subNode].son[1] _ Exp[tb[subNode].son[1], typeANY]; [subType,bType] _ StripRelative[CanonicalType[RType[]]]; attr _ RAttr[]; RPop[]; saveNP _ phraseNP; SELECT seb[NormalType[subType]].typeTag FROM basic, ref => NULL; ENDCASE => Log.ErrorTree[typeClash, tb[subNode].son[1]]; long _ seb[subType].typeTag = long; tb[subNode].son[2] _ Rhs[tb[subNode].son[2], dataPtr.typeINT]; attr _ And[RAttr[], attr]; RPop[]; phraseNP _ MergeNP[saveNP][phraseNP]; IF tb[subNode].son[3] # Tree.Null THEN { tb[subNode].son[3] _ TypeExp[tb[subNode].son[3]]; cType _ TypeForTree[tb[subNode].son[3]]; fixed _ range}}; ENDCASE; IF aType = SENull THEN { WITH seb[nTarget] SELECT FROM arraydesc => { subType _ UnderType[describedType]; WITH t: seb[subType] SELECT FROM array => IF fixed = none OR (fixed = range AND UnderType[t.componentType] = UnderType[cType]) THEN { aType _ describedType; GO TO old}; ENDCASE}; ENDCASE; GO TO new; EXITS old => NULL; new => { aType _ MakeNonCtxSe[SERecord.cons.array.SIZE]; seb[aType] _ [mark3: TRUE, mark4: TRUE, body: cons[array[ packed: packed, indexType: IF fixed < both THEN dataPtr.idCARDINAL ELSE iType, componentType: IF fixed > none THEN cType ELSE typeANY]]]}}; BEGIN WITH t: seb[nTarget] SELECT FROM arraydesc => IF UnderType[t.describedType] = UnderType[aType] THEN GO TO old; ENDCASE => IF fixed = none AND target = typeANY THEN Log.ErrorNode[noTarget, node]; GO TO new; EXITS old => type _ nTarget; new => { type _ MakeNonCtxSe[SERecord.cons.arraydesc.SIZE]; seb[type].typeInfo _ arraydesc[ readOnly:FALSE, var: FALSE, describedType:aType]; seb[type].mark3 _ seb[type].mark4 _ TRUE}; END; IF (attr2 _ long) THEN type _ MakeLongType[type, subTarget]; IF bType # SENull THEN type _ MakeRelativeType[type, bType, target]; attr.const _ FALSE; RPush[type, attr]; RETURN}; }. Úfile Pass3Xc.mesa last modified by Satterthwaite, December 9, 1982 3:48 pm called by allocator whenever table area is repacked ranges operations on enumerated types operations on addresses make type description Ê ˜Jšœ™Jšœ8™8J˜šÏk ˜ šœœœ˜J˜JJ˜ —Jšœœœ ˜Jšœ œœ1˜DJšœœœ5˜GJšœœœ'˜6šœœœ˜J˜)J˜EJ˜5—Jšœœœ ˜šœ œœ˜J˜6J˜"—šœ œœ˜J˜E—Jšœœœ%˜5šœ œœ˜J˜DJ˜:J˜——šœ ˜š˜J˜-J˜—Jšœ˜Jšœ%˜)J˜JšœÏc!˜0Jšœž%˜8J˜šœ œ˜%Jšœ3™3J˜/J˜J˜—Jšœ™˜šÏnœœœ œ˜NJ˜šœ ˜˜J˜"Jš œœœœœ˜H—šœ˜J˜Jš œœœœœ˜H—šœ˜ šœœ˜J˜J˜K—šœ˜J˜Jšœœ˜———J˜Jšœœœ˜NJšœ˜J˜—šŸœœœ˜@J˜/J˜FJ˜5J˜9J˜5J˜?Jšœ˜J˜—šŸ œœœ˜:J˜!J˜-Jšœœ˜)J˜J˜——Jšœ™˜Jšœ œ˜J˜šŸœœœœ˜EJ˜%šœœœ˜.J˜Jšœœ˜—šœœ˜J˜=˜ šœ œ˜J˜(J˜1—šœ˜Jšœœ ˜%J˜/J˜2J˜1šœ˜J˜-Jšœ˜—šœ˜J˜+Jšœ˜ ———Jšœ&˜-—Jšœ˜J˜—šŸœœ œ˜Jšœœ˜˜ J˜šœœœ˜J˜)šœœ˜,J˜(—Jšœ+˜2——˜ J˜šœœ˜!J˜=J˜;J˜>J˜>Jšœ˜ ——Jšœœ˜(J˜——JšŸœœœ˜CJ˜šŸœœœ˜9J˜šœ;œ˜]Jšœ œ˜—Jšœ˜J˜—JšŸœœœ˜MJ˜šŸœœœ˜EJ˜J˜šœœ˜ J˜šœ œ˜.Jšœ.œ˜7——Jšœ˜J˜—šŸœœœœ˜=Jšœœ)˜J˜4—˜ J˜4—J˜Jšœœ˜——Jšœ ˜—Jšœ˜J˜J˜—šŸ œœœ%˜Ršœ œ˜J˜=Jšœ#˜*—Jšœ˜J˜—šŸœœ1˜GJšœ˜J˜šœ œ˜˜ Jšœœ(œœ˜S—Jšœ˜—šœœœ˜:Jšœ%˜)Jšœ˜ —Jšœ,œ˜2˜J˜J˜J˜—Jšœ&œ˜+Jšœ ˜J˜J˜—šŸœœ)˜3Jšœ ˜J˜(J˜J˜ Jšœœ˜ Jšœœ&˜Bšœœ˜ J˜J˜7J˜J˜Bšœ œ˜˜ J˜ Jšœœ'˜HJ˜—J˜RJšœœœ"˜D——šœ˜J˜+Jšœ.œ˜5—J˜1Jšœœ&˜J˜#J˜%šœ œ˜(J˜1J˜:——Jšœ˜—šœœ˜šœœ˜˜J˜#šœœ˜ ˜šœ ˜šœœ0œ˜KJšœœœ˜"———Jšœ˜ ——Jšœ˜—Jšœœ˜ š˜Jšœœ˜ ˜Jšœ)œ˜/šœœ œ˜'˜J˜Jšœ œœœ˜>Jšœœœœ˜<—————šœ™Jš˜šœœ˜ ˜ Jšœ/œœœ˜@—šœ˜ Jšœœœ˜H——Jšœœ˜ š˜J˜˜Jšœ,œ˜2˜Jšœ œœ˜1—Jšœ$œ˜*——Jšœ˜—Jšœœ&˜