Bugfix for BRZ and BMI commands that weren't advancing the PC past
authorAaron Taylor <ataylor@subgeniuskitty.com>
Thu, 11 Jul 2019 10:52:53 +0000 (03:52 -0700)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Thu, 11 Jul 2019 10:52:53 +0000 (03:52 -0700)
the included label when not following the branch.

tests/4100_flowcontrol_branches_not_taken.pvvs [new file with mode: 0644]
vv_interpreter.c
vv_test.py

diff --git a/tests/4100_flowcontrol_branches_not_taken.pvvs b/tests/4100_flowcontrol_branches_not_taken.pvvs
new file mode 100644 (file)
index 0000000..fc9c2d0
--- /dev/null
@@ -0,0 +1,15 @@
+# This test verifies correct program flow when not
+# following a conditional branch.
+
+SSSTSSSSSTN     | ST: Push +65 (ASCII A)
+SSSTN           | ST: Push +1
+NTSTSTSTSN      | FC: BRZ -> '42'
+SSSTN           | ST: Push +1
+NTTTSTSTSN      | FC: BMI -> '42'
+TNSS            | IO: Output character
+NNN             | FC: Terminate program
+
+NSSVTSTSTSN     | FC: Mark label '42'
+SSSTSSSSTSN     | ST: Push +66 (ASCII B)
+TNSS            | IO: Output character
+NNN             | FC: Terminate program
index 337fd61..b816c30 100644 (file)
@@ -118,7 +118,7 @@ parse_label(uint8_t * code, size_t * pc)
     uint8_t c;
     while ((c = code[(*pc)++]) != '\n') {
         label = label << 1;
     uint8_t c;
     while ((c = code[(*pc)++]) != '\n') {
         label = label << 1;
-        if (c == ' ') label++;
+        if (c == '\t') label++;
     }
     // TODO: Where should I handle attempts to access an unitialized label?
     //       For now, leave it undefined in a nasal demon sense.
     }
     // TODO: Where should I handle attempts to access an unitialized label?
     //       For now, leave it undefined in a nasal demon sense.
@@ -130,11 +130,10 @@ populate_labels(size_t * labels, uint8_t * code, size_t code_size)
 {
     size_t cp = 0;
     while (cp <= code_size) {
 {
     size_t cp = 0;
     while (cp <= code_size) {
-        if (code[cp] == '\v') {
+        if (code[cp++] == '\v') {
             uint16_t temp_label = parse_label(code, &cp);
             labels[temp_label] = cp;
         }
             uint16_t temp_label = parse_label(code, &cp);
             labels[temp_label] = cp;
         }
-        cp++;
     }
 }
 
     }
 }
 
@@ -248,6 +247,7 @@ void
 process_imp_flowcontrol(uint8_t * code, size_t * pc, int64_t ** sp, size_t * labels,
                         size_t ** rsp)
 {
 process_imp_flowcontrol(uint8_t * code, size_t * pc, int64_t ** sp, size_t * labels,
                         size_t ** rsp)
 {
+    size_t temp_pc;
     switch (next_code_byte(code,pc)) {
         case '\n':
             /* Technically another LF is required but we ignore it. */
     switch (next_code_byte(code,pc)) {
         case '\n':
             /* Technically another LF is required but we ignore it. */
@@ -266,11 +266,9 @@ process_imp_flowcontrol(uint8_t * code, size_t * pc, int64_t ** sp, size_t * lab
                         break;
                     case '\t':
                         /* Call a subroutine. */
                         break;
                     case '\t':
                         /* Call a subroutine. */
-                        {
-                            size_t temp_pc = labels[parse_label(code, pc)];
-                            *((*rsp)++) = *pc;
-                            *pc = temp_pc;
-                        }
+                        temp_pc = labels[parse_label(code, pc)];
+                        *((*rsp)++) = *pc;
+                        *pc = temp_pc;
                         break;
                     case '\n':
                         /* Jump unconditionally to a label. */
                         break;
                     case '\n':
                         /* Jump unconditionally to a label. */
@@ -287,11 +285,13 @@ process_imp_flowcontrol(uint8_t * code, size_t * pc, int64_t ** sp, size_t * lab
                 switch (next_code_byte(code,pc)) {
                     case ' ':
                         /* Jump to a label if TOS == 0 */
                 switch (next_code_byte(code,pc)) {
                     case ' ':
                         /* Jump to a label if TOS == 0 */
-                        if (stack_pop(sp) == 0) *pc = labels[parse_label(code, pc)];
+                        temp_pc = labels[parse_label(code, pc)];
+                        if (stack_pop(sp) == 0) *pc = temp_pc;
                         break;
                     case '\t':
                         /* Jump to a label if TOS < 0. */
                         break;
                     case '\t':
                         /* Jump to a label if TOS < 0. */
-                        if (stack_pop(sp) < 0) *pc = labels[parse_label(code, pc)];
+                        temp_pc = labels[parse_label(code, pc)];
+                        if (stack_pop(sp) < 0) *pc = temp_pc;
                         break;
                     case '\n':
                         /* Return from subroutine. */
                         break;
                     case '\n':
                         /* Return from subroutine. */
index 2cdadd9..a2779ab 100755 (executable)
@@ -32,6 +32,7 @@ tests = [
         ['4004_flowcontrol_jump_if_tos_is_negative', '', 'A'],
         ['4005_flowcontrol_jump_to_subroutine', '', 'A'],
         ['4006_flowcontrol_return_from_subroutine', '', 'A'],
         ['4004_flowcontrol_jump_if_tos_is_negative', '', 'A'],
         ['4005_flowcontrol_jump_to_subroutine', '', 'A'],
         ['4006_flowcontrol_return_from_subroutine', '', 'A'],
+        ['4100_flowcontrol_branches_not_taken', '', 'A'],
         ['5001_io_output_character', '', 'A'],
         ['5002_io_output_digit', '', '2'],
         ['5003_io_input_character', 'A', 'A'],
         ['5001_io_output_character', '', 'A'],
         ['5002_io_output_digit', '', '2'],
         ['5003_io_input_character', 'A', 'A'],