summary refs log tree commit diff
diff options
context:
space:
mode:
-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 = {