|
@@ -14,10 +14,17 @@ let tape = [];
|
|
|
* progress the pointer by one position.
|
|
|
*/
|
|
|
let tapePointer = 0;
|
|
|
+/**
|
|
|
+ * A boolean value to determine whether a label is waiting to receive an address
|
|
|
+ */
|
|
|
+let labelStartActive = false;
|
|
|
/**
|
|
|
* A dictionary of labels and the line numbers they start at
|
|
|
*/
|
|
|
-const labelDictionary = {};
|
|
|
+const labelDictionary = {
|
|
|
+ /** Stores labels that haven't had their address found yet */
|
|
|
+ _toSet: undefined,
|
|
|
+};
|
|
|
/**
|
|
|
* A dictionary of variables created in the assembly
|
|
|
*/
|
|
@@ -61,11 +68,27 @@ const ASM_DICTIONARY = {
|
|
|
*/
|
|
|
function transpileAssembly(assembly) {
|
|
|
for (const line of assembly) {
|
|
|
- const instruction = line.shift();
|
|
|
- if (!ASM_DICTIONARY[instruction]) {
|
|
|
+ let instruction = line.shift();
|
|
|
+ // Check if the "instruction" is actually a label start
|
|
|
+ if (isLabelStart(instruction)) {
|
|
|
+ // Store the label in the dictionary, sans the colon
|
|
|
+ labelDictionary._toSet = instruction.substring(0, instruction.length -1);
|
|
|
+ labelStartActive = true;
|
|
|
+
|
|
|
+ // If the line only contained the label start, continue to the next line
|
|
|
+ if (line.length == 0) { continue; }
|
|
|
+ // Otherwise, grab the next next string, which must be the instruction
|
|
|
+ instruction = line.shift();
|
|
|
+ }
|
|
|
+ else if (!ASM_DICTIONARY[instruction]) {
|
|
|
throw new Error(`No function defined for the ${instruction} instruction.`);
|
|
|
}
|
|
|
|
|
|
+ // If a label is waiting to be set, the tape pointer is currently where
|
|
|
+ // the next instruction is going to be put, so we can set the label's
|
|
|
+ // pointer here
|
|
|
+ setLabelStart();
|
|
|
+
|
|
|
// Call the function for this instruction, and pass the rest of the line as parameters
|
|
|
ASM_DICTIONARY[instruction](...line);
|
|
|
}
|
|
@@ -213,15 +236,14 @@ function placeVariables() {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Check if a given parameter is, or contains, a label
|
|
|
+ * Check if a given string matches a label start definition
|
|
|
*
|
|
|
* @param {string} parameter The parameter to check
|
|
|
*
|
|
|
* @returns {boolean}
|
|
|
*/
|
|
|
-function isLabel(parameter) {
|
|
|
- const labelMatcher = new RegExp("\w+(?:\s*[+]\s*\d*)?");
|
|
|
- return labelMatcher.test(parameter);
|
|
|
+function isLabelStart(parameter) {
|
|
|
+ return /^\w+:$/.test(parameter);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -281,6 +303,18 @@ function instructionNotYetImplemented(instruction) {
|
|
|
throw new Error(`The ${instruction} instruction has not yet been implemented`);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Assigns a label waiting an address to the current pointer position
|
|
|
+ *
|
|
|
+ * @returns {void}
|
|
|
+ */
|
|
|
+function setLabelStart() {
|
|
|
+ if (labelDictionary._toSet === undefined) { return };
|
|
|
+
|
|
|
+ labelDictionary[labelDictionary._toSet] = tapePointer;
|
|
|
+ labelDictionary._toSet = undefined;
|
|
|
+}
|
|
|
+
|
|
|
/* MAIN FUNCTIONALITY */
|
|
|
|
|
|
/**
|
|
@@ -315,6 +349,8 @@ function main() {
|
|
|
transpileAssembly(ret);
|
|
|
|
|
|
console.log("Parsed IntCode: ", tape.join(", "));
|
|
|
+
|
|
|
+ console.log("Labels:", labelDictionary);
|
|
|
}
|
|
|
|
|
|
main();
|