import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; import java.io.Reader; import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.TreeMap; import java.util.Properties; import java.util.Random; import java.util.Set; import java.util.logging.Level; /** * Implements a <em>temporary variables pool</em>, providing methods to * retrieve free variables from the pool, reset the pool and generate * Java declarations for the variables. * * @layer<bali2javacc> */ public class Variables { final public String LOWER = "abcdefghijklmnopqrstuvwxyz" ; final public String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; public Variables() { this.declarations = new ArrayList() ; this.prefixSet = new HashSet() ; this.random = new Random( 0L ) ; this.typeMap = new TreeMap() ; this.usedSet = new HashSet() ; } public String declare( String type, String name, String value ) { declarations.add( type + ' ' + name + " = " + value ) ; return name ; } public String getFree( String type ) { TypeData data = ( TypeData ) typeMap.get( type ) ; if ( data == null ) { data = new TypeData( type ) ; typeMap.put( type, data ) ; } String variable = data.prefix + data.count ; data.limit = Math.max( data.limit, ++data.count ) ; return variable ; } public String randomChars() { char one = UPPER.charAt( random.nextInt( UPPER.length() ) ) ; char two = LOWER.charAt( random.nextInt( LOWER.length() ) ) ; return new String( new char[] {one, two} ) ; } /** * Frees all the variables currently in use in this pool. * * @layer<bali2javacc> */ public void reset() { for ( Iterator p = typeMap.values().iterator() ; p.hasNext() ; ) { TypeData data = ( TypeData ) p.next() ; data.count = 0 ; } } /** * Returns a String of Java declarations for the variables in the pool. * * @layer<bali2javacc> */ public String toString() { StringBuffer buffer = new StringBuffer() ; Collections.sort( declarations ) ; for ( Iterator p = declarations.iterator() ; p.hasNext() ; ) { if ( buffer.length() > 0 ) buffer.append( Main.LINE_SEPARATOR ) ; buffer.append( p.next().toString() ) ; buffer.append( " ;" ) ; } for ( Iterator p = typeMap.entrySet().iterator() ; p.hasNext() ; ) { Map.Entry entry = ( Map.Entry ) p.next() ; String type = ( String ) entry.getKey() ; TypeData data = ( TypeData ) entry.getValue() ; if ( buffer.length() > 0 ) buffer.append( Main.LINE_SEPARATOR ) ; buffer.append( type ) ; buffer.append( ' ' ) ; for ( int n = data.limit ; --n > 0 ; ) buffer.append( data.prefix + n + "=null, " ) ; buffer.append( data.prefix + "0=null ;" ) ; } return buffer.toString() ; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // final private List declarations ; final private Set prefixSet ; final private Random random ; final private Map typeMap ; final private Set usedSet ; final public class TypeData { TypeData( String type ) { String leader = type.substring( 0,2 ).toLowerCase() ; String prefix = leader ; while ( prefixSet.contains( prefix ) ) prefix = leader + randomChars() ; prefixSet.add( prefix ) ; this.count = 0 ; this.limit = 0 ; this.prefix = prefix ; } public int count ; public int limit ; public String prefix ; } }