diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-05-21 18:30:52 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-05-21 18:30:52 -0700 |
| commit | 5183b72b296b82a6a39f8412a3de2ac77be92c73 (patch) | |
| tree | 187e9784bd716093041651b82550bcb72c16846f | |
| parent | ff09b120141e9d8acbd930d44c3f0596eb05a016 (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.e | 12 | ||||
| -rw-r--r-- | input.e | 101 | ||||
| -rw-r--r-- | transform.e | 63 |
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 = { |