📄 name.java
字号:
*/ private static void rehash() { Name[] oldHash = allNames; int newSize = oldHash.length*2 + 3; if (newSize < 0) throw new IndexOutOfBoundsException(); Name[] newHash = new Name[GenMath.primeSince(newSize)]; for (Name n: oldHash) { if (n == null) continue; int i = n.ns.hashCode() & 0x7FFFFFFF; i %= newHash.length; for (int j = 1; newHash[i] != null; j += 2) { i += j; if (i >= newHash.length) i -= newHash.length; } newHash[i] = n; } allNames = newHash; } /** * Returns the trimmed string for given string. * @param ns given string * @return trimmed string, or null if argument is null */ private static String trim(String ns) { if (ns == null) return null; int len = ns.length(); int newLen = 0; for (int i = 0; i < len; i++) { if (ns.charAt(i) > ' ') newLen++; } if (newLen == len) return ns; StringBuffer buf = new StringBuffer(newLen); for (int i = 0; i < len; i++) { if (ns.charAt(i) > ' ') buf.append(ns.charAt(i)); } return buf.toString(); } /** * Constructs a <CODE>Name</CODE> (cannot be called). */ private Name(String s) { String canonic; if (INTERN) { s = s.intern(); canonic = TextUtils.canonicString(s); if (canonic != s) canonic = canonic.intern(); } else { canonic = TextUtils.canonicString(s); if (canonic == s) { Name canonicName = canonicNames.get(s); if (canonicName != null) { canonic = s = canonicName.canonicString; canonicNames.remove(canonic); } } else { Name canonicName = findTrimmedName(canonic, false, false); if (canonicName == null) canonicName = canonicNames.get(s); if (canonicName != null) canonic = canonicName.canonicString; else canonicNames.put(canonic, this); } } ns = s; canonicString = canonic; int suffix = -1; Name base = null; try { flags = checkNameThrow(ns); } catch (NumberFormatException e) { flags = ERROR; } if ((flags & ERROR) == 0 && (flags & TEMP) != 0) { int l = ns.length(); while (l > 0 && TextUtils.isDigit(ns.charAt(l-1))) l--; if (l == ns.length()-1 && ns.charAt(ns.length() - 1) == '0') { base = this; suffix = 0; } else { base = newTrimmedName(ns.substring(0,l)+'0', false); suffix = Integer.parseInt(ns.substring(l)); } } this.numSuffix = suffix; this.basename = base; if (flags == ERROR) return; if ((flags & BUS) == 0) return; // Make subnames if (isList()) { makeListSubNames(); return; } int split = ns.indexOf('['); if (split == 0) split = ns.lastIndexOf('['); if (split == 0) makeBracketSubNames(); else makeSplitSubNames(split); } /** * Makes subnames of a bus whose name is a list of names separated by commas. */ private void makeListSubNames() { List<Name> subs = new ArrayList<Name>(); for (int beg = 0; beg <= ns.length(); ) { int end = beg; while (end < ns.length() && ns.charAt(end) != ',') { if (ns.charAt(end) == '[') { while (ns.charAt(end) != ']') end++; } end++; } Name nm = newTrimmedName(ns.substring(beg,end), true); for (int j = 0; j < nm.busWidth(); j++) subs.add(nm.subname(j)); beg = end + 1; } setSubnames(subs); } /** * Makes subnames of a bus whose name is indices list in brackets. */ private void makeBracketSubNames() { List<Name> subs = new ArrayList<Name>(); for (int beg = 1; beg < ns.length(); ) { int end = ns.indexOf(',', beg); if (end < 0) end = ns.length() - 1; /* index of ']' */ int colon = ns.indexOf(':', beg); if (colon < 0 || colon >= end) { Name nm = newTrimmedName("["+ns.substring(beg,end)+"]", false); subs.add(nm); } else { int ind1 = Integer.parseInt(ns.substring(beg, colon)); int ind2 = Integer.parseInt(ns.substring(colon+1, end)); if (ind1 < ind2) { for (int i = ind1; i <= ind2; i++) subs.add(newTrimmedName("["+i+"]", false)); } else { for (int i = ind1; i >= ind2; i--) subs.add(newTrimmedName("["+i+"]", false)); } } beg = end+1; } setSubnames(subs); } private void setSubnames(List<Name> subs) { subnames = new Name[subs.size()]; subs.toArray(subnames); // check duplicates Name[] sorted = new Name[subs.size()]; subs.toArray(sorted); Arrays.sort(sorted); for (int i = 1; i < sorted.length; i++) { if (sorted[i].equals(sorted[i-1])) { flags |= DUPLICATES; break; } } } /** * Makes subnames of a bus whose name consists of simpler names. * @param split index dividing name into simpler names. */ private void makeSplitSubNames(int split) { // if (ns.length() == 0) return; if (split < 0 || split >= ns.length()) { System.out.println("HEY! string is '"+ns+"' but want index "+split); return; } Name baseName = newTrimmedName(ns.substring(0,split), true); Name indexList = newTrimmedName(ns.substring(split),true); subnames = new Name[baseName.busWidth()*indexList.busWidth()]; for (int i = 0; i < baseName.busWidth(); i++) { String bs = baseName.subname(i).toString(); for (int j = 0; j < indexList.busWidth(); j++) { String is = indexList.subname(j).toString(); subnames[i*indexList.busWidth()+j] = newTrimmedName(bs+is, false); } } if (baseName.hasDuplicates() || indexList.hasDuplicates()) flags |= DUPLICATES; } /** * Method to check whether or not string is a valid name. * Throws exception on invaliod string * @param ns given string * @return flags describing the string. */ private static int checkNameThrow(String ns) throws NumberFormatException { int flags = SIMPLE; int bracket = -1; boolean wasBrackets = false; int colon = -1; if (ns.length() == 0 || ns.charAt(ns.length() - 1) == ',') flags |= HAS_EMPTIES; for (int i = 0; i < ns.length(); i++) { char c = ns.charAt(i); if (bracket < 0) { colon = -1; if (c == ']') throw new NumberFormatException("unmatched ']' in name"); if (c == ':') throw new NumberFormatException("':' out of brackets"); if (c == '[') { bracket = i; flags &= ~SIMPLE; if (i == 0 || ns.charAt(i-1) == ',') flags |= HAS_EMPTIES; wasBrackets = true; } else if (c == ',') { flags |= (LIST|BUS); flags &= ~SIMPLE; if (i == 0 || ns.charAt(i-1) == ',') flags |= HAS_EMPTIES; wasBrackets = false; } else if (wasBrackets) throw new NumberFormatException("Wrong character after brackets"); if (c == '@') { for (int j = i + 1; j < ns.length(); j++) { char cj = ns.charAt(j); if (cj < '0' || cj > '9') throw new NumberFormatException("Wrong number suffix in temporary name"); } if (i == ns.length() - 1 || ns.charAt(i + 1) == '0' && i != ns.length() - 2) throw new NumberFormatException("Wrong temporary name"); if ((flags & SIMPLE) == 0) throw new NumberFormatException("list of temporary names"); Integer.parseInt(ns.substring(i + 1)); // throws exception on bad number assert flags == SIMPLE; return SIMPLE|TEMP; } continue; } if (c == '[') throw new NumberFormatException("nested bracket '[' in name"); if (c == ':') { if (colon >= 0) throw new NumberFormatException("too many ':' inside brackets"); if (i == bracket + 1) throw new NumberFormatException("has missing start of index range"); if (ns.charAt(bracket+1) == '-') throw new NumberFormatException("has negative start of index range"); for (int j = bracket + 1; j < i; j++) { if (!TextUtils.isDigit(ns.charAt(j))) throw new NumberFormatException("has nonnumeric start of index range"); } colon = i; flags |= BUS; } if (colon >= 0 && (c == ']' || c == ',')) { if (i == colon + 1) throw new NumberFormatException("has missing end of index range"); if (ns.charAt(colon+1) == '-') throw new NumberFormatException("has negative end of index range"); for (int j = colon + 1; j < i; j++) { if (!TextUtils.isDigit(ns.charAt(j))) throw new NumberFormatException("has nonnumeric end of index range"); } if (Integer.parseInt(ns.substring(bracket+1,colon)) == Integer.parseInt(ns.substring(colon+1,i))) throw new NumberFormatException("has equal start and end indices"); colon = -1; } if (c == ']') { if (i == bracket + 1) flags |= HAS_EMPTIES; bracket = -1; } if (c == ',') { if (i == bracket + 1) flags += HAS_EMPTIES; bracket = i; flags |= BUS; } if (c == '@') throw new NumberFormatException("'@' in brackets"); } if (bracket != -1) throw new NumberFormatException("Unclosed bracket"); return flags; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -