diff options
Diffstat (limited to 'transform.e')
| -rw-r--r-- | transform.e | 117 |
1 files changed, 105 insertions, 12 deletions
diff --git a/transform.e b/transform.e index 7af668b..581cb0b 100644 --- a/transform.e +++ b/transform.e @@ -312,11 +312,14 @@ allocate-transform-state s" transform-state" variable : describe-transformation - ." active here " here @ .hex64 space ." latest " latest @ .hex64 newline - ." saved here " transform-state transform-state-saved-here + ." active here " here @ .hex64 space + ." latest " latest @ .hex64 newline + ." saved here " transform-state transform-state-saved-here @ .hex64 space ." latest " transform-state transform-state-saved-latest @ .hex64 newline - ." output start " transform-state transform-state-output-buffer-start + ." output start " transform-state transform-state-output-buffer-start + @ .hex64 newline + ." user stack depth " transform-state transform-state-user-stack-depth @ .hex64 newline ; @@ -1464,12 +1467,14 @@ allocate-transform-state s" transform-state" variable ~ As usual, we do these in reverse. L@' log-load-comma L@' log-load-comma + L@' log-load-find-execution-token L@' litstring swap-transform-variables ~ The overall stack delta of this sequence is 0. offset-to-target-address-space , ~ litstring here @ s" lit" packstring 8 packalign here ! + offset-to-target-address-space , ~ log-load-find-execution-token offset-to-target-address-space , ~ log-load-comma swap , ~ the value offset-to-target-address-space , ~ log-load-comma @@ -1482,24 +1487,27 @@ allocate-transform-state s" transform-state" variable ~ creating an entry on the log directly, its job is to output words which, ~ when they're later executed, will do create's job. ~ -~ The implementations of log-load-find-execution-token and log-load-create -~ are in log-load.e. +~ In practice that means outputting a codeword pointer to run a +~ statically-compiled word that does the work. The implementation of +~ log-load-create is in log-load.e. ~ -~ (string pointer --) +~ It's worth keeping in mind that this alternate only gets called for +~ manual invocations of "create". It isn't called from the colon alternate. : log-load-create-alternate log-load-roll-log-address swap-transform-variables - ~ Just like in log-load-compile-dynamic-word, we do this in reverse. L@' log-load-create - L@' litstring + L@' swap swap-transform-variables ~ The overall stack delta of this sequence is 0. - offset-to-target-address-space , ~ litstring - swap here @ swap packstring 8 packalign here ! + offset-to-target-address-space , ~ swap offset-to-target-address-space , ~ log-load-create + ~ We've consumed a string pointer from the stack, so that's a delta of -1. + -1 transform-apply-stack-delta + log-load-unroll-log-address ; @@ -1508,8 +1516,25 @@ allocate-transform-state s" transform-state" variable ~ to be extremely useful to read and understand ":" in interpret.e before ~ attempting to understand "log-load-colon-alternate". : log-load-colon-alternate - ~ This calls "log-load-create" instead of "create". - word value@ log-load-create-alternate dropstring + word value@ + + ~ 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-create + L@' litstring + swap-transform-variables + + ~ The overall stack delta of this sequence is 0. + offset-to-target-address-space , ~ litstring + swap here @ swap packstring 8 packalign here ! + offset-to-target-address-space , ~ log-load-create + + log-load-unroll-log-address + + dropstring ~ We generate code that looks up "docol" by name, runs it to get the ~ codeword pointer, then finally appends it to the entry. @@ -1575,6 +1600,65 @@ allocate-transform-state s" transform-state" variable ; make-immediate +~ This just does the same thing [ always does, but having it as an alternate +~ means it happens at transformation time, which is sooner than "immediate" +~ time. The log load transform is weird like that, it has three different +~ times things can happen, rather than the usual two. +: log-load-left-square-brace-alternate + ~ Since [ is an immediate word, we have to go to extra trouble to compile + ~ it as part of the alternate. + [ ' [ entry-to-execution-token , ] + ; make-immediate + +~ We need this one, too. It's not even an immediate word normally! +: log-load-right-square-brace-alternate ] ; make-immediate + +~ Yeah comments have to go. +: log-load-tilde-alternate + ' ~ entry-to-execution-token execute + ; make-immediate + +~ Strings are important and must happen now, now, now. +: log-load-string-alternate + ~ Something subtle here: s" is state-dependent. That is, it does different + ~ things depending on the interpreter flags. We would really rather know + ~ which version we're getting, and also it would be best if it didn't + ~ scribble on the output buffer. Fortunately we can achieve both of these, + ~ by coercing things into a known state while calling it. + ~ + ~ We could choose either version of s", but the interpreted one is more + ~ convenient because it doesn't mess with a spurious litstring invocation, + ~ just scribbled into scratch space after "here". Of course, that raises the + ~ additional concern that we have the wrong "here", but we can just swap + ~ that around, too. + ~ + ~ This is all worth it to avoid reimplementing s". If we had two + ~ implementations, they'd have to be kept in sync, and it's an important + ~ user-facing word with semantics that are likely to improve over time. + interpreter-flags @ + ' s" entry-to-execution-token + swap-transform-variables + ~ Since [ is an immediate word, we have to go to extra trouble to compile + ~ it as part of the alternate. + [ ' [ entry-to-execution-token , ] + execute + swap-transform-variables + swap interpreter-flags ! + ~ Whew. What a mouthful. + ~ (string pointer) + + swap-transform-variables + L@' litstring + swap-transform-variables + + offset-to-target-address-space , ~ litstring + here @ swap packstring 8 packalign here ! + + ~ Now the string pointer is on the stack, so we apply a delta for it. + 1 transform-apply-stack-delta + ; make-immediate + + ~ Because docol requires it, we provide a special mini-version of the label ~ system. We only do L@' and L!', because that's all we need. Unlike the ~ version of this feature for the label transform, for the log-load transform, @@ -1663,6 +1747,15 @@ allocate-transform-state s" transform-state" variable swap drop ' log-load-semicolon-alternate swap } if dup s" ;asm" stringcmp 0 = { swap drop ' log-load-semicolon-assembly-alternate swap } if + dup s" [" stringcmp 0 = { + swap drop ' log-load-left-square-brace-alternate swap } if + dup s" ]" stringcmp 0 = { + swap drop ' log-load-right-square-brace-alternate swap } if + dup s" ~" stringcmp 0 = { + swap drop ' log-load-tilde-alternate swap } if + ~ It is nontrivial to construct a string with a double-quote in it. + dup ' s" entry-to-name stringcmp 0 = { + swap drop ' log-load-string-alternate swap } if dup s" L@'" stringcmp 0 = { swap drop ' log-load-L@'-alternate swap } if dup s" L!'" stringcmp 0 = { swap drop ' log-load-L!'-alternate swap } if ~ (name as stack string, 0 or alternate entry pointer, name pointer) |