Object subclass: #Pile.
Pile instanceVariableNames: 'taille index buffer'.

Pile class extend [
    new: taille[
        | pile |
        <category: 'instance creation'>
        pile := super new.
        'Création d''une nouvelle pile.' displayNl.
        pile init: taille.
        ^pile.
    ]
]

Pile extend[
    init: taille_[
        <category: 'initialization'>
        taille := taille_.
        index := 1.
        buffer := Array new: taille.
    ]
    isEmpty[
        ^(index == 1).
    ]
    push: element[
        "Si la pile est pleine"
        (index == taille)
            ifTrue: [ self pilePleineException ].
    
        "Sinon, on retourne le dernier élément de la pile"
        buffer at: index put: element.
        index := index + 1.
        'Élément ajouté à la pile.' displayNl.
    ]
    pop[
        "Si la pile est vide, on lève un exception"
        self isEmpty
            ifTrue: [ self pileVideException ].
    
        index := index - 1.
        ^buffer at: index.
    ]
    top[
        ^buffer at: index - 1.
    ]
    printString[
        | str |
        str := ''. "String to return"
        1 to: index-1 do: [ :i | str := str, (buffer at: i) printString, ', ' ].
        ^str.
    ]
    pileVideException[
        self error: 'Pile vide.'
    ]
    pilePleineException[
        self error: 'Pile pleine.'
    ]
]

p := Pile new: 20.

"Test si la pile est vide"
(p isEmpty)
    ifTrue: [ 'La pile est vide' displayNl ]
    ifFalse: [ 'La pile n''est pas vide' displayNl ].
    
"Ajout d'éléments à la pile"
p push: 42.
p push: 25.
p push: 12.

"Affichage de la pile"
'Affichage de la pile' displayNl.
p printString displayNl.

"Quel est l'élément en haut de la pile ?"
'Affichage de l''élément en haut de la pile' displayNl.
p top printString displayNl.

"Retrait d'éléments de la liste"
'Retrait des éléments de la liste' displayNl.
p pop printString displayNl.
p pop printString displayNl.
p pop printString displayNl.

"Levée de l'exception"
'On essaie de lever une exception' displayNl.
p pop.