From cf4e6a88a19d8bbe42f0e41c1d9168009d3addab Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Sun, 3 May 2026 18:43:37 -0700 Subject: the heavy lifting of refilling a circular buffer is implemented now it's not hooked up to the read logic yet, and some of the finicky cases aren't fully tested yet because it will be necessary to alternate reads and refills a bit to exercise them. Force-Push: yes Change-Id: Ic7442787068ea4ae985832ae597531d7d7bdcea9 --- quine.asm | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 114 insertions(+), 12 deletions(-) diff --git a/quine.asm b/quine.asm index 806616b..3abbfc9 100644 --- a/quine.asm +++ b/quine.asm @@ -6258,20 +6258,13 @@ cold_start: 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, "swap", early_find, entry_to_execution_token, early_comma + ; (capacity in bytes, metadata pointer) dq litstring, "dup", early_find, entry_to_execution_token, early_comma dq litstring, "3unroll", 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 - ; (capacity in bytes, metadata pointer) dq litstring, "buffer-physical-length", early_find, entry_to_execution_token dq early_comma dq litstring, "!", early_find, entry_to_execution_token, early_comma @@ -8628,6 +8621,9 @@ defword sys_write, 0 next +; In: +; length +; address defword sys_read, 0 dq $ + 8 pop.qreg rcx ; address from stack @@ -11330,10 +11326,110 @@ defword boot_source, 0x40 dq " entry-to-name s"" docol"" stringcmp 0 = ; " + ; If the buffer is empty, make sure its logical position is at the + ; physical start. Otherwise, leave it alone. + ; + ; In: + ; pointer to buffer metadata + dq ": normalize-buffer " + dq " dup buffer-logical-length @ 0 = " + dq " { dup buffer-physical-start @ swap " + dq " buffer-logical-start ! } { drop } if-else " + dq " ; " + + + ; Find the next contiguous area of a buffer to write incoming data to. + ; This will begin at the logical end. Depending on the order things are in, + ; the available space might run from there to the physical end, or to the + ; logical start. Those are the only two possibilities. + ; + ; If the buffer is full, this will return as normal but the length will + ; be zero. The caller should make sure to respect that. + ; + ; In: + ; pointer to buffer metadata + ; Out: + ; destination start + ; destination length + dq ": compute-next-buffer-free-block " + dq " dup buffer-physical-start @ swap dup buffer-physical-length @ " + dq " swap 3unroll + swap " + ; (physical end, metadata pointer) + dq " dup buffer-logical-start @ swap dup buffer-logical-length @ " + dq " swap 3unroll + swap 3unroll " + ; (metadata pointer, physical end, logical end not yet wrapped) + + dq " 2dup >= " + dq " { " + ; If the logical end is greater than or equal to the physical end, find + ; where it wraps to and start from there. + dq " - swap dup buffer-physical-start @ swap 3unroll + " + ; (metadata pointer, destination start) + ; In this scenario, the logical start is the end of the free space, so + ; compute how far away it is. + dq " dup 3roll " + ; (destination start, destination start, metadata pointer) + dq " dup buffer-logical-start @ swap drop swap - } " + + dq " { " + dq " dup 3roll swap - " + ; If the logical end is less than the physical end, it is the destination; + ; the physical end is also the end of the free space, so compute how far + ; away it is. + dq " } if-else " + ; (metadata pointer, destination start, destination length) + dq " ; " + + + + ; In: + ; pointer to buffer metadata + dq ": refill-input-buffer-from-stdin " + dq " dup normalize-buffer " + dq " compute-next-buffer-free-block " + ; Check whether the buffer is full. If not, do a read. If so, that's not + ; an error, just clean up and take no action. + dq " dup { swap sys-read " + dq " dup -2 = " + dq " { drop drop s"" Read error."" emitstring 0 sys-exit } " + dq " { swap dup buffer-logical-length @ 3roll + " + dq " swap buffer-logical-length ! } if-else } " + dq " { drop drop } if-else ; " + + +; TODO this is the step for after refilling works +; dq ": relink-main-input-buffer-to-stdin " +; dq " 1024 allocate-input-buffer main-input-buffer ! " +; dq " ' refill-input-buffer-from-stdin entry-to-execution-token " +; dq " main-input-buffer @ input-buffer-refill ! " +; dq " main-input-buffer @ hexdump bye " +; dq " ; " +; ; In: +; ; pointer to buffer metadata +; dq ": attach-stdin-to-input-buffer " +; dq " dup buffer-physical-start here swap ! " +; ; (metadata pointer) +; dq " dup buffer-physical-end here 1024 + dup here ! swap ! " +; ; (metadata pointer) +; dq " dup buffer-physical-start @ swap dup 3unroll " +; dq " buffer-logical-start ! " +; dq " dup buffer-physical-end @ swap dup 3unroll " +; dq " buffer-logical-end ! " +; dq " hexdump ; " +; +; dq "main-input-buffer @ attach-stdin-to-input-buffer bye " +; dq "relink-main-input-buffer-to-stdin " +; dq ": hmm 16 here sys-read stack here hexdump ; hmm " + + ; The word named "docol" has the job of returning the value that gets used - ; as the actual codeword. We make the assumption that, if so, the codeword - ; will point somewhere near the entry header; we allow for the possibility - ; that it might be before or after. + ; as the actual codeword. We make the assumption that the codeword will + ; point somewhere near the entry header; we allow for the possibility that + ; it might be before or after. + ; + ; Generally, it's possible for there to be several copies of docol due to + ; alternate heaps and things like that, so the goal is to recognize any of + ; them. dq ": is-docol-codeword " dq " dup is-in-heap { drop 0 exit } unless " dq " containing-entry dup " @@ -11432,8 +11528,14 @@ defword boot_source, 0x40 ;dq "68719587456 containing-entry stackhex " ;dq "587456 containing-entry stackhex " ;dq "68719607808 containing-entry stackhex " - dq "list-dictionary " + ;dq "list-dictionary " ;dq "describe-all " + dq ": doittoit 16 allocate-input-buffer " + dq " dup stackhex refill-input-buffer-from-stdin " + dq " stackhex dup 256 hexdump-from " + dq " dup refill-input-buffer-from-stdin " + dq " stackhex dup 256 hexdump-from " + dq " bye ; doittoit " dq " " ; TODO define ( ... ) comments -- cgit 1.4.1