summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-04-08 20:44:07 -0700
committerIrene Knapp <ireneista@irenes.space>2026-04-08 20:44:07 -0700
commitef12766fe71d222557b6be277898c60c69f0f108 (patch)
treeae44b8064f8a32da9e0f6c508556afbb38ed22e6
parent2c9a8635792f6c4bdad0a18cadaa3c1a7fcf9502 (diff)
implement the new assembly-based words that needed heap implementations
Force-Push: yes
Change-Id: I5afdff11ce6003deaeae5a9a0844596a593bd393
-rw-r--r--quine.asm47
1 files changed, 36 insertions, 11 deletions
diff --git a/quine.asm b/quine.asm
index ed1d277..ba1c7c4 100644
--- a/quine.asm
+++ b/quine.asm
@@ -2411,6 +2411,33 @@ cold_start:
   dq rbx, eax, mov_reg32_indirect_reg64
   dq pack_next, lit, 8, packalign, early_here_store
 
+  ; This was "store_control_stack". Jonesforth calls it RSP!, which looks as
+  ; if it's meant to be an Intel register name but is actually short for
+  ; return stack pointer. There is no register by that name, it's a
+  ; Forth-provided abstraction. That's super confusing, plus as discussed
+  ; above we call it the control stack not the return stack, so we call it...
+  dq litstring, "control!", 0, early_create, early_self_codeword
+  dq early_here, fetch
+  dq rbp, pop_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
+  ; This was "fetch_control_stack".
+  dq litstring, "control@", 0, early_create, early_self_codeword
+  dq early_here, fetch
+  dq rbp, push_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
+  ; This was "store_value_stack". Jonesforth calls it DSP!, for data stack
+  ; pointer. Again, there's no Intel register by that name, and we call it the
+  ; value stack, so...
+  dq litstring, "value!", early_create, early_self_codeword
+  dq early_here, fetch
+  dq rsp, pop_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
+  ; This was "fetch_value_stack".
+  dq litstring, "value@", early_create, early_self_codeword
+  dq early_here, fetch
+  dq rsp, push_reg64
+  dq pack_next, lit, 8, packalign, early_here_store
+
   dq litstring, "memcopy", early_create, early_self_codeword
   dq early_here, fetch
   dq rsi, rdx, mov_reg64_reg64
@@ -2659,10 +2686,8 @@ cold_start:
   ;;;   and, or, xor, invert
   ;;;   lit, litstring
   ;;;   store, fetch
-  ;;;   fetch_control_stack, store_control_stack
-  ;;;     TODO needs heap impl
-  ;;;   fetch_value_stack, store_value_stack
-  ;;;     TODO needs heap impl
+  ;;;   store_control_stack,fetch_control_stack,
+  ;;;   store_value_stack, fetch_value_stack,
   ;;;   addstore, substore, store8, fetch8, store16, fetch16, store32, fetch32
   ;;;   memcopy, stringlen
   ;;;   reverse_stringlen, reverse_padding_len
@@ -3369,18 +3394,13 @@ defword fetch, 0
 ; The result, or the new value, is on the top of the data stack. That's the
 ; same as how it works for any other word, but given the metacircular nature
 ; of these ones it's easy to get confused about that...
-defword fetch_control_stack, 0
-  dq $ + 8
-  push.qreg rbp
-  next
 defword store_control_stack, 0
   dq $ + 8
   pop.qreg rbp
   next
-defword fetch_value_stack, 0
+defword fetch_control_stack, 0
   dq $ + 8
-  ; Per Intel's description of PUSH this pushes the old value.
-  push.qreg rsp
+  push.qreg rbp
   next
 defword store_value_stack, 0
   dq $ + 8
@@ -3389,6 +3409,11 @@ defword store_value_stack, 0
   ; it increments the register then overwrites it, in that order.
   pop.qreg rsp
   next
+defword fetch_value_stack, 0
+  dq $ + 8
+  ; Per Intel's description of PUSH this pushes the old value.
+  push.qreg rsp
+  next
 
 ; Address on top, value second
 ; I might have done it the other way, but this is what Jonesforth does and it