diff --git a/hex.e b/hex.e
index 51e7703..963b82a 100644
--- a/hex.e
+++ b/hex.e
@@ -228,8 +228,8 @@
elf-file-header
elf-program-header-writable
output-start-routine
- output-read-byte
output-exit
+ output-read-byte
output-decode-nibble
output-error-handlers
output-messages
diff --git a/transform.e b/transform.e
index 7d392f1..ebf493f 100644
--- a/transform.e
+++ b/transform.e
@@ -2692,6 +2692,18 @@ allocate-transformation-state s" transformation-state" variable
s" swap" find entry-to-execution-token , ;
+~ This "replacement" is a little different from an alternate: When the code
+~ under transformation attempts to compile its own version of sys-write, it
+~ gets a stub that calls this word instead. It's swapped out by
+~ hex-colon-alternate, whereas the regular alternates are swapped out by
+~ hex-transform-one.
+~ (length to write, base address --)
+: hex-sys-write-replacement
+ { over } {
+ dup 8@ .hex8 space
+ 1+ swap 1- swap
+ } while ;
+
~ By overriding colon, we can special-case the definitions of particular
~ words. It's very metacircular.
: hex-colon-alternate
@@ -2800,6 +2812,21 @@ allocate-transformation-state s" transformation-state" variable
exit
} if
+ ~ We are entirely replacing sys-write with our own version. It's an
+ ~ assembly word, and we're replacing it with a Forth word, so there's some
+ ~ matching code in the ;asm alternate that makes sure to not mess that up.
+ dup s" sys-write" stringcmp 0 = {
+ create dropstring
+ s" docol" find entry-to-execution-token execute ,
+ make-hidden
+
+ ' hex-sys-write-replacement entry-to-execution-token ,
+ s" exit" find entry-to-execution-token ,
+
+ ' ] entry-to-execution-token execute
+ exit
+ } if
+
~ If no special case matches, we fall back to just being a regular colon.
~ We already read the word name above, so we have to do the rest of the
~ steps ourselves as well.
@@ -2812,7 +2839,25 @@ allocate-transformation-state s" transformation-state" variable
: hex-semicolon-alternate [ ' ; entry-to-execution-token , ]
; make-immediate
-: hex-semicolon-assembly-alternate [ ' ;asm entry-to-execution-token , ]
+: hex-semicolon-assembly-alternate
+ latest @ entry-to-name
+ dup s" sys-write" stringcmp 0 = {
+ ~ As detailed in hex-colon-alternate, above, sys-write is implemented in
+ ~ assembly but we replace it with Forth. This logic here collaborates with
+ ~ the logic there to make that work.
+ ~
+ ~ The transformed code will still have compiled some assembly, though it
+ ~ won't be reached and would crash, so we need to fix alignment before we
+ ~ call semicolon.
+ drop
+ here @ 8 packalign here !
+ [ ' ; entry-to-execution-token , ]
+ exit
+ } if
+ drop
+
+ ~ If no special case matches, we fall back to the regular behavior.
+ [ ' ;asm entry-to-execution-token , ]
; make-immediate
~ Because docol requires it, we provide a special mini-version of the label
|