CLU példaprogramok

Stack Page

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:

 A típus nem egy potenciálisan végtelen tömb, nem ennek megvalósítása a célja, ezért nincs tetszőleges indexű elemet kiolvasó művelete, bár annak megvalósítása triviális az oldalak méretének ismeretében a GetFrom függvény használatával.


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