package serviziesprreali;

// si fa riferimento alle classi dell'altro package
import esprreali.*;

// serve Map
import java.util.*;

public class ServiziEsprReali {

	// in questo caso, fare riferimento alle classi degli
	// oggetti e' necessario perche' imposto dalle
	// specifiche
  public static double valuta(EsprReale e, Map a) {

	// costante: il valore e' quello che si trova
	// nell'oggetto; il map viene in questo caso ignorato
    if(e instanceof Costante)
      return ((Costante) e).getValore();

	// variabile: possiamo contare sul fatto che a.get() non
	// ritorna null: questo e' detto nella specifica: "si
	// assume che tutte le variabili in e siano incluse in a"
    else if(e instanceof Variabile) {
      Object o=a.get(((Variabile) e).getNome());
      return ((Double) o).doubleValue();
    }

	// somma e prodotto: in questo caso, bisogna fare la
	// valutazione ricorsiva delle sottoespressioni, e
	// combinarle opportunamente
    else if(e instanceof Somma) {
      Somma s=(Somma) e;
      return valuta(s.prima(), a)+valuta(s.seconda(), a);
    }

	// prodotto: ci basiamo sul fatto che il prodotto di zero
	// espressioni vale uno
    else if(e instanceof Prodotto) {
      Prodotto p=(Prodotto) e;
      double ris=1;
      Iterator<EsprReale> i;

      i=p.iterator();
      while(i.hasNext()) {
        EsprReale r=i.next();
        ris=ris*valuta(r, a);
      }

      return ris;
    }

	// mettiamo questa ultima istruzione per il caso in cui
	// venga definito un nuovo tipo di espressione, ma ci si
	// dimentichi di aggiornare questa classe
    throw new RuntimeException("Tipo di espressione non previsto");
  }
}

