Sfoglia il codice sorgente

Switch parameter parsing to separate function

I wrote a huge chunk of code to handle the parameter parsing for the add
function only to realize that it'd be better handled in a general use
function.
ApisNecros 4 mesi fa
parent
commit
1a8c27fcd8
1 ha cambiato i file con 41 aggiunte e 23 eliminazioni
  1. 41 23
      yaict.pl

+ 41 - 23
yaict.pl

@@ -67,7 +67,7 @@ sub parseAssembly
         }
         elsif($opcodes{$asmInstruction})
         {
-            parseOpcodeAndParams($opcodes{$asmInstruction}, \@parameters);
+            parseOpcodeAndParams($opcodes{$asmInstruction}, \@parameters, \$instructionNumber);
         }
         else
         {
@@ -76,37 +76,55 @@ sub parseAssembly
     }
 }
 
-# TODO
 sub parseOpcodeAndParams
 {
+    # A reference to the current instruction number
+    # Need to assign first due to usage for opcode index
+    my $instructionNumber = $_[2];
+    # The opcode
     my $opcode = $_[0];
+    # Store program index of opcode now because opcode may be modified in the parameter loop
+    my $opcodeIdx = $$instructionNumber++;
+    # Parameters for the opcode
     my @parameters = @{ $_[1] };
-    my $operand1 = $parameters[0];
-    if(isImmediate($parameters[0]))
-    {
-        $opcode = length($opcode) == 1 ? "10$opcode" : "1$opcode";
-    }
-    else
-    {
-        $operand1 = getAddress($parameters[0])
-    }
 
-    my $operand2 = $parameters[1];
-    if(isImmediate($parameters[1]))
+    # Store at is usually the last parameter, if there are any parameters
+    my $storeAt = $#parameters > 0 ? getAddress(pop(@parameters)) : -1;
+
+    # The amount of digits the opcode is expected to be when the parameter tries to add its parameter mode
+    my $parameterModeIdx = 2;
+
+    foreach my $param (@parameters)
     {
-        $opcode = length($opcode) < 3 ? "100$opcode" : "1$opcode";
+        if(isImmediate($param))
+        {
+            if(length($opcode) < $parameterModeIdx)
+            {
+                $opcode = "0$opcode";
+            }
+            $opcode = "1$opcode";
+        }
+        else
+        {
+            $param = getAddress($param);
+        }
+        $parameterModeIdx++;
+
+
+        $program[$$instructionNumber++] = $param;
+        if($$instructionNumber == 9)
+        {
+            print "$opcode, $param";
+            die "Overwriting memory!";
+        }
     }
-    else
+    # Insert opcode back where it belongs
+    $program[$opcodeIdx] = $opcode;
+    if($storeAt > -1)
     {
-        $operand2 = getAddress($parameters[1])
+        # Add the storeAt address
+        $program[$$instructionNumber++] = $storeAt;
     }
-
-    my $storeAt = getAddress($parameters[2]);
-
-    $program[$instructionNumber++] = $opcode;
-    $program[$instructionNumber++] = $operand1;
-    $program[$instructionNumber++] = $operand2;
-    $program[$instructionNumber++] = $storeAt;
 }
 
 # Check if a parameter is Immediate Mode or Position