/**
* Traduction "machine" du programme Simple.java.
* Il s'agit demontrer comment un appel de fonction est réalisé.
* Pour cela des conventions d'appel sont nécessaires :
* - qu'est ce qui est transmis et dans quel ordre ?
* - qui empile et dépile ?
*
* Toute convention fonctionnelle est correcte, même si certaines sont plus
* malines que d'autres.
* Ici nous avons convenu de :
* - on transmet sur la pile en empilant dans l'ordre : l'adresse de retour,
* puis les paramètres dans l'ordre de leur apparition dans la définition
* - l'appellant empile ET dépile tout lui-même.
*
* L'effet important à noter (au-delà de la convention) est qu'une fonction
* accède donc à ses arguments, etc directement DANS la pile, et donc via
* des adresses relatives!
*/
public class SimpleTraduit {
public static void main(String []a) {
// v:0
// 1.. : la pile
int []memoire = new int[1000];
int instructionCourante = 1;
boolean fin = false;
int sommetDePile = 1; // adresse du debut de la pile
while (!fin) {
switch(instructionCourante) {
// boucle for
case 1: // v = 0;
memoire[0] = 0;
break;
case 2: // test v<10 ?
if (memoire[0]<10) instructionCourante = 3-1; // saut 1ere ins. boucle
else instructionCourante = 12-1; // saut après boucle
break;
case 3: // 1ere ins. du corps de la boucle
System.out.println("avant appel f()");
break;
case 4: // seconde instruction du corps de la boucle
// préparation de l'appel, i.e. empile dans l'ordre "retour","arguments"
// push (adresseDeRetour)
memoire[sommetDePile] = 7-1; // on devra retourne en 7
sommetDePile++;
break;
case 5: // push(v)
memoire[sommetDePile] = memoire[0];
sommetDePile++;
break;
case 6: // saut vers le debut de la fonction f
instructionCourante = 1000-1; // tout est prêt
break;
case 7: // retour de l'appel on nettoie les choses devenues inutiles
sommetDePile -= 1; // pop valeur transmise
break;
case 8:
sommetDePile -= 1; // pop adresse de retour
break;
case 9: // instruction qui suit l'appel à f()
System.out.println("apres appel f()");
break;
case 10: // v++, fin du corps de la boucle
memoire[0]++;
break;
case 11: // retour au for...
instructionCourante = 2-1;
break;
case 12: // après la boucle for
System.out.println("Termine");
break;
case 13: // appel à f(50)
memoire[sommetDePile] = 16-1; // adresse de retour 16
sommetDePile++;
break;
case 14: // paramètre de valeur 50
memoire[sommetDePile] = 50;
sommetDePile++;
break;
case 15: // hop saut vers f()
instructionCourante = 1000-1;
break;
case 16: // retour de l'appel
sommetDePile--; // pop devenu inutile
break;
case 17:
sommetDePile--; // pop devenu inutile
break;
case 18: // fin du programme
fin = true;
break;
case 1000: // debut de la fonction f
System.out.println("Voici la variable i : "+memoire[sommetDePile-1]);
break;
case 1001: // return : retour à l'appelant...
instructionCourante = memoire[sommetDePile-2];
break;
}
instructionCourante++;
}
System.out.println("Le somme de pile est : "+sommetDePile);
}
}