From 7504fa3a7926282fffc4b7c9a34073aafeeda7c1 Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Fri, 28 Nov 2025 14:45:16 -0800 Subject: 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 --- quine.asm | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file 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 -- cgit 1.4.1