1 cananian 1.1.2.1  // Spec.java, created Wed Feb 17 22:05:18 1999 by cananian
   2 cananian 1.1.2.1  // Copyright (C) 1999 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.Tools.PatMat;
   5 cananian 1.1.2.1  
   6 cananian 1.7      import net.cscott.jutil.BitString;
   7 pnkfelix 1.1.2.27 import harpoon.Util.Util;
   8 pnkfelix 1.1.2.27 import harpoon.IR.Tree.Type;
   9 pnkfelix 1.1.2.27 
  10 cananian 1.1.2.1  import java.util.List;
  11 cananian 1.1.2.1  
  12 cananian 1.1.2.1  /**
  13 pnkfelix 1.1.2.32  * <code>Spec</code> represents the parsed specification of a set of
  14 pnkfelix 1.1.2.32  * Instruction Patterns for a target backend .  
  15 pnkfelix 1.1.2.5   *
  16 pnkfelix 1.1.2.5   * <BR> <B>NOTE:</B> Current documentation was written late at night
  17 pnkfelix 1.1.2.5   * and therefore may be misleading; I'm worried that it isn't META
  18 pnkfelix 1.1.2.5   * enough.  Must go over it and make sure that its clear that I'm
  19 pnkfelix 1.1.2.5   * talking about the specification for a set of instruction patterns,
  20 pnkfelix 1.1.2.12  * and <B>NOT</B> the actual IR for the code being analyzed and optimized by the
  21 pnkfelix 1.1.2.5   * compiler.
  22 cananian 1.1.2.1   * 
  23 cananian 1.1.2.1   * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
  24 pnkfelix 1.1.2.9   * @author  Felix S. Klock II <pnkfelix@mit.edu>
  25 cananian 1.7       * @version $Id: Spec.java,v 1.7 2004/02/08 01:59:54 cananian Exp $
  26 cananian 1.1.2.1   */
  27 cananian 1.1.2.1  public class Spec  {
  28 pnkfelix 1.1.2.4  
  29 pnkfelix 1.1.2.4      /** Java code statements that are going to be placed outside class
  30 pnkfelix 1.1.2.4          body (package declaration, import statements).
  31 pnkfelix 1.1.2.4      */
  32 cananian 1.3.2.2      public final String global_stms;
  33 pnkfelix 1.1.2.4  
  34 pnkfelix 1.1.2.4      /** Java code statements that are going to be placed inside class
  35 pnkfelix 1.1.2.4          body (helper methods, fields, inner classes).
  36 pnkfelix 1.1.2.4      */
  37 cananian 1.3.2.2      public final String class_stms;
  38 pnkfelix 1.1.2.4  
  39 cananian 1.1.2.16     /** Java code statements to be inserted in the prologue of the
  40 cananian 1.1.2.16      *  code generator method body.
  41 cananian 1.1.2.16      */
  42 cananian 1.3.2.2      public final String method_prologue_stms;
  43 cananian 1.1.2.16 
  44 cananian 1.1.2.16     /** Java code statements to be inserted in the epilogue of the
  45 cananian 1.1.2.16      *  code generator method body.
  46 cananian 1.1.2.16      */
  47 cananian 1.3.2.2      public final String method_epilogue_stms;
  48 cananian 1.1.2.16 
  49 pnkfelix 1.1.2.4      /** List of Instruction Patterns for this machine specification.
  50 pnkfelix 1.1.2.14         <code>null</code> is a legal value.
  51 pnkfelix 1.1.2.4       */
  52 cananian 1.3.2.2      public final RuleList rules;
  53 cananian 1.1.2.1      
  54 cananian 1.1.2.1      /** Creates a <code>Spec</code>. */
  55 cananian 1.1.2.16     public Spec(String global_stms, String class_stms,
  56 cananian 1.1.2.16                 String method_prologue_stms, String method_epilogue_stms,
  57 cananian 1.1.2.16                 RuleList rules) {
  58 cananian 1.1.2.1          this.global_stms = global_stms;
  59 cananian 1.1.2.1          this.class_stms = class_stms;
  60 cananian 1.1.2.16         this.method_prologue_stms = method_prologue_stms;
  61 cananian 1.1.2.16         this.method_epilogue_stms = method_epilogue_stms;
  62 cananian 1.1.2.1          this.rules = rules;
  63 cananian 1.1.2.1      }
  64 cananian 1.1.2.1      public String toString() {
  65 cananian 1.1.2.16         return global_stms+"\n%%\n"+class_stms+"\n%%\n"+
  66 cananian 1.1.2.16             ((method_prologue_stms==null)?"":
  67 cananian 1.1.2.16              ("%start with %{"+method_prologue_stms+"}%\n"))+
  68 cananian 1.1.2.16             ((method_epilogue_stms==null)?"":
  69 cananian 1.1.2.16              ("%end with %{"+method_epilogue_stms+"}%\n"))+
  70 cananian 1.1.2.16             rules;
  71 cananian 1.1.2.1      }
  72 cananian 1.1.2.1  
  73 pnkfelix 1.1.2.9  
  74 pnkfelix 1.1.2.4      // *** inner classes ***
  75 pnkfelix 1.1.2.4  
  76 pnkfelix 1.1.2.9      /** Visitor class for traversing a set of <code>Spec.Rule</code>s
  77 pnkfelix 1.1.2.9          and performing some action depending on the type of
  78 pnkfelix 1.1.2.9          <code>Spec.Rule</code> visited.  Subclasses should implement a
  79 pnkfelix 1.1.2.9          <code>visit</code> method for generic <code>Rule</code>s and
  80 pnkfelix 1.1.2.9          also override the <code>visit</code> method for subclasses of
  81 pnkfelix 1.1.2.9          <code>Rule</code> that the subclass cares about.
  82 cananian 1.5              @see "<U>Design Patterns</U> pgs. 331-344"
  83 pnkfelix 1.1.2.9      */
  84 pnkfelix 1.1.2.9      public static abstract class RuleVisitor {
  85 pnkfelix 1.1.2.9          public abstract void visit(Rule r);
  86 pnkfelix 1.1.2.9          public void visit(RuleExp r) { visit((Rule)r); }
  87 pnkfelix 1.1.2.9          public void visit(RuleStm r) { visit((Rule)r); }
  88 pnkfelix 1.1.2.14         /** Visits elements of <code>l</code>.
  89 pnkfelix 1.1.2.14             If (l!=null) visits l.head then l.tail.  Else does nothing.
  90 pnkfelix 1.1.2.14         */
  91 pnkfelix 1.1.2.14         public void visit(RuleList l) {
  92 pnkfelix 1.1.2.14             if(l!=null){l.head.accept(this); visit(l.tail);}
  93 pnkfelix 1.1.2.14         }
  94 pnkfelix 1.1.2.9      }
  95 pnkfelix 1.1.2.9  
  96 pnkfelix 1.1.2.4      /** Abstract immutable representation of an Instruction Pattern.
  97 pnkfelix 1.1.2.4          Contains a <code>Spec.DetailList</code> and a series of Java
  98 pnkfelix 1.1.2.4          code statements.
  99 pnkfelix 1.1.2.4       */
 100 cananian 1.1.2.2      public static abstract class Rule {
 101 pnkfelix 1.1.2.5  
 102 pnkfelix 1.1.2.4          /** List of the extra details associated with
 103 pnkfelix 1.1.2.5              <code>this</code> (speed-cost, size-cost, predicates, etc.).
 104 pnkfelix 1.1.2.14             <code>null</code> is a legal value.
 105 pnkfelix 1.1.2.4          */
 106 cananian 1.1.2.1          public final DetailList details;
 107 pnkfelix 1.1.2.4  
 108 pnkfelix 1.1.2.4          /** Java code to execute if <code>this</code> fires (ie. this
 109 pnkfelix 1.1.2.4              pattern is chosen as part of the optimal set).
 110 pnkfelix 1.1.2.4          */
 111 cananian 1.1.2.1          public final String action_str;
 112 pnkfelix 1.1.2.4          
 113 pnkfelix 1.1.2.4          /** Constructs a new <code>Spec.Rule</code>.
 114 pnkfelix 1.1.2.4              <BR> <B>requires:</B> 
 115 pnkfelix 1.1.2.4                   <code>action_str</code> is a series of valid Java
 116 pnkfelix 1.1.2.4                   code statements. 
 117 pnkfelix 1.1.2.4              <BR> <B>effects:</B> 
 118 pnkfelix 1.1.2.4                   constructs a new <code>Spec.Rule</code> object with
 119 pnkfelix 1.1.2.4                   associated <code>Spec.DetailList</code> and action to
 120 pnkfelix 1.1.2.4                   perform if <code>this</code> fires.
 121 pnkfelix 1.1.2.4              @param details List of extra details associated with
 122 pnkfelix 1.1.2.4                             <code>this</code> (speed-cost, size-cost,
 123 pnkfelix 1.1.2.5                             predicates, etc.).
 124 pnkfelix 1.1.2.4              @param action_str Series of Java code statements that
 125 pnkfelix 1.1.2.4                                represent the action to perform if
 126 pnkfelix 1.1.2.4                                <code>this</code> fires.
 127 pnkfelix 1.1.2.4          */
 128 cananian 1.1.2.1          public Rule(DetailList details, String action_str) {
 129 cananian 1.1.2.1              this.details = details; this.action_str = action_str;
 130 cananian 1.1.2.1          }
 131 pnkfelix 1.1.2.4  
 132 pnkfelix 1.1.2.9          /** Applies <code>v</code>'s <code>visit</code> method to
 133 pnkfelix 1.1.2.9              <code>this</code>.  This is effectively a gludge to
 134 pnkfelix 1.1.2.9              emulate <B>multiple dispatch</B>.  Must be reimplemented
 135 pnkfelix 1.1.2.9              by all subclasses of <code>Spec.Rule</code>.
 136 pnkfelix 1.1.2.9              <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
 137 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
 138 pnkfelix 1.1.2.9          */
 139 cananian 1.1.2.35         public abstract void accept(RuleVisitor v);
 140 pnkfelix 1.1.2.9  
 141 cananian 1.1.2.1          public String toString() {
 142 cananian 1.1.2.3              String s = " %{" + action_str + "}%";
 143 cananian 1.1.2.3              if (details==null) return s;
 144 cananian 1.1.2.3              else return details.toString()+s;
 145 cananian 1.1.2.1          }
 146 pnkfelix 1.1.2.40 
 147 cananian 1.1.2.1      }
 148 pnkfelix 1.1.2.4  
 149 pnkfelix 1.1.2.4      /** Extension of <code>Spec.Rule</code> that also contains a
 150 pnkfelix 1.1.2.4          <code>Spec.Exp</code> to match <code>Tree</code> expressions
 151 pnkfelix 1.1.2.5          and the identifier for the result that <code>this</code>
 152 pnkfelix 1.1.2.5          produces.  
 153 pnkfelix 1.1.2.4          
 154 pnkfelix 1.1.2.4          <code>Spec.RuleExp</code>s match (sub)expressions in the code,
 155 pnkfelix 1.1.2.4          which is why it is necessary to associate a
 156 pnkfelix 1.1.2.4          <code>result_id</code>: expression matching is context
 157 pnkfelix 1.1.2.4          sensitive, depending on what the outerlying expression or
 158 pnkfelix 1.1.2.4          statement is expecting the nested expression to return.
 159 pnkfelix 1.1.2.4  
 160 pnkfelix 1.1.2.4      */
 161 cananian 1.1.2.2      public static class RuleExp extends Rule {
 162 pnkfelix 1.1.2.5  
 163 pnkfelix 1.1.2.4          /** Expression <code>this</code> matches. */
 164 cananian 1.1.2.1          public final Exp exp;
 165 pnkfelix 1.1.2.5  
 166 pnkfelix 1.1.2.5          /** Identifier for return value of expression that
 167 pnkfelix 1.1.2.5              <code>this</code> matches. */ 
 168 cananian 1.1.2.1          public final String result_id;
 169 pnkfelix 1.1.2.4          
 170 pnkfelix 1.1.2.4          /** Constructs a new <code>Spec.RuleExp</code>.
 171 pnkfelix 1.1.2.4              <BR> <B>requires:</B> 
 172 pnkfelix 1.1.2.4                   <code>action_str</code> is a series of valid Java
 173 pnkfelix 1.1.2.4                   code statements.
 174 pnkfelix 1.1.2.4              <BR> <B>effects:</B> 
 175 pnkfelix 1.1.2.4                  constructs a new <code>Spec.RuleExp</code> object with
 176 pnkfelix 1.1.2.4                  associated <code>Spec.Exp</code>,
 177 pnkfelix 1.1.2.4                  <code>result_id</code>, <code>Spec.DetailList</code>,
 178 pnkfelix 1.1.2.4                  and action to perform if <code>this</code> fires.
 179 pnkfelix 1.1.2.4              @param exp <code>Spec.Exp</code> associated with
 180 pnkfelix 1.1.2.4                         <code>this</code>.
 181 pnkfelix 1.1.2.4              @param result_id Tag identifying type of result that
 182 pnkfelix 1.1.2.4                               <code>this</code> produces.
 183 pnkfelix 1.1.2.4              @param details List of extra details associated with
 184 pnkfelix 1.1.2.4                             <code>this</code> (speed-cost, size-cost,
 185 pnkfelix 1.1.2.5                             predicates, etc.). 
 186 pnkfelix 1.1.2.4              @param action_str Series of Java code statements that
 187 pnkfelix 1.1.2.4                                represent the action to perform if
 188 pnkfelix 1.1.2.4                                <code>this</code> fires.
 189 pnkfelix 1.1.2.4          */
 190 cananian 1.1.2.1          public RuleExp(Exp exp, String result_id,
 191 cananian 1.1.2.1                         DetailList details, String action_str) {
 192 cananian 1.1.2.1              super(details, action_str);
 193 cananian 1.1.2.1              this.exp = exp; this.result_id = result_id;
 194 cananian 1.1.2.1          }
 195 pnkfelix 1.1.2.9          public void accept(RuleVisitor v) { v.visit(this); }
 196 cananian 1.1.2.1          public String toString() {
 197 cananian 1.1.2.1              return exp + "=" + result_id +" " + super.toString();
 198 cananian 1.1.2.1          }
 199 cananian 1.1.2.1      }
 200 pnkfelix 1.1.2.4      
 201 pnkfelix 1.1.2.4      /** Extension of <code>Spec.Rule</code> that also contains a
 202 pnkfelix 1.1.2.4          <code>Spec.Stm</code> to match <code>Tree</code> statements. 
 203 pnkfelix 1.1.2.4      */
 204 cananian 1.1.2.2      public static class RuleStm extends Rule {
 205 pnkfelix 1.1.2.5  
 206 pnkfelix 1.1.2.4          /** Statement associated with <code>this</code>. */
 207 cananian 1.1.2.1          public final Stm stm;
 208 pnkfelix 1.1.2.4  
 209 pnkfelix 1.1.2.4          /** Constructs a new <code>Spec.RuleStm</code>.
 210 pnkfelix 1.1.2.4              <BR> <B>requires:</B> 
 211 pnkfelix 1.1.2.4                   <code>action_str</code> is a series of valid Java
 212 pnkfelix 1.1.2.4                   code statements. 
 213 pnkfelix 1.1.2.4              <BR> <B>effects:</B> 
 214 pnkfelix 1.1.2.4                   constructs a new <code>Spec.RuleStm</code> object
 215 pnkfelix 1.1.2.4                   with associated <code>Spec.Stm</code>,
 216 pnkfelix 1.1.2.4                   <code>Spec.DetailList</code>, and action to perform
 217 pnkfelix 1.1.2.4                   if <code>this</code> fires.
 218 pnkfelix 1.1.2.4              @param stm <code>Spec.Stm</code> associated with
 219 pnkfelix 1.1.2.4                         <code>this</code>. 
 220 pnkfelix 1.1.2.4              @param details List of extra details associated with
 221 pnkfelix 1.1.2.4                             <code>this</code> (speed-cost, size-cost,
 222 pnkfelix 1.1.2.5                             predicates, etc.). 
 223 pnkfelix 1.1.2.4              @param action_str Series of Java code statements that
 224 pnkfelix 1.1.2.4                                represent the action to perform if
 225 pnkfelix 1.1.2.4                                <code>this</code> fires.
 226 pnkfelix 1.1.2.4          */
 227 cananian 1.1.2.1          public RuleStm(Stm stm, DetailList details, String action_str) {
 228 cananian 1.1.2.1              super(details, action_str);
 229 cananian 1.1.2.1              this.stm = stm;
 230 cananian 1.1.2.1          }
 231 pnkfelix 1.1.2.9          public void accept(RuleVisitor v) { v.visit(this); }
 232 cananian 1.1.2.1          public String toString() {
 233 cananian 1.1.2.1              return stm + " " + super.toString();
 234 cananian 1.1.2.1          }
 235 cananian 1.1.2.1      }
 236 cananian 1.1.2.1  
 237 pnkfelix 1.1.2.9      /** Visitor class for traversing a set of <code>Spec.Exp</code>s
 238 pnkfelix 1.1.2.9          and performing some action depending on the type of
 239 pnkfelix 1.1.2.9          <code>Spec.Exp</code> visited.  Subclasses should implement a
 240 pnkfelix 1.1.2.12         <code>visit</code> method for generic <code>Spec.Exp</code>s and
 241 pnkfelix 1.1.2.9          also override the <code>visit</code> method for subclasses of
 242 pnkfelix 1.1.2.12         <code>Spec.Exp</code> that the subclass cares about.
 243 cananian 1.5              @see "<U>Design Patterns</U> pgs. 331-344"
 244 pnkfelix 1.1.2.9      */
 245 pnkfelix 1.1.2.9      public static abstract class ExpVisitor {
 246 pnkfelix 1.1.2.9          public abstract void visit(Exp e);
 247 pnkfelix 1.1.2.9          public void visit(ExpBinop e) { visit((Exp)e); }
 248 pnkfelix 1.1.2.9          public void visit(ExpConst e) { visit((Exp)e); }
 249 pnkfelix 1.1.2.9          public void visit(ExpId e) { visit((Exp)e); }
 250 pnkfelix 1.1.2.9          public void visit(ExpMem e) { visit((Exp)e); }
 251 pnkfelix 1.1.2.9          public void visit(ExpName e) { visit((Exp)e); }
 252 pnkfelix 1.1.2.9          public void visit(ExpTemp e) { visit((Exp)e); }
 253 pnkfelix 1.1.2.9          public void visit(ExpUnop e) { visit((Exp)e); }
 254 pnkfelix 1.1.2.9      }
 255 pnkfelix 1.1.2.9  
 256 pnkfelix 1.1.2.4      /** Abstract immutable representation of an Expression in an
 257 pnkfelix 1.1.2.4          Instruction Pattern. 
 258 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.Exp
 259 pnkfelix 1.1.2.4      */
 260 pnkfelix 1.1.2.9      public static abstract class Exp { 
 261 pnkfelix 1.1.2.9          
 262 pnkfelix 1.1.2.9          /** Applies <code>v</code>'s <code>visit</code> method to
 263 pnkfelix 1.1.2.9              <code>this</code>.  This is effectively a gludge to
 264 pnkfelix 1.1.2.9              emulate <B>multiple dispatch</B>.  Must be reimplemented
 265 pnkfelix 1.1.2.9              by all subclasses of <code>Spec.Exp</code>.
 266 pnkfelix 1.1.2.9              <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
 267 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
 268 pnkfelix 1.1.2.9          */
 269 cananian 1.1.2.35         public abstract void accept(ExpVisitor v);
 270 pnkfelix 1.1.2.9          
 271 cananian 1.1.2.42         /** Creates a new <code>Spec.Exp</code> similar to this one,
 272 cananian 1.1.2.42          *  using the provided <code>Spec.ExpList</code> of children. */
 273 cananian 1.1.2.42         public abstract Exp build(ExpList kids);
 274 cananian 1.1.2.42         /** Creates an <code>Spec.ExpList</code> of children of this
 275 cananian 1.1.2.42          *  <code>Spec.Exp</code>. */
 276 cananian 1.1.2.42         public abstract ExpList kids();
 277 pnkfelix 1.1.2.9      }
 278 pnkfelix 1.1.2.4      
 279 pnkfelix 1.1.2.4      /** Extension of <code>Spec.Exp</code> that represents an
 280 pnkfelix 1.1.2.4          Identifier in the code.  Essentially a wrapper around a
 281 pnkfelix 1.1.2.4          <code>String</code>.
 282 pnkfelix 1.1.2.4      */
 283 cananian 1.1.2.2      public static class ExpId extends Exp {
 284 pnkfelix 1.1.2.4          /** Identifier that <code>this</code> represents. */
 285 cananian 1.1.2.1          public final String id;
 286 pnkfelix 1.1.2.5  
 287 pnkfelix 1.1.2.5          /** Constructs a <code>Spec.ExpId</code> around
 288 pnkfelix 1.1.2.5              <code>id</code>. 
 289 pnkfelix 1.1.2.5              @param id The Identifier that <code>this</code>
 290 pnkfelix 1.1.2.5                        represents. 
 291 pnkfelix 1.1.2.5          */
 292 cananian 1.1.2.1          public ExpId(String id) { this.id = id; }
 293 pnkfelix 1.1.2.9          public void accept(ExpVisitor v) { v.visit(this); }
 294 cananian 1.1.2.42         public Exp build(ExpList kids) {
 295 cananian 1.3.2.1              assert kids==null;
 296 cananian 1.1.2.42             return new ExpId(this.id);
 297 cananian 1.1.2.42         }
 298 cananian 1.1.2.42         public ExpList kids() { return null; }
 299 cananian 1.1.2.1          public String toString() { return id; }
 300 cananian 1.1.2.1      }
 301 pnkfelix 1.1.2.4  
 302 pnkfelix 1.1.2.4      /** Extension of <code>Spec.Exp</code> that represents a Binary
 303 pnkfelix 1.1.2.5          Operation in the code.  An implicit restriction on our binary
 304 pnkfelix 1.1.2.5          operations is that both operands must have equivalent domains
 305 pnkfelix 1.1.2.5          (there is only one <code>Spec.TypeSet</code> for a given
 306 pnkfelix 1.1.2.6          <code>Spec.ExpBinop</code>).
 307 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.BINOP
 308 pnkfelix 1.1.2.4      */
 309 cananian 1.1.2.2      public static class ExpBinop extends Exp {
 310 pnkfelix 1.1.2.5          
 311 pnkfelix 1.1.2.4          /** Types of values that <code>this</code> operates on. */
 312 cananian 1.1.2.1          public final TypeSet types;
 313 pnkfelix 1.1.2.5          
 314 pnkfelix 1.1.2.5          /** Opcode for <code>this</code>.
 315 pnkfelix 1.1.2.30             @see harpoon.IR.Tree.Bop
 316 pnkfelix 1.1.2.5          */
 317 cananian 1.1.2.1          public final Leaf opcode;
 318 pnkfelix 1.1.2.5          
 319 pnkfelix 1.1.2.4          /** Expression on the left side of <code>this</code>. */
 320 pnkfelix 1.1.2.4          public final Exp left;
 321 pnkfelix 1.1.2.4  
 322 pnkfelix 1.1.2.5          /** Expression on the right side of <code>this</code>. */
 323 pnkfelix 1.1.2.4          public final Exp right;
 324 pnkfelix 1.1.2.5  
 325 pnkfelix 1.1.2.5          /** Constructs a <code>Spec.ExpBinop</code> that operates on
 326 pnkfelix 1.1.2.5              expressions of <code>types</code>.
 327 pnkfelix 1.1.2.5              @param types Types that <code>left</code> and
 328 pnkfelix 1.1.2.5                           <code>right</code> may be. 
 329 pnkfelix 1.1.2.5              @param opcode The binary operation that is being performed
 330 pnkfelix 1.1.2.5                            on <code>left</code> and <code>right</code>.
 331 pnkfelix 1.1.2.5              @param left The left operand.
 332 pnkfelix 1.1.2.5              @param right The right operand.
 333 pnkfelix 1.1.2.5          */
 334 cananian 1.1.2.1          public ExpBinop(TypeSet types, Leaf opcode, Exp left, Exp right) {
 335 cananian 1.1.2.1              this.types = types; this.opcode = opcode;
 336 cananian 1.1.2.1              this.left = left;   this.right = right;
 337 cananian 1.3.2.1              assert !types.containsSmall() : ("BINOP cannot be precisely typed: "+this);
 338 cananian 1.1.2.1          }
 339 pnkfelix 1.1.2.9          public void accept(ExpVisitor v) { v.visit(this); }
 340 cananian 1.1.2.42         public Exp build(ExpList kids) {
 341 cananian 1.3.2.1              assert kids!=null && kids.tail!=null && kids.tail.tail==null;
 342 cananian 1.1.2.42             return new ExpBinop((TypeSet)this.types.clone(),
 343 cananian 1.1.2.42                                 opcode/*immutable*/,
 344 cananian 1.1.2.42                                 kids.head, kids.tail.head);
 345 cananian 1.1.2.42         }
 346 cananian 1.1.2.42         public ExpList kids() {
 347 cananian 1.1.2.42             return new ExpList(left, new ExpList(right, null));
 348 cananian 1.1.2.42         }
 349 cananian 1.1.2.1          public String toString() {
 350 cananian 1.1.2.42             return "BINOP"+types+"("+opcode.toBop()+","
 351 cananian 1.1.2.1                  +left+","+right+")";
 352 cananian 1.1.2.1          }
 353 cananian 1.1.2.1      }
 354 pnkfelix 1.1.2.5  
 355 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Exp</code> that represents a Constant
 356 pnkfelix 1.1.2.5          value in the code.
 357 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.CONST
 358 pnkfelix 1.1.2.5      */
 359 cananian 1.1.2.2      public static class ExpConst extends Exp {
 360 pnkfelix 1.1.2.5  
 361 pnkfelix 1.1.2.5          /** The set of types that <code>value</code> may take. */
 362 cananian 1.1.2.1          public final TypeSet types;
 363 pnkfelix 1.1.2.5  
 364 pnkfelix 1.1.2.5          /** The constant value associated with <code>this</code>. */
 365 cananian 1.1.2.1          public final Leaf value;
 366 pnkfelix 1.1.2.5  
 367 pnkfelix 1.1.2.5          /** Constructs a <code>Spec.ExpConst</code>. 
 368 pnkfelix 1.1.2.5              @param types Types that <code>value</code> may be.
 369 pnkfelix 1.1.2.5              @param value The constant value.
 370 pnkfelix 1.1.2.5           */
 371 cananian 1.1.2.1          public ExpConst(TypeSet types, Leaf value) {
 372 cananian 1.1.2.1              this.types = types; this.value = value;
 373 cananian 1.1.2.1          }
 374 pnkfelix 1.1.2.9          public void accept(ExpVisitor v) { v.visit(this); }
 375 cananian 1.1.2.42         public Exp build(ExpList kids) {
 376 cananian 1.3.2.1              assert kids==null;
 377 cananian 1.1.2.42             return new ExpConst((TypeSet)types.clone(),value/*immutable*/);
 378 cananian 1.1.2.42         }
 379 cananian 1.1.2.42         public ExpList kids() { return null; }
 380 cananian 1.1.2.1          public String toString() { return "CONST"+types+"("+value+")"; }
 381 cananian 1.1.2.1      }
 382 pnkfelix 1.1.2.5  
 383 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Exp</code> that represents a Memory
 384 pnkfelix 1.1.2.5          Access in the code (could be either Load or Store;
 385 pnkfelix 1.1.2.5          Context-Sensitive).
 386 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.MEM
 387 pnkfelix 1.1.2.5      */
 388 cananian 1.1.2.2      public static class ExpMem extends Exp {
 389 pnkfelix 1.1.2.5  
 390 pnkfelix 1.1.2.5          /** The set of types that the values at <code>addr</code> may be. */ 
 391 cananian 1.1.2.1          public final TypeSet types;
 392 pnkfelix 1.1.2.5  
 393 pnkfelix 1.1.2.5          /** The expression that computes the address of memory
 394 pnkfelix 1.1.2.5              represented by <code>this</code>.
 395 pnkfelix 1.1.2.5          */
 396 cananian 1.1.2.1          public final Exp addr;
 397 pnkfelix 1.1.2.5  
 398 pnkfelix 1.1.2.5          /** Constructs a <code>Spec.ExpMem</code>.
 399 pnkfelix 1.1.2.5              @param types Types that the value at <code>addr</code> may be.
 400 pnkfelix 1.1.2.5              @param addr Address of memory for <code>this</code>.
 401 pnkfelix 1.1.2.5          */
 402 cananian 1.1.2.1          public ExpMem(TypeSet types, Exp addr) {
 403 cananian 1.1.2.1              this.types = types; this.addr = addr;
 404 cananian 1.1.2.1          }
 405 pnkfelix 1.1.2.9          public void accept(ExpVisitor v) { v.visit(this); }
 406 cananian 1.1.2.42         public Exp build(ExpList kids) {
 407 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 408 cananian 1.1.2.42             return new ExpMem((TypeSet)types.clone(), kids.head);
 409 cananian 1.1.2.42         }
 410 cananian 1.1.2.42         public ExpList kids() { return new ExpList(addr, null); }
 411 cananian 1.1.2.1          public String toString() { return "MEM"+types+"("+addr+")"; }
 412 cananian 1.1.2.1      }
 413 pnkfelix 1.1.2.5  
 414 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Exp</code> that represents a symbolic
 415 pnkfelix 1.1.2.5          constant.  Usually used to represent an Assembly Language
 416 pnkfelix 1.1.2.5          Label in the data segment. 
 417 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.NAME
 418 pnkfelix 1.1.2.5      */
 419 cananian 1.1.2.2      public static class ExpName extends Exp {
 420 pnkfelix 1.1.2.5  
 421 pnkfelix 1.1.2.12         /** Name for <code>this</code>. 
 422 cananian 1.4                  @see harpoon.Temp.Label
 423 pnkfelix 1.1.2.12          */
 424 cananian 1.1.2.1          public final String name;
 425 pnkfelix 1.1.2.5  
 426 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.ExpName</code> representing
 427 pnkfelix 1.1.2.5              <code>name</code>. */
 428 cananian 1.1.2.1          public ExpName(String name) { this.name = name; }
 429 pnkfelix 1.1.2.13         public void accept(ExpVisitor v) { v.visit(this); }
 430 cananian 1.1.2.42         public Exp build(ExpList kids) {
 431 cananian 1.3.2.1              assert kids==null;
 432 cananian 1.1.2.42             return new ExpName(name);
 433 cananian 1.1.2.42         }
 434 cananian 1.1.2.42         public ExpList kids() { return null; }
 435 cananian 1.1.2.1          public String toString() { return "NAME("+name+")"; }
 436 cananian 1.1.2.1      }
 437 pnkfelix 1.1.2.5  
 438 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Exp</code> that represents a Temporary
 439 pnkfelix 1.1.2.5          value in the code.
 440 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.TEMP
 441 pnkfelix 1.1.2.5      */
 442 cananian 1.1.2.2      public static class ExpTemp extends Exp {
 443 pnkfelix 1.1.2.5  
 444 pnkfelix 1.1.2.5          /** The set of types that <code>this</code> may take. */
 445 cananian 1.1.2.1          public final TypeSet types;
 446 pnkfelix 1.1.2.5  
 447 pnkfelix 1.1.2.12         /** Identifier for <code>this</code>. 
 448 pnkfelix 1.1.2.12             @see harpoon.Temp.Temp
 449 pnkfelix 1.1.2.12          */
 450 cananian 1.1.2.1          public final String name;
 451 pnkfelix 1.1.2.5  
 452 pnkfelix 1.1.2.5          /** Constructs a <code>Spec.ExpTemp</code>.
 453 pnkfelix 1.1.2.5              @param types Types that <code>this</code> may be.
 454 pnkfelix 1.1.2.5              @param name Identifier for <code>this</code>.
 455 pnkfelix 1.1.2.5          */
 456 cananian 1.1.2.1          public ExpTemp(TypeSet types, String name) {
 457 cananian 1.1.2.1              this.types = types; this.name = name;
 458 cananian 1.3.2.1              assert !types.containsSmall() : ("TEMP cannot be precisely typed: "+this);
 459 cananian 1.1.2.1          }
 460 pnkfelix 1.1.2.9          public void accept(ExpVisitor v) { v.visit(this); }
 461 cananian 1.1.2.42         public Exp build(ExpList kids) {
 462 cananian 1.3.2.1              assert kids==null;
 463 cananian 1.1.2.42             return new ExpTemp((TypeSet)types.clone(), name);
 464 cananian 1.1.2.42         }
 465 cananian 1.1.2.42         public ExpList kids() { return null; }
 466 cananian 1.1.2.1          public String toString() { return "TEMP"+types+"("+name+")"; }
 467 cananian 1.1.2.1      }
 468 pnkfelix 1.1.2.5  
 469 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Exp</code> that represents a Unary
 470 pnkfelix 1.1.2.5          operation. 
 471 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.UNOP
 472 pnkfelix 1.1.2.5      */
 473 cananian 1.1.2.2      public static class ExpUnop extends Exp {
 474 pnkfelix 1.1.2.5  
 475 pnkfelix 1.1.2.5          /** Set of Types that <code>this</code> operates on. (The
 476 pnkfelix 1.1.2.5              types returned are part of the <code>opcode</code>).
 477 pnkfelix 1.1.2.5          */
 478 cananian 1.1.2.1          public final TypeSet types;
 479 pnkfelix 1.1.2.5  
 480 pnkfelix 1.1.2.5          /** Opcode for <code>this</code>.
 481 pnkfelix 1.1.2.30             @see harpoon.IR.Tree.Uop
 482 pnkfelix 1.1.2.5          */
 483 cananian 1.1.2.1          public final Leaf opcode;
 484 cananian 1.1.2.1          public final Exp exp;
 485 cananian 1.1.2.1          public ExpUnop(TypeSet types, Leaf opcode, Exp exp) {
 486 cananian 1.1.2.1              this.types = types; this.opcode = opcode; this.exp = exp;
 487 cananian 1.3.2.1              assert !types.containsSmall() : ("UNOP cannot be precisely typed: "+this);
 488 cananian 1.1.2.1          }
 489 pnkfelix 1.1.2.9          public void accept(ExpVisitor v) { v.visit(this); }
 490 cananian 1.1.2.42         public Exp build(ExpList kids) {
 491 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 492 cananian 1.1.2.42             return new ExpUnop((TypeSet)types.clone(), opcode/*immutable*/,
 493 cananian 1.1.2.42                                kids.head);
 494 cananian 1.1.2.42         }
 495 cananian 1.1.2.42         public ExpList kids() { return new ExpList(exp, null); }
 496 cananian 1.1.2.1          public String toString() {
 497 cananian 1.1.2.42             return "UNOP"+types+"("+opcode.toUop()+","+exp+")";
 498 cananian 1.1.2.1          }
 499 cananian 1.1.2.1      }
 500 cananian 1.1.2.1  
 501 pnkfelix 1.1.2.9      /** Visitor class for traversing a set of <code>Spec.Stm</code>s
 502 pnkfelix 1.1.2.9          and performing some action depending on the type of
 503 pnkfelix 1.1.2.9          <code>Spec.Stm</code> visited.  Subclasses should implement a
 504 pnkfelix 1.1.2.12         <code>visit</code> method for generic <code>Spec.Stm</code>s and
 505 pnkfelix 1.1.2.9          also override the <code>visit</code> method for subclasses of
 506 pnkfelix 1.1.2.12         <code>Spec.Stm</code> that the subclass cares about.
 507 cananian 1.5              @see "<U>Design Patterns</U> pgs. 331-344"
 508 pnkfelix 1.1.2.9      */
 509 pnkfelix 1.1.2.9      public static abstract class StmVisitor {
 510 pnkfelix 1.1.2.9          public abstract void visit(Stm s);
 511 cananian 1.1.2.36         public void visit(StmAlign s) { visit((Stm)s); }
 512 pnkfelix 1.1.2.9          public void visit(StmCall s) { visit((Stm)s); }
 513 pnkfelix 1.1.2.9          public void visit(StmCjump s) { visit((Stm)s); }
 514 cananian 1.1.2.19         public void visit(StmData s) { visit((Stm)s); }
 515 pnkfelix 1.1.2.9          public void visit(StmExp s) { visit((Stm)s); }
 516 pnkfelix 1.1.2.9          public void visit(StmJump s) { visit((Stm)s); }
 517 pnkfelix 1.1.2.9          public void visit(StmLabel s) { visit((Stm)s); }
 518 cananian 1.1.2.23         public void visit(StmMethod s) { visit((Stm)s); }
 519 pnkfelix 1.1.2.9          public void visit(StmMove s) { visit((Stm)s); }
 520 pnkfelix 1.1.2.9          public void visit(StmNativeCall s) { visit((Stm)s); }
 521 pnkfelix 1.1.2.9          public void visit(StmReturn s) { visit((Stm)s); }
 522 cananian 1.1.2.17         public void visit(StmSegment s) { visit((Stm)s); }
 523 pnkfelix 1.1.2.9          public void visit(StmSeq s) { visit((Stm)s); }
 524 pnkfelix 1.1.2.9          public void visit(StmThrow s) { visit((Stm)s); }
 525 pnkfelix 1.1.2.9      }
 526 pnkfelix 1.1.2.9  
 527 pnkfelix 1.1.2.5      /** Abstract immutable representation of a Statement in an
 528 pnkfelix 1.1.2.5          Instruction Pattern.
 529 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.Stm
 530 pnkfelix 1.1.2.5      */
 531 pnkfelix 1.1.2.9      public static abstract class Stm { 
 532 pnkfelix 1.1.2.9  
 533 pnkfelix 1.1.2.9          /** Applies <code>v</code>'s <code>visit</code> method to
 534 pnkfelix 1.1.2.9              <code>this</code>.  This is effectively a gludge to
 535 pnkfelix 1.1.2.9              emulate <B>multiple dispatch</B>.  Must be reimplemented
 536 pnkfelix 1.1.2.9              by all subclasses of <code>Spec.Stm</code>.
 537 pnkfelix 1.1.2.9              <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
 538 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
 539 pnkfelix 1.1.2.9          */
 540 cananian 1.1.2.35         public abstract void accept(StmVisitor v);
 541 pnkfelix 1.1.2.40 
 542 cananian 1.1.2.42         /** Creates a new <code>Spec.Stm</code> similar to this one,
 543 cananian 1.1.2.42          *  using the provided <code>Spec.ExpList</code> of children. */
 544 cananian 1.1.2.42         public abstract Stm build(ExpList kids);
 545 cananian 1.1.2.42         /** Creates an <code>Spec.ExpList</code> of children of this
 546 cananian 1.1.2.42          *  <code>Spec.Stm</code>. */
 547 cananian 1.1.2.42         public abstract ExpList kids();
 548 pnkfelix 1.1.2.40 
 549 pnkfelix 1.1.2.40         /** Checks if this <code>Stm</code> object is valid for Data
 550 pnkfelix 1.1.2.40             patterns. 
 551 pnkfelix 1.1.2.40             Most patterns are for code generation, not data tables.
 552 pnkfelix 1.1.2.40             Specific subclasses of <code>Stm</code> that wish to be
 553 pnkfelix 1.1.2.40             matched when generating data tables should override this
 554 pnkfelix 1.1.2.40             method to return true.
 555 pnkfelix 1.1.2.40         */
 556 pnkfelix 1.1.2.40         public boolean canBeRootOfData() { return false; }
 557 pnkfelix 1.1.2.40 
 558 cananian 1.1.2.36     }
 559 cananian 1.1.2.36 
 560 cananian 1.1.2.36     /** Extension of <code>Spec.Stm</code> representing an alignment
 561 cananian 1.1.2.36      *  request.
 562 cananian 1.1.2.36      *  @see harpoon.IR.Tree.ALIGN
 563 cananian 1.1.2.36      */
 564 cananian 1.1.2.36     public static class StmAlign extends Stm {
 565 cananian 1.1.2.36         /** Type of segment. */
 566 cananian 1.1.2.36         public final Leaf alignment;
 567 cananian 1.1.2.36         /** Constructs a new <code>Spec.StmSegment</code>.
 568 cananian 1.1.2.36          *  @param segtype Segment type.
 569 cananian 1.1.2.36          */
 570 cananian 1.1.2.36         public StmAlign(Leaf alignment) {
 571 cananian 1.3.2.1              assert alignment instanceof LeafId ||
 572 cananian 1.1.2.36                         (alignment instanceof LeafNumber &&
 573 cananian 1.3.2.1                           ((LeafNumber)alignment).number instanceof Integer) : "Only integer alignments make sense for ALIGN";
 574 cananian 1.1.2.36             this.alignment = alignment;
 575 cananian 1.1.2.36         }
 576 cananian 1.1.2.36         public void accept(StmVisitor v) { v.visit(this); }
 577 cananian 1.1.2.42         public Stm build(ExpList kids) {
 578 cananian 1.3.2.1              assert kids==null;
 579 cananian 1.1.2.42             return new StmAlign(alignment/*immutable*/);
 580 cananian 1.1.2.42         }
 581 cananian 1.1.2.42         public ExpList kids() { return null; }
 582 cananian 1.1.2.36         public String toString() { return "ALIGN("+alignment+")"; }
 583 pnkfelix 1.1.2.40         public boolean canBeRootOfData() { return true; }
 584 pnkfelix 1.1.2.9      }
 585 pnkfelix 1.1.2.5  
 586 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> that represents a call to a
 587 pnkfelix 1.1.2.5          procedure. 
 588 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.CALL
 589 pnkfelix 1.1.2.5      */
 590 cananian 1.1.2.2      public static class StmCall extends Stm {
 591 pnkfelix 1.1.2.10         /** Return value destination expression. 
 592 cananian 1.1.2.37             @see harpoon.IR.Tree.TEMP
 593 pnkfelix 1.1.2.10          */
 594 cananian 1.1.2.37         public final String retval;
 595 pnkfelix 1.1.2.10         /** Exception value destination expression. 
 596 cananian 1.1.2.37             @see harpoon.IR.Tree.TEMP
 597 pnkfelix 1.1.2.10          */
 598 cananian 1.1.2.37         public final String retex;
 599 pnkfelix 1.1.2.10         /** Function location expression. 
 600 pnkfelix 1.1.2.30             @see harpoon.IR.Tree.Exp
 601 pnkfelix 1.1.2.10          */
 602 pnkfelix 1.1.2.5          public final Exp func;
 603 pnkfelix 1.1.2.10         /** Arguments being passed to procedure. 
 604 pnkfelix 1.1.2.34             @see harpoon.IR.Tree.TempList
 605 pnkfelix 1.1.2.10          */
 606 cananian 1.1.2.1          public final String arglist;
 607 cananian 1.1.2.37         /** Exception handler label.
 608 cananian 1.1.2.37          *  @see harpoon.IR.Tree.NAME
 609 cananian 1.1.2.37          */
 610 cananian 1.1.2.37         public final String handler;
 611 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmCall</code>.
 612 pnkfelix 1.1.2.5              @param retval Return value destination expression.
 613 pnkfelix 1.1.2.5              @param retex Exception value destination expression. 
 614 pnkfelix 1.1.2.5              @param func Function location expression.
 615 pnkfelix 1.1.2.5              @param arglist Arguments.
 616 cananian 1.1.2.37             @param handler Exception handler location.
 617 pnkfelix 1.1.2.5          */
 618 cananian 1.1.2.37         public StmCall(String retval, String retex, Exp func, String arglist,
 619 cananian 1.1.2.37                        String handler) {
 620 cananian 1.1.2.1              this.retval = retval; this.retex = retex; this.func = func;
 621 cananian 1.1.2.37             this.arglist = arglist; this.handler = handler;
 622 cananian 1.1.2.1          }
 623 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 624 cananian 1.1.2.42         public Stm build(ExpList kids) {
 625 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 626 cananian 1.1.2.42             return new StmCall(retval, retex, kids.head, arglist, handler);
 627 cananian 1.1.2.42         }
 628 cananian 1.1.2.42         public ExpList kids() { return new ExpList(func, null); }
 629 cananian 1.1.2.1          public String toString() {
 630 cananian 1.1.2.37             return "CALL("+retval+","+retex+","+func+","+arglist+","+
 631 cananian 1.1.2.37                            handler+")";
 632 cananian 1.1.2.1          }
 633 cananian 1.1.2.1      }
 634 pnkfelix 1.1.2.5  
 635 cananian 1.1.2.19     /** Extension of <code>Spec.Stm</code> representing a conditional
 636 pnkfelix 1.1.2.5          branch. 
 637 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.CJUMP
 638 pnkfelix 1.1.2.5      */
 639 cananian 1.1.2.2      public static class StmCjump extends Stm {
 640 pnkfelix 1.1.2.5          /** Boolean expression that decides which direction we're
 641 pnkfelix 1.1.2.5              jumping. */
 642 cananian 1.1.2.1          public final Exp test;
 643 pnkfelix 1.1.2.12         /** Label to branch to on a True value. 
 644 pnkfelix 1.1.2.12             @see harpoon.Temp.Label
 645 pnkfelix 1.1.2.12          */
 646 pnkfelix 1.1.2.5          public final String t_label;
 647 pnkfelix 1.1.2.12         /** Label to branch to on a False value. 
 648 pnkfelix 1.1.2.12             @see harpoon.Temp.Label
 649 pnkfelix 1.1.2.12          */
 650 pnkfelix 1.1.2.5          public final String f_label;
 651 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmCjump</code>.
 652 pnkfelix 1.1.2.5              @param test Text expression.
 653 pnkfelix 1.1.2.5              @param t_label True Label.
 654 pnkfelix 1.1.2.5              @param f_label False Label.
 655 pnkfelix 1.1.2.5          */
 656 cananian 1.1.2.1          public StmCjump(Exp test, String t_label, String f_label) {
 657 cananian 1.1.2.1              this.test = test; this.t_label = t_label; this.f_label = f_label;
 658 cananian 1.1.2.1          }
 659 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 660 cananian 1.1.2.42         public Stm build(ExpList kids) {
 661 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 662 cananian 1.1.2.42             return new StmCjump(kids.head, t_label, f_label);
 663 cananian 1.1.2.42         }
 664 cananian 1.1.2.42         public ExpList kids() { return new ExpList(test, null); }
 665 cananian 1.1.2.1          public String toString() {
 666 cananian 1.1.2.1              return "CJUMP("+test+","+t_label+","+f_label+")";
 667 cananian 1.1.2.19         }
 668 cananian 1.1.2.19     }
 669 cananian 1.1.2.19 
 670 cananian 1.1.2.19     /** Extension of <code>Spec.Stm</code> representing a raw datum in
 671 cananian 1.1.2.19         memory.
 672 cananian 1.1.2.38         @see harpoon.IR.Tree.DATUM
 673 cananian 1.1.2.19     */
 674 cananian 1.1.2.19     public static class StmData extends Stm {
 675 cananian 1.1.2.19         /** A <code>IR.Tree.CONST</code> or <code>IR.Tree.NAME</code>
 676 cananian 1.1.2.19             specifying the value with which to initialize this location.
 677 cananian 1.1.2.19         */
 678 cananian 1.1.2.19         public final Exp data;
 679 cananian 1.1.2.19         /** Constructs a new <code>Spec.StmData</code>.
 680 cananian 1.1.2.19             @param data Value expression.
 681 cananian 1.1.2.19         */
 682 cananian 1.1.2.19         public StmData(Exp data) {
 683 cananian 1.1.2.19             this.data = data;
 684 cananian 1.1.2.19         }
 685 cananian 1.1.2.19         public void accept(StmVisitor v) { v.visit(this); }
 686 cananian 1.1.2.42         public Stm build(ExpList kids) {
 687 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 688 cananian 1.1.2.42             return new StmData(kids.head);
 689 cananian 1.1.2.42         }
 690 cananian 1.1.2.42         public ExpList kids() { return new ExpList(data, null); }
 691 cananian 1.1.2.19         public String toString() {
 692 cananian 1.1.2.38             return "DATUM("+data+")";
 693 cananian 1.1.2.1          }
 694 pnkfelix 1.1.2.40         public boolean canBeRootOfData() { return true; }
 695 cananian 1.1.2.1      }
 696 pnkfelix 1.1.2.5  
 697 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> representing an expression
 698 pnkfelix 1.1.2.5          which is evaluated for its side effects (i.e. we throw away
 699 pnkfelix 1.1.2.5          the return value).
 700 jwhaley  1.1.2.44         @see harpoon.IR.Tree.EXPR
 701 pnkfelix 1.1.2.5      */
 702 cananian 1.1.2.2      public static class StmExp extends Stm {
 703 pnkfelix 1.1.2.5          /** Expression for <code>this</code>. */
 704 cananian 1.1.2.1          public final Exp exp;
 705 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmExp</code>.
 706 pnkfelix 1.1.2.5              @param exp Expression to be evaluated.
 707 pnkfelix 1.1.2.5          */
 708 cananian 1.1.2.1          public StmExp(Exp exp) { this.exp = exp; }
 709 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 710 cananian 1.1.2.42         public Stm build(ExpList kids) {
 711 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 712 cananian 1.1.2.42             return new StmExp(kids.head);
 713 cananian 1.1.2.42         }
 714 cananian 1.1.2.42         public ExpList kids() { return new ExpList(exp, null); }
 715 jwhaley  1.1.2.44         public String toString() { return "EXPR("+exp+")"; }
 716 cananian 1.1.2.1      }
 717 pnkfelix 1.1.2.5      
 718 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> representing an
 719 pnkfelix 1.1.2.5          unconditional branch.
 720 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.JUMP
 721 pnkfelix 1.1.2.5      */
 722 cananian 1.1.2.2      public static class StmJump extends Stm {
 723 pnkfelix 1.1.2.5          /** Expression which yields the target of this jump. */
 724 cananian 1.1.2.1          public final Exp exp;
 725 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmJump</code>.
 726 pnkfelix 1.1.2.5              @param exp Jump target.
 727 pnkfelix 1.1.2.5          */
 728 cananian 1.1.2.1          public StmJump(Exp exp) { this.exp = exp; }
 729 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 730 cananian 1.1.2.42         public Stm build(ExpList kids) {
 731 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 732 cananian 1.1.2.42             return new StmJump(kids.head);
 733 cananian 1.1.2.42         }
 734 cananian 1.1.2.42         public ExpList kids() { return new ExpList(exp, null); }
 735 cananian 1.1.2.1          public String toString() { return "JUMP("+exp+")"; }
 736 cananian 1.1.2.1      }
 737 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> representing a label which
 738 pnkfelix 1.1.2.5          is the target of a branch or call.
 739 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.LABEL
 740 pnkfelix 1.1.2.5      */
 741 cananian 1.1.2.2      public static class StmLabel extends Stm {
 742 pnkfelix 1.1.2.12         /** Label. 
 743 pnkfelix 1.1.2.12             @see harpoon.Temp.Label
 744 pnkfelix 1.1.2.12          */
 745 cananian 1.1.2.1          public final String name;
 746 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmLabel</code>.
 747 pnkfelix 1.1.2.5              @param name Label.
 748 pnkfelix 1.1.2.5          */
 749 cananian 1.1.2.1          public StmLabel(String name) { this.name = name; }
 750 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 751 cananian 1.1.2.42         public Stm build(ExpList kids) {
 752 cananian 1.3.2.1              assert kids==null;
 753 cananian 1.1.2.42             return new StmLabel(name);
 754 cananian 1.1.2.42         }
 755 cananian 1.1.2.42         public ExpList kids() { return null; }
 756 cananian 1.1.2.1          public String toString() { return "LABEL("+name+")"; }
 757 pnkfelix 1.1.2.40         public boolean canBeRootOfData() { return true; }
 758 cananian 1.1.2.1      }
 759 cananian 1.1.2.23     /** Extension of <code>Spec.Stm</code> representing a method header.
 760 pnkfelix 1.1.2.30      *  @see harpoon.IR.Tree.METHOD
 761 cananian 1.1.2.23      */
 762 cananian 1.1.2.23     public static class StmMethod extends Stm {
 763 cananian 1.1.2.23         /** Identifier name to get params field of <code>Tree.METHOD</code>. */
 764 cananian 1.1.2.23         public final String params;
 765 cananian 1.1.2.23         /** Constructs a new <code>Spec.StmMethod</code>.
 766 cananian 1.1.2.23          *  @param params Identifier to get params field of 
 767 cananian 1.1.2.23          *                <code>Tree.METHOD</code>.
 768 cananian 1.1.2.23          */
 769 cananian 1.1.2.23         public StmMethod(String params) { this.params = params; }
 770 cananian 1.1.2.23         public void accept(StmVisitor v) { v.visit(this); }
 771 cananian 1.1.2.42         public Stm build(ExpList kids) {
 772 cananian 1.3.2.1              assert kids==null;
 773 cananian 1.1.2.42             return new StmMethod(params);
 774 cananian 1.1.2.42         }
 775 cananian 1.1.2.42         public ExpList kids() { return null; }
 776 cananian 1.1.2.23         public String toString() { return "METHOD("+params+")"; }
 777 cananian 1.1.2.23     }
 778 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> representing an expression
 779 pnkfelix 1.1.2.5          which moves a value from one place to another.
 780 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.MOVE
 781 pnkfelix 1.1.2.5      */
 782 cananian 1.1.2.2      public static class StmMove extends Stm {
 783 cananian 1.1.2.11         /** The set of Types that <code>src</code> and <code>dst</code>
 784 cananian 1.1.2.11          *  may be (they will always be the same type). */
 785 cananian 1.1.2.11         public final TypeSet types;
 786 pnkfelix 1.1.2.5          /** Expression yielding the destination of this move. */
 787 pnkfelix 1.1.2.5          public final Exp dst;
 788 pnkfelix 1.1.2.5          /** Expression yielding the source data of this move. */
 789 pnkfelix 1.1.2.5          public final Exp src;
 790 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmMove</code>.
 791 pnkfelix 1.1.2.5              @param dst Destination expression.
 792 pnkfelix 1.1.2.5              @param src Source expression.
 793 pnkfelix 1.1.2.5          */
 794 cananian 1.1.2.11         public StmMove(TypeSet types, Exp dst, Exp src) {
 795 cananian 1.1.2.11             this.types = types; this.dst = dst; this.src = src;
 796 cananian 1.3.2.1              assert !types.containsSmall() : ("MOVE cannot be precisely typed: "+this);
 797 cananian 1.1.2.11         }
 798 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 799 cananian 1.1.2.42         public Stm build(ExpList kids) {
 800 cananian 1.3.2.1              assert kids!=null && kids.tail!=null && kids.tail.tail==null;
 801 cananian 1.1.2.42             return new StmMove((TypeSet)types.clone(),
 802 cananian 1.1.2.42                                kids.head, kids.tail.head);
 803 cananian 1.1.2.42         }
 804 cananian 1.1.2.42         public ExpList kids() {
 805 cananian 1.1.2.42             return new ExpList(dst, new ExpList(src, null));
 806 cananian 1.1.2.42         }
 807 cananian 1.1.2.11         public String toString() { return "MOVE"+types+"("+dst+","+src+")"; }
 808 cananian 1.1.2.1      }
 809 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> representing an expression
 810 pnkfelix 1.1.2.5          which is evaluated for its side effects (i.e. we throw away
 811 pnkfelix 1.1.2.5          the return value).
 812 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.NATIVECALL
 813 pnkfelix 1.1.2.5      */
 814 cananian 1.1.2.2      public static class StmNativeCall extends Stm {
 815 pnkfelix 1.1.2.12         /** Return value destination expression. 
 816 pnkfelix 1.1.2.30             @see harpoon.IR.Tree.Exp
 817 pnkfelix 1.1.2.12          */
 818 cananian 1.1.2.37         public final String retval;
 819 pnkfelix 1.1.2.12         /** Function location expression. 
 820 pnkfelix 1.1.2.30             @see harpoon.IR.Tree.Exp
 821 pnkfelix 1.1.2.12          */
 822 pnkfelix 1.1.2.5          public final Exp func;
 823 pnkfelix 1.1.2.12         /** Arguments being passed to procedure. 
 824 pnkfelix 1.1.2.34             @see harpoon.IR.Tree.TempList
 825 pnkfelix 1.1.2.12         */
 826 cananian 1.1.2.1          public final String arglist;
 827 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmNativeCall</code>.
 828 pnkfelix 1.1.2.5              @param retval Return value destination expression.
 829 pnkfelix 1.1.2.5              @param func Function location expression.
 830 pnkfelix 1.1.2.5              @param arglist Arguments.
 831 pnkfelix 1.1.2.5          */
 832 cananian 1.1.2.37         public StmNativeCall(String retval, Exp func, String arglist) {
 833 cananian 1.1.2.21             this.retval = retval; this.func = func;
 834 cananian 1.1.2.1              this.arglist = arglist;
 835 cananian 1.1.2.1          }
 836 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 837 cananian 1.1.2.42         public Stm build(ExpList kids) {
 838 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 839 cananian 1.1.2.42             return new StmNativeCall(retval, kids.head, arglist);
 840 cananian 1.1.2.42         }
 841 cananian 1.1.2.42         public ExpList kids() { return new ExpList(func, null); }
 842 cananian 1.1.2.1          public String toString() {
 843 cananian 1.1.2.21             return "NATIVECALL("+retval+","+func+","+arglist+")";
 844 cananian 1.1.2.1          }
 845 cananian 1.1.2.1      }
 846 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> representing an expression
 847 pnkfelix 1.1.2.5          which is evaluated for its side effects (i.e. we throw away
 848 pnkfelix 1.1.2.5          the return value).
 849 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.RETURN
 850 pnkfelix 1.1.2.5      */
 851 cananian 1.1.2.2      public static class StmReturn extends Stm {
 852 pnkfelix 1.1.2.5          /** The set of Types that <code>retval</code> may be. */
 853 cananian 1.1.2.1          public final TypeSet types;
 854 pnkfelix 1.1.2.5          /** Return value expression. */
 855 cananian 1.1.2.1          public final Exp retval;
 856 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmReturn</code>.
 857 pnkfelix 1.1.2.5              @param types Types that <code>retval</code> may be.
 858 pnkfelix 1.1.2.5              @param retval Return value. 
 859 pnkfelix 1.1.2.5          */
 860 cananian 1.1.2.1          public StmReturn(TypeSet types, Exp retval) {
 861 cananian 1.1.2.1              this.types = types; this.retval = retval;
 862 cananian 1.3.2.1              assert !types.containsSmall() : ("RETURN cannot be precisely typed: "+this);
 863 cananian 1.1.2.1          }
 864 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 865 cananian 1.1.2.42         public Stm build(ExpList kids) {
 866 cananian 1.3.2.1              assert kids!=null && kids.tail==null;
 867 cananian 1.1.2.42             return new StmReturn((TypeSet)types.clone(), kids.head);
 868 cananian 1.1.2.42         }
 869 cananian 1.1.2.42         public ExpList kids() { return new ExpList(retval, null); }
 870 cananian 1.1.2.1          public String toString() { return "RETURN"+types+"("+retval+")"; }
 871 cananian 1.1.2.1      }
 872 cananian 1.1.2.17 
 873 cananian 1.1.2.17     /** Extension of <code>Spec.Stm</code> representing a change of
 874 cananian 1.1.2.17      *  output segment.
 875 pnkfelix 1.1.2.30      *  @see harpoon.IR.Tree.SEGMENT
 876 cananian 1.1.2.17      */
 877 cananian 1.1.2.17     public static class StmSegment extends Stm {
 878 cananian 1.1.2.17         /** Type of segment. */
 879 cananian 1.1.2.17         public final Leaf segtype;
 880 cananian 1.1.2.17         /** Constructs a new <code>Spec.StmSegment</code>.
 881 cananian 1.1.2.17          *  @param segtype Segment type.
 882 cananian 1.1.2.17          */
 883 cananian 1.1.2.17         public StmSegment(Leaf segtype) { this.segtype = segtype; }
 884 cananian 1.1.2.17         public void accept(StmVisitor v) { v.visit(this); }
 885 cananian 1.1.2.42         public Stm build(ExpList kids) {
 886 cananian 1.3.2.1              assert kids==null;
 887 cananian 1.1.2.42             return new StmSegment(segtype/*immutable*/);
 888 cananian 1.1.2.42         }
 889 cananian 1.1.2.42         public ExpList kids() { return null; }
 890 cananian 1.1.2.17         public String toString() { return "SEGMENT("+segtype+")"; }
 891 pnkfelix 1.1.2.40         public boolean canBeRootOfData() { return true; }
 892 cananian 1.1.2.17     }
 893 cananian 1.1.2.17 
 894 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> representing a sequence of
 895 pnkfelix 1.1.2.5          statements to be executed in order.
 896 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.SEQ
 897 pnkfelix 1.1.2.5      */
 898 cananian 1.1.2.2      public static class StmSeq extends Stm {
 899 pnkfelix 1.1.2.5          /** First statement to execute. */
 900 pnkfelix 1.1.2.5          public final Stm s1;
 901 pnkfelix 1.1.2.5          /** Second statement to execute. */
 902 pnkfelix 1.1.2.5          public final Stm s2;
 903 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmSeq</code>. 
 904 pnkfelix 1.1.2.5              @param s1 First statement
 905 pnkfelix 1.1.2.5              @param s2 Second statement
 906 pnkfelix 1.1.2.5          */
 907 cananian 1.1.2.1          public StmSeq(Stm s1, Stm s2) { this.s1 = s1; this.s2 = s2; }
 908 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 909 cananian 1.1.2.42         public Stm build(ExpList kids) {
 910 cananian 1.1.2.42             throw new Error("build not valid for Seq");
 911 cananian 1.1.2.42         }
 912 cananian 1.1.2.42         public ExpList kids() {
 913 cananian 1.1.2.42             throw new Error("build not valid for Seq");
 914 cananian 1.1.2.42         }
 915 cananian 1.1.2.1          public String toString() { return "SEQ("+s1+","+s2+")"; }
 916 cananian 1.1.2.1      }
 917 pnkfelix 1.1.2.5  
 918 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Stm</code> representing a operation to
 919 pnkfelix 1.1.2.5          throw an exception.
 920 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.THROW
 921 pnkfelix 1.1.2.5      */
 922 cananian 1.1.2.2      public static class StmThrow extends Stm {
 923 pnkfelix 1.1.2.5          /** The exceptional value. */
 924 cananian 1.1.2.24         public final Exp retex;
 925 cananian 1.1.2.24         /** The location of the exception-handling code to return to. */
 926 cananian 1.1.2.24         public final Exp handler;
 927 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.StmThrow</code>.
 928 cananian 1.1.2.24             @param retex The exceptional value expression.
 929 cananian 1.1.2.24             @param handler The location of the exception-handling code.
 930 pnkfelix 1.1.2.5          */
 931 cananian 1.1.2.24         public StmThrow(Exp retex, Exp handler)
 932 cananian 1.1.2.24         { this.retex = retex; this.handler = handler; }
 933 cananian 1.1.2.24         /** Provisional: REMOVE this. */
 934 cananian 1.1.2.24         public StmThrow(Exp exp) { this.retex = exp; this.handler=null;}
 935 pnkfelix 1.1.2.9          public void accept(StmVisitor v) { v.visit(this); }
 936 cananian 1.1.2.42         public Stm build(ExpList kids) {
 937 cananian 1.3.2.1              assert kids!=null && kids.tail!=null && kids.tail.tail==null;
 938 cananian 1.1.2.42             return new StmThrow(kids.head, kids.tail.head);
 939 cananian 1.1.2.42         }
 940 cananian 1.1.2.42         public ExpList kids() {
 941 cananian 1.1.2.42             return new ExpList(retex, new ExpList(handler, null));
 942 cananian 1.1.2.42         }
 943 cananian 1.1.2.24         public String toString() { return "THROW("+retex+","+handler+")"; }
 944 cananian 1.1.2.1      }
 945 cananian 1.1.2.1  
 946 pnkfelix 1.1.2.12     /** Visitor class for traversing a set of <code>Spec.Leaf</code> objects 
 947 pnkfelix 1.1.2.12         and performing some action depending on the type of
 948 pnkfelix 1.1.2.12         <code>Spec.Leaf</code> visited.  Subclasses should implement a
 949 pnkfelix 1.1.2.12         <code>visit</code> method for generic <code>Spec.Leaf</code>s (ed. note: Leaves?) and
 950 pnkfelix 1.1.2.12         also override the <code>visit</code> method for subclasses of
 951 pnkfelix 1.1.2.12         <code>Spec.Leaf</code> that the subclass cares about.
 952 cananian 1.5              @see "<U>Design Patterns</U> pgs. 331-344"
 953 pnkfelix 1.1.2.12     */
 954 pnkfelix 1.1.2.12     public static abstract class LeafVisitor {
 955 pnkfelix 1.1.2.12         public abstract void visit(Leaf l);
 956 pnkfelix 1.1.2.12         public void visit(LeafId l) { visit((Leaf)l); }
 957 pnkfelix 1.1.2.12         public void visit(LeafOp l) { visit((Leaf)l); }
 958 cananian 1.1.2.22         public void visit(LeafNull l) { visit((Leaf)l); }
 959 pnkfelix 1.1.2.12         public void visit(LeafNumber l) { visit((Leaf)l); }
 960 cananian 1.1.2.18         public void visit(LeafSegType l) { visit((Leaf)l); }
 961 pnkfelix 1.1.2.12     }
 962 pnkfelix 1.1.2.12 
 963 pnkfelix 1.1.2.5      /** Abstract representation of leaves in the instruction pattern. */
 964 cananian 1.1.2.2      public static abstract class Leaf {
 965 cananian 1.1.2.1          public String toBop() { return this.toString(); }
 966 cananian 1.1.2.1          public String toUop() { return this.toString(); }
 967 pnkfelix 1.1.2.12 
 968 pnkfelix 1.1.2.12         /** Applies <code>v</code>'s <code>visit</code> method to
 969 pnkfelix 1.1.2.12             <code>this</code>.
 970 pnkfelix 1.1.2.12             This is effectively a gludge to emulate <B>multiple
 971 pnkfelix 1.1.2.12             dispatch</B>.  Must be reimplemented by all subclasses of
 972 pnkfelix 1.1.2.12             <code>Spec.Leaf</code>.
 973 pnkfelix 1.1.2.12             <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
 974 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
 975 pnkfelix 1.1.2.12         */
 976 cananian 1.1.2.35         public abstract void accept(Spec.LeafVisitor v);
 977 cananian 1.1.2.1      }
 978 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Leaf</code> which represents an
 979 pnkfelix 1.1.2.5          Identifier. */
 980 cananian 1.1.2.2      public static class LeafId extends Leaf {
 981 pnkfelix 1.1.2.5          /** Identifier string. */
 982 cananian 1.1.2.1          public final String id;
 983 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.LeafId</code>.
 984 pnkfelix 1.1.2.5              @param id Identifier string.
 985 pnkfelix 1.1.2.5          */
 986 cananian 1.1.2.1          public LeafId(String id) {
 987 cananian 1.1.2.1              this.id = id;
 988 cananian 1.1.2.1          }
 989 pnkfelix 1.1.2.12         /** Applies <code>v</code>'s <code>visit</code> method to
 990 pnkfelix 1.1.2.12             <code>this</code>.
 991 pnkfelix 1.1.2.12             This is effectively a gludge to emulate <B>multiple
 992 pnkfelix 1.1.2.12             dispatch</B>.  Must be reimplemented by all subclasses of
 993 pnkfelix 1.1.2.12             <code>Spec.Leaf</code>.
 994 pnkfelix 1.1.2.12             <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
 995 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
 996 pnkfelix 1.1.2.12         */
 997 pnkfelix 1.1.2.12         public void accept(Spec.LeafVisitor v) { v.visit(this); }
 998 cananian 1.1.2.1          public String toString() { return id; }
 999 cananian 1.1.2.22     }
1000 cananian 1.1.2.22     /** Extension of <code>Spec.Leaf</code> representing a null constant. */
1001 cananian 1.1.2.22     public static class LeafNull extends Leaf {
1002 cananian 1.1.2.22         /** Constructs a new <code>Spec.LeafNull</code>. */
1003 cananian 1.1.2.22         public LeafNull() { }
1004 cananian 1.1.2.22         public String toString() { return "null"; }
1005 cananian 1.1.2.22         public void accept(Spec.LeafVisitor v) { v.visit(this); }
1006 cananian 1.1.2.1      }
1007 cananian 1.1.2.8      /** Extension of <code>Spec.Leaf</code> representing an opcode
1008 cananian 1.1.2.8       *  for <code>Uop</code> and/or <code>Bop</code>.  */
1009 cananian 1.1.2.8      public static class LeafOp extends Leaf {
1010 cananian 1.1.2.8          /* Enumerated opcode. */
1011 cananian 1.1.2.8          public final int op;
1012 cananian 1.1.2.8          /** Constructs a new <code>Spec.LeafOp</code>.
1013 cananian 1.1.2.8              @param op Enumerated opcode.
1014 cananian 1.1.2.8          */
1015 cananian 1.1.2.8          public LeafOp(int op) {
1016 cananian 1.1.2.8              this.op = op;
1017 cananian 1.1.2.8          }
1018 cananian 1.1.2.8          public String toString() { return Integer.toString(op); }
1019 cananian 1.1.2.42         public String toBop() { return harpoon.IR.Tree.Bop.toString(op).toUpperCase(); }
1020 cananian 1.1.2.42         public String toUop() { return harpoon.IR.Tree.Uop.toString(op).toUpperCase(); }
1021 cananian 1.1.2.18         /** Applies <code>v</code>'s <code>visit</code> method to
1022 cananian 1.1.2.18             <code>this</code>.
1023 cananian 1.1.2.18             This is effectively a gludge to emulate <B>multiple
1024 cananian 1.1.2.18             dispatch</B>.  Must be reimplemented by all subclasses of
1025 cananian 1.1.2.18             <code>Spec.Leaf</code>.
1026 cananian 1.1.2.18             <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
1027 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
1028 cananian 1.1.2.18         */
1029 cananian 1.1.2.18         public void accept(Spec.LeafVisitor v) { v.visit(this); }
1030 cananian 1.1.2.18     }
1031 cananian 1.1.2.18     /** Extension of <code>Spec.Leaf</code> which represents a
1032 cananian 1.1.2.18         segment type in the specification.
1033 cananian 1.1.2.18     */
1034 cananian 1.1.2.18     public static class LeafSegType extends Leaf {
1035 cananian 1.1.2.18         /* Enumerated segment type. */
1036 cananian 1.1.2.18         public final int segtype;
1037 cananian 1.1.2.18         /** Constructs a new <code>Spec.LeafSegType</code>.
1038 cananian 1.1.2.18             @param segtype Segment type.
1039 cananian 1.1.2.18         */
1040 cananian 1.1.2.18         public LeafSegType(int segtype) {
1041 cananian 1.1.2.18             this.segtype = segtype;
1042 cananian 1.1.2.18         }
1043 cananian 1.1.2.18         public String toString() {
1044 pnkfelix 1.1.2.25             return harpoon.IR.Tree.SEGMENT.decode(segtype);
1045 cananian 1.1.2.18         }
1046 pnkfelix 1.1.2.12         /** Applies <code>v</code>'s <code>visit</code> method to
1047 pnkfelix 1.1.2.12             <code>this</code>.
1048 pnkfelix 1.1.2.12             This is effectively a gludge to emulate <B>multiple
1049 pnkfelix 1.1.2.12             dispatch</B>.  Must be reimplemented by all subclasses of
1050 pnkfelix 1.1.2.12             <code>Spec.Leaf</code>.
1051 pnkfelix 1.1.2.12             <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
1052 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
1053 pnkfelix 1.1.2.12         */
1054 pnkfelix 1.1.2.12         public void accept(Spec.LeafVisitor v) { v.visit(this); }
1055 cananian 1.1.2.8      }
1056 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Leaf</code> which represents a
1057 cananian 1.1.2.8          explicit number in the specification.
1058 pnkfelix 1.1.2.5      */
1059 cananian 1.1.2.2      public static class LeafNumber extends Leaf {
1060 pnkfelix 1.1.2.5          /** Number. */
1061 cananian 1.1.2.8          public final Number number;
1062 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.LeafNumber</code>.
1063 pnkfelix 1.1.2.5              @param number Number.
1064 pnkfelix 1.1.2.5          */
1065 cananian 1.1.2.8          public LeafNumber(Number number) {
1066 cananian 1.1.2.1              this.number = number;
1067 cananian 1.1.2.1          }
1068 cananian 1.1.2.8          public String toString() { return number.toString(); }
1069 pnkfelix 1.1.2.12         /** Applies <code>v</code>'s <code>visit</code> method to
1070 pnkfelix 1.1.2.12             <code>this</code>.
1071 pnkfelix 1.1.2.12             This is effectively a gludge to emulate <B>multiple
1072 pnkfelix 1.1.2.12             dispatch</B>.  Must be reimplemented by all subclasses of
1073 pnkfelix 1.1.2.12             <code>Spec.Leaf</code>.
1074 pnkfelix 1.1.2.12             <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
1075 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
1076 pnkfelix 1.1.2.12         */
1077 pnkfelix 1.1.2.12         public void accept(Spec.LeafVisitor v) { v.visit(this); }
1078 cananian 1.1.2.1      }
1079 cananian 1.1.2.1  
1080 pnkfelix 1.1.2.9  
1081 pnkfelix 1.1.2.9      /** Visitor class for traversing a set of <code>Spec.Detail</code>s
1082 pnkfelix 1.1.2.9          and performing some action depending on the type of
1083 pnkfelix 1.1.2.9          <code>Spec.Detail</code> visited.  Subclasses should implement a
1084 pnkfelix 1.1.2.9          <code>visit</code> method for generic <code>Detail</code>s and
1085 pnkfelix 1.1.2.9          also override the <code>visit</code> method for subclasses of
1086 pnkfelix 1.1.2.9          <code>Detail</code> that the subclass cares about.
1087 cananian 1.5              @see "<U>Design Patterns</U> pgs. 331-344"
1088 pnkfelix 1.1.2.9      */
1089 pnkfelix 1.1.2.9      public static abstract class DetailVisitor {
1090 pnkfelix 1.1.2.9          public abstract void visit(Detail d);
1091 pnkfelix 1.1.2.9          public void visit(DetailExtra d) { visit((Detail)d); }
1092 pnkfelix 1.1.2.9          public void visit(DetailPredicate d) { visit((Detail)d); }
1093 pnkfelix 1.1.2.9          public void visit(DetailWeight d) { visit((Detail)d); }
1094 pnkfelix 1.1.2.14         /** Visits elements of <code>l</code>.
1095 pnkfelix 1.1.2.14             If (l!=null) visits l.head then l.tail.  Else does nothing.
1096 pnkfelix 1.1.2.14         */
1097 pnkfelix 1.1.2.14         public void visit(DetailList l) { 
1098 pnkfelix 1.1.2.14             if(l!=null){l.head.accept(this); visit(l.tail);}
1099 pnkfelix 1.1.2.14         }
1100 pnkfelix 1.1.2.9      }
1101 pnkfelix 1.1.2.9  
1102 pnkfelix 1.1.2.5      /** A detail is an abstract representation for a piece of data
1103 pnkfelix 1.1.2.5          about the Instruction Pattern or <code>Rule</code>.  Details
1104 pnkfelix 1.1.2.5          include predicates, speed-costs, size-costs...
1105 pnkfelix 1.1.2.5      */
1106 pnkfelix 1.1.2.9      public static abstract class Detail { 
1107 pnkfelix 1.1.2.9  
1108 pnkfelix 1.1.2.9          /** Applies <code>v</code>'s <code>visit</code> method to
1109 pnkfelix 1.1.2.9              <code>this</code>.  This is effectively a gludge to
1110 pnkfelix 1.1.2.9              emulate <B>multiple dispatch</B>.  Must be reimplemented
1111 pnkfelix 1.1.2.9              by all subclasses of <code>Spec.Detail</code>.
1112 pnkfelix 1.1.2.9              <BR> <B>effects:</B> Calls <code>v.visit(this)</code>. 
1113 cananian 1.5                  @see "<U>Design Patterns</U> pgs. 331-344"
1114 pnkfelix 1.1.2.9          */
1115 cananian 1.1.2.35         public abstract void accept(DetailVisitor v);
1116 pnkfelix 1.1.2.9      }
1117 pnkfelix 1.1.2.5  
1118 cananian 1.1.2.7      /** Extension of <code>Spec.Detail</code> that requests an extra
1119 cananian 1.1.2.7       *  temporary register for the use of the action clause.  For example,
1120 cananian 1.1.2.7       *  if multiplying two 32-bit registers generates a 64-bit result on
1121 cananian 1.1.2.7       *  the target architecture, you might need to request an extra
1122 cananian 1.1.2.7       *  <code>Temp</code> to have a place to put the high word of the
1123 cananian 1.1.2.7       *  result (before you throw it away). The <code>DetailExtra</code>
1124 cananian 1.1.2.7       *  element contains a list of identifiers naming the working temps
1125 pnkfelix 1.1.2.15      *  that you are requesting. 
1126 pnkfelix 1.1.2.15      * 
1127 pnkfelix 1.1.2.15      *  <P> <B>syntax:</B> <code> %extra { </code> ID-LIST <code> } </code>
1128 pnkfelix 1.1.2.15      */
1129 cananian 1.1.2.2      public static class DetailExtra extends Detail {
1130 cananian 1.1.2.43         public final int type;
1131 cananian 1.1.2.1          public final IdList extras;
1132 cananian 1.1.2.43         public DetailExtra(int type, IdList extras) {
1133 cananian 1.1.2.43             this.type = type; this.extras = extras;
1134 cananian 1.1.2.1          }
1135 pnkfelix 1.1.2.14         /** Applies <code>v</code>'s <code>visit</code> method to <code>this</code>. */
1136 pnkfelix 1.1.2.9          public void accept(DetailVisitor v) { v.visit(this); }
1137 cananian 1.1.2.1          public String toString() {
1138 cananian 1.1.2.43             return "%extra"+new TypeSet(type)+"{"+((extras==null)?"":extras.toString())+"}";
1139 cananian 1.1.2.1          }
1140 cananian 1.1.2.1      }
1141 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Detail</code> that stores a
1142 pnkfelix 1.1.2.5          <code>predicate_string</code> which is a piece of Java code
1143 pnkfelix 1.1.2.5          that decides if a particular <code>Spec.Rule</code> can be
1144 pnkfelix 1.1.2.5          applied. 
1145 pnkfelix 1.1.2.15 
1146 pnkfelix 1.1.2.15         <P> <B>syntax:</B> <code> %pred %( </code> BOOLEAN-EXPRESSION <code> )% </code>
1147 pnkfelix 1.1.2.5      */
1148 cananian 1.1.2.2      public static class DetailPredicate extends Detail {
1149 cananian 1.1.2.1          public final String predicate_string;
1150 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.DetailPredicate</code>. 
1151 pnkfelix 1.1.2.5              <BR> <B>requires:</B> <code> predicate_string is a valid
1152 pnkfelix 1.1.2.5                   Java expression that will evaluate to a boolean
1153 pnkfelix 1.1.2.5                   value.  
1154 pnkfelix 1.1.2.5              @param predicate_string Predicate to check for
1155 pnkfelix 1.1.2.5                     applicability of <code>Spec.Rule</code>
1156 pnkfelix 1.1.2.5          */
1157 cananian 1.1.2.1          public DetailPredicate(String predicate_string) {
1158 cananian 1.1.2.1              this.predicate_string = predicate_string;
1159 cananian 1.1.2.1          }
1160 pnkfelix 1.1.2.9          public void accept(DetailVisitor v) { v.visit(this); }
1161 cananian 1.1.2.1          public String toString() { return "%pred %("+predicate_string+")%"; }
1162 cananian 1.1.2.1      }
1163 pnkfelix 1.1.2.5  
1164 pnkfelix 1.1.2.5      /** Extension of <code>Spec.Detail</code> that stores a 
1165 pnkfelix 1.1.2.5          (name,weight) pair.  This weight can be used by the
1166 pnkfelix 1.1.2.5          Instruction Generator to choose one pattern over another if
1167 pnkfelix 1.1.2.5          it is attempting to optimize for the property 
1168 pnkfelix 1.1.2.5          (speed, size, etc) given in <code>name</code>.
1169 pnkfelix 1.1.2.15 
1170 pnkfelix 1.1.2.15         <P> <B>syntax:</B> <code> %weight &lt; </code> ID <code> , </code> WEIGHT <code> &gt; </code>
1171 pnkfelix 1.1.2.5      */
1172 cananian 1.1.2.2      public static class DetailWeight extends Detail {
1173 pnkfelix 1.1.2.5          /** Describes what metric <code>value</code> is measuring. */
1174 cananian 1.1.2.1          public final String name;
1175 pnkfelix 1.1.2.5          /** The weight associated with <code>name</code>. */
1176 cananian 1.1.2.8          public final double value;
1177 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.DetailWeight</code>.
1178 pnkfelix 1.1.2.5              @param name Metric that <code>value</code> is measuring.
1179 pnkfelix 1.1.2.5              @param value Weight associated with <code>name</code>.
1180 pnkfelix 1.1.2.5          */
1181 cananian 1.1.2.8          public DetailWeight(String name, double value) {
1182 cananian 1.1.2.1              this.name = name; this.value = value;
1183 cananian 1.1.2.1          }
1184 pnkfelix 1.1.2.9          public void accept(DetailVisitor v) { v.visit(this); }
1185 cananian 1.1.2.1          public String toString() { return "%weight<"+name+","+value+">"; }
1186 cananian 1.1.2.1      }
1187 cananian 1.1.2.1  
1188 pnkfelix 1.1.2.5      /** A representation for storing Types that values can be. 
1189 pnkfelix 1.1.2.15         
1190 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.Type
1191 pnkfelix 1.1.2.30         @see harpoon.IR.Tree.PreciselyTyped
1192 pnkfelix 1.1.2.5       */
1193 cananian 1.1.2.2      public static class TypeSet {
1194 pnkfelix 1.1.2.27         // maps Type->boolean
1195 pnkfelix 1.1.2.27         final BitString bs;
1196 pnkfelix 1.1.2.27         
1197 pnkfelix 1.1.2.27         // maps ( bitLength - 1 )->boolean
1198 pnkfelix 1.1.2.27         // (should only be on if this.contains(PreciseType.SMALL))
1199 pnkfelix 1.1.2.27         final BitString unsignedPrecises;
1200 pnkfelix 1.1.2.27 
1201 pnkfelix 1.1.2.27         // maps ( bitLength - 1 )->boolean
1202 pnkfelix 1.1.2.27         // (should only be on if this.contains(PreciseType.SMALL))
1203 pnkfelix 1.1.2.27         final BitString signedPrecises;
1204 pnkfelix 1.1.2.27 
1205 pnkfelix 1.1.2.5          /** Constructs a new <code>Spec.TypeSet</code>. */
1206 pnkfelix 1.1.2.27         public TypeSet() {
1207 cananian 1.1.2.39             bs = new BitString(5);//ACK: too tightly coupled to Tree.Type
1208 pnkfelix 1.1.2.27             unsignedPrecises = new BitString(32);
1209 pnkfelix 1.1.2.27             signedPrecises = new BitString(32);
1210 pnkfelix 1.1.2.41         }
1211 pnkfelix 1.1.2.41 
1212 pnkfelix 1.1.2.41         /** Constructs a new <code>Spec.TypeSet</code> with type <code>t</code>. */
1213 cananian 1.1.2.42         public TypeSet(int t) { this(); set(t); }
1214 cananian 1.1.2.42 
1215 cananian 1.1.2.42         /** Constructs a new <code>Spec.TypeSet</code> with the same
1216 cananian 1.1.2.42          *  contents as the supplied <code>Spec.TypeSet</code>. */
1217 cananian 1.1.2.42         public TypeSet(TypeSet ts) {
1218 cananian 1.1.2.42             this.bs = (BitString) ts.bs.clone();
1219 cananian 1.1.2.42             this.unsignedPrecises = (BitString) ts.unsignedPrecises.clone();
1220 cananian 1.1.2.42             this.signedPrecises = (BitString) ts.signedPrecises.clone();
1221 pnkfelix 1.1.2.27         }
1222 cananian 1.1.2.42 
1223 cananian 1.1.2.42         /** Clones a <code>Spec.TypeSet</code>. */
1224 cananian 1.1.2.42         public Object clone() { return new TypeSet(this); }
1225 pnkfelix 1.1.2.5          
1226 pnkfelix 1.1.2.5          /** Checks if <code>this</code> contains <code>type</code>.
1227 pnkfelix 1.1.2.5              <BR> <B>effects:</B> Returns true if <code>type</code> has
1228 pnkfelix 1.1.2.5                   been turned on by a call to <code>set(type)</code> or
1229 pnkfelix 1.1.2.5                   <code>setAll()</code>.  Else returns false.
1230 pnkfelix 1.1.2.5          */
1231 cananian 1.1.2.1          public boolean contains(int type) {
1232 cananian 1.1.2.1              return bs.get(type);
1233 cananian 1.1.2.1          }
1234 cananian 1.1.2.28         /** Returns true if <code>this</code> contains any small types. */
1235 cananian 1.1.2.28         public boolean containsSmall() {
1236 cananian 1.1.2.29             return !(unsignedPrecises.isZero() && signedPrecises.isZero());
1237 cananian 1.1.2.29         }
1238 cananian 1.1.2.29         /** Returns true if <code>this</code> contains the specified
1239 cananian 1.1.2.29          *  signed precise type. */
1240 cananian 1.1.2.29         public boolean containsSigned(int bitwidth) {
1241 cananian 1.1.2.29             return signedPrecises.get(bitwidth-1);
1242 cananian 1.1.2.29         }
1243 cananian 1.1.2.29         /** Returns true if <code>this</code> contains the specified
1244 cananian 1.1.2.29          *  unsigned precise type. */
1245 cananian 1.1.2.29         public boolean containsUnsigned(int bitwidth) {
1246 cananian 1.1.2.29             return unsignedPrecises.get(bitwidth-1);
1247 cananian 1.1.2.28         }
1248 cananian 1.1.2.28 
1249 pnkfelix 1.1.2.5          /** Records that <code>this</code> contains
1250 pnkfelix 1.1.2.5              <code>type</code>.  
1251 pnkfelix 1.1.2.5          */
1252 cananian 1.1.2.1          public void set(int type) {
1253 cananian 1.1.2.1              bs.set(type);
1254 cananian 1.1.2.26         }
1255 cananian 1.1.2.26 
1256 pnkfelix 1.1.2.27         /** Recordes that <code>this</code> contains
1257 pnkfelix 1.1.2.27             a signed, specific precise type value
1258 pnkfelix 1.1.2.27             <BR> <B>requires:</B>  1 <= numBits <= 32
1259 pnkfelix 1.1.2.27             @param numBits The bit length of the type. 
1260 pnkfelix 1.1.2.27         */
1261 pnkfelix 1.1.2.27         public void setSignedPrecise(int numBits) {
1262 cananian 1.3.2.1              assert (numBits <= 32) && (numBits >= 1) : ("invalid bit length:"+numBits);
1263 pnkfelix 1.1.2.27             signedPrecises.set(numBits-1);
1264 pnkfelix 1.1.2.27         }
1265 pnkfelix 1.1.2.27 
1266 pnkfelix 1.1.2.27         /** Recordes that <code>this</code> contains
1267 pnkfelix 1.1.2.27             an unsigned, specific precise type value
1268 pnkfelix 1.1.2.27             <BR> <B>requires:</B>  1 <= numBits <= 32
1269 pnkfelix 1.1.2.27             @param numBits The bit length of the type. 
1270 pnkfelix 1.1.2.27         */
1271 pnkfelix 1.1.2.27         public void setUnsignedPrecise(int numBits) {
1272 cananian 1.3.2.1              assert (numBits <= 32) && (numBits >= 1) : ("invalid bit length:"+numBits);
1273 pnkfelix 1.1.2.27             unsignedPrecises.set(numBits-1);
1274 pnkfelix 1.1.2.27         }
1275 pnkfelix 1.1.2.27         
1276 cananian 1.1.2.26         /** Adds all the types contained in <code>TypeSet</code>
1277 cananian 1.1.2.26          *  <code>ts</code> to <code>this</code>.
1278 cananian 1.1.2.26          */
1279 cananian 1.1.2.26         public void addAll(TypeSet ts) {
1280 cananian 1.1.2.26             bs.or(ts.bs);
1281 cananian 1.1.2.31             signedPrecises.or(ts.signedPrecises);
1282 cananian 1.1.2.31             unsignedPrecises.or(ts.unsignedPrecises);
1283 cananian 1.1.2.1          }
1284 pnkfelix 1.1.2.5          
1285 pnkfelix 1.1.2.27         /** Records that <code>this</code> contains all five basic
1286 pnkfelix 1.1.2.27             Types,  { INT, LONG, FLOAT, DOUBLE, POINTER }.
1287 pnkfelix 1.1.2.27             Note that it does not set any bits for the PreciseTypes.
1288 pnkfelix 1.1.2.5          */
1289 pnkfelix 1.1.2.5          public void setAll() { 
1290 cananian 1.1.2.1              set(harpoon.IR.Tree.Type.INT);
1291 cananian 1.1.2.1              set(harpoon.IR.Tree.Type.LONG);
1292 cananian 1.1.2.1              set(harpoon.IR.Tree.Type.FLOAT);
1293 cananian 1.1.2.1              set(harpoon.IR.Tree.Type.DOUBLE);
1294 cananian 1.1.2.1              set(harpoon.IR.Tree.Type.POINTER);
1295 cananian 1.1.2.1          }
1296 cananian 1.1.2.1          public String toString() {
1297 cananian 1.1.2.1              StringBuffer sb = new StringBuffer();
1298 pnkfelix 1.1.2.27             if (contains(Type.INT))     sb.append(",i");
1299 pnkfelix 1.1.2.27             if (contains(Type.LONG))    sb.append(",l");
1300 pnkfelix 1.1.2.27             if (contains(Type.FLOAT))   sb.append(",f");
1301 pnkfelix 1.1.2.27             if (contains(Type.DOUBLE))  sb.append(",d");
1302 pnkfelix 1.1.2.27             if (contains(Type.POINTER)) sb.append(",p");
1303 cananian 1.1.2.28             for(int i=0; i<32; i++)
1304 cananian 1.1.2.28                 if(unsignedPrecises.get(i))
1305 cananian 1.1.2.28                     sb.append(",u:"+(i+1));
1306 cananian 1.1.2.28             for(int i=0; i<32; i++)
1307 cananian 1.1.2.28                 if(signedPrecises.get(i))
1308 cananian 1.1.2.28                     sb.append(",s:"+(i+1));
1309 cananian 1.1.2.1              if (sb.length()>0) sb.setCharAt(0, '<'); else sb.append('<');
1310 cananian 1.1.2.1              sb.append('>');
1311 cananian 1.1.2.1              return sb.toString();
1312 cananian 1.1.2.1          }
1313 cananian 1.1.2.1      }
1314 pnkfelix 1.1.2.5  
1315 pnkfelix 1.1.2.5      /** Linked list representation for representing the series of
1316 pnkfelix 1.1.2.5          <code>Spec.Rule</code>s in this <code>Spec</code>.  
1317 pnkfelix 1.1.2.5      */
1318 cananian 1.1.2.2      public static class RuleList {
1319 cananian 1.1.2.1          public final Rule head;
1320 cananian 1.1.2.1          public final RuleList tail;
1321 cananian 1.1.2.1          public RuleList(Rule head, RuleList tail) {
1322 cananian 1.1.2.1              this.head = head; this.tail = tail;
1323 cananian 1.1.2.1          }
1324 cananian 1.1.2.1          public String toString() {
1325 cananian 1.1.2.1              if (tail==null) return head.toString();
1326 cananian 1.1.2.1              else return head.toString() + "\n" + tail.toString();
1327 cananian 1.1.2.1          }
1328 pnkfelix 1.1.2.14         /** Applies <code>v</code>'s <code>visit</code> method to <code>this</code>. */
1329 pnkfelix 1.1.2.14         public void accept(RuleVisitor v) { v.visit(this); }
1330 cananian 1.1.2.1      }
1331 pnkfelix 1.1.2.5  
1332 cananian 1.1.2.42     /** Linked list representation for representing the series of
1333 cananian 1.1.2.42      *  <code>Spec.Exp</code>s in a given <code>Spec.Exp</code> or
1334 cananian 1.1.2.42      *  <code>Spec.Stm</code>.
1335 cananian 1.1.2.42      */
1336 cananian 1.1.2.42     public static class ExpList {
1337 cananian 1.1.2.42         public final Exp head;
1338 cananian 1.1.2.42         public final ExpList tail;
1339 cananian 1.1.2.42         public ExpList(Exp head, ExpList tail) {
1340 cananian 1.1.2.42             this.head = head; this.tail = tail;
1341 cananian 1.1.2.42         }
1342 cananian 1.1.2.42         public String toString() {
1343 cananian 1.1.2.42             if (tail==null) return head.toString();
1344 cananian 1.1.2.42             else return head.toString() + " " + tail.toString();
1345 cananian 1.1.2.42         }
1346 cananian 1.1.2.42     }
1347 pnkfelix 1.1.2.5      /** Linked list representation for representing the series of
1348 pnkfelix 1.1.2.5          <code>Spec.Detail</code>s in this <code>Spec</code>.  
1349 pnkfelix 1.1.2.5      */
1350 cananian 1.1.2.2      public static class DetailList {
1351 cananian 1.1.2.1          public final Detail head;
1352 cananian 1.1.2.1          public final DetailList tail;
1353 cananian 1.1.2.1          public DetailList(Detail head, DetailList tail) {
1354 cananian 1.1.2.1              this.head = head; this.tail = tail;
1355 cananian 1.1.2.1          }
1356 cananian 1.1.2.1          public String toString() {
1357 cananian 1.1.2.1              if (tail==null) return head.toString();
1358 cananian 1.1.2.1              else return head.toString() + " " + tail.toString();
1359 cananian 1.1.2.1          }
1360 pnkfelix 1.1.2.14         public void accept(DetailVisitor v) { v.visit(this); }
1361 cananian 1.1.2.1      }
1362 pnkfelix 1.1.2.5  
1363 pnkfelix 1.1.2.5      /** Linked list representation for representing a series of
1364 pnkfelix 1.1.2.5          Identifier <code>String</code>s in this <code>Spec</code>. 
1365 pnkfelix 1.1.2.5      */
1366 cananian 1.1.2.2      public static class IdList {
1367 cananian 1.1.2.1          public final String head;
1368 cananian 1.1.2.1          public final IdList tail;
1369 cananian 1.1.2.1          public IdList(String head, IdList tail) {
1370 cananian 1.1.2.1              this.head = head; this.tail = tail;
1371 cananian 1.1.2.1          }
1372 cananian 1.1.2.1          public String toString() {
1373 cananian 1.1.2.1              if (tail==null) return head;
1374 cananian 1.1.2.1              else return head + "," + tail.toString();
1375 cananian 1.1.2.1          }
1376 cananian 1.1.2.1      }
1377 cananian 1.2      }