1 cananian 1.1.2.1 // DerivationChecker.java, created Fri Jun 29 13:53:10 2001 by cananian
 2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu>
 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
 4 cananian 1.1.2.1 package harpoon.Analysis.Tree;
 5 cananian 1.1.2.1 
 6 cananian 1.1.2.1 import harpoon.Analysis.Maps.Derivation;
 7 cananian 1.1.2.1 import harpoon.ClassFile.HClass;
 8 cananian 1.1.2.1 import harpoon.ClassFile.HCode;
 9 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory;
10 cananian 1.1.2.1 import harpoon.ClassFile.HMethod;
11 cananian 1.1.2.1 import harpoon.IR.Tree.Exp;
12 cananian 1.1.2.2 import harpoon.IR.Tree.Stm;
13 cananian 1.1.2.1 import harpoon.IR.Tree.Tree;
14 cananian 1.1.2.1 import harpoon.IR.Tree.TreeDerivation;
15 cananian 1.1.2.1 
16 cananian 1.1.2.1 import java.util.Iterator;
17 cananian 1.1.2.1 /**
18 cananian 1.1.2.1  * A <code>DerivationChecker</code> checks that all subtrees in
19 cananian 1.1.2.1  * a <code>Tree.Code</code> have proper derivations.
20 cananian 1.1.2.1  * 
21 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
22 cananian 1.3      * @version $Id: DerivationChecker.java,v 1.3 2002/02/26 22:42:47 cananian Exp $
23 cananian 1.1.2.1  */
24 cananian 1.1.2.1 public class DerivationChecker {
25 cananian 1.1.2.1     
26 cananian 1.1.2.1     /** No one can create a <code>DerivationChecker</code> object. */
27 cananian 1.1.2.1     private DerivationChecker() { }
28 cananian 1.1.2.1 
29 cananian 1.1.2.1     /** Create an <code>HCodeFactory</code> that will check the
30 cananian 1.1.2.1      *  derivations of every "converted" <code>HCode</code>. */
31 cananian 1.1.2.1     public static HCodeFactory codeFactory(final HCodeFactory hcf) {
32 cananian 1.1.2.1         return new HCodeFactory() {
33 cananian 1.1.2.1             public String getCodeName() { return hcf.getCodeName(); }
34 cananian 1.1.2.1             public void clear(HMethod m) { hcf.clear(m); }
35 cananian 1.1.2.1             public HCode convert(HMethod m) {
36 cananian 1.1.2.1                 HCode hc = hcf.convert(m);
37 cananian 1.1.2.1                 if (hc!=null) check(hc);
38 cananian 1.1.2.1                 return hc;
39 cananian 1.1.2.1             }
40 cananian 1.1.2.1         };
41 cananian 1.1.2.1     }
42 cananian 1.1.2.1     /** Check the given <code>HCode</code> for <code>Derivation</code>
43 cananian 1.1.2.1      *  errors. */
44 cananian 1.1.2.1     public static void check(HCode hcode) {
45 cananian 1.1.2.1         harpoon.IR.Tree.Code c = (harpoon.IR.Tree.Code) hcode;
46 cananian 1.1.2.1         // look at the derivation for every lowquad.
47 cananian 1.1.2.1         TreeDerivation d = c.getTreeDerivation();
48 cananian 1.1.2.2         ASSERT(d!=null, "Checker found no derivation! "+c);
49 cananian 1.1.2.1         for (Iterator it=c.getElementsI(); it.hasNext(); ) {
50 cananian 1.1.2.1             Tree t = (Tree) it.next();
51 cananian 1.1.2.1             if (!(t instanceof Exp)) continue;
52 cananian 1.1.2.1             try {
53 cananian 1.1.2.1                 HClass hc = d.typeMap((Exp)t);
54 cananian 1.1.2.1                 Derivation.DList dl = d.derivation((Exp)t);
55 cananian 1.1.2.2                 ASSERT(hc!=null ^ dl!=null, t, "BAD TYPE: "+hc+" / "+dl);
56 cananian 1.1.2.1             } catch (Derivation.TypeNotKnownException tnke) {
57 cananian 1.1.2.2                 ASSERT(false, t, tnke);
58 cananian 1.1.2.2             } catch (RuntimeException re) {
59 cananian 1.1.2.2                 ASSERT(false, t, re);
60 cananian 1.1.2.1             }
61 cananian 1.1.2.1         }
62 cananian 1.1.2.1     }
63 cananian 1.1.2.1     /** Simple assertion facility -- this is not intended to be
64 cananian 1.1.2.1      *  "compiled away" or turned off for speed like the standard
65 cananian 1.3          *  harpoon.Util.Util.ASSERTion facility. */
66 cananian 1.1.2.2     private static final void ASSERT(boolean cond, Object errmsg) {
67 cananian 1.1.2.1         if (!cond) throw new Error(errmsg.toString());
68 cananian 1.1.2.2     }
69 cananian 1.1.2.2     private static final void ASSERT(boolean cond, Tree t, Object errmsg) {
70 cananian 1.1.2.2         if (!cond) {
71 cananian 1.1.2.2             while (!(t instanceof Stm)) t=t.getParent();
72 cananian 1.1.2.2             throw new Error(errmsg + harpoon.IR.Tree.Print.print(t));
73 cananian 1.1.2.2         }
74 cananian 1.1.2.1     }
75 cananian 1.2     }