summary refs log tree commit diff
path: root/quine.asm
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2025-11-28 14:45:16 -0800
committerIrene Knapp <ireneista@irenes.space>2025-11-28 14:45:16 -0800
commit7504fa3a7926282fffc4b7c9a34073aafeeda7c1 (patch)
tree910ed7bd742b3057ec4305be8bce80d834e5286e /quine.asm
parent47207b87dcd376b835cd4470e9fcfc19329c9b7e (diff)
all the basic Forth words are implemented on the heap now
yay

the assembly-defining words are still not

Force-Push: yes
Change-Id: I561a9304741f98d8f30209d3ba1c3bec9b84c950
Diffstat (limited to 'quine.asm')
-rw-r--r--quine.asm110
1 files changed, 99 insertions, 11 deletions
diff --git a/quine.asm b/quine.asm
index 5206368..5d79b36 100644
--- a/quine.asm
+++ b/quine.asm
@@ -2434,6 +2434,15 @@ cold_start:
   dq rsi, pop_reg64
   dq pack_next, lit, 8, packalign, early_here_store
 
+  ;   This one has the honor of being the first word written in Forth. To do
+  ; that, it needs to be able to look up the words we've defined so far, to
+  ; reference them. We have a valid dictionary data structure, and early_find
+  ; is able to search it, so we can do that.
+  ;
+  ;   One thing to be cautious of is that if we inadvertently reference a word
+  ; by the wrong name, we'll get the copy that's statically included in the
+  ; ELF, rather than the copy on the heap. Watch carefully for that, with all
+  ; the lookups from here on.
   dq litstring, "emitstring", early_create, early_docol_codeword
   dq litstring, "dup", early_find, early_comma
   dq litstring, "stringlen", early_find, early_comma
@@ -2453,49 +2462,128 @@ cold_start:
   ; because the user of pack64 and its variants is always doing something
   ; where exact byte sizes are crucial.
   dq litstring, "pack64", early_create, early_docol_codeword
-  ; TODO this is actually in Forth
+  dq litstring, "swap", early_find, early_comma
+  dq litstring, "dup", early_find, early_comma
+  dq litstring, "3unroll", early_find, early_comma
+  dq litstring, "store", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 8, early_comma
+  dq litstring, "+", early_find, early_comma
+  dq litstring, "exit", early_find, early_comma
   dq early_here, fetch, lit, 8, packalign, early_here_store
 
   dq litstring, "pack32", early_create, early_docol_codeword
-  ; TODO this is actually in Forth
+  dq litstring, "swap", early_find, early_comma
+  dq litstring, "dup", early_find, early_comma
+  dq litstring, "3unroll", early_find, early_comma
+  dq litstring, "store32", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 4, early_comma
+  dq litstring, "+", early_find, early_comma
+  dq litstring, "exit", early_find, early_comma
   dq early_here, fetch, lit, 8, packalign, early_here_store
 
   dq litstring, "pack16", early_create, early_docol_codeword
-  ; TODO this is actually in Forth
+  dq litstring, "swap", early_find, early_comma
+  dq litstring, "dup", early_find, early_comma
+  dq litstring, "3unroll", early_find, early_comma
+  dq litstring, "store16", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 2, early_comma
+  dq litstring, "+", early_find, early_comma
+  dq litstring, "exit", early_find, early_comma
   dq early_here, fetch, lit, 8, packalign, early_here_store
 
   dq litstring, "pack8", early_create, early_docol_codeword
-  ; TODO this is actually in Forth
+  dq litstring, "swap", early_find, early_comma
+  dq litstring, "dup", early_find, early_comma
+  dq litstring, "3unroll", early_find, early_comma
+  dq litstring, "store8", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 1, early_comma
+  dq litstring, "+", early_find, early_comma
+  dq litstring, "exit", early_find, early_comma
   dq early_here, fetch, lit, 8, packalign, early_here_store
 
   dq litstring, "packstring", early_create, early_docol_codeword
-  ; TODO this is actually in Forth
+  dq litstring, "dup", early_find, early_comma
+  dq litstring, "stringlen", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 1, early_comma
+  dq litstring, "+", early_find, early_comma
+  dq litstring, "dup", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 4, early_comma
+  dq litstring, "roll", early_find, early_comma
+  dq litstring, "dup", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 5, early_comma
+  dq litstring, "unroll", early_find, early_comma
+  dq litstring, "+", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 4, early_comma
+  dq litstring, "unroll", early_find, early_comma
+  dq litstring, "memcopy", early_find, early_comma
+  dq litstring, "exit", early_find, early_comma
   dq early_here, fetch, lit, 8, packalign, early_here_store
 
   dq litstring, "packalign", early_create, early_docol_codeword
-  ; TODO this is actually in Forth
+  dq litstring, "2dup", early_find, early_comma
+  dq litstring, "/%", early_find, early_comma
+  dq litstring, "drop", early_find, early_comma
+  dq litstring, "0branch", early_find, early_comma
+  dq lit, 8*8, early_comma
+  dq litstring, "swap", early_find, early_comma
+  dq litstring, "lit", early_find, early_comma
+  dq lit, 0, early_comma
+  dq litstring, "pack8", early_find, early_comma
+  dq litstring, "swap", early_find, early_comma
+  dq litstring, "branch", early_find, early_comma
+  dq lit, -11*8, early_comma
+  dq litstring, "drop", early_find, early_comma
+  dq litstring, "exit", early_find, early_comma
   dq early_here, fetch, lit, 8, packalign, early_here_store
 
   dq litstring, "litpack64", early_create, early_self_codeword
   dq early_here, fetch
-  ; TODO
+  dq lods64
+  dq rax, push_reg64
+  ; ("heap", modified "here")
+  dq swap, litstring, "pack64", early_find, entry_to_execution_token
+  ; (modified "here", "heap", execution token)
+  dq swap, unroll3, pack_beforenext
   dq lit, 8, packalign, early_here_store
 
   dq litstring, "litpack32", early_create, early_self_codeword
   dq early_here, fetch
-  ; TODO
+  dq lods64
+  dq rax, push_reg64
+  ; ("heap", modified "here")
+  dq swap, litstring, "pack32", early_find, entry_to_execution_token
+  ; (modified "here", "heap", execution token)
+  dq swap, unroll3, pack_beforenext
   dq lit, 8, packalign, early_here_store
 
   dq litstring, "litpack16", early_create, early_self_codeword
   dq early_here, fetch
-  ; TODO
+  dq lods64
+  dq rax, push_reg64
+  ; ("heap", modified "here")
+  dq swap, litstring, "pack16", early_find, entry_to_execution_token
+  ; (modified "here", "heap", execution token)
+  dq swap, unroll3, pack_beforenext
   dq lit, 8, packalign, early_here_store
 
   ; This name is exactly eight bytes long. Don't even ask (go read litstring's
   ; code if you really need to know).
   dq litstring, "litpack8", 0, early_create, early_self_codeword
   dq early_here, fetch
-  ; TODO
+  dq lods64
+  dq rax, push_reg64
+  ; ("heap", modified "here")
+  dq swap, litstring, "pack8", early_find, entry_to_execution_token
+  ; (modified "here", "heap", execution token)
+  dq swap, unroll3, pack_beforenext
   dq lit, 8, packalign, early_here_store
 
   ;;; For triage's sake, here's an inventory of everything else in the file.
@@ -4848,7 +4936,7 @@ defword pack_next, 0
 ; Stack out:
 ;   new base address
 defword pack_beforenext, 0
-  dq docol, rax, swap, mov_reg64_imm64, rax, jmp_abs_indirect_reg64, exit
+  dq docol, rax, mov_reg64_imm64, rax, jmp_abs_indirect_reg64, exit
 
 ;   This is another helper "macro" that we'll use in defining assembly words
 ; from Forth. In particular, this one is used in docol. As before, see the