33 * (GPL) Version 2 or later (the "License"); you may not use this file except *
44 * in compliance with the License. You may obtain a copy of the License at *
55 * http://www.gnu.org/copyleft/gpl.html *
6- * *
6+ * *
77 * Software distributed under the License is distributed on an "AS IS" basis, *
88 * without warranty of any kind, either expressed or implied. See the License *
99 * for the specific language governing rights and limitations under the *
1010 * License. *
11- * *
11+ * *
1212 * This file was originally developed as part of the software suite that *
1313 * supports the book "The Elements of Computing Systems" by Nisan and Schocken, *
1414 * MIT Press 2005. If you modify the contents of this file, please document and *
@@ -57,21 +57,18 @@ public abstract class GateClass {
5757 protected boolean [] isOutputClocked ;
5858
5959 // Mapping from pin names to their types (INPUT_PIN_TYPE, OUTPUT_PIN_TYPE)
60- protected Hashtable namesToTypes ;
60+ protected Hashtable < String , Byte > namesToTypes ;
6161
6262 // Mapping from pin names to their numbers (Integer objects)
63- protected Hashtable namesToNumbers ;
63+ protected Hashtable < String , Integer > namesToNumbers ;
6464
6565 // a table that maps a gate name with its GateClass
66- protected static Hashtable GateClasses = new Hashtable ();
67-
68- protected static final Set <String > classesBeingLoaded = new HashSet <String >();
69-
66+ protected static Hashtable <String , GateClass > GateClasses = new Hashtable <String , GateClass >();
7067
7168 // Constructs a new GateCLass (public access through the getGateClass method)
7269 protected GateClass (String gateName , PinInfo [] inputPinsInfo , PinInfo [] outputPinsInfo ) {
73- namesToTypes = new Hashtable ();
74- namesToNumbers = new Hashtable ();
70+ namesToTypes = new Hashtable < String , Byte > ();
71+ namesToNumbers = new Hashtable < String , Integer > ();
7572
7673 this .name = gateName ;
7774
@@ -89,16 +86,15 @@ protected GateClass(String gateName, PinInfo[] inputPinsInfo, PinInfo[] outputPi
8986 * If the GateClass doesn't exist yet, creates the GateClass by parsing the hdl file.
9087 */
9188 public static GateClass getGateClass (String gateName , boolean containsPath ) throws HDLException {
92- String fileName = null ;
89+ String fileName ;
9390
9491 // find hdl file name according to the gate name.
9592 if (!containsPath ) {
9693 fileName = GatesManager .getInstance ().getHDLFileName (gateName );
9794 if (fileName == null )
9895 throw new HDLException ("Chip " + gateName +
99- " is not found in the working and built in folders" );
100- }
101- else {
96+ " is not found in the working and built in folders" );
97+ } else {
10298 fileName = gateName ;
10399 File file = new File (fileName );
104100 if (!file .exists ())
@@ -108,22 +104,17 @@ public static GateClass getGateClass(String gateName, boolean containsPath) thro
108104 }
109105
110106 // Try to find the gate in the "cache"
111- GateClass result = ( GateClass ) GateClasses .get (fileName );
107+ GateClass result = GateClasses .get (fileName );
112108
113109 // gate wasn't found in cache
114110 if (result == null ) {
115- try {
116- if (classesBeingLoaded .contains (gateName ))
117- throw new HDLException ("Cyclic dependency. Gate definition (possibly indirectly) depends on itself: "
118- + gateName );
119-
120- classesBeingLoaded .add (gateName );
121- HDLTokenizer input = new HDLTokenizer (fileName );
122- result = readHDL (input , gateName );
123- GateClasses .put (fileName , result );
124- } finally {
125- classesBeingLoaded .remove (gateName );
126- }
111+ GateClasses .put (fileName , new GateClassUnderLoad (fileName ));
112+ HDLTokenizer input = new HDLTokenizer (fileName );
113+ result = readHDL (input , gateName );
114+ GateClasses .put (fileName , result );
115+ } else if (result instanceof GateClassUnderLoad ) {
116+ throw new HDLException ("Cyclic dependency. Gate definition (possibly indirectly) depends on itself: "
117+ + gateName );
127118 }
128119
129120 return result ;
@@ -146,12 +137,12 @@ public static boolean gateClassExists(String gateName) {
146137
147138 // Loads the HDL from the given input, creates the appropriate GateClass and returns it.
148139 private static GateClass readHDL (HDLTokenizer input , String gateName )
149- throws HDLException {
140+ throws HDLException {
150141
151142 // read CHIP keyword
152143 input .advance ();
153144 if (!(input .getTokenType () == HDLTokenizer .TYPE_KEYWORD
154- && input .getKeywordType () == HDLTokenizer .KW_CHIP ))
145+ && input .getKeywordType () == HDLTokenizer .KW_CHIP ))
155146 input .HDLError ("Missing 'CHIP' keyword" );
156147
157148 // read gate name
@@ -165,53 +156,50 @@ private static GateClass readHDL(HDLTokenizer input, String gateName)
165156 // read '{' symbol
166157 input .advance ();
167158 if (!(input .getTokenType () == HDLTokenizer .TYPE_SYMBOL
168- && input .getSymbol () == '{' ))
159+ && input .getSymbol () == '{' ))
169160 input .HDLError ("Missing '{'" );
170161
171162 // read IN keyword
172163 PinInfo [] inputPinsInfo , outputPinsInfo ;
173164 input .advance ();
174165 if (input .getTokenType () == HDLTokenizer .TYPE_KEYWORD
175- && input .getKeywordType () == HDLTokenizer .KW_IN ) {
166+ && input .getKeywordType () == HDLTokenizer .KW_IN ) {
176167 // read input pins list
177168 inputPinsInfo = getPinsInfo (input , readPinNames (input ));
178169 input .advance ();
179- }
180- else
170+ } else
181171 // no input pins
182172 inputPinsInfo = new PinInfo [0 ];
183173
184174 // read OUT keyword
185175 if (input .getTokenType () == HDLTokenizer .TYPE_KEYWORD
186- && input .getKeywordType () == HDLTokenizer .KW_OUT ){
176+ && input .getKeywordType () == HDLTokenizer .KW_OUT ) {
187177 // read output pins list
188178 outputPinsInfo = getPinsInfo (input , readPinNames (input ));
189179 input .advance ();
190- }
191- else
180+ } else
192181 // no output pins
193182 outputPinsInfo = new PinInfo [0 ];
194183
195184 GateClass result = null ;
196185
197186 // read BuiltIn/Parts keyword
198187 if (input .getTokenType () == HDLTokenizer .TYPE_KEYWORD
199- && input .getKeywordType () == HDLTokenizer .KW_BUILTIN )
188+ && input .getKeywordType () == HDLTokenizer .KW_BUILTIN )
200189 result = new BuiltInGateClass (gateName , input , inputPinsInfo , outputPinsInfo );
201190 else if (input .getTokenType () == HDLTokenizer .TYPE_KEYWORD
202- && input .getKeywordType () == HDLTokenizer .KW_PARTS ) {
191+ && input .getKeywordType () == HDLTokenizer .KW_PARTS ) {
203192 result = new CompositeGateClass (gateName , input , inputPinsInfo , outputPinsInfo );
204- }
205- else
193+ } else
206194 input .HDLError ("Keyword expected" );
207195
208196 return result ;
209197 }
210198
211199 // Returns an array of pin names read from the input (names may contain width specification).
212200 protected static String [] readPinNames (HDLTokenizer input )
213- throws HDLException {
214- Vector list = new Vector ();
201+ throws HDLException {
202+ Vector < String > list = new Vector < String > ();
215203 boolean exit = false ;
216204 input .advance ();
217205
@@ -230,7 +218,7 @@ protected static String[] readPinNames(HDLTokenizer input)
230218 // check seperator
231219 input .advance ();
232220 if (!(input .getTokenType () == HDLTokenizer .TYPE_SYMBOL
233- && (input .getSymbol () == ',' || input .getSymbol () == ';' )))
221+ && (input .getSymbol () == ',' || input .getSymbol () == ';' )))
234222 input .HDLError ("',' or ';' expected" );
235223 if (input .getTokenType () == HDLTokenizer .TYPE_SYMBOL && input .getSymbol () == ',' )
236224 input .advance ();
@@ -245,7 +233,7 @@ protected static String[] readPinNames(HDLTokenizer input)
245233 // Returns a PinInfo array according to the given pin names
246234 // (which may contain width specification).
247235 private static PinInfo [] getPinsInfo (HDLTokenizer input , String [] names )
248- throws HDLException {
236+ throws HDLException {
249237 PinInfo [] result = new PinInfo [names .length ];
250238
251239 for (int i = 0 ; i < names .length ; i ++) {
@@ -254,13 +242,12 @@ private static PinInfo[] getPinsInfo(HDLTokenizer input, String[] names)
254242 if (bracketsPos >= 0 ) {
255243 try {
256244 String width = names [i ].substring (bracketsPos + 1 , names [i ].indexOf ("]" ));
257- result [i ].width = (byte )Integer .parseInt (width );
245+ result [i ].width = (byte ) Integer .parseInt (width );
258246 result [i ].name = names [i ].substring (0 , bracketsPos );
259247 } catch (Exception e ) {
260248 input .HDLError (names [i ] + " has an invalid bus width" );
261249 }
262- }
263- else {
250+ } else {
264251 result [i ].width = 1 ;
265252 result [i ].name = names [i ];
266253 }
@@ -305,35 +292,35 @@ public PinInfo getPinInfo(String name) {
305292 */
306293 protected void registerPins (PinInfo [] pins , byte type ) {
307294 for (int i = 0 ; i < pins .length ; i ++) {
308- namesToTypes .put (pins [i ].name , new Byte ( type ) );
309- namesToNumbers .put (pins [i ].name , new Integer ( i ) );
295+ namesToTypes .put (pins [i ].name , type );
296+ namesToNumbers .put (pins [i ].name , i );
310297 }
311298 }
312299
313300 /**
314301 * Registers the given pin with its given type and number.
315302 */
316303 protected void registerPin (PinInfo pin , byte type , int number ) {
317- namesToTypes .put (pin .name , new Byte ( type ) );
318- namesToNumbers .put (pin .name , new Integer ( number ) );
304+ namesToTypes .put (pin .name , type );
305+ namesToNumbers .put (pin .name , number );
319306 }
320307
321308 /**
322309 * Returns the type of the given pinName.
323310 * If not found, returns UNKNOWN_PIN_TYPE.
324311 */
325312 public byte getPinType (String pinName ) {
326- Byte result = ( Byte ) namesToTypes .get (pinName );
327- return ( result != null ? result . byteValue () : UNKNOWN_PIN_TYPE ) ;
313+ Byte result = namesToTypes .get (pinName );
314+ return result != null ? result : UNKNOWN_PIN_TYPE ;
328315 }
329316
330317 /**
331318 * Returns the number of the given pinName.
332319 * If not found, returns -1.
333320 */
334321 public int getPinNumber (String pinName ) {
335- Integer result = ( Integer ) namesToNumbers .get (pinName );
336- return ( result != null ? result . intValue () : -1 ) ;
322+ Integer result = namesToNumbers .get (pinName );
323+ return result != null ? result : -1 ;
337324 }
338325
339326 /**
0 commit comments