% ------------------------------- % Symbol Table Scott (c) 1997-99 % Stack Page - Version 1.31CLU % ------------------------------- TStackPage=cluster [Elmt:type,PageSize:int] is Create, IsEmpty, AddPage, DelPage, PutIntoLast, GetFromLast, GetFrom % Functions: % Create.......Creates a new empty page stack % IsEmpty......Return true, if page stack is empty % AddPage......Append a page to the tail of existing page stack, and fill % its element array with Elmt argument in size of PageSize % DelPage......Delete the last page of the stack % PutIntoLast..Put a value in type of element to the defined index % in the last page % GetFromLast..Get the value from the defined index in the last page % Exceptions % STP_NullStack...DeletePage from a null stack % STP_WrongIndex..GetFrom calling with a non-existing page number argument TOnePage = record [ Prev:TStackPage[Elmt,PageSize], Elements:array[Elmt], Cnt:int] rep = oneof [ LastPage:TOnePage, Empty:null ] % own out:stream := stream$primary_output() % for debug reasons % ---------------------[ Create ]------------------------ Create = proc () returns (cvt) return (rep$make_Empty(nil)) end Create % ---------------------[ IsEmpty ]----------------------- IsEmpty = proc (Page:cvt) returns (bool) tagcase Page tag empty: return (true) tag LastPage (Last:TOnePage): return (false) end end IsEmpty % ---------------------[ AddPage ]------------------------ AddPage = proc (Page:cvt,E:Elmt) returns (cvt) NewPage:TOnePage tagcase Page tag empty: NewPage:=TOnePage${Prev:up(rep$make_Empty(nil)), Elements:array[Elmt]$Fill(0,PageSize,E), Cnt:0 } tag LastPage (Last:TOnePage): NewPage:=TOnePage${Prev:up(Page), Elements:array[Elmt]$Fill(0,PageSize,E), Cnt:Last.Cnt+1 } end return (rep$make_LastPage(NewPage)) end AddPage % -------------------------[ DelPage ]------------------------ DelPage = proc (Page:cvt) returns (cvt) signals (STP_NullStack) tagcase Page tag empty: % the stack of pages is empty signal STP_NullStack tag LastPage (Last:TOnePage): tagcase down(Last.Prev) tag empty: % it's the first and the last return(rep$make_Empty(nil)) tag LastPage (LastBefore:TOnePage): return (down(Last.Prev)) end end end DelPage % ---------------------[ PutIntoLast ]------------------------ PutIntoLast = proc (Page:cvt,i:int,e:elmt) signals (STP_NullStack) tagcase Page tag empty: % the stack of pages is empty signal STP_NullStack tag LastPage (Last:TOnePage): Last.Elements[i]:=e end end PutIntoLast % ---------------------[ GetFromLast ]------------------------ GetFromLast = proc (Page:cvt,i:int) returns (elmt) signals (STP_NullStack) tagcase Page tag empty: % the stack of pages is empty signal STP_NullStack tag LastPage (Last:TOnePage): return(Last.Elements[i]) end end GetFromLast % -------------------------[ GetFrom ]------------------------ GetFrom = proc (Page:cvt,cnt:int,i:int) returns (elmt) signals (STP_NullStack,STP_WrongIndex) while (true) do tagcase Page tag empty: % the stack of pages is empty signal STP_NullStack tag LastPage (Last:TOnePage): if (Last.Cnt=cnt) then return (Last.Elements[i]) end tagcase down(Last.Prev) tag empty: % it's the first and the last break tag LastPage (LastBefore:TOnePage): Page:=down(Last.Prev) end end end signal STP_WrongIndex end GetFrom end TStackPage