summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-04-21 12:00:41 -0700
committerIrene Knapp <ireneista@irenes.space>2026-04-21 12:00:41 -0700
commit272df1c32b0ef1ed8ed71e945981b16bdeed26d7 (patch)
treecfb43b2e373c26e802b795f08f68723f1539be8b
parent1a766dde1518cd9c208544ce0f4afd2f9ab61f0a (diff)
add a variable for interpreter state
it's not used yet; this uncovered a problem with the stack string buffers, which needs to be fixed first. they grow in the wrong direction.

Force-Push: yes
Change-Id: I208897f9008d956996493b28fff831e04a67a366
-rw-r--r--quine.asm47
1 files changed, 36 insertions, 11 deletions
diff --git a/quine.asm b/quine.asm
index 70f5e8a..c5148ef 100644
--- a/quine.asm
+++ b/quine.asm
@@ -1961,8 +1961,6 @@ _start:
 
   align 8
 cold_start:
-  ;;; TODO this is probably where we should deal with that "heap" that we passed
-  ;;; on the stack
   ;;;   Before handing off to us, _start pushed a single value onto the stack,
   ;;; a pointer to the beginning of the heap. Now, we load our entire Forth
   ;;; implementation onto that heap, beginning with the minimal set of words
@@ -6914,6 +6912,20 @@ cold_start:
   dq early_here, fetch, lit, 8, packalign, early_here_store
 
 
+  dq litstring, "interpreter-flags-storage", early_create
+  dq litstring, "interpreter-flags-storage", early_find
+  dq dup, lit, 1, store_entry_flags
+  dq entry_to_execution_token
+  ; (heap pointer, storage pointer)
+  dq swap, lit, 0, early_comma
+  dq litstring, "variable", 0, early_find, entry_to_execution_token
+  ; (storage pointer, heap pointer, execution token)
+  dq swap, unroll3
+  ; (heap pointer, storage pointer, execution token)
+  dq litstring, "interpreter-flags", swap
+  ; (heap pointer, storage pointer, string pointer, execution token)
+  dq execute
+
   dq litstring, "interpret", early_create, early_docol_codeword
   ; Start of the loop.
   dq litstring, "word", early_find, entry_to_execution_token, early_comma
@@ -6981,8 +6993,14 @@ cold_start:
   dq early_here, fetch, lit, 8, packalign, early_here_store
 
 
-  dq litstring, "interpret", early_find, entry_to_execution_token, execute
-  dq lit, 0, sys_exit
+  dq litstring, "interpret", early_find, entry_to_execution_token
+
+  ; Get rid of that heap pointer on the stack, we're finally done with it!
+  dq swap, drop
+  dq execute
+
+  ; We won't be coming back, but if we do, complain.
+  dq lit, 1, sys_exit
 
 
   ;;; TODO rethink this, it needs to not use space on the value stack
@@ -10535,10 +10553,6 @@ defword self_raw, 0
   dq exit
 
 
-defword boot_source, 1
-  dq "6 7 * ."
-  dq 0
-
 ; Routines that traverse the raw code need a way to guess where the end of a
 ; word's contents are, lest they traverse off the edge of the world and
 ; segfault. On the heap, we have the "here" pointer to provide an upper bound.
@@ -10549,9 +10563,20 @@ defword boot_source, 1
 ; that would make us more dependent on specifics of the ABI and the kernel.
 ; Instead, we invent this concept of a metadata word, which is designated with
 ; a new flag bit and exists to annotate the address space rather than to be
-; invoked. This is the only one there is right now, and the traversal routines
-; hard-code their knowledge of it.
-defword end_segment, 1
+; invoked. The traversal routines hardcode the expectation that the text
+; segment ends with a metadata word. Also, they skip metadata words when
+; describing things.
+;
+; Since the boot source is a raw string, not a Forth word, it also needs to
+; be flagged as metadata. For convenience's sake, we use a single metadata
+; word both to delimit the segment end, and to hold the boot source. Cute,
+; right?
+defword boot_source, 1
+  ; Keep in mind that these words don't exist in memory, so branching won't
+  ; have the intended effect. Any logic that requires branching needs to be
+  ; written to the heap instead, and branch while running there.
+  dq "0 sys-exit"
+  dq 0
 
 
 final_word_name = latest_word