/** * Contexte.java 7 mai 2021 * IUT Rodez info1 2020-2021, pas de copyright, aucun droit */ package interpreteurlir; import java.util.ArrayList; import interpreteurlir.donnees.*; import interpreteurlir.donnees.litteraux.*; /** * Le contexte contiens l'ensemble des variables définies au cours d'un session * d'interpréteur LIR. * Il est le seul moyen d'accéder et modifier ces variables. * Il sert donc d'interface entre le programme et les variables. * L'accès à une variable se fait à partir d'un Identificateur. * Les variables sont listée par ordre alphabétique des identificateurs. * @author Nicolas Caminade * @author Sylvan Courtiol * @author Pierre Debas * @author Heïa Dexter * @author Lucas Vabre */ public class Contexte { /** Valeur par défaut pour une Chaine */ public static final Chaine CHAINE_DEFAUT = new Chaine("\"\""); /** Valeur par défaut pour un Entier */ public static final Entier ENTIER_DEFAUT = new Entier(0); /** Listes des variables définies dans ce contexte */ private ArrayList variables; /** * Initialise un contexte vide (aucune variable de définie) */ public Contexte() { super(); variables = new ArrayList(); } /** * Affecte valeur à la variable dans le contexte * ayant pour identificateur id. * Si cette variable n'existe pas alors elle est créée * et référence dans le contexte. * @param id identificateur typé de la Variable * @param valeur valeur typée à affecter à la variable * @throws InterpreteurException si Variable lance l'exception. * {@link Variable#Variable(Identificateur, Litteral)} */ public void ajouterVariable(Identificateur id, Litteral valeur) { int indexVar = indexVariable(id); /* Ajout de variable absente à la fin */ if (variables.size() == indexVar) { variables.add(indexVar, new Variable(id, valeur)); return; } // else Variable varAIndex = variables.get(indexVar); /* Variable déjà présente */ if (varAIndex.getIdentificateur().compareTo(id) == 0) { varAIndex.setValeur(valeur); } else { /* Variable absente : ajout à son index trié */ variables.add(indexVar, new Variable(id, valeur)); } } /** * Lecture de la valeur d'une variable du contexte. * @param id identificateur de la variable dont on veut la valeur * @return Si la variable est définie alors sa valeur est retournée. * Sinon la valeur par défaut (CHAINE_DEFAUT ou ENTIER_DEFAUT) * selon type de id est retournée. */ public Litteral lireValeurVariable(Identificateur id) { Litteral valeur; int indexVar = indexVariable(id); if (variables.size() > indexVar && variables.get(indexVar).getIdentificateur().compareTo(id) == 0) { /* La variables est présente */ valeur = variables.get(indexVar).getValeur(); } else if (id instanceof IdentificateurChaine) { valeur = CHAINE_DEFAUT; } else { valeur = ENTIER_DEFAUT; } return valeur; } /** * Recherche de l'index théorique ou réel de la variable ayant id comme * identificateur. * @param id identificateur dont on cherche l'index de la variable * @return index de la Variable ayant id comme identificateur. * Si la variable n'existe pas alors c'est l'index de la place * théorique de variable pour qu'elle soit triée qui est renvoyé. */ private int indexVariable(Identificateur id) { int index; int taille = variables.size(); for (index = 0; index < taille; index++) { if (variables.get(index).getIdentificateur().compareTo(id) >= 0) { return index; } } return index; } /* non javadoc * @see java.lang.Object#toString() */ @Override public String toString() { final String MSG_VIDE = "aucune variable n'est définie\n"; int taille = variables.size(); if (taille == 0) { return MSG_VIDE; } // else StringBuilder resultat = new StringBuilder(""); for (int index = 0 ; index < taille ; index++) { resultat.append(variables.get(index) + "\n"); } return resultat.toString(); } /** * Remise à zéro du contexte. * Efface toutes les variables mémorisée par le contexte. */ public void raz() { variables.clear(); } }