diff options
| -rw-r--r-- | quine.asm | 391 |
1 files changed, 390 insertions, 1 deletions
diff --git a/quine.asm b/quine.asm index e9f15fd..4c68373 100644 --- a/quine.asm +++ b/quine.asm @@ -5871,7 +5871,367 @@ cold_start: dq litstring, "exit", early_find, entry_to_execution_token, early_comma dq early_here, fetch, lit, 8, packalign, early_here_store - dq early_describe_all, lit, 0, sys_exit + ;;; Now here we have some "original" words that rely on the heap and don't + ;;; have flatassembler-based equivalents. + + ; In: + ; name string + dq litstring, "create", early_create, early_docol_codeword + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "@", early_find, entry_to_execution_token, early_comma + dq litstring, "latest", early_find, entry_to_execution_token, early_comma + dq litstring, "@", early_find, entry_to_execution_token, early_comma + dq litstring, "pack64", early_find, entry_to_execution_token, early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 0, early_comma + dq litstring, "pack8", early_find, entry_to_execution_token, early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 0, early_comma + dq litstring, "pack8", early_find, entry_to_execution_token, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "packstring", early_find, entry_to_execution_token + dq early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 8, early_comma + dq litstring, "packalign", early_find, entry_to_execution_token, early_comma + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "@", early_find, entry_to_execution_token, early_comma + dq litstring, "latest", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; In: + ; value to append to current word-in-progress + dq litstring, ",", early_create, early_docol_codeword + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "@", early_find, entry_to_execution_token, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "pack64", early_find, entry_to_execution_token, early_comma + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + dq litstring, "self-codeword", early_create, early_docol_codeword + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "@", early_find, entry_to_execution_token, early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 8, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, ",", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; In: + ; address for new variable word to return + ; name string + dq litstring, "variable", 0, early_create, early_docol_codeword + dq litstring, "create", early_find, entry_to_execution_token, early_comma + dq litstring, "self-codeword", early_find, entry_to_execution_token + dq early_comma + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "@", early_find, entry_to_execution_token, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, ":rax", early_find, entry_to_execution_token, early_comma + dq litstring, "mov-reg64-imm64", early_find, entry_to_execution_token + dq early_comma + dq litstring, ":rax", early_find, entry_to_execution_token, early_comma + dq litstring, "push-reg64", early_find, entry_to_execution_token + dq early_comma + dq litstring, "pack-next", early_find, entry_to_execution_token, early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 8, early_comma + dq litstring, "packalign", early_find, entry_to_execution_token, early_comma + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; Allocates bytes on the heap by incrementing the global "here" pointer. + ; The "here" pointer is kept aligned to an 8-byte boundary, regardless of + ; the size requested. + ; + ; This does not create dictionary entries, it's just a raw memory + ; interface. It's suitable for allocating data or scratch space. + ; + ; In: + ; size in bytes + ; Out: + ; pointer to start + dq litstring, "allocate", 0, early_create, early_docol_codeword + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "@", early_find, entry_to_execution_token, early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + ; (size, here value, here value) + dq litstring, "3roll", early_find, entry_to_execution_token, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 8, early_comma + dq litstring, "packalign", early_find, entry_to_execution_token, early_comma + dq litstring, "here", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; In: + ; pointer to buffer metadata + ; Out: + ; pointer to buffer "physical-start" field + dq litstring, "buffer-physical-start", early_create, early_docol_codeword + ; The physical-start field happens to be the first thing in the metadata, so + ; this is an nop, but it still exists as a word because having it reduces + ; confusion. + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; In: + ; pointer to buffer metadata + ; Out: + ; pointer to buffer "physical-end" field + dq litstring, "buffer-physical-end", early_create, early_docol_codeword + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 8, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; In: + ; pointer to buffer metadata + ; Out: + ; pointer to buffer "logical-start" field + dq litstring, "buffer-logical-start", early_create, early_docol_codeword + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 2*8, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; In: + ; pointer to buffer metadata + ; Out: + ; pointer to buffer "logical-end" field + dq litstring, "buffer-logical-end", early_create, early_docol_codeword + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 3*8, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; In: + ; pointer to input buffer metadata + ; Out: + ; pointer to input buffer "refill" field + dq litstring, "input-buffer-refill", early_create, early_docol_codeword + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 4*8, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; Given an initialized buffer (input or otherwise), sets its "start" and + ; "end" pointers to indicate the buffer is empty. This relies on the buffer + ; having a backing store attached, but does not alter the backing store or + ; its contents. + ; + ; In: + ; pointer to buffer metadata + dq litstring, "clear-buffer", early_create, early_docol_codeword + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-physical-start", early_find, entry_to_execution_token + dq early_comma + dq litstring, "@", early_find, entry_to_execution_token, early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "3roll", early_find, entry_to_execution_token, early_comma + ; (address of backing store, address of backing store, metadata pointer) + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "3unroll", early_find, entry_to_execution_token, early_comma + ; (address of backing store, metadata pointer, + ; address of backing store, metadata pointer) + dq litstring, "buffer-logical-start", early_find, entry_to_execution_token + dq early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-logical-end", early_find, entry_to_execution_token + dq early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; Sets all fields in an input buffer metadata structure to zero, + ; effectively detaching and leaking any backing store that had been attached + ; to it. Suitable for use during initialization. + ; + ; In: + ; pointer to input buffer metadata + dq litstring, "zero-input-buffer-metadata", early_create + dq early_docol_codeword + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-physical-start", early_find, entry_to_execution_token + dq early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 0, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-physical-end", early_find, entry_to_execution_token + dq early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 0, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-logical-start", early_find, entry_to_execution_token + dq early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 0, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-logical-end", early_find, entry_to_execution_token + dq early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 0, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + ; Notice the absence of a dup this time. + dq litstring, "input-buffer-refill", early_find, entry_to_execution_token + dq early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 0, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; Allocates buffer metadata, with no backing store attached. Initializes + ; the metadata to all zeroes. + ; + ; Out: + ; pointer to buffer metadata + dq litstring, "allocate-input-buffer-metadata", early_create + dq early_docol_codeword + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 5*8, early_comma + dq litstring, "allocate", 0, early_find, entry_to_execution_token + dq early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "zero-input-buffer-metadata", early_find + dq entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; Allocates input buffer metadata and a backing store, in one operation. + ; Points the metadata to the backing store. + ; + ; In: + ; buffer capacity in bytes + ; Out: + ; pointer to buffer metadata + dq litstring, "allocate-input-buffer", early_create, early_docol_codeword + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 5*8, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, "allocate", 0, early_find, entry_to_execution_token + dq early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "zero-input-buffer-metadata", early_find + dq entry_to_execution_token, early_comma + ; (capacity in bytes, metadata pointer) + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "lit", early_find, entry_to_execution_token, early_comma + dq lit, 5*8, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + ; (capacity in bytes, metadata pointer, metadata pointer, physical start) + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "3unroll", early_find, entry_to_execution_token, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-physical-start", early_find, entry_to_execution_token + dq early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + ; (capacity in bytes, metadata pointer, physical start) + dq litstring, "3roll", early_find, entry_to_execution_token, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "3unroll", early_find, entry_to_execution_token, early_comma + ; (metadata pointer, physical end, metadata pointer) + dq litstring, "buffer-physical-end", early_find, entry_to_execution_token + dq early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + ; (metadata pointer) + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "clear-buffer", early_find, entry_to_execution_token + dq early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ; Sets the backing store of an input buffer to point at a null-teriminated + ; string and read from it. + ; + ; In: + ; pointer to string + ; pointer to buffer metadata + dq litstring, "attach-string-to-input-buffer", early_create + dq early_docol_codeword + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + ; (string pointer, metadata pointer) + dq litstring, "2dup", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-physical-start", early_find, entry_to_execution_token + dq early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + ; (string pointer, metadata pointer) + dq litstring, "2dup", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-logical-start", early_find, entry_to_execution_token + dq early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + ; (string pointer, metadata pointer) + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + dq litstring, "dup", early_find, entry_to_execution_token, early_comma + dq litstring, "stringlen", early_find, entry_to_execution_token, early_comma + dq litstring, "+", early_find, entry_to_execution_token, early_comma + dq litstring, "swap", early_find, entry_to_execution_token, early_comma + ; (string end pointer, metadata pointer) + dq litstring, "2dup", early_find, entry_to_execution_token, early_comma + dq litstring, "buffer-physical-end", early_find, entry_to_execution_token + dq early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + ; (string end pointer, metadata pointer) + dq litstring, "buffer-logical-end", early_find, entry_to_execution_token + dq early_comma + dq litstring, "!", early_find, entry_to_execution_token, early_comma + dq litstring, "exit", early_find, entry_to_execution_token, early_comma + dq early_here, fetch, lit, 8, packalign, early_here_store + + ;;; Initialize our runtime data structures. + ; (heap pointer) + dq litstring, "allocate-input-buffer-metadata", early_find + dq entry_to_execution_token, execute + ; (heap pointer, metadata pointer) + dq swap, litstring, "attach-string-to-input-buffer", early_find + ; (metadata pointer, heap pointer, entry pointer) + dq entry_to_execution_token, swap, unroll3 + ; (heap pointer, metadata pointer, execution token) + dq swap, dup, unroll3 + ; (heap pointer, metadata pointer, execution token, metadata pointer) + dq lit, boot_source, roll3 + ; (heap pointer, metadata pointer, metadata pointer, string pointer, + ; execution token) + dq execute + ; (heap pointer, metadata pointer) + dq swap, litstring, "variable", 0, early_find, entry_to_execution_token + ; (metadata pointer, heap pointer, execution token) + dq swap, unroll3 + ; (heap pointer, metadata pointer, execution token) + dq litstring, "main-input-buffer", swap + ; (heap pointer, metadata pointer, string pointer, execution token) + dq execute + dq litstring, "main-input-buffer", early_find, entry_to_execution_token + dq execute + dq lit, 0, sys_exit ;;; For triage's sake, here's an inventory of everything else in the file. ;;; @@ -8787,6 +9147,28 @@ defword show_source_or_hex_between, 0 dq show_source_between, exit +;;;;;;;;;;;;;; +;;; Lexing ;;; +;;;;;;;;;;;;;; + + +; In: +; next input address +; Out: +; next input address (updated) +; input byte +defword key, 0 + dq docol + dq dup, dup, lit, -8, and, fetch, swap, lit, 7, and + ; (next input address, 64-bit input word, byte index within word) + dq dup, zbranch, 13*8 + dq lit, 1, sub, swap, lit, 256, divmod, swap, drop, swap, branch, -14*8 + dq drop, lit, 0xFF, and + dq swap, lit, 1, add, swap + dq exit + + + ;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Heap bootstrapping ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -9320,6 +9702,13 @@ defword self_raw, 0 dq memcopy dq exit + +defword foo, 0 + dq docol, litstring, "foooooooo", emitstring, exit +defword boot_source, 0 + dq "foo " + dq 0 + ; Routines that traverse the raw code need a way to guess where the end of a ; word's contents are, lest they traverse off the edge of the world and ; segfault. On the heap, we have the "here" pointer to provide an upper bound. |