8 Commits b214d20bab ... a9c27c6839

Autor SHA1 Mensagem Data
  Bee Hudson a9c27c6839 Update isImmediate check 4 meses atrás
  Bee Hudson 71151ded11 Add isLabel function 4 meses atrás
  Bee Hudson 44bfc312ca Move hash of labels to global scope 4 meses atrás
  Bee Hudson 0fec9cea29 Rename test from simple to addition 4 meses atrás
  Bee Hudson f9e605ab12 Add comments to getAddress 4 meses atrás
  Bee Hudson 26da645f6e Switch parameter parsing to separate function 4 meses atrás
  Bee Hudson e82cab0e05 Consolidate final output 4 meses atrás
  Bee Hudson 7c162a5483 Swap substr for regex in getAddress 4 meses atrás
2 arquivos alterados com 55 adições e 30 exclusões
  1. 0 0
      tests/addition.icasm
  2. 55 30
      yaict.pl

+ 0 - 0
tests/simple.icasm → tests/addition.icasm


+ 55 - 30
yaict.pl

@@ -8,6 +8,8 @@ my $VERSION = 0.01;
 
 # The array of intcodes making up the program
 my @program;
+# A hash of labels and their corresponding starting line number
+my %labels;
 # Opcodes that may be encounted and their corresponding ints
 my %opcodes = (
     "add"   => "01",
@@ -41,8 +43,6 @@ sub parseAssembly
 {
 
     my @assembly = @_;
-    # A hash of labels and their corresponding starting line number
-    my %labels;
     # The current instruction number
     my $instructionNumber = 0;
 
@@ -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
@@ -114,12 +132,21 @@ sub parseOpcodeAndParams
 # Parameter is considered Position mode if it's prefixed with "0d"
 sub isImmediate
 {
-    return !(shift =~ /^0d/);
+    return shift =~ /^-?\d+$/;
 }
 
+# Check if a parameter
+sub isLabel
+{
+    $_[0] =~ /(\w+?)(?:\s*+\s*\d*)?/;
+    print "Testing: $_[0]\n";
+    return !!$labels{$1};
+}
+
+# Get the address a value represents
 sub getAddress
 {
-    return substr(shift, 2);
+    return (shift =~ s/^0d//r);
 }
 
 sub readFile
@@ -145,6 +172,4 @@ sub readFile
 
 parseAssembly(readFile($ARGV[0]));
 
-print "[".join(",", @program)."]";
-
-print "\n";
+print "[".join(",", @program)."]\n";