summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--evoke.e10
-rw-r--r--execution.e16
-rw-r--r--log-load.e10
-rw-r--r--transform.e52
4 files changed, 79 insertions, 9 deletions
diff --git a/evoke.e b/evoke.e
index 05e500e..1d545b1 100644
--- a/evoke.e
+++ b/evoke.e
@@ -39,12 +39,16 @@ here !
     here ! ] ;asm
 
 ~   Now that we have exit, semicolon will also work and we can define
-~ non-assembly words.
-: foo 4 5 + ;
+~ non-assembly words. However, it will be hard to make them do much until we
+~ have lit as well.
+: lit
+  [ here @
+    lods64
+    :rax push-reg64
+    here ! ] ;asm
 
 42 sys-exit
 
-
 pyrzqxgl
 ~ 0 sys-exit
 s" source-to-copy-to-log" variable
diff --git a/execution.e b/execution.e
index c3f99f2..2c8b869 100644
--- a/execution.e
+++ b/execution.e
@@ -176,7 +176,15 @@
 ~ pointer where we asked; we don't need to check what those addresses are,
 ~ because they're not randomized.
 ~
-~   This routine is really only responsible for one-time initialization.
+~   Notably, though cold-start points rbp to the control stack, it leaves
+~ the control stack empty, so trying to return will pop a value that doesn't
+~ exist, and crash. Eventually, the bottom value on the control stack will
+~ be the word "quit", which loops forever and is the closest thing Forth has
+~ to a "main" word, but it's up to warm-start to make that happen.
+~
+~   Cold-start is really only responsible for one-time initialization.
+~
+~
 ~
 ~ Registers in:
 ~
@@ -186,11 +194,9 @@
 ~
 ~ Registers out:
 ~
-~ * rsi points within "quit"
-~     Quit is the word that's Forth's closest equivalent to main().
+~ * rsi points within "warm-start"
 ~ * rsp points to the top of the value stack
-~
-~   Notably, rbp is still uninitialialized after _start.
+~ * rbp points to the top of the control stack
 ~
 ~ Stack in:
 ~
diff --git a/log-load.e b/log-load.e
index f386b26..e496e04 100644
--- a/log-load.e
+++ b/log-load.e
@@ -199,7 +199,15 @@
 ~
 ~ (log address, string pointer -- log address, execution token or 0)
 : log-load-find-execution-token
-  log-load-find dup { entry-to-execution-token } if ;
+  dup 3unroll log-load-find dup
+  {
+    3roll drop
+    entry-to-execution-token
+  } {
+    drop swap
+    ." No such word: " emitstring newline
+    0
+  } if-else ;
 
 
 ~   This is the same as "create", from interpret.e, except that it takes the
diff --git a/transform.e b/transform.e
index 723484c..507c1f1 100644
--- a/transform.e
+++ b/transform.e
@@ -826,6 +826,53 @@ allocate-transform-state s" transform-state" variable
   ; make-immediate
 
 
+~   It's convenient to be able to work with strings in label-transformed
+~ code. If we don't provide an alternate for it, we get codeword pointers in
+~ the host address space, which therefore don't work.
+: label-string-alternate
+  ~   Wrapping s" is surprisingly difficult; see log-load-string-alternate
+  ~ for detailed notes on how it works. This is pretty much the same
+  ~ implementation, except the label transform doesn't track user stack depth
+  ~ so we don't have to worry about that part.
+  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)
+
+  ~   Now. If we are in immediate mode, we've left the string on the stack and
+  ~ that's all we wanted. If we're in compile mode, it's our job to output
+  ~ a litstring invocation.
+  interpreter-flags @ 0x01 & {
+    swap-transform-variables
+    L@' litstring
+    swap-transform-variables
+
+    offset-to-target-address-space ,     ~ litstring
+    here @ swap packstring 8 packalign here !
+  } if
+  ; make-immediate
+
+
+: label-dot-string-alternate
+  ' label-string-alternate entry-to-execution-token execute
+
+  interpreter-flags @ 0x01 & {
+    swap-transform-variables
+    L@' emitstring
+    swap-transform-variables
+
+    offset-to-target-address-space ,     ~ emitstring
+  } { emitstring } if-else
+  ; 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. These are real
 ~ labels; there can be arbitrarily many of them, and they can have forward
@@ -1028,6 +1075,11 @@ allocate-transform-state s" transform-state" variable
   dup s" ;" stringcmp 0 = { swap drop ' label-semicolon-alternate swap } if
   dup s" ;asm" stringcmp 0 = {
     swap drop ' label-semicolon-assembly-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 ' label-string-alternate swap } if
+  dup ' ." entry-to-name stringcmp 0 = {
+    swap drop ' label-dot-string-alternate swap } if
   dup s" L@'" stringcmp 0 = { swap drop ' label-L@'-alternate swap } if
   dup s" L!'" stringcmp 0 = { swap drop ' label-L!'-alternate swap } if
   dup s" keyword" stringcmp 0 = {