/**
 * Un bloc/frame d'appel a la forme suivante :
 *  valeur de retour, adresse de retour, paramètres
 * La valeur de retour est créée et détruite par la partie appelante.
 * L'adresse de retour et les paramètres sont créés par l'appelant mais détruits
 * par l'appelé.
 * Attention ici car la fonction fact() utilise une variable locale!
 */
public class Prog5Traduit {
  public static void main(String []args) {
    int []memoire = new int[1000];
    int instruction=1;
    int sommetDePile=0;
    while (true) {
      switch(instruction) {
      case 1:
        sommetDePile = sommetDePile+1;
        memoire[sommetDePile] = 2; 
        sommetDePile = sommetDePile+1;
        memoire[sommetDePile] = 10; 
        sommetDePile = sommetDePile+1;
        instruction = 100; break;
      case 2:
        sommetDePile = sommetDePile-1;
        System.out.println("10!="+memoire[sommetDePile]);
        instruction++; break;
      case 3:
        System.exit(0);

      case 100: // fact n:sommetDePile-1
        if (memoire[sommetDePile-1]==1) instruction++;
        else instruction = 102;
        break;
      case 101: // return 1
        sommetDePile = sommetDePile-1; // suppression 'n'
        sommetDePile = sommetDePile-1; // AR
        instruction = memoire[sommetDePile];
        memoire[sommetDePile-1] = 1;   // VR
        break;
      case 102: // r
        sommetDePile = sommetDePile+1; // création de 'r'
        instruction++; break;
      case 103: // appel fact
        sommetDePile = sommetDePile+1; // VR
        memoire[sommetDePile] = 104; 
        sommetDePile = sommetDePile+1; // AR
        memoire[sommetDePile] = memoire[sommetDePile-4]-1; // n-1
        sommetDePile = sommetDePile+1;
        instruction = 100; break;
      case 104:
        sommetDePile = sommetDePile-1; // suppression VR
        memoire[sommetDePile-1] = memoire[sommetDePile];
        instruction++; break;
      case 105:
        sommetDePile = sommetDePile-1; // suppression 'r'
        sommetDePile = sommetDePile-1; // suppression 'n'
        sommetDePile = sommetDePile-1; // AR
        instruction = memoire[sommetDePile];
        memoire[sommetDePile-1] = memoire[sommetDePile+1]*memoire[sommetDePile+2]; // VR
        break;
      }        
    }
  } 
}