summary refs log tree commit diff
path: root/quine.asm
diff options
context:
space:
mode:
Diffstat (limited to 'quine.asm')
-rw-r--r--quine.asm40
1 files changed, 38 insertions, 2 deletions
diff --git a/quine.asm b/quine.asm
index 9ffb10c..f9a5ad7 100644
--- a/quine.asm
+++ b/quine.asm
@@ -11112,7 +11112,7 @@ defword boot_source, 0x40
   dq ": } dup here @ swap - ; make-immediate                          "
 
   ; (start pointer, length)
-  dq ": if dup2 swap dup 5 8 * + 3unroll swap                         "
+  dq ": if 2dup swap dup 5 8 * + 3unroll swap                         "
   ; (start pointer, length, start pointer, adjusted start pointer, length)
   dq "  memmove                                                       "
   ; (start pointer, length)
@@ -11126,7 +11126,43 @@ defword boot_source, 0x40
   ; (old here, length)
   dq "  drop 5 8 * + here ! ; make-immediate                          "
 
-  dq ": foo 5 6 < { 42 . } if ; foo                                   "
+  ; (true start, true length, false start, false length)
+  dq ": if-else                                                       "
+  ;dq "  dup 4 roll dup 5 unroll +                                     "
+  ;
+  ;   First we slide the false-block forward, then the true-block. We slide
+  ; them both directly into their final positions, leaving space at the start
+  ; for a test and branch, and space in between for an unconditional branch.
+  ; Those spaces will take five words, and two words, respectively. So the
+  ; false-block gets moved by seven words, and the true-block gets moved by
+  ; five words.
+  dq "  2dup swap dup 7 8 * + swap 3roll memmove                      "
+  dq "  4 roll dup 5 unroll 4 roll dup 5 unroll                       "
+  dq "  swap dup 5 8 * + swap 3roll memmove                           "
+  ; (true start, true length, false start, false length)
+  ;
+  ;   Now we write out the initial test-and-branch.
+  dq "  4 roll dup 5 unroll here @ 6 unroll here !                    "
+  ; (old here, true start, true length, false start, false length)
+  dq "  ' lit entry-to-execution-token , 0 ,                          "
+  dq "  ' = entry-to-execution-token ,                                "
+  ;   Branch past the length field, the true-block, and the unconditional
+  ; branch in the middle.
+  dq "  ' 0branch entry-to-execution-token ,                          "
+  dq "  3roll dup 4 unroll 3 8 * + ,                                  "
+  ;
+  ;  Next, write out the unconditional branch in the middle.
+  dq "  swap dup 3unroll 5 8 * + here !                               "
+  dq "  ' branch entry-to-execution-token ,                           "
+  ;  Branch past the length field and the false-block.
+  dq "  dup 8 + ,                                                     "
+  ;
+  ;  Set "here" to point to the true end.
+  dq "  drop drop drop drop 7 8 * + here !                            "
+  dq "  ; make-immediate                                              "
+
+  dq ": foo 5 6 < { 42 . } if ; foo ' foo forget                      "
+  dq ": foo 5 6 > { 42 } { 69 } if-else . ; foo ' foo forget          "
 
   dq "                                                                "