diff options
Diffstat (limited to 'input.e')
| -rw-r--r-- | input.e | 101 |
1 files changed, 87 insertions, 14 deletions
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 |