extracted helper methods for DW instruction parsing

This commit is contained in:
sourav 2025-08-25 11:03:02 +05:30
parent ac374f5b52
commit 1c6981c7ed

View File

@ -138,13 +138,13 @@ public class Assembler {
private static byte[] parseDWInstruction(String line, HashMap<String, Character> labels, int currentLine)
throws InvalidOperandException {
if (!line.trim().toUpperCase().startsWith("DW")){
return null;
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(bos);
//System.out.println(line);
if (line.length() >= 2 && line.substring(0, 2).toUpperCase().equals("DW")) {
try {
//Special thanks to https://stackoverflow.com/questions/1757065/
@ -157,10 +157,73 @@ public class Assembler {
String[] valueTokens = value.split("\\s+");
//Handle DUP operator
if (valueTokens.length == 2 && valueTokens[1].toUpperCase().contains("DUP(")) {
if (isDup(valueTokens)) {
out.write(parseDUPOperator16(valueTokens, labels, currentLine));
} else if (value.startsWith("\"") && value.endsWith("\"")) {
//Handle string
}
else if (isValidString(value)) {
handleStringOperand(value, out, currentLine);
}
else if (isValidLabel(value, labels)) {
//Handle label
out.writeChar(labels.get(value));
}
else {
handleIntegerOperand(value, out, labels, currentLine);
}
}
} catch (IOException e) {
e.printStackTrace();
}
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);
@ -174,23 +237,32 @@ public class Assembler {
}
out.write(string.getBytes(StandardCharsets.UTF_16BE));
} else if (labels != null && labels.containsKey(value)) {
//Handle label
out.writeChar(labels.get(value));
} else {
}
/**
* 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) {
// Write placeholder word
out.writeChar(0);
} else {
out.writeChar(0);// Write placeholder word
return;
}
//Integer.decode failed, try binary
if (value.startsWith("0b")) {
@ -199,26 +271,15 @@ public class Assembler {
} catch (NumberFormatException e2) {
throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine);
}
} else {
return;
}
throw new InvalidOperandException("Invalid operand \"" + value + '"', currentLine);
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
return null;
}
return bos.toByteArray();
}
/**
* Parse the DW instruction (Define word). Handles DUP operator