|
@@ -18,6 +18,10 @@ let tapePointer = 0;
|
|
* A dictionary of labels and the line numbers they start at
|
|
* A dictionary of labels and the line numbers they start at
|
|
*/
|
|
*/
|
|
const labelDictionary = {};
|
|
const labelDictionary = {};
|
|
|
|
+/**
|
|
|
|
+ * A dictionary of variables created in the assembly
|
|
|
|
+ */
|
|
|
|
+const variableDictionary = {};
|
|
/**
|
|
/**
|
|
* The dictionary of opcodes and their values
|
|
* The dictionary of opcodes and their values
|
|
*/
|
|
*/
|
|
@@ -66,6 +70,9 @@ function transpileAssembly(assembly) {
|
|
ASM_DICTIONARY[instruction](...line);
|
|
ASM_DICTIONARY[instruction](...line);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Replace variables with address
|
|
|
|
+ placeVariables();
|
|
|
|
+
|
|
// Clean the values on the tape
|
|
// Clean the values on the tape
|
|
tape = tape.map((inst) => strToDecimal(inst));
|
|
tape = tape.map((inst) => strToDecimal(inst));
|
|
}
|
|
}
|
|
@@ -79,7 +86,19 @@ function transpileAssembly(assembly) {
|
|
* @param {number} value
|
|
* @param {number} value
|
|
*/
|
|
*/
|
|
function loadToAddress(address, value) {
|
|
function loadToAddress(address, value) {
|
|
- tape[strToDecimal(address)] = value;
|
|
|
|
|
|
+ if (isVariable(address)) {
|
|
|
|
+ if (!variableDictionary[address]) {
|
|
|
|
+ variableDictionary[address] = {
|
|
|
|
+ value: value,
|
|
|
|
+ address: null,
|
|
|
|
+ };
|
|
|
|
+ } else {
|
|
|
|
+ variableDictionary[address]["value"] = value;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ tape[strToDecimal(address)] = value;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -178,6 +197,21 @@ function insertHalt() {
|
|
|
|
|
|
/* HELPER FUNCTIONS */
|
|
/* HELPER FUNCTIONS */
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Places variables in the dictionary on the tape
|
|
|
|
+ *
|
|
|
|
+ * Places the values loaded into variables at the end of the tape,
|
|
|
|
+ * and stores those addresses.
|
|
|
|
+ */
|
|
|
|
+function placeVariables() {
|
|
|
|
+ // move the tape pointer to the end of the tape
|
|
|
|
+ tapePointer = tape.length;
|
|
|
|
+ for (const variable of Object.keys(variableDictionary)) {
|
|
|
|
+ variableDictionary[variable]["address"] = ++tapePointer;
|
|
|
|
+ tape[tapePointer] = variableDictionary[variable]["value"];
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Check if a given parameter is, or contains, a label
|
|
* Check if a given parameter is, or contains, a label
|
|
*
|
|
*
|
|
@@ -198,7 +232,18 @@ function isLabel(parameter) {
|
|
* @returns {string} The memory address
|
|
* @returns {string} The memory address
|
|
*/
|
|
*/
|
|
function isAddress(parameter) {
|
|
function isAddress(parameter) {
|
|
- return !!parameter.match(/^0d/);
|
|
|
|
|
|
+ return isVariable(parameter) || !!parameter.match(/^0d/);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Check if a parameter resembles a variable
|
|
|
|
+ *
|
|
|
|
+ * @param {any} parameter
|
|
|
|
+ * @returns {boolean}
|
|
|
|
+ */
|
|
|
|
+function isVariable(parameter) {
|
|
|
|
+ if (typeof parameter != "string") { return false; }
|
|
|
|
+ return !!parameter.match(/^\@/);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -222,6 +267,8 @@ function strToDecimal(decimalValue) {
|
|
return decimalValue;
|
|
return decimalValue;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (isVariable(decimalValue)) { return variableDictionary[decimalValue]["address"]; }
|
|
|
|
+
|
|
return parseInt(decimalValue.replace(/^0d/, ""), 10);
|
|
return parseInt(decimalValue.replace(/^0d/, ""), 10);
|
|
}
|
|
}
|
|
|
|
|