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.