Embed sys.f into binary and start working on POP-WORD
authorJonas Hvid <mail@johv.dk>
Sun, 8 Mar 2020 14:27:49 +0000 (15:27 +0100)
committerJonas Hvid <mail@johv.dk>
Sun, 8 Mar 2020 14:27:49 +0000 (15:27 +0100)
Makefile
example.f
impl.asm
main.asm

index 1bfaabe82ac9c90f294f7c2fc0f7f7e7f9620cd3..cb7bff3854cd40502f74373033635311c96e5f55 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 run: main
        cat sys.f - | ./main
 
-main: main.asm impl.asm bootstrap.asm
+main: main.asm impl.asm bootstrap.asm sys.f
        fasm $< $@
 
 .PHONY: clean
index 41993d73ba877de3f7c7c72491ecee6318a43d80..547887f2894b1be397683889ffd475c87904a2f0 100644 (file)
--- a/example.f
+++ b/example.f
@@ -25,4 +25,9 @@ S" 10 FIB = " TELL
 10 FIB .U
 SPACE S" (Expected: 59)" TELL NEWLINE
 
+S" Word:" TELL NEWLINE
+SYSCODE POP-WORD TELL NEWLINE
+S" Remaining:" TELL NEWLINE
+TELL
+
 TERMINATE
index a9b8564e19faeb9c6bdf3ed7b8906f1dccf7d533..c713036c82afb2743c45a547e4b315ac4bf41ba4 100644 (file)
--- a/impl.asm
+++ b/impl.asm
@@ -129,6 +129,27 @@ read_word:
 
   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:
index 538039b5ab29b0cd402d26105e3df89d3c5f2424..c9a7fc42acc1d9deb022010648f9c36c1aab30ee 100644 (file)
--- a/main.asm
+++ b/main.asm
@@ -207,6 +207,25 @@ forth_asm READ_WORD, 'READ-WORD'
   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'
@@ -505,6 +524,11 @@ forth HERE, 'HERE'
   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
@@ -538,3 +562,12 @@ here_top rq $4000
 ;; 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
+