1 cananian 1.14.2.10 // Temp.java, created Tue Jul 28  1:09:44 1998 by cananian
  2 cananian 1.13      // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.13      // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.2       package harpoon.Temp;
  5 cananian 1.1       
  6 cananian 1.14.2.16 import java.util.HashMap;
  7 cananian 1.14.2.16 import java.util.Map;
  8 cananian 1.14.2.1  import harpoon.Util.ArrayFactory;
  9 cananian 1.18      import net.cscott.jutil.ReferenceUnique;
 10 pnkfelix 1.14.2.13 import harpoon.Util.Util;
 11 cananian 1.1       
 12 cananian 1.1       /** 
 13 cananian 1.6        * The <code>Temp</code> class represents a temporary
 14 cananian 1.1        * variable.  This class maintains static state to allow us to allocate
 15 cananian 1.1        * guaranteed-unique names for our temps.
 16 cananian 1.1        *
 17 cananian 1.4        * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 18 cananian 1.18       * @version $Id: Temp.java,v 1.18 2004/02/08 01:59:47 cananian Exp $
 19 cananian 1.11       * @see harpoon.Analysis.Maps.TypeMap
 20 cananian 1.11       * @see harpoon.Analysis.Maps.ConstMap
 21 cananian 1.1        * @see TempList
 22 cananian 1.1        */
 23 cananian 1.16.2.2  public class Temp implements Cloneable, Comparable<Temp>, ReferenceUnique, java.io.Serializable {
 24 cananian 1.16.2.3    final TempFactory tf;
 25 cananian 1.16.2.3    final String name;
 26 cananian 1.16.2.3    final int hashcode;
 27 cananian 1.1       
 28 cananian 1.18        /** A <code>net.cscott.jutil.Indexer</code> specifically for working
 29 cananian 1.14.2.18       <b>only</b> with <code>Temp</code>s generated by
 30 pnkfelix 1.14.2.17       <code>this.tempFactory()</code>. 
 31 pnkfelix 1.14.2.17   */
 32 cananian 1.18        public static net.cscott.jutil.Indexer INDEXER = 
 33 cananian 1.18          new net.cscott.jutil.Indexer() {
 34 pnkfelix 1.14.2.17       public int getID(Object o) {
 35 pnkfelix 1.14.2.17         return ((Temp)o).id;
 36 pnkfelix 1.14.2.17       }
 37 pnkfelix 1.14.2.17     };
 38 pnkfelix 1.14.2.17   private int id;
 39 cananian 1.1       
 40 cananian 1.14.2.4    /** Default temp name. */
 41 cananian 1.14.2.4    private static final String default_name = "t";
 42 cananian 1.1       
 43 cananian 1.8         /** Creates a unique temporary variable, using default prefix ("t").
 44 cananian 1.1          */
 45 cananian 1.14.2.4    public Temp(final TempFactory tf) { 
 46 cananian 1.14.2.4      this(tf, null); /* use default prefix. */
 47 cananian 1.14.2.4    }
 48 cananian 1.14.2.4    /** Creates a new temp based on the name of an existing temp. */
 49 cananian 1.14.2.4    public Temp(final Temp t) {
 50 cananian 1.14.2.4      this(t.tf, t.name);
 51 cananian 1.1         }
 52 cananian 1.6         /** Creates a unique temporary with a suggested name.
 53 cananian 1.14.2.4     *  Trailing digits will be stripped from the suggested name,
 54 cananian 1.14.2.4     *  and a digit string will be appended to make the name unique
 55 cananian 1.14.2.4     *  within the scope of the <code>TempFactory</code>.
 56 cananian 1.14.2.4     *  @param prefix the name prefix.
 57 cananian 1.14.2.4     *                  <code>prefix</code> may not be null.
 58 cananian 1.1          */
 59 cananian 1.14.2.4    public Temp(final TempFactory tf, final String prefix) {
 60 cananian 1.16.2.1      assert tf != null : "TempFactory cannot be null";
 61 cananian 1.14.2.4      this.tf = tf;
 62 cananian 1.14.2.4      this.name = tf.getUniqueID(prefix!=null?prefix:default_name);
 63 cananian 1.14.2.4      this.hashcode = tf.getScope().hashCode() ^ name.hashCode();
 64 pnkfelix 1.14.2.17     this.id = tf.newID();
 65 cananian 1.1         }
 66 cananian 1.1       
 67 cananian 1.14.2.4    /** Returns the full name of this temporary, including scope information. */
 68 cananian 1.14.2.4    public String fullname() { return tf.getScope()+":"+name; }
 69 cananian 1.1       
 70 cananian 1.14.2.4    /** Returns the common name of this <code>Temp</code>; scope information
 71 cananian 1.14.2.4     *  not included. */
 72 cananian 1.14.2.4    public String name() { return name; }
 73 cananian 1.1         /** Returns a string representation of this temporary. */
 74 cananian 1.14.2.4    public String toString() { return name; }
 75 cananian 1.14.2.6    /** Returns the tempFactory of this temporary. */
 76 cananian 1.14.2.6    public TempFactory tempFactory() { return tf; }
 77 cananian 1.14      
 78 cananian 1.14.2.5    /** Clones a <code>Temp</code> into a different <code>TempFactory</code>. */
 79 cananian 1.14.2.5    public Temp clone(TempFactory tf) {
 80 cananian 1.14.2.5      return new Temp(tf, this.name);
 81 cananian 1.14.2.5    }
 82 cananian 1.14.2.5    /** Clones a <code>Temp</code> using the same <code>TempFactory</code>. */
 83 cananian 1.18        public Temp clone() { return clone(this.tf); }
 84 cananian 1.14      
 85 cananian 1.14        /** Returns a hashcode for this temporary.
 86 cananian 1.14.2.4     *  The hashcode is formed from the scope name and the temporary name.
 87 cananian 1.14         */
 88 cananian 1.14.2.4    public int hashCode() { return hashcode; }
 89 cananian 1.14.2.9  
 90 cananian 1.14.2.9    /** Comparable interface: sorted by fullname(). */
 91 cananian 1.16.2.2    public int compareTo(Temp o) {
 92 cananian 1.16.2.2      return fullname().compareTo(o.fullname());
 93 cananian 1.14.2.9    }
 94 cananian 1.14.2.4  
 95 cananian 1.14.2.4    /** Returns a new <code>TempFactory</code> with the given scope. */
 96 cananian 1.14.2.4    public static TempFactory tempFactory(final String scope) {
 97 cananian 1.14.2.18     abstract class SerializableTempFactory extends TempFactory
 98 cananian 1.14.2.18       implements java.io.Serializable { /* only declare inheritance */ }
 99 cananian 1.14.2.18     return new SerializableTempFactory() {
100 cananian 1.14.2.16       // declare table as HashMap, not Map, for slight efficiency gain.
101 cananian 1.14.2.16       private final HashMap table = new HashMap();
102 cananian 1.14.2.4        public String getScope() { return scope; }
103 andyb    1.14.2.8        protected synchronized String getUniqueID(String suggestion) {
104 cananian 1.14.2.4          // strip digits from the end of the suggestion.
105 cananian 1.14.2.15         int lastchar = suggestion.length();
106 cananian 1.14.2.15         char c;
107 cananian 1.14.2.15         do {
108 cananian 1.14.2.15           c = suggestion.charAt(--lastchar);
109 cananian 1.14.2.15         } while (c >= '0' && c <= '9');
110 cananian 1.14.2.15         suggestion = suggestion.substring(0, 1+lastchar);
111 cananian 1.14.2.4          // look up appropriate suffix.
112 cananian 1.14.2.4          Integer i = (Integer) table.get(suggestion);
113 cananian 1.14.2.4          if (i==null) i = new Integer(0);
114 cananian 1.14.2.4          // update the table.
115 cananian 1.14.2.4          table.put(suggestion, new Integer(i.intValue()+1));
116 cananian 1.14.2.4          // return the unique identifier.
117 cananian 1.14.2.4          return suggestion+i;
118 cananian 1.14.2.4        }
119 cananian 1.14.2.4      };
120 cananian 1.14.2.4    }
121 cananian 1.14.2.1  
122 cananian 1.14.2.1    // Array Factory interface:
123 cananian 1.14.2.1  
124 cananian 1.14.2.1    /** Returns an array of <code>Temp</code>s. */
125 cananian 1.16.2.2    public static final ArrayFactory<Temp> arrayFactory =
126 cananian 1.16.2.2      new ArrayFactory<Temp>() {
127 cananian 1.16.2.2        public Temp[] newArray(int len) { return new Temp[len]; }
128 cananian 1.14.2.1      };
129 cananian 1.14.2.1    /** Returns an array of <code>Temp[]</code>s. */
130 cananian 1.16.2.2    public static final ArrayFactory<Temp[]> doubleArrayFactory =
131 cananian 1.16.2.2      new ArrayFactory<Temp[]>() {
132 cananian 1.16.2.2        public Temp[][] newArray(int len) { return new Temp[len][]; }
133 cananian 1.14.2.1      };
134 cananian 1.12      
135 cananian 1.1       }
136 cananian 1.6       // set emacs indentation style.
137 cananian 1.6       // Local Variables:
138 cananian 1.6       // c-basic-offset:2
139 cananian 1.6       // End: