some cleanup forthfixing
authorRalph Ronnquist <ralph.ronnquist@gmail.com>
Wed, 12 May 2021 01:40:53 +0000 (11:40 +1000)
committerRalph Ronnquist <ralph.ronnquist@gmail.com>
Wed, 12 May 2021 01:40:53 +0000 (11:40 +1000)
src/impl.asm
src/main.asm

index 2e7a037f6b41905e113e45dc1b2ef90ac4985dd9..150a8cf34c1f73a5687115083b4eca450b525ea6 100644 (file)
@@ -1,3 +1,6 @@
+;; This file provides a small collection of fundamental subroutines that
+;; are used by the core forth words.
+
 section '.text' code readable executable
 
 macro printlen msg, len {
@@ -71,7 +74,8 @@ find:
   ret
 
 ;; Read a word from a buffer. Returns the buffer without the word, as
-;; well as the word that was read (including lengths).
+;; well as the word that was read (including lengths). Treats space,
+;; tab and newline as whitespace.
 ;;
 ;; Inputs:
 ;;   * rsi = Input buffer
@@ -79,44 +83,51 @@ find:
 ;;
 ;; Outputs:
 ;;   * rsi = Updated buffer
-;;   * rcx = Length of updated buffer
-;;   * rdi = Word buffer
+;;   * rcx = Length of remaining buffer
+;;   * rdi = Word start in buffer
 ;;   * rdx = Length of word buffer
+
 pop_word:
+  mov rdx, 0
+  jmp .skip_whitespace
+
+.got_whitespace:
+  ;; The buffer starts with whitespace: consume that and try again.
+  ;; Note: indefinite
+  inc rsi
+  dec rcx
+  je .no_more
+
 .skip_whitespace:
   mov al, [rsi]
   cmp al, ' '
   je .got_whitespace
+  cmp al, 9
+  je .got_whitespace
   cmp al, $A
   je .got_whitespace
-  jmp .alpha
-.got_whitespace:
-  ;; The buffer starts with whitespace; discard the first character
-  ;; from the buffer.
-  inc rsi
-  dec rcx
-  jmp .skip_whitespace
 
-.alpha:
-  ;; We got a character that wasn't whitespace. Now read the actual
-  ;; word.
+  ;; We got a character that wasn't whitespace. Now read the actual word.
   mov rdi, rsi ; This is where the word starts
-  mov rdx, 1   ; Length of word
 
 .read_alpha:
+  inc rdx      ; Length of word
+
   ;; Extract character from original buffer:
   inc rsi
   dec rcx
+  je .no_more
 
   ;; When we hit whitespace, we are done with this word
   mov al, [rsi]
   cmp al, ' '
   je .end
+  cmp al, 9
+  je .end
   cmp al, $A
   je .end
 
-  ;; It wasn't whitespace; add it to word buffer
-  inc rdx
+  ;; It wasn't whitespace; include it in word
   jmp .read_alpha
 
 .end:
@@ -124,9 +135,11 @@ pop_word:
   inc rsi
   dec rcx
 
+.no_more:
+  ;; Buffer ended
   ret
 
-;; Parses a string.
+;; Parses a string of decimal digits
 ;;
 ;; Parameters:
 ;;   * rcx = Length of string
@@ -197,4 +210,3 @@ find.search_buffer dq ?
 
 parse_number.length dq ?
 parse_number.error_msg string "Invalid number: "
-
index 3914b11c72bf20fd41fa07d182203fc707b75ba7..ddecb23e2e021305218739223145972ecfa39a87 100644 (file)
@@ -31,14 +31,17 @@ macro next {
 }
 
 ;; pushr and popr work on the return stack, whose location is stored in the
-;; register RBP. Always allocates an extra 8 bytes as "local frame"
+;; register RBP. Always allocates an extra 8 bytes as "local frame
+;; variable".
+
 macro pushr x {
-  sub rbp, 8
+  sub rbp, 16
   mov qword [rbp], x
 }
+
 macro popr x {
   mov x, [rbp]
-  add rbp, 8
+  add rbp, 16
 }
 
 ;; The following macro generates the dictionary header. It updates the
@@ -76,6 +79,7 @@ macro forth_asm label, name, immediate {
 .start:
 }
 
+;; ############################################################
 section '.text' code readable executable
 
 include "impl.asm"      ; Misc. subroutines
@@ -179,9 +183,16 @@ forth_asm ZBRANCH, '0BRANCH'
                 ; the offset.
   next
 
-;; Push the return stack pointer. "grows" negatively
+;; Push the return stack pointer address. "grows" negatively
 forth_asm RSPGET, 'R='
-  push rbp
+  lea rax, [rbp]
+  push rax
+  next
+
+;; Push the address of the frame quad
+forth_asm RSP0, 'R1'
+  lea rax, [ rbp + 8 ]
+  push rax
   next
 
 ;; The return stack "grows" negatively, and rbp is the address of the top
@@ -193,7 +204,8 @@ forth_asm RSPADD, 'R+'
 
 ;; Push top of the stack.
 forth_asm TOP_, 'TOP'
-  push rsp
+  lea rax, [rsp]
+  push rax
   next
 
 ;; Duplicate the top of the stack.