summary refs log tree commit diff
path: root/quine.asm
diff options
context:
space:
mode:
Diffstat (limited to 'quine.asm')
-rw-r--r--quine.asm391
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.