MODULE DataStacks;
IMPORT NbrInt, DataErrors, DataIO;
CONST
VERSION* = 1;
TYPE
Node = POINTER TO RECORD
next: Node;
obj: OBJECT;
END;
Stack* = OBJECT
VAR len-: NbrInt.Integer;
root: Node;
PROCEDURE Read*( R: DataIO.Reader );
VAR i, length: NbrInt.Integer; p: OBJECT;
BEGIN {EXCLUSIVE}
R.Integer( length );
FOR i := 1 TO length DO R.Object( p ); Push( p ) END
END Read;
PROCEDURE Write*( W: DataIO.Writer );
VAR i, k: NbrInt.Integer; node: Node;
BEGIN
W.Integer( len );
FOR i := len TO 1 BY -1 DO
k := 1; node := root;
WHILE k # i DO NbrInt.Inc( k ); node := node.next END;
W.Object( node.obj )
END
END Write;
PROCEDURE Pop*( VAR obj: OBJECT );
VAR prev: Node;
BEGIN
IF len > 0 THEN obj := root.obj; prev := root; root := prev.next; prev.next := NIL; prev.obj := NIL; NbrInt.Dec( len )
ELSE obj := NIL
END
END Pop;
PROCEDURE Push*( obj: OBJECT );
VAR node: Node;
BEGIN
IF obj # NIL THEN NEW( node ); node.obj := obj; node.next := root; root := node; NbrInt.Inc( len ) END
END Push;
END Stack;
PROCEDURE LoadObj( R: DataIO.Reader; VAR obj: OBJECT );
VAR version: SHORTINT; ver: NbrInt.Integer; new: Stack;
BEGIN
R.RawSInt( version );
IF version = -1 THEN
obj := NIL
ELSE
IF version = VERSION THEN NEW( new ); new.Read( R ); obj := new
ELSE
ver := version; DataErrors.IntError( ver, "Alien version number encountered." ); HALT( 1000 )
END
END
END LoadObj;
PROCEDURE StoreObj( W: DataIO.Writer; obj: OBJECT );
VAR old: Stack;
BEGIN
IF obj = NIL THEN W.RawSInt( -1 ) ELSE W.RawSInt( VERSION ); old := obj( Stack ); old.Write( W ) END
END StoreObj;
PROCEDURE Register;
VAR anInstanceOf: Stack;
BEGIN
NEW( anInstanceOf ); DataIO.PlugIn( anInstanceOf, LoadObj, StoreObj )
END Register;
PROCEDURE Load*( R: DataIO.Reader; VAR obj: Stack );
VAR ptr: OBJECT;
BEGIN
R.Object( ptr ); obj := ptr( Stack )
END Load;
PROCEDURE Store*( W: DataIO.Writer; obj: Stack );
BEGIN
W.Object( obj )
END Store;
BEGIN
Register
END DataStacks.