diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-04-08 20:44:07 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-04-08 20:44:07 -0700 |
| commit | ef12766fe71d222557b6be277898c60c69f0f108 (patch) | |
| tree | ae44b8064f8a32da9e0f6c508556afbb38ed22e6 | |
| parent | 2c9a8635792f6c4bdad0a18cadaa3c1a7fcf9502 (diff) | |
implement the new assembly-based words that needed heap implementations
Force-Push: yes Change-Id: I5afdff11ce6003deaeae5a9a0844596a593bd393
| -rw-r--r-- | quine.asm | 47 |
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 |