commit c54d77850972826175e624f376825362906ece84
parent ad1ee3243fe6a83760842cbf5c6b13fcb253cc0e
Author: Christian Ermann <christianermann@gmail.com>
Date: Sat, 16 Dec 2023 13:56:51 -0500
Add FIND
Diffstat:
M | forth.asm | | | 58 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
1 file changed, 56 insertions(+), 2 deletions(-)
diff --git a/forth.asm b/forth.asm
@@ -279,7 +279,7 @@ macro set_program init_stack_macro, program_label {
;
defcode "EMIT", 4, 0, EMIT
-; Print a character.
+; Print a character.
;
; The character is temporarily stored in the `.char_buffer` local variable.
; `.char_buffer` is defined as a 1-byte variable in the data section at the
@@ -353,15 +353,69 @@ defcode "WORD", 4, 0, WORD_
push rdx
NEXT
+defcode "FIND", 4, 0, FIND
+ pop rcx ; string length
+ pop rdi ; string address
+
+ push rsi
+ mov rdx, link
+
+.match_word:
+ test rdx, rdx ; check if null (start of dictionary / out of words)
+ je .end
+
+ movzx rax, byte [rdx + 9] ; al = name length
+
+ ; TEMP: print current word for debugging
+ push rax
+ push rcx
+ push rdx
+ push rdi
+ lea rcx, [rdx + 10]
+ mov rdx, rax
+ call sys_print_string
+ pop rdi
+ pop rdx
+ pop rcx
+ pop rax
+
+ cmp cl, al ; check if word lengths match
+ jne .next_word
+
+ push rdi ; Save word address
+ push rcx ; Save word length
+ lea rsi, [rdx + 10] ; Get word name address
+
+ ; RSI = src string
+ ; RDI = dst string
+ ; RCX = # of characters to compare
+ repe cmpsb
+ pop rcx
+ pop rdi
+
+ jne .next_word
+
+.end:
+ pop rsi
+ push rdx
+ mov rax, rdx
+ NEXT
+
+.next_word:
+ mov rdx, [rdx]
+ jmp .match_word
+
+
macro initialize_stack_s4 {
push version_string
push version_string.length
+ mov rdx, [link]
}
program_s4:
dq TYPE
dq WORD_
- dq TYPE
+ dq FIND
set_program initialize_stack_s4, program_s4