diff options
Diffstat (limited to 'transform.e')
| -rw-r--r-- | transform.e | 106 |
1 files changed, 86 insertions, 20 deletions
diff --git a/transform.e b/transform.e index 71f767b..e987689 100644 --- a/transform.e +++ b/transform.e @@ -1471,6 +1471,11 @@ allocate-transformation-state s" transformation-state" variable : label-transform ~ : blank-line ~ : blank-line + ~ : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ : blank-line ~ : This is the start of a long block of code which has been processed by ~ : the label transform, meaning it consists of ready-to-run Forth word ~ : definitions that reference each other by address, suitable for direct @@ -1489,6 +1494,8 @@ allocate-transformation-state s" transformation-state" variable ~ : ~ : The warm-start routine relies on words defined by the label transform, ~ : as does the log-load routine. + ~ : blank-line + ~ : blank-line main-input-buffer dup push-input-buffer 3roll attach-string-to-input-buffer @@ -4956,6 +4963,12 @@ allocate-transformation-state s" transformation-state" variable ~ substitution occurs before the flow control words start sliding code around, ~ and it updates "here" appropriately. ~ +~ Because hex-tilde-replacement is called in various situations during +~ various phases of compilation and interpreting, it can't take responsibility +~ for knowing how the string pointer it's given is allocated. It assumes the +~ string pointer will be valid indefinitely; it's the caller's responsibility +~ to make sure of that. +~ ~ (has non-space this line, string pointer --) : hex-tilde-replacement transformation-state transformation-state-output-metadata @ @@ -5346,7 +5359,74 @@ allocate-transformation-state s" transformation-state" variable ; make-immediate +~ This word runs whenever the label transform, running inside the hex +~ transform, encounters a tilde. It completely replaces the normal invocation +~ of tilde, just as hex-tilde-alternate does. It has the same responsibilities +~ around magic comments as hex-tilde-alternate, but for code which is +~ lexically processed by label-transform-one rather than by hex-transform-one. +~ +~ The actions it takes upon finding various sorts of comments differ from +~ hex-tilde-alternate, because the behavior of the label transform is +~ different from the behavior of the hex transform. +~ +~ This is installed by hex-label-word-replacement, bypassing the label +~ transform's normal precedence rules, so there's no need for it to be +~ immediate. +~ +~ Installing this word is the most significant change the hex transform +~ makes to the behavior of the label transform. +: hex-label-tilde-alternate + hex-read-magic-comment-introducer + ~ (body string pointer, result code) + + { + ~ It's a magic comment, which may or may not be empty. We want to either + ~ compile or execute a call to hex-tilde-replacement. + interpreter-flags @ 0x01 & { + ~ We're in compile mode. We ignore magic comments in compile mode, + ~ because they shouldn't become part of the program being compiled. + drop + } { + ~ We're in interpret mode. We run the magic comment immediately. + has-non-space-this-input-line@ swap + swap-transform-variables allocate-string swap-transform-variables + hex-tilde-replacement + } if-else + } { + ~ If it's a regular comment, we just ignore it. + drop + } if-else + + ~ Regardless of what path we took, we just consumed a newline, so make + ~ note of the fact. + 0 has-non-space-this-input-line! ; + + +~ This input helper is a very unusual thing: It's used by hex-transform-one +~ and hex-label-word-replacement to skip the space between words. That's +~ necessary because we need to keep track of whether we've had any non-blank +~ stuff on each line yet, so that the tilde replacement can figure out certain +~ cases where a magic comment needs to be a suffix comment rather than a line +~ comment. +: hex-skip-space + { peek dup is-space } + { consume + ~ This will set the flag once for each newline, if we have multiple + ~ consecutive ones or something like that, but that's harmless. + 0x0a = { 0 has-non-space-this-input-line! } if + } while drop ; + + + +~ This word is installed into label-transform-one by the hex-word-alternate, +~ when the label transform runs inside the hex transform. It has the job of +~ performing substantive changes to the label transform's behavior, as +~ required by the hex transform. +~ +~ Most notably, it calls hex-label-tilde-alternate any time a tilde is +~ encountered as a word. It also calls hex-skip-space before reading a word. : hex-label-word-replacement + hex-skip-space word value@ @@ -5354,11 +5434,7 @@ allocate-transformation-state s" transformation-state" variable ~ We won't be going back to label-transform-one; clear away its state. drop dropstring - ~ TODO we would very much like to run hex-tilde-alternate here, but it - ~ needs to be refactored first. - transformation-state transformation-state-saved-latest @ - s" ~" find-in - entry-to-execution-token execute + hex-label-tilde-alternate ~ Return directly to label-transform, faking the "not done" return value ~ from label-transform-one. @@ -5374,6 +5450,11 @@ allocate-transformation-state s" transformation-state" variable ~ "word" is called from lexically within label-transform-one, and at no other ~ time. ~ +~ Notice how the job of each transform's inner bits can be thought of as +~ calling "word" and doing something with the result, with all the lexical +~ processing delegated to "word". This makes "word" a good place to install a +~ modification to the transform's behavior. +~ ~ Its structure is highly similar to that of hex-allocate-alternate. : hex-word-alternate interpreter-flags @ 0x01 & { @@ -5394,21 +5475,6 @@ allocate-transformation-state s" transformation-state" variable } if-else ; make-immediate -~ This input helper is a very unusual thing: It's used by hex-transform-one -~ to skip the space between words. That's necessary because we need to keep -~ track of whether we've had any non-blank stuff on each line yet, so that the -~ tilde replacement can figure out certain cases where a magic comment needs -~ to be a suffix comment rather than a line comment. -: hex-skip-space - { peek dup is-space } - { consume - ~ This will set the flag once for each newline, if we have multiple - ~ consecutive ones or something like that, but that's harmless. - 0x0a = { 0 has-non-space-this-input-line! } if - } while drop ; - - - ~ This implements the hex transform for a single word. It is directly ~ analogous to "interpret", and reading interpret.e may help in understanding ~ it, though it's meant to still make sense on its own. |