20-CS-4003-001 Organization of Programming Languages Fall 2017
Exceptions

Lambda calculus, Type theory, Formal semantics, Program analysis

    Previous     Next     All lectures        Code     Exception Hierarchy    

Add Up Exception Class for Control

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.*;

interface Variable { 
   void checkit() throws Up;  
   int v();  
}

class Up extends Exception { }

class Choose implements Variable {
   Variable next_for;
   int val = 0;
   
   Choose (Variable next_for) { 
      this.next_for = next_for; 
   }

   public void checkit () throws Up {
      for ( ; val < 2 ; val++) {
         try { 
            next_for.checkit(); 
         } catch (Up up) { }
      }
      val = 0;
      throw new Up();
   }

   public int v() { return val; }
}

class Evaluate implements Variable {
   Variable i,j,k;
   Exception_7Frame f;

   public Evaluate (Exception_7Frame f) {  
      this.f = f; 
      f.out.append("\n Solve: ((1-i)*j + i*(1-k)"+
                   "+ (1-j)*k)\n\n");
   }
   
   public void assert_ (boolean e) throws Up { 
      if (!e) throw new Up(); 
   }

   public void checkit() throws Up {
      assert_((((1-i.v())*j.v()+i.v()*(1-k.v())+
                (1-j.v())*k.v()) % 2) == 1);
      f.out.append("i="+i.v()+" j="+j.v()+
                   " k="+k.v()+"\n");
      throw new Up();
   }

   public void solve () {
      try {
         k = new Choose(this);
         j = new Choose(k);
         i = new Choose(j);
         i.checkit();
      } catch (Up up) {}
   }

   public int v() { return 0; }
}

class Exception_7Frame
   extends JFrame implements ActionListener {
   JTextArea out;
   JButton button;

   public Exception_7Frame () {
      setLayout(new FlowLayout());
      add(new JScrollPane(out = new JTextArea(16,30)));
      add(button = new JButton("Press Me"));
      button.addActionListener(this);
      out.setFont(new Font("TimesRoman",Font.PLAIN,18));
   }

   public void doit() {
      Evaluate eval = new Evaluate(this);
      eval.solve();
   }

   public void actionPerformed (ActionEvent evt) {  
      doit(); 
   }
}

public class exception_7 
   extends Applet implements ActionListener {
   JButton go;

   public void init () {
      setLayout(new BorderLayout());
      setBackground(new Color(255,255,223));
      add("Center", go = new JButton("Applet"));
      go.addActionListener(this);
   }

   public void actionPerformed (ActionEvent evt) {
      Exception_7Frame hf = new Exception_7Frame();
      hf.setSize(550,450);
      hf.setVisible(true);
   }
}
 -  The interface Variable has changed: its checkit() method no longer returns a boolean and, instead, throws an Up exception. Accordingly, the Up class is defined, without state, to extend the Exception class. The checkit() method catches an Up exception from its Choose object: this is what keeps the loop going until it ends and, when that happens, checkit() throws an Up to the next higher level. By using Up we can define method assert_() in the Evaluate class: if an expression evaluates to 0 (false), an Up is thrown by assert_(). This allows all control statements to be removed from checkit() in Evaluate which is significant because, except for solve(), that is the method that a user will have to change for every different problem this approach is going to be used to solve.

Two improvements can be made right away to the code below. If we only want one result instead of all results we can define an Out exception class and raise that exception when a solution is found. The Out object will then be passed right up to the top, bypassing all the intermediate catch blocks which are looking for Up exceptions. The second improvement is to remove the v() and abstract_() methods from the Evaluate class. The abstract_() method will be needed to solve any problem like this so let's put it in a Puzzle class and extend from that. We might as well put the v() in there too to get it out of the way. This is done on the next slide.