summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-05-21 18:30:52 -0700
committerIrene Knapp <ireneista@irenes.space>2026-05-21 18:30:52 -0700
commit5183b72b296b82a6a39f8412a3de2ac77be92c73 (patch)
tree187e9784bd716093041651b82550bcb72c16846f
parentff09b120141e9d8acbd930d44c3f0596eb05a016 (diff)
okay, input buffers should work now (untested though)
the word "variable" also needed special treatment, in the same way that "keyword" did. it's not immediately clear why.

Force-Push: yes
Change-Id: I15fae39b1b9ec928281150c76260940717b8e27a
-rw-r--r--execution.e12
-rw-r--r--input.e101
-rw-r--r--transform.e63
3 files changed, 146 insertions, 30 deletions
diff --git a/execution.e b/execution.e
index e1b894d..ce4c2c4 100644
--- a/execution.e
+++ b/execution.e
@@ -478,7 +478,17 @@
 
   ~ (input string pointer, output buffer start, output point)
   3roll
-  log-load-transform ;
+  log-load-transform
+  ~ (output point)
+
+  ~   Now everything we need has been added to the log and we're almost ready
+  ~ to jump into it. It's inconvenient for code under the log-load transform
+  ~ to interact with the label system, so we initialize main-input-buffer
+  ~ here.
+  ~
+  ~ TODO or not ;)
+  ~ main-input-buffer boot-source attach-string-to-input-buffer
+  ;
 
 
 ~ Where next?
diff --git a/input.e b/input.e
index c7093e6..5cf2aeb 100644
--- a/input.e
+++ b/input.e
@@ -94,6 +94,88 @@
   buffer-logical-length ! ;
 
 
+~ (metadata pointer --)
+: consume-from
+  ~ If the length is zero, exit without doing anything.
+  dup buffer-logical-length @ 0 = 0branch [ 2 8 * , ] exit
+
+  ~ Decrement the logical length. We do this now to get it over with, since
+  ~ adjusting the start pointer is more complex.
+  dup buffer-logical-length dup @ 1 - swap !
+  ~ (metadata pointer)
+
+  ~ We compute the physical end. We'll need it in adjusting the logical start,
+  ~ and doing it now means less stack juggling later.
+  dup dup buffer-physical-start @ swap buffer-physical-length @ + swap
+  ~ (physical end, metadata pointer)
+
+  ~ Compute the incremented logical start.
+  dup buffer-logical-start @ 1 +
+  ~ (physical end, metadata pointer, updated start pointer)
+
+  ~ Check whether the updated start is equal to the physical end.
+  dup 4 roll =
+  ~ (metadata pointer, updated start, updated start, physical end)
+  0branch [ 5 8 * , ]
+
+  ~ If the logical start pointer is now equal to the physical end pointer,
+  ~ we want to wrap to the physical start. That's what makes it a circular
+  ~ buffer.
+  ~ (metadata pointer, updated start)
+  drop dup buffer-physical-start @
+
+  ~ However we got here, save the updated logical start pointer.
+  ~ (metadata pointer, updated start)
+  swap buffer-logical-start ! ;
+
+
+~ (metadata pointer -- byte or 0)
+: peek-from
+  dup buffer-logical-length @ 0 = 0branch [ 28 8 * , ]
+
+  ~ If the length is zero, there is no input, but we can still try calling
+  ~ the "refill" word.
+  ~ (metadata pointer)
+  dup input-buffer-refill @ dup 0branch [ 17 8 * , ]
+
+  ~ If the refill word is nonzero, call it. It expects a copy of the metadata
+  ~ pointer as its parameter, so set that up.
+  ~ (metadata pointer, refill word)
+  swap dup 3roll execute
+  ~ (metadata pointer)
+  ~ Now we check if the length is still zero.
+  dup buffer-logical-length @ 0 = 0branch [ 10 8 * , ]
+
+  ~ The length is zero even after calling the refill word, so return null.
+  ~ (metadata pointer)
+  drop 0 exit
+
+  ~ If the refill word is zero, we can't help, just return null.
+  ~ (metadata pointer, refill word)
+  drop drop 0 exit
+
+  ~   The buffer is non-empty, so read a byte from it. We might have reached
+  ~ this point either from the original check, or from the second check after
+  ~ calling the refill word.
+  ~
+  ~   While it might be more extensible to call an "unpack" word here, such as
+  ~ unpack8, we actually just want to get the value, and delegate the pointer
+  ~ adjustments to "consume".
+  ~
+  ~ (metadata pointer)
+  buffer-logical-start @ 8@ ;
+
+
+~ (metadata pointer)
+: key-from
+  dup peek-from
+  ~ (metadata pointer, result byte)
+  ~ We unconditionally consume, because we have no way to distinguish between
+  ~ reading a zero byte and having nothing left to read.
+  swap consume-from ;
+
+
+
 ~   Here we have some imperative code that runs immediately, to initialize
 ~ some runtime data structures.
 ~
@@ -109,19 +191,10 @@ s" main-input-buffer-metadata" find 0x01 entry-flags!
 allocate-input-buffer-metadata
 s" main-input-buffer" variable
 
-~   We also initialize the metadata here, pointing it to the boot source as
-~ its backing store. We could do that later, but it's convenient to do it
-~ here.
-~
-~ TODO attach it to something
-~ boot-source attach-string-to-input-buffer
-
+~   We'll leave it to warm-start, in execution.e, to attach the buffer. It's
+~ easier that way.
 
+: peek main-input-buffer peek-from ;
+: consume main-input-buffer consume-from ;
+: key main-input-buffer key-from ;
 
-~ TODO
-~ consume-from                                          00000010000187c0
-~ peek-from                                             0000001000018960
-~ key-from                                              0000001000018ab8
-~ peek                                                  0000001000018d20
-~ consume                                               0000001000018d50
-~ key                                                   0000001000018d88
diff --git a/transform.e b/transform.e
index 61ef373..6b2b64b 100644
--- a/transform.e
+++ b/transform.e
@@ -1779,26 +1779,57 @@ allocate-transform-state s" transform-state" variable
   ; make-immediate
 
 
-~ TODO there should really be an actual word that this alternate is replacing
-~
-~ If it existed, that word would be (string pointer --).
+: log-load-variable-alternate
+  ~   In immediate mode, we have special behavior because of the "here" magic.
+  ~ In compile mode, we compile a dynamic call, which is the same thing that
+  ~ would happen if we didn't have an alternate at all.
+  interpreter-flags @ 0x01 & {
+    s" variable" log-load-compile-dynamic-word
+  } {
+    ~   Calling log-load-create-alternate would result in some redundant rolling
+    ~ and unrolling, so we do it together like this instead.
+    log-load-roll-log-address
+
+    swap-transform-variables
+    L@' log-load-variable
+    L@' 3unroll
+    swap-transform-variables
+
+    offset-to-target-address-space ,     ~ 3unroll
+    offset-to-target-address-space ,     ~ log-load-variable
+
+    ~   We consumed the string and address, so we apply a delta.
+    -2 transform-apply-stack-delta
+
+    log-load-unroll-log-address
+  } if-else
+  ; make-immediate
+
+
 : log-load-keyword-alternate
-  ~   Calling log-load-create-alternate would result in some redundant rolling
-  ~ and unrolling, so we do it together like this instead.
-  log-load-roll-log-address
+  ~   In immediate mode, we have special behavior because of the "here" magic.
+  ~ In compile mode, we compile a dynamic call, which is the same thing that
+  ~ would happen if we didn't have an alternate at all.
+  interpreter-flags @ 0x01 & {
+    s" keyword" log-load-compile-dynamic-word
+  } {
+    ~   Calling log-load-create-alternate would result in some redundant rolling
+    ~ and unrolling, so we do it together like this instead.
+    log-load-roll-log-address
 
-  swap-transform-variables
-  L@' log-load-keyword
-  L@' swap
-  swap-transform-variables
+    swap-transform-variables
+    L@' log-load-keyword
+    L@' swap
+    swap-transform-variables
 
-  offset-to-target-address-space ,     ~ swap
-  offset-to-target-address-space ,     ~ log-load-keyword
+    offset-to-target-address-space ,     ~ swap
+    offset-to-target-address-space ,     ~ log-load-keyword
 
-  ~   We consumed the string, so we apply a delta.
-  -1 transform-apply-stack-delta
+    ~   We consumed the string, so we apply a delta.
+    -1 transform-apply-stack-delta
 
-  log-load-unroll-log-address
+    log-load-unroll-log-address
+  } if-else
   ; make-immediate
 
 
@@ -2130,6 +2161,8 @@ allocate-transform-state s" transform-state" variable
     swap drop ' log-load-right-square-brace-alternate swap } if
   dup s" '" stringcmp 0 = { swap drop ' log-load-tick-alternate swap } if
   dup s" ," stringcmp 0 = { swap drop ' log-load-comma-alternate swap } if
+  dup s" variable" stringcmp 0 = {
+    swap drop ' log-load-variable-alternate swap } if
   dup s" keyword" stringcmp 0 = {
     swap drop ' log-load-keyword-alternate swap } if
   dup s" ~" stringcmp 0 = {