10 FIB .U
SPACE S" (Expected: 59)" TELL NEWLINE
+S" Word:" TELL NEWLINE
+SYSCODE POP-WORD TELL NEWLINE
+S" Remaining:" TELL NEWLINE
+TELL
+
TERMINATE
ret
+;; Read a word from a buffer. Returns the buffer without the word, as well as
+;; the word that was read (including lengths).
+;;
+;; Inputs:
+;; * rsi = Input buffer
+;; * rcx = Length of buffer
+;;
+;; Outputs:
+;; * rsi = Updated buffer
+;; * rcx = Length of updated buffer
+;; * rdi = Word buffer
+;; * rdx = Length of word buffer
+pop_word:
+ mov rdi, rsi
+ mov rdx, 10
+
+ add rsi, 10
+ sub rcx, 10
+
+ ret
+
;; Parses a string.
;;
;; Parameters:
mov rsi, [.rsi]
next
+;; Read a word from a buffer. Expects (buffer buffer-length) on the stack.
+;; Updates buffer and buffer-length, such that the word has been removed from
+;; the buffer. Appends (word-buffer word-buffer-length) to the stack.
+forth_asm POP_WORD, 'POP-WORD'
+ pushr rsi
+
+ pop rcx ; Length
+ pop rsi ; Buffer
+
+ call pop_word
+
+ push rsi ; Updated buffer
+ push rcx ; Length of updated buffer
+ push rdi ; Word buffer
+ push rdx ; Length of word buffer
+
+ popr rsi
+ next
+
;; Takes a string on the stack and replaces it with the decimal number that the
;; string represents.
forth_asm PARSE_NUMBER, 'PARSE-NUMBER'
dq LIT, here
dq EXIT
+forth SYSCODE, 'SYSCODE'
+ dq LIT, sysf
+ dq LIT, sysf.len
+ dq EXIT
+
segment readable writable
;; The LATEST variable holds a pointer to the word that was last added to the
;; Return stack
rq $2000
return_stack_top:
+
+segment readable
+
+;; We store some Forth code in sys.f that defined common words that the user
+;; would expect to have available at startup. To execute these words, we just
+;; include the file directly in the binary, and then interpret it at startup.
+sysf file 'sys.f'
+sysf.len = $ - sysf
+