From dc84d26e2d6ffa1fb51e4d677876349a328a0afc Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Wed, 20 May 2026 04:24:27 -0700 Subject: create works now, and docol outputs successfully having some trouble with colon Force-Push: yes Change-Id: I5fc0f4519bdd8de1033e24730f63296d8076782e --- evoke.e | 39 ++++++++++++++------ transform.e | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 134 insertions(+), 22 deletions(-) diff --git a/evoke.e b/evoke.e index df59a2a..4252e91 100644 --- a/evoke.e +++ b/evoke.e @@ -10,6 +10,8 @@ s" source-to-precompile" variable ~ : fooze 4 . ; fooze 1024 read-to-buffer +~ 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. here @ dup L!' docol-codeword-value :rsi pack-pushcontrol @@ -19,20 +21,37 @@ pack-next 8 packalign here ! -: docol - [ here @ - L@' docol-codeword-value :rax mov-reg64-imm64 - :rax push-reg64 - here ! ] ;asm +~ 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. +s" docol" create +here @ +dup 8 + pack64 +L@' docol-codeword-value :rax mov-reg64-imm64 +:rax push-reg64 +pack-next +8 packalign +here ! + -: exit - [ here @ - :rsi pack-popcontrol - here ! ] ;asm +s" exit" create +here @ +dup 8 + pack64 +:rsi pack-popcontrol +here ! + +: foo [ crash 1 2 + ; -: foo 1 2 + ; 0 sys-exit + +~ Now that we have docol, colon will work and we can define exit the normal +~ way. +~ : exit +~ [ here @ +~ :rsi pack-popcontrol +~ here ! ] ;asm + pyrzqxgl +~ 0 sys-exit s" source-to-copy-to-log" variable ~ (output memory start, current output point 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) -- cgit 1.4.1