Also implement BRANCH
[rrq/jonasforth.git] / main.asm
index e5444b87a58ba20ad0f984627d05ef0e99efecec..f665f952ba5c44ffa02204c2528ee5f4ca090daa 100644 (file)
--- a/main.asm
+++ b/main.asm
@@ -59,6 +59,28 @@ LIT:
   push rax
   next
 
+;; 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:
+  ;; Compare top of stack to see if we should branch
+  pop rax
+  cmp rax, 0
+  jnz .dont_branch
+.do_branch:
+  jmp BRANCH.start
+.dont_branch:
+  add rsi, 8     ; We need to skip over the next word, which contains the offset.
+  next
+
 ;; Expects a character on the stack and prints it to standard output.
 EMIT:
   dq .start
@@ -138,7 +160,7 @@ READ_WORD:  ; 400170
 
 ;; Takes a string (in the form of a pointer and a length on the stack) and
 ;; prints it to standard output.
-TYPE:
+TELL:
   dq .start
 .start:
   mov rbx, rsi
@@ -196,9 +218,10 @@ MAIN:
   dq READ_WORD
   dq LIT, you_typed_string
   dq LIT, you_typed_string.length
-  dq TYPE
-  dq TYPE
+  dq TELL
+  dq TELL
   dq NEWLINE
+  dq BRANCH, -72
   dq HELLO
   dq TERMINATE