Also implement BRANCH
authorJonas Hvid <mail@johv.dk>
Sat, 23 Nov 2019 16:21:29 +0000 (17:21 +0100)
committerJonas Hvid <mail@johv.dk>
Sat, 23 Nov 2019 16:21:37 +0000 (17:21 +0100)
I feel like we should theoretically be able to implement this in terms of
0BRANCH, but since we don't have a mechanism for getting the "outer" value of
RSI inside the function, we can't just implement it as

  : BRANCH 0 0BRANCH ;

In that case, RSI would point to EXIT when executing 0BRANCH.

main.asm

index 4ddb26785e04a419d221f986de7c3ac223321f2a..f665f952ba5c44ffa02204c2528ee5f4ca090daa 100644 (file)
--- a/main.asm
+++ b/main.asm
@@ -59,9 +59,15 @@ LIT:
   push rax
   next
 
-;; 0BRANCH is the fundamental mechanism for branching. If the top of the stack
-;; is zero, we jump by the given offset. 0BRANCH is given the offset as an
-;; integer after the word.
+;; BRANCH is the fundamental mechanism for branching. BRANCH reads the next word
+;; as a signed integer literal and jumps by that offset.
+BRANCH:
+  dq .start
+.start:
+  add rsi, [rsi] ; [RSI], which is the next word, contains the offset; we add this to the instruction pointer.
+  next           ; Then, we can just continue execution as normal
+
+;; 0BRANCH is like BRANCH, but it jumps only if the top of the stack is zero.
 ZBRANCH:
   dq .start
 .start:
@@ -70,8 +76,7 @@ ZBRANCH:
   cmp rax, 0
   jnz .dont_branch
 .do_branch:
-  add rsi, [rsi] ; [RSI], which is the next word, contains the offset; we add this to the instruction pointer.
-  next           ; Then, we can just continue execution as normal
+  jmp BRANCH.start
 .dont_branch:
   add rsi, 8     ; We need to skip over the next word, which contains the offset.
   next
@@ -216,6 +221,7 @@ MAIN:
   dq TELL
   dq TELL
   dq NEWLINE
+  dq BRANCH, -72
   dq HELLO
   dq TERMINATE