<<>> <> <> <> <> DIRECTORY C2CBasics, C2CDefs, C2CMode, C2CAddressing, IntCodeDefs, Rope; C2CModeImpl: CEDAR MONITOR IMPORTS C2CBasics EXPORTS C2CMode = BEGIN ModeRep: <> 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 <> PROC [m: IMode] = { < 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: <> PROC [] RETURNS [m: IMode] = { < 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.