Tetszőlegesen rögzített hosszú, tetszőleges
elem-típusú tömbök potenciálisan végtelen vermének generikus implementálása.
A megvalósítás a CLU-ban megszokott módszerekkel és eszközökkel történik:
a reprezentáció egy variant, lineárisan láncolva egymáshoz az elemeket.
A verem OneOf típusú, s két lehetséges állapota van: üres, vagy van
benne legalább egy elem (ami ügye itt egy tömböt jelent, avagy egy "oldalt",
"köteget") Ha nem üres, akkor mindig a legutolsó oldalra mutat a reprezentáció
referenciája, azaz egy TOnePage típusú rekordra.
Műveletek:
TStackPage=cluster [Elmt:type,PageSize:int] is
Create, IsEmpty, AddPage, DelPage,
PutIntoLast, GetFromLast, GetFrom
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