C2CModeImpl.mesa
Copyright Ó 1987, 1988, 1990, 1991 by Xerox Corporation. All rights reserved.
Christian Jacobi, March 3, 1988 1:25:39 pm PST
Christian Jacobi, January 22, 1993 1:49 pm PST
DIRECTORY
C2CBasics,
C2CDefs,
C2CMode,
C2CAddressing,
IntCodeDefs,
Rope;
C2CModeImpl: CEDAR MONITOR
IMPORTS C2CBasics
EXPORTS C2CMode =
BEGIN
ModeRep: <<PUBLIC>> TYPE = IModeRec;
IModeRec: TYPE = C2CDefs.ModeRec;
IMode: TYPE = REF IModeRec;
freeModeCount: NAT = 128;
--longish to increase probability of detection of illegal reuse
freeModeSeq: REF FreeModeSeq ¬ NEW[FreeModeSeq];
FreeModeSeq: TYPE = RECORD [
in, out: NAT ¬ 0, --equal = empty
items: ARRAY [0..freeModeCount) OF IMode --circular to detect problems
];
FreeMode: PUBLIC <<ENTRY>> PROC [m: IMode] = {
ENABLE UNWIND => freeModeSeq ← NIL; --don't UNWIND for speed
IF m#NIL THEN {
nextIn: NAT;
IF m.illegal THEN RETURN WITH ERROR C2CBasics.CantHappen;
m.illegal ¬ TRUE;
m.am ¬ bad; m.lHSMaskNShiftNode ¬ NIL; m.ac ¬ [NIL, NIL];
nextIn ¬ (freeModeSeq.in + 1) MOD freeModeCount;
IF nextIn#freeModeSeq.out THEN {--don't make it look empty
freeModeSeq.items[freeModeSeq.in] ¬ m;
freeModeSeq.in ¬ nextIn;
};
};
};
NewMode: <<ENTRY>> PROC [] RETURNS [m: IMode] = {
ENABLE UNWIND => freeModeSeq ← NIL; --don't UNWIND for speed
out: NAT ¬ freeModeSeq.out;
IF freeModeSeq.in # out THEN { --not empty
m ¬ freeModeSeq.items[out];
freeModeSeq.out ¬ (out + 1) MOD freeModeCount;
IF ~m.illegal THEN RETURN WITH ERROR C2CBasics.CantHappen;
m­ ¬ [lhs: FALSE, expr: TRUE, illegal: FALSE];
RETURN;
};
m ¬ NEW[IModeRec ¬ [lhs: FALSE, expr: TRUE, illegal: FALSE]];
};
CopyMode: PROC [m: IMode¬NIL] RETURNS [c: IMode] = INLINE {
c ¬ NewMode[];
IF m#NIL THEN c­ ¬ m­;
IF c.illegal THEN C2CBasics.CantHappen
};
SetExpr: PUBLIC PROC [m: IMode¬NIL, expr: BOOL] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.expr ¬ expr;
RETURN [m];
};
SetLHS: PUBLIC PROC [m: IMode¬NIL, lhs: BOOL ¬ FALSE] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.lhs ¬ lhs;
RETURN [m];
};
SetAMode: PUBLIC PROC [m: IMode, am: C2CAddressing.AddressMode] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.am ¬ am;
RETURN [m];
};
DSetAMode: PUBLIC PROC [m: IMode, am: C2CAddressing.AddressMode] RETURNS [IMode] = {
IF m=NIL THEN m ¬ NewMode[] ELSE IF m.illegal THEN ERROR;
m.am ¬ am;
RETURN [m];
};
SetAddrContainer: PUBLIC PROC [m: IMode, ac: C2CAddressing.AddressContainer] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.ac ¬ ac;
RETURN [m];
};
SetTemplate: PUBLIC PROC [m: IMode, tmp: Rope.ROPE] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.ac ¬ [tmp, NIL];
RETURN [m];
};
SetBaseSize: PUBLIC PROC [m: IMode, sz: INT] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.baseSz ¬ sz;
RETURN [m];
};
DSetBaseSize: PUBLIC PROC [m: IMode, sz: INT] RETURNS [IMode] = {
IF m=NIL THEN m ¬ NewMode[] ELSE IF m.illegal THEN ERROR;
m.baseSz ¬ sz;
RETURN [m];
};
UseValue: PUBLIC PROC [sz: INT, m: IMode] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.baseSz ¬ sz;
m.expr ¬ TRUE;
m.lhs ¬ FALSE;
m.am ¬ value;
m.ac ¬ [];
RETURN [m];
};
SetContainerSize: PUBLIC PROC [m: IMode, sz: INT] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.containerSz ¬ sz;
RETURN [m];
};
SetUnitSize: PUBLIC PROC [m: IMode, sz: INT] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.unitSz ¬ sz;
RETURN [m];
};
SetLHSMaskNShiftNode: PUBLIC PROC [m: IMode, node: IntCodeDefs.Node] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.lHSMaskNShiftNode ¬ node;
RETURN [m];
};
DSetUnitSize: PUBLIC PROC [m: IMode, sz: INT] RETURNS [IMode] = {
IF m=NIL THEN m ¬ NewMode[] ELSE IF m.illegal THEN ERROR;
m.unitSz ¬ sz;
RETURN [m];
};
ExpMode: PUBLIC PROC [m: IMode] RETURNS [BOOL] = {
RETURN [m.expr];
};
LHSMode: PUBLIC PROC [m: IMode] RETURNS [BOOL] = {
RETURN [m.lhs];
};
GetAMode: PUBLIC PROC [m: IMode] RETURNS [am: C2CAddressing.AddressMode] = {
IF m.illegal THEN ERROR C2CBasics.CantHappen;
RETURN [m.am];
};
GetAddrContainer: PUBLIC PROC [m: IMode] RETURNS [ac: C2CAddressing.AddressContainer] = {
RETURN [m.ac];
};
GetTemplate: PUBLIC PROC [m: IMode] RETURNS [Rope.ROPE] = {
RETURN [m.ac.words];
};
BaseSize: PUBLIC PROC [m: IMode] RETURNS [INT] = {
IF m.baseSz<0 THEN C2CBasics.CantHappen; --not initialized
RETURN [m.baseSz];
};
ContainerSize: PUBLIC PROC [m: IMode] RETURNS [INT] = {
IF m.containerSz<=0 THEN C2CBasics.CantHappen; --not initialized
RETURN [m.containerSz];
};
UnitSize: PUBLIC PROC [m: IMode] RETURNS [INT] = {
IF m.unitSz<=0 THEN C2CBasics.CantHappen; --not initialized
RETURN [m.unitSz];
};
LHSMaskNShiftNode: PUBLIC PROC [m: IMode] RETURNS [IntCodeDefs.Node] = {
RETURN [m.lHSMaskNShiftNode];
};
Like: PUBLIC PROC [m: IMode¬NIL, lhs, rhs, expr, stat: BOOL ¬ FALSE] RETURNS [IMode] = {
m ¬ CopyMode[m];
IF rhs THEN m.lhs ¬ FALSE ELSE IF lhs THEN m.lhs ¬ TRUE;
IF expr THEN m.expr ¬ TRUE ELSE IF stat THEN m.expr ¬ FALSE;
RETURN [m];
};
SetAModeNC: PUBLIC PROC [m: IMode, am: C2CAddressing.AddressMode] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.am ¬ am;
m.ac ¬ [];
RETURN [m];
};
SetAssBitAddr: PUBLIC PROC [m: IMode¬NIL, ac: C2CAddressing.AddressContainer] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.am ¬ assBitAddr;
m.ac ¬ ac;
RETURN [m];
};
SetAssAddr: PUBLIC PROC [m: IMode¬NIL, tmp: Rope.ROPE] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.am ¬ assAddr;
m.ac ¬ [tmp, NIL];
RETURN [m];
};
SetAssUnits: PUBLIC PROC [m: IMode¬NIL, tmp: Rope.ROPE, sz: INT] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.am ¬ assUnits;
m.ac ¬ [tmp, NIL];
m.containerSz ¬ sz;
RETURN [m];
};
SetAssBits: PUBLIC PROC [m: IMode¬NIL, ac: C2CAddressing.AddressContainer, sz: INT] RETURNS [IMode] = {
m ¬ CopyMode[m];
m.am ¬ assBits;
m.ac ¬ ac;
m.containerSz ¬ sz;
RETURN [m];
};
END.