/*
* Copyright (c) Anton Kraievoy, IASA, Kiev, Ukraine, 2006.
* This work is based on code of Dr. Dalton R. Hunkins, CS dept. of St. Bonaventure University, 2006.
*/
package elw.dp.mips.asm;
import java.util.regex.Pattern;
public class Data {
private static final String DIGITS = "0123456789";
private static final String HEX_DIGITS = "0123456789ABCDEF";
private static final Pattern PATTERN_BIN = Pattern.compile("^[0-1]+$");
private static final Pattern PATTERN_OCT = Pattern.compile("^[0-7]+$");
private static final Pattern PATTERN_HEX = Pattern.compile("^[0-9a-fA-F]+$");
private static final Pattern PATTERN_DEC = Pattern.compile("^[0-9]+$");
private static boolean isHexDigit(char c) {
return '0' <= c && c <= '9' || 'A' <= c && c <= 'F' || 'a' <= c && c <= 'f';
}
public static boolean isLetter(char c) {
return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z';
}
public static boolean isDecDigit(char c) {
return '0' <= c && c <= '9';
}
public static long int2long(int value) {
if (value >= 0) {
return value;
} else {
return -2 * (long) Integer.MIN_VALUE + value;
}
}
public static boolean isHexPositive(String token) {
for (int i = 0; i < token.length(); i++) {
if (!isHexDigit(token.charAt(i))) return false;
}
return true;
}
public static boolean isDecPositive(String token) {
for (int i = 0; i < token.length(); i++) {
if (!isDecDigit(token.charAt(i))) {
return false;
}
}
return true;
}
public static boolean isHexPositive(String token, int numberOfDigits) {
token = token.toUpperCase();
if (token.length() == 0) return false;
for (int i = 0; i < token.length(); i++) {
if (!isHexDigit(token.charAt(i))) return false;
}
return token.length() <= numberOfDigits;
}
private static int valueOfHex(char c) {
if ('0' <= c && c <= '9') return c - '0';
if ('A' <= c && c <= 'F') return 10 + c - 'A';
if ('a' <= c && c <= 'f') return 10 + c - 'a';
throw new IllegalArgumentException("Illegal: '" + c + "'");
}
private static int valueOfDec(char c) {
if ('0' <= c && c <= '9') return c - '0';
throw new IllegalArgumentException("illegal: '" + c + "'");
}
public static long hex2long(String address) {
long value = 0;
for (int i = 0; i < address.length(); i++) {
value = 16 * value + valueOfHex(address.charAt(i));
}
return value;
}
private static String invert(final String hex) {
StringBuffer result = new StringBuffer();
for (int i = 0; i < hex.length(); i++) {
final int value = valueOfHex(hex.charAt(i));
final int invertedValue = 15 - value;
result.append(HEX_DIGITS.charAt(invertedValue));
}
return result.toString();
}
public static int hex2int(String hex) {
if (hex.length() == 0) {
return 0;
}
if (hex.length() < 8 || '0' <= hex.charAt(0) && hex.charAt(0) <= '7') {
return (int) hex2long(hex);
} else {
return (int) -(hex2long(invert(hex)) + 1L);
}
}
public static String int2hex(int value, int numberOfDigits) {
if (value >= 0) {
return long2hex(value, numberOfDigits);
} else {
return long2hex(-2 * (long) Integer.MIN_VALUE + value);
}
}
public static int dec2int(String registerNumber) {
int value = 0;
for (int i = 0; i < registerNumber.length(); i++) {
value = 10 * value + valueOfDec(registerNumber.charAt(i));
}
return value;
}
public static String long2hex(long word) {
return long2hex(word, 1);
}
public static String long2hex(long number, int numberOfDigits) {
if (number < 0) {
System.out.println("number = " + number);
return int2hex((int) number, numberOfDigits);
}
StringBuffer result = new StringBuffer();
long intermediateValue = number;
int digitCount = 0;
while (intermediateValue > 0 || digitCount < numberOfDigits) {
int digitValue = (int) (intermediateValue % 16);
result.insert(0, HEX_DIGITS.charAt(digitValue));
digitCount++;
intermediateValue /= 16;
}
return result.toString();
}
public static String int2dec(int number, int numberOfDigits) {
final StringBuffer result = new StringBuffer();
final boolean sign;
long intermediateValue;
if (number < 0) {
sign = true;
intermediateValue = -(long) number;
} else {
sign = false;
intermediateValue = number;
}
int digitCount = 0;
while (intermediateValue > 0 || digitCount < numberOfDigits) {
int digitValue = (int) (intermediateValue % 10);
result.insert(0, DIGITS.charAt(digitValue));
digitCount++;
intermediateValue /= 10;
}
if (sign) {
result.insert(0, "-");
}
return result.toString();
}
public static String int2dec(int word) {
return int2dec(word, 1);
}
public static String str(final long val, final int radix, final int digits) {
final StringBuffer str = new StringBuffer(Long.toString(val, radix));
final int offs = str.charAt(0) == '-' ? 1 : 0;
while (str.length() < digits + offs) {
str.insert(offs, '0');
}
return str.toString();
}
public static String strTwosComplement(final long val, final int digits) {
final StringBuffer str = new StringBuffer(Long.toBinaryString(val));
final char paddingChar = val < 0 ? '1' : '0';
while (str.length() < digits) {
str.insert(0, paddingChar);
}
return str.substring(str.length() - digits);
}
public static long comp(long val, int digits) {
return val < 0 ? (2 << digits) - val : val;
}
public static boolean isNum(final String num, int bits) {
if (num == null || num.length() == 0) {
return false;
}
final StringBuffer numBuf = new StringBuffer(num.toLowerCase());
int sign = 0;
if (numBuf.charAt(0) == '-') {
numBuf.deleteCharAt(0);
sign = 1;
if (numBuf.indexOf("-") >= 0 || numBuf.length() == 0) {
return false;
}
}
if (numBuf.charAt(numBuf.length() - 1) == 'b') {
numBuf.deleteCharAt(numBuf.length() - 1);
if (numBuf.length() == 0) {
return false;
}
while (numBuf.charAt(0) == '0' && numBuf.length() > 1) {
numBuf.deleteCharAt(0);
}
return numBuf.length() <= bits - sign && PATTERN_BIN.matcher(numBuf).matches();
} else if (numBuf.charAt(numBuf.length() - 1) == 'o') {
numBuf.deleteCharAt(numBuf.length() - 1);
if (numBuf.length() == 0) {
return false;
}
while (numBuf.charAt(0) == '0' && numBuf.length() > 1) {
numBuf.deleteCharAt(0);
}
return (numBuf.length() - 1) * 3 <= bits && PATTERN_OCT.matcher(numBuf).matches() && width(Long.parseLong(numBuf.toString(), 8)) <= bits - sign;
} else if (numBuf.charAt(numBuf.length() - 1) == 'h') {
numBuf.deleteCharAt(numBuf.length() - 1);
if (numBuf.length() == 0) {
return false;
}
while (numBuf.charAt(0) == '0' && numBuf.length() > 1) {
numBuf.deleteCharAt(0);
}
return (numBuf.length() - 1) * 4 <= bits && PATTERN_HEX.matcher(numBuf).matches() && width(Long.parseLong(numBuf.toString(), 16)) <= bits - sign;
} else if (numBuf.length() >= 2 && "0x".equals(numBuf.subSequence(0, 2))) {
numBuf.delete(0, 2);
if (numBuf.length() == 0) {
return false;
}
while (numBuf.charAt(0) == '0' && numBuf.length() > 1) {
numBuf.deleteCharAt(0);
}
return (numBuf.length() - 1) * 4 <= bits && PATTERN_HEX.matcher(numBuf).matches() && width(Long.parseLong(numBuf.toString(), 16)) <= bits - sign;
} else {
while (numBuf.charAt(0) == '0' && numBuf.length() > 1) {
numBuf.deleteCharAt(0);
}
return (numBuf.length() - 1) * 3 <= bits && PATTERN_DEC.matcher(numBuf).matches() && width(parse(numBuf.toString())) <= bits - sign;
}
}
public static long parse(final String num) {
if (num.startsWith("-") && num.lastIndexOf('-') == 0) {
return -parse(num.substring(1));
}
if (num.endsWith("b")) {
return Long.parseLong(num.substring(0, num.length() - 1), 2);
}
if (num.endsWith("o")) {
return Long.parseLong(num.substring(0, num.length() - 1), 8);
}
if (num.endsWith("h")) {
return Long.parseLong(num.substring(0, num.length() - 1), 16);
}
if (num.startsWith("0x")) {
return Long.parseLong(num.substring(2), 16);
}
return Long.parseLong(num);
}
public static int width(long value) {
int msb = 0;
while (value >= 1l << 16) {
value >>= 16;
msb += 16;
}
while (value >= 1l << 4) {
value >>= 4;
msb += 4;
}
while (value >= 1) {
value >>= 1;
msb += 1;
}
return msb;
}
}