Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/voytechs/jnetstream/npl/ArrayDimensionNode.java


1   /*
2    * File: ArrayDimensionNode.java
3    * Auth: Mark Bednarczyk
4    * Date: DATE
5    *   Id: $Id: ArrayDimensionNode.java,v 1.1.1.1 2003/09/22 16:32:20 voytechs Exp $
6    ********************************************
7    Copyright (C) 2003  Mark Bednarczyk
8   
9    This program is free software; you can redistribute it and/or
10   modify it under the terms of the GNU General Public License
11   as published by the Free Software Foundation; either version 2
12   of the License, or (at your option) any later version.
13  
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18  
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22   ********************************************
23   * $Log: ArrayDimensionNode.java,v $
24   * Revision 1.1.1.1  2003/09/22 16:32:20  voytechs
25   * Initial import.
26   *
27   */
28  package com.voytechs.jnetstream.npl;
29  
30  import java.lang.*;
31  import java.util.*;
32  
33  /**
34   * Support class that allows muti-dimensional array manipulation.
35   * Since array references can have dynamic code associated with array lookup,
36   * a number of convenience functions are performed by the class.
37   * 1) Bounds checking for MAX and MIN bounds for all dimensions.
38   * 2) Node traversal for each dimension
39   * 3) Scalar array size computation which also needs to be done at run time 
40   *    because of dynamic code.
41   */
42  public class ArrayDimensionNode 
43    extends NodeList {
44  
45    /* Internal attributes */
46    private static final boolean debug = false;
47  
48    private boolean constantDimension = false;
49    private int scalarSize = -1; // Indicates we haven't initialized yet.
50  
51    /**
52     *
53     * @param
54     * @exception
55     */
56    public ArrayDimensionNode() {
57    }
58  
59  
60    /**
61     * Returns the scalar equivelent value of the entire array.
62     * Since the value has to be evaluated dynamically, there some caching of the
63     * value is done to improve performance.
64     */
65    public int toScalar(ArrayDimensionNode dim)
66      throws NodeException {
67  
68      if(constantDimension) {
69        if(scalarSize == -1)
70          scalarSize = calculateScalarSize(this, dim);
71  
72        return(scalarSize);
73      }
74  
75      return(calculateScalarSize(this, dim));
76    }
77  
78    public int toScalar()
79      throws NodeException {
80      
81      return(calculateArraySize());
82    }
83  
84  
85    /**
86     * Calculates the scalar dimension of the entire array. This is how many
87     * elements the array takes overall.
88     * 
89     * @param max Maximim multidimensional boundaries of the array.
90     * @param dim the value to convert to scalar based on max as the array sizes.
91     */
92    public int calculateScalarSize(ArrayDimensionNode dim) throws NodeException { return(calculateScalarSize(this, dim)); }
93    protected static int calculateScalarSize(ArrayDimensionNode max, ArrayDimensionNode dim) 
94      throws NodeException {
95  
96      if(max.size() != dim.size())
97        throw new NodeException("Array sizes don't match. Can not compute Scalar size.", max);
98  
99      int s = 0;
100     int m = 1;
101 
102     for(int i = dim.size() -1; i >= 0; i --) {
103       s += m * dim.getInt(i);
104       m *= max.getInt(i);
105     }
106 
107     return(s);
108   }
109 
110   public int calculateArraySize() throws NodeException { return(calculateArraySize(this, 0)); }
111   protected static int calculateArraySize(ArrayDimensionNode max, int level) 
112     throws NodeException {
113 
114     int s = 1;
115     for(int i = level; i < max.size(); i ++)
116       s *= max.getInt(i);
117 
118     return(s);
119   }
120 
121   public String createLabel(int scalar) 
122     throws NodeException {
123 
124     String q = "";
125     int r = 0;
126 
127     for(int i = 1; i < size(); i ++) {
128 
129       r = scalar / calculateArraySize(this, i);
130 
131       scalar -= r * calculateArraySize(this, i);
132 
133 
134       q += "[" + r + "]";
135     }
136 
137     q += "[" + scalar + "]";
138 
139     return(q);
140   }
141 
142 
143   /**
144    * Checks that "dim" is within allocated limits of the array dimension.
145    * 
146    * @return true if within limits, false if not.
147    * @exception NodeException since we are also excecuting dynamic expression code.
148    */
149   public boolean checkBoundary(ArrayDimensionNode dim) 
150     throws NodeException {
151 
152     if(size() != dim.size())
153       return(false);
154 
155     /**
156      * Now compare each element of the dimension and make sure we
157      * always bigger. For Array dereferencing, we should be the Reference
158      * with static IntNode() object for each dimension. This should be taken
159      * care of by the Interpreter. The linker is not able to execute dynamic code
160      * at this point to calculate the static array sizes.
161      */
162     for(int i = 0; i < size(); i ++) {
163       if(getInt(i) <= dim.getInt(i))
164         return(false);
165     }
166 
167     return(true);
168   }
169 
170   /**
171    * This method evaluates the code to its NodeInt equivelent and
172    * creates a new Dimension object with static values. This is needed
173    * for when arrays are first instantiated, the dynamic code can only be
174    * run once, otherwise array dimensions could suddenly change on us.
175    * Make sure this method is called only when all the reference have been resolved
176    * and context loaded with primitives. Otherwise an NodeException will be thrown if
177    * references can not be properly dereferenced.
178    *
179    * @exception NodeException if reference(s) can not be derefereced to a primitive. Becarefull when
180    * evaluating in linkers and such where the dynamic runtime structures aren't ready yet. Can use the
181    * canOptimize() function. If top level node can be optimized, this usually means that there are no
182    * references in the code to be evaluated.
183    */
184   public ArrayDimensionNode evaluateToStatic() 
185     throws NodeException {
186     ArrayDimensionNode dim = new ArrayDimensionNode();
187 
188     for(int i = 0; i < size(); i ++) {
189       dim.add(new IntNodeImpl(getInt(i)));
190     }
191 
192     dim.constantDimension = true;
193 
194     return(dim);
195   }
196 
197   /**
198    * Test function for ArrayDimensionNode
199    * @param args command line arguments
200    */
201   public static void main(String [] args) {
202 
203     ArrayDimensionNode max = new ArrayDimensionNode();
204     max.add(new IntNodeImpl(3));
205     max.add(new IntNodeImpl(4));
206     max.add(new IntNodeImpl(5));
207 
208     ArrayDimensionNode dim = new ArrayDimensionNode();
209     dim.add(new IntNodeImpl(2));
210     dim.add(new IntNodeImpl(3));
211     dim.add(new IntNodeImpl(20));
212 
213     try {
214       System.out.println("max=" + max.calculateArraySize());
215       System.out.println("dim=" + ArrayDimensionNode.calculateScalarSize(max, dim));
216 
217       for(int i = 0; i < max.toScalar(); i ++) {
218       System.out.println("dim.label=" + max.createLabel(i));
219       }
220     }
221     catch(NodeException ne) {
222       ne.printStackTrace();
223     }
224   }
225 
226 } /* END OF: ArrayDimensionNode */