package linguaggio;

public class IstruzioneIf extends Istruzione {

// una istruzione if e' composta da una variabile e da due
// istruzioni; si tratta quindi semplicemente di tradurre
// questa specifica nel fatto che l'oggetto contiene una
// componente Variabile e due componenti Istruzione

  private Variabile cond;
  private Istruzione ithen;
  private Istruzione ielse;

// gli oggetti che si possono mettere in ithen e ielse
// saranno poi necessariamente IstruzioneStampa oppure
// IstruzioneIf oppure IstruzioneSequenza, ma questo non ci
// interessa finche' riusciamo a scrivere tutto usando solo
// la classe Istruzione

  public IstruzioneIf(Variabile v, Istruzione a, Istruzione b) {
    if((v==null)||(a==null)||(b==null))
      throw new RuntimeException("Tentativo di inserire null durante la costruzione di una IstruzioneIf");

    cond=v;
    ithen=a;
    ielse=b;
  }

// metodi get

  public Variabile getCond() {
    return cond;
  }

  public Istruzione getThen() {
    return ithen;
  }

  public Istruzione getElse() {
    return ielse;
  }

// metodi set

  public void setCond(Variabile v) {
    if(v==null)
      throw new RuntimeException("Tentativo di inserire null durante la costruzione di una IstruzioneIf");

    cond=v;
  }

  public void setThen(Istruzione a) {
    if(a==null)
      throw new RuntimeException("Tentativo di inserire null durante la costruzione di una IstruzioneIf");

    ithen=a;
  }

  public void setElse(Istruzione b) {
    if(b==null)
      throw new RuntimeException("Tentativo di inserire null durante la costruzione di una IstruzioneIf");

    ielse=b;
  }

// metodo toString

  public String toString() {
    return "if("+cond+","+ithen+","+ielse+")";
  }

// equals: anche qui, non c'e' bisogno di controllare null
// sulle componenti

  public boolean equals(Object o) {
    if(o==null)
      return false;

    if(o.getClass()!=this.getClass())
      return false;

    IstruzioneIf i;
    i=(IstruzioneIf) o;

    return (i.cond.equals(cond))&&
           (i.ithen.equals(ithen))&&
           (i.ielse.equals(ielse));
  }


// hashCode: dato abbiamo due componenti, usiamo il
// meccanismo standard della somma pesata

  public int hashCode() {
    int res=7;

    res=7*res+cond.hashCode();
    res=7*res+ithen.hashCode();
    res=7*res+ielse.hashCode();

    return res;
  }

// notare che le istruzioni di assegnamento sono
//     res=7*res+ componente.hashCode()
// in altre parole, e' res che viene moltiplicato per 7, non
// componente.hashcode

// manca ora il metodo clone; notare che sia Variabile che
// Istruzione sono clonabili; quindi, tutte e tre le
// componenti vanno clonate; non c'e' pero' bisogno di
// catturare le eccezioni perche' questo viene fatto nella
// sovraclass

  public Object clone() {
    IstruzioneIf i=(IstruzioneIf) super.clone();

    i.cond=(Variabile) this.cond.clone();
    i.ithen=(Istruzione) this.ithen.clone();
    i.ielse=(Istruzione) this.ielse.clone();

    return i;
  }
}


