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    

The Loop Structure is Flattened

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

// Use interface to hook all the variables and the 
// evaluator together.  A 'Variable' must have a 
// value (v) AND a connector to the next nested 
// for loop (checkit).
interface Variable { boolean checkit();  int v();  }

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

   public boolean checkit () {
      for ( ; val < 2 ; val++) 
         if (next_for.checkit()) return true;
      val = 0;
      return false;
   }

   public int v() { return val; }
}

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

   public Evaluate (Exception_5Frame f) {  
      this.f = f; 
   }
   
   void set (Choose i, Choose j, Choose k) { 
      this.i = i; 
      this.j = j; 
      this.k = k; 
   }

   public boolean checkit () {
      if ( (((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");
         return true;
      }
      return false;
   }

   public int v() { return 0; }
}

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

   public Exception_5Frame () {
      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() {
      out.append("\n Solve: ((1-i)*j + i*(1-k)"+
		           "+ (1-j)*k)\n\n");
      Evaluate eval = new Evaluate(this);
      Choose k = new Choose(eval);
      Choose j = new Choose(k);
      Choose i = new Choose(j);
      eval.set(i,j,k);
      if (!i.checkit()) out.append("No solution!\n");
   }

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

public class exception_5 
   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_5Frame hf = new Exception_5Frame();
      hf.setSize(550,450);
      hf.setVisible(true);
   }
}
 -  The loop structure is flattened. Each Choose object executes the for loop for a particular variable. Each for loop is linked, in order of nesting, through the Choose constructor. The Evaluate object eval solves the problem and must be linked to the most deeply nested loop. But that means it should be the same type as Choose, which creates a problem. The problem is solved by defining a Variable interface which is implemented by Evaluate and Choose. The interface requires checkit() which is the method that either loops through variable values in the case of Choose objects or evaluates the given expression in the case of eval. The interface also requires implementing v() which returns the current value of a Choose object and is used by eval to instantiate values for testing in the given logic expression.

The code is a bit awkward, though, because a set method is needed in the Evaluate class so that eval knows what Variable object values to apply to its logical expression - these cannot be given to eval when it is created because it must be created before the Choose objects. One solution, shown in the next slide, is to create the variables from within the Evaluate object.