public class PileExt {
  double haut ;
  PileExt suite ;

  PileExt (double elt, PileExt old) {
    haut = elt ;
    suite = old ;
  }

  private static void error (String msg) {
    System.err.println (msg) ;
    System.exit (2) ;
  }

  static PileExt push (PileExt pile, double elt) {
    // empile un réel
    return new PileExt (elt, pile) ;
  }

  static double top (PileExt pile) {
    // haut de pile
    if (pile == null)
      error ("Top sur pile vide") ;
    return pile.haut ;
  }

  static PileExt pop (PileExt pile) {
    // dépile
    if (pile == null)
      error ("Pop sur pile vide") ;
    return pile.suite ;
  }

  static String toString (PileExt pile) {
    // impression du contenu de la pile
    // version itérative
    String out = "" ;
    int rang = 0;
    while (pile != null) {
      out = rang + ": " + pile.haut + "\n" + out ;
      pile = pile.suite ;
      rang++ ;
    }
    return out;
  }

  static PileExt delete (PileExt pile, int n) {
    if (pile == null)
      error ("Pile trop petite pour delete") ;
    if (n == 0) return pile.suite ;
    pile.suite = delete (pile.suite, n - 1) ;
    return pile ;
  }

  static PileExt copy (PileExt pile, int n) {
    // copie le n-ième élément
    if (n < 0)
      error ("copy doit avoir un argument positif") ;
    return push (pile, get (pile, n)) ;
  }

  static double get (PileExt pile, int n) {
    // valeur du n-ième élément
    if (pile == null)
      error ("Pile trop petite pour get") ;
    if (n == 0) return pile.haut ;
    return get (pile.suite, n - 1) ;
  }

  static PileExt rotate (PileExt pile, int n) {
    return delete (copy (pile, n), n+1) ;
  }

  public static void main (String[] args) {
    PileExt p = null;
    p = push (p, 1.2) ;
    p = push (p, 1.5) ;
    p = push (p, 1.8) ;
    p = copy (p, 1) ;
    System.out.print (toString (p)) ;
    p = pop (p) ;
    p = pop (p) ;
    System.out.print (toString (p)) ;
  }
}
