From 4137177c016928a6d255bbef762f0d220945083c Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Tue, 15 Sep 2026 14:14:50 -0700 Subject: do magic comments from the label transform when inside the hex transform the meaning of them in that setting is a bit different, which deserves to be documented eventually Change-Id: Ia7725bc776420c0ad62091a2e5100700868a6bfa Force-Push: yes --- core.e | 8 +++++ transform.e | 106 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 94 insertions(+), 20 deletions(-) diff --git a/core.e b/core.e index bbe1ba8..44f9fd5 100644 --- a/core.e +++ b/core.e @@ -68,6 +68,12 @@ ~ ~ We begin by outputting the actual docol routine, the one that codewords ~ should point to. Note that this is before we've done any word header. +~ +~ : This is the actual docol routine, the interpreter which is pointed to by +~ : the codeword of every interpreted word. It does not itself have an entry +~ : in the dictionary; the word "docol" will return a pointer to this routine. +~ : The word's entry follows immediately after the routine. +~ : indent here @ dup L!' docol-codeword-value :rsi pack-pushcontrol @@ -76,6 +82,7 @@ dup L!' docol-codeword-value pack-next 8 packalign here ! +~ : deindent ~ We can't use colon to create docol, not even the part that's a word, ~ because colon tries to dynamically invoke docol to fill in the codeword. @@ -87,6 +94,7 @@ L@' docol-codeword-value :rax mov-reg64-imm64 pack-next 8 packalign here ! +~ : deindent ~ Now that we have docol, colon will work and we can define words the normal ~ way. 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. -- cgit 1.4.1