7 Commits 219f0513ec ... c5747fd97e

Tác giả SHA1 Thông báo Ngày
  ApisNecros c5747fd97e Set final version of the tests 1 tháng trước cách đây
  ApisNecros 0d95a8b089 Add ability to jump to labels 1 tháng trước cách đây
  ApisNecros f0a9f46685 Add ability to create labels in icasm 1 tháng trước cách đây
  ApisNecros 472bd5ddf4 Tidy up final output 1 tháng trước cách đây
  ApisNecros 04b5fa80e1 Update opcodes to match new ones 1 tháng trước cách đây
  ApisNecros 7aa6345947 Update labels test 1 tháng trước cách đây
  ApisNecros dc72d63d1e Fixup output 4 tháng trước cách đây
2 tập tin đã thay đổi với 87 bổ sung25 xóa
  1. 13 12
      tests/labels.icasm
  2. 74 13
      yaict

+ 13 - 12
tests/labels.icasm

@@ -1,13 +1,14 @@
-ld 0d19, 0              // jpt, jpf, eq, lt register
-ld 0d20, 10             // loop counter
-ld 0d30, 0              // lower number
-ld 0d31, 1              // higher number
-ld 0d33, 0              // storage space
+ld @regA, 0              // jz, seq register
+ld @regB, 0              // storage space
+ld @counter, 10          // loop counter
+ld @lower, 0             // lower number
+ld @higher, 1            // higher number
 Fibonacci:
-add 0d31, 0, 0d33       // Move higher number to a storage point
-add 0d31, 0d30, 0d31    // Add higher and lower number, and store in higher number slot
-add 0d33, 0, 0d30       // Move stored number to lower number slot
-add 0d20, -1, 0d20      // Subtract 1 from the loop counter
-eq 0d20, 0, 0d19        // Check if the loop counter is 0
-jpf 0d19, Fibonacci + 1 // Loop the function if not
-hlt                     // Otherwise, exit
+add @higher, 0, @regB           // Move higher number to a storage point
+add @higher, @lower, @higher    // Add higher and lower number, and store in higher number slot
+out @higher                     // Output the current highest number
+add @regB, 0, @lower            // Move stored number to lower number slot
+add @counter, -1, @counter      // Subtract 1 from the loop counter
+seq @counter, 0, @regA          // Check if the loop counter is 0
+jz @regA, Fibonacci             // Loop the function if not
+hlt                             // Otherwise, exit

+ 74 - 13
yaict

@@ -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);
     }
@@ -146,10 +169,10 @@ function insertOutput(outputParameter) {
  * @param {string} testingParameter The parameter to test. Could be an immediate value or an address
  * @param {string} jumpDestination The address to jump to if the test passes
  */
-function insertTestJump(opcode, testingParameter, jumpDestination) {
+function insertTestJump(opcode, testingParameter, jumpDestination, offset) {
     tape[tapePointer++] = getParameterMode(jumpDestination) + getParameterMode(testingParameter) + opcode;
     tape[tapePointer++] = testingParameter;
-    tape[tapePointer++] = jumpDestination;
+    tape[tapePointer++] = validateJumpDestination(jumpDestination, offset);
 }
 
 /**
@@ -213,15 +236,41 @@ 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);
+}
+
+/**
+ * Confirm that a label exists
+ *
+ * @param {string} labelName The possible label name to check
+ *
+ * @returns {boolean}
+ */
+function validateLabel(labelName) {
+    return labelDictionary.hasOwnProperty(labelName);
+}
+
+/**
+ * Get the address to jump to
+ * 
+ * @param {string} jumpDestination The destination to jump to. Could be either a memory address or 
+ * @param {number} [offset] An offset for the jump destination. Only used if the jump destination is a label
+ *
+ * @returns {string|number} The address to jump to
+ */
+function validateJumpDestination(jumpDestination, offset = 0) {
+    if (isAddress(jumpDestination)) { return jumpDestination; }
+    if (validateLabel(jumpDestination)) {
+        return labelDictionary[jumpDestination] + offset
+    }
+    return;
 }
 
 /**
@@ -281,6 +330,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 */
 
 /**
@@ -308,15 +369,15 @@ function readFile(filename) {
 function main() {
     const ret = readFile(process.argv[2]);
 
-    console.log(typeof ret);
-    console.log(ret);
+    console.log("Assembly provided: ", ret);
 
     console.log("Parsing assembly...");
 
     transpileAssembly(ret);
 
-    console.log("Parsed Assembly: ")
-    console.log(tape.join(", "));
+    console.log("Parsed IntCode: ", tape.join(", "));
+
+    console.log("Labels:", labelDictionary);
 }
 
 main();