Merge 1c6981c7eda05593ad3ba7177005869088ec45dd into ac374f5b525615da3ecb36b08cc5fc53ab73dc96

This commit is contained in:
sourav2342 2025-08-25 01:37:10 -04:00 committed by GitHub
commit c4c4f72a42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -138,88 +138,149 @@ public class Assembler {
private static byte[] parseDWInstruction(String line, HashMap<String, Character> labels, int currentLine) private static byte[] parseDWInstruction(String line, HashMap<String, Character> labels, int currentLine)
throws InvalidOperandException { throws InvalidOperandException {
if (!line.trim().toUpperCase().startsWith("DW")){
return null;
}
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(bos); DataOutputStream out = new DataOutputStream(bos);
//System.out.println(line); try {
if (line.length() >= 2 && line.substring(0, 2).toUpperCase().equals("DW")) { //Special thanks to https://stackoverflow.com/questions/1757065/
String[] values = line.substring(2).split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
try { for (String value : values) {
//Special thanks to https://stackoverflow.com/questions/1757065/ value = value.trim();
String[] values = line.substring(2).split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
for (String value : values) { String[] valueTokens = value.split("\\s+");
value = value.trim(); //Handle DUP operator
if (isDup(valueTokens)) {
String[] valueTokens = value.split("\\s+"); out.write(parseDUPOperator16(valueTokens, labels, currentLine));
}
//Handle DUP operator else if (isValidString(value)) {
if (valueTokens.length == 2 && valueTokens[1].toUpperCase().contains("DUP(")) { handleStringOperand(value, out, currentLine);
out.write(parseDUPOperator16(valueTokens, labels, currentLine)); }
} else if (value.startsWith("\"") && value.endsWith("\"")) { else if (isValidLabel(value, labels)) {
//Handle string //Handle label
out.writeChar(labels.get(value));
//Unescape the string }
String string = value.substring(1, value.length() - 1); else {
handleIntegerOperand(value, out, labels, currentLine);
try {
string = StringEscapeUtils.unescapeJava(string);
} catch (IllegalArgumentException e) {
throw new InvalidOperandException(
"Invalid string operand \"" + string + "\": " + e.getMessage(),
currentLine);
}
out.write(string.getBytes(StandardCharsets.UTF_16BE));
} else if (labels != null && labels.containsKey(value)) {
//Handle label
out.writeChar(labels.get(value));
} else {
//Handle integer value
try {
out.writeChar(Integer.decode(value));
} catch (NumberFormatException e) {
//Handle assumed label
if (labels == null) {
// Write placeholder word
out.writeChar(0);
} else {
//Integer.decode failed, try binary
if (value.startsWith("0b")) {
try {
out.writeChar(Integer.parseInt(value.substring(2), 2));
} catch (NumberFormatException e2) {
throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine);
}
} else {
throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine);
}
}
}
}
} }
} catch (IOException e) {
e.printStackTrace();
} }
} else { } catch (IOException e) {
return null; e.printStackTrace();
} }
return bos.toByteArray(); return bos.toByteArray();
} }
/**
* Checks if the given value tokens represent a DUP operator.
*
* @param valueTokens Tokens from the operand string
* @return true if DUP(...) syntax is detected, false otherwise
*/
private static boolean isDup(String[] valueTokens){
return valueTokens.length == 2 && valueTokens[1].toUpperCase().contains("DUP(");
}
/**
* Checks if the given value is a valid string operand.
* A valid string starts and ends with quotation marks.
*
* @param value The operand string
* @return true if the operand is a quoted string, false otherwise
*/
private static boolean isValidString(String value){
return value.startsWith("\"") && value.endsWith("\"");
}
/**
* Checks if the given value matches a known label.
*
* @param value The operand string
* @param labels Map of label definitions (may be null if not available)
* @return true if the operand exists in the labels map, false otherwise
*/
private static boolean isValidLabel(String value, HashMap<String, Character> labels){
return labels != null && labels.containsKey(value);
}
/**
* Handles a string operand by unescaping and writing its UTF-16BE bytes
* to the output stream.
*
* @param value The quoted string operand
* @param out Output stream to write to
* @param currentLine Current line number (for error reporting)
* @throws IllegalArgumentException if the string contains invalid escape sequences
*/
private static void handleStringOperand(String value, DataOutputStream out, int currentLine) throws IllegalArgumentException, InvalidOperandException, IOException{
//Unescape the string
String string = value.substring(1, value.length() - 1);
try {
string = StringEscapeUtils.unescapeJava(string);
} catch (IllegalArgumentException e) {
throw new InvalidOperandException(
"Invalid string operand \"" + string + "\": " + e.getMessage(),
currentLine);
}
out.write(string.getBytes(StandardCharsets.UTF_16BE));
}
/**
* Handles integer operands, including decimal, hexadecimal, binary,
* placeholders for unresolved labels, and throws an error on invalid operands.
*
* @param value The operand string
* @param out Output stream to write to
* @param labels Map of label definitions (may be null if not available)
* @param currentLine Current line number (for error reporting)
* @throws InvalidOperandException if the operand cannot be parsed as a valid integer
*/
private static void handleIntegerOperand(String value, DataOutputStream out, HashMap<String, Character> labels, int currentLine) throws InvalidOperandException, IOException {
//Handle integer value
try {
out.writeChar(Integer.decode(value));
} catch (NumberFormatException e) {
//Handle assumed label
if (labels == null) {
out.writeChar(0);// Write placeholder word
return;
}
//Integer.decode failed, try binary
if (value.startsWith("0b")) {
try {
out.writeChar(Integer.parseInt(value.substring(2), 2));
} catch (NumberFormatException e2) {
throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine);
}
return;
}
throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine);
}
}
/** /**
* Parse the DW instruction (Define word). Handles DUP operator * Parse the DW instruction (Define word). Handles DUP operator
* *