package compiler;

import java.util.ArrayList;
import java.util.List;

/**
 * Gestion des fonctions usuelles, de leur paramètres et valeur de retour.
 * 
 */
public class IdFun extends Ident {

	// L'ordre des paramètres est important car c'est
	// lui qui défini l'odre d'appel
	private List<Parameter> parameters;
	private int currentParameterIndex = -1; // no parameters

	/****************************************
	 * Sous-classe pour gérer les paramètres.
	 ****************************************/
	class Parameter {

		String name;
		IdVar id;

		/* Constructeur */
		public Parameter(String n, IdVar p) {
			name = n;
			id = p;
		}

		/* GetSet */
		public String getName(){ return name; }
		public IdVar getIdent(){ return id; }

		public String toString(){
			return name+" "+id;
		}

	}

	/**
	 * Contructeur de fonction.
	 * Initialement sans paramètres
	 * @param t
	 */
	public IdFun(Type t) {
		super(t); // type de retour
		parameters =  new ArrayList<Parameter>();
	}

	/* GetSet */
	public List<Parameter> getParameters(){ return parameters; }

	/**
	 * Ajoute un paramètre à la fonction.
	 * L'offset est mis à la construction
	 */
	public void addParameter(String name, IdVar p){
		//System.out.println("Add parameter to "+Declaration.getNameCurrentFunction()+"@"+p.getOffset());
		parameters.add(new Parameter(name, p));
		computeParametersOffets();
	}
	
	/**
	 * Calcul les offsets des paramètres et les assignes.
	 */
	public void computeParametersOffets(){
		int end = parameters.size()*2+2;
		for (Parameter p : parameters) {
			p.getIdent().setOffset(end);
			end -= 2;
		}
	}

	/**
	 * Retourne le paramètre correspondant à l'appel courant.
	 */
	public void callParameter(String name){
		parameters.get(currentParameterIndex++);
	}

	/**
	 * Retourne l'offset de retour de la fonction.
	 * @return (n_param + 2) * 2
	 */
	public int getReturnOffset(){
		return getNumberOfParameters()*2+4;
	}

	/**
	 * Retourne le nombre de paramètres de la fonction
	 * @return nombre de paramètres de la fonction
	 */
	public int getNumberOfParameters(){
		return parameters.size();
	}

	/**
	 * String output for debug purpose
	 */
	public String toString(){
		String s = new String("FONCTION\n");
		for (Parameter i : parameters) {
			s += i;
		}
		return s;
	}
}

@@ -62,16 +62,40 @@
 il.List;
+%0Aimport java.util.Stack;
 %0A%0A/**%0A *
@@ -338,19 +338,265 @@
 s;%0A%09
-private int
+/**%0A%09 *  Pile qui indique l'%C3%A9tat actuel de l'appel des param%C3%A8tres pour cette fonction%0A%09 *  au cours de leur traitement.%0A%09 *  Il s'agit d'une pile car la fonction peux %C3%AAtre rappel%C3%A9 r%C3%A9cursivement.%0A%09 *  Exemple : foo(5, foo(3, 8))%0A%09 */ %0A%09private Stack%3CInteger%3E
  cur
@@ -620,28 +620,29 @@
 x = 
--1; // no parameters
+new Stack%3CInteger%3E();
 %0A%0A%09/
@@ -1470,108 +1470,8 @@
 p)%7B%0A
-%09%09//System.out.println(%22Add parameter to %22+Declaration.getNameCurrentFunction()+%22@%22+p.getOffset());%0A
 %09%09pa
@@ -1834,16 +1834,52 @@
 ourant.%0A
+%09 * Passe %C3%A9galement %C3%A0 l'appel suiva%0A
 %09 */%0A%09pu
@@ -1916,16 +1916,59 @@
  name)%7B%0A
+%09%09int index = currentParameterIndex.pop();%0A
 %09%09parame
@@ -1976,16 +1976,28 @@
 ers.get(
+index++);%0A%09%09
 currentP
@@ -2005,26 +2005,35 @@
 rameterIndex
-++
+.push(index
 );%0A%09%7D%0A%0A%09/**%0A

Implement parameter stack