summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-05-07 15:29:43 -0700
committerIrene Knapp <ireneista@irenes.space>2026-05-07 15:29:43 -0700
commitd33ffd64d77b3d8e088f7dfd01794d683bb9ea47 (patch)
tree98b872133f4b4e4137264cd81b962feb607f4737
parent24a3e78b55e84951257ee021447490b55dc797b8 (diff)
compute the fixed point of the label addresses
yay

this is everything important that flatassembler was doing for us, so now it's time to rewrite Evocation itself, wow!

Force-Push: yes
Change-Id: Ifc2a901801d3edcc6d81b063a0a7c3efacdd255e
-rw-r--r--make-hello.e59
1 files changed, 53 insertions, 6 deletions
diff --git a/make-hello.e b/make-hello.e
index 57a08dc..c4bbb9e 100644
--- a/make-hello.e
+++ b/make-hello.e
@@ -66,7 +66,7 @@ init-labels
 ~ (label entry pointer -- label value)
 : use-label
   ~ If it hasn't been defined yet, mark it used-before-set.
-  dup label-status dup @ dup 0x01 & not { 0x02 | swap ! } { drop drop } if-else
+  dup label-status dup @ dup 0x02 & not { 0x04 | swap ! } { drop drop } if-else
 
   ~ Mark it used. It's faster to just do this than to check if it's needed.
   dup label-status dup @ 0x01 | swap !
@@ -98,6 +98,47 @@ init-labels
 ~  -- output memory start, current output point, offset)
 : current-offset 2dup swap - ;
 
+~ For a label to have "converged", at least one of the following must be true:
+~
+~ 1. The label must never have been used (bit zero clear);
+~ 2. The label was both used and defined, but not used before it was defined
+~    (bits zero and one set; bit two clear);
+~ 3. The label was both used and defined, and the guessed value equalled the
+~    actual value (bits zero, one, and three set).
+~ (label entry pointer)
+: check-label-converged
+  label-status @
+  dup 0x01 & not swap
+  dup 0x03 & 0x03 = swap dup 0x04 & not swap 3unroll && swap
+  0x0b & 0x0b =
+  || || ;
+
+: check-labels-converged
+  1
+  labels @ { dup }
+  { dup check-label-converged 3roll && swap
+    @ } while drop ;
+
+: reset-labels
+  labels @ { dup }
+  { dup label-status 0 swap !
+    @ } while drop ;
+
+~ (execution token -- output start, output length)
+: label-loop
+  0 swap
+  0x1000 allocate dup
+  ~ (iteration count, execution token, output start, output point)
+  { 3 pick 100 > }
+  { 2 pick execute 4 roll 1+ 4 unroll
+    check-labels-converged
+    { 4 roll drop
+      3 roll drop
+      current-offset swap drop
+      exit } if
+    drop dup
+    reset-labels } while
+  drop drop drop ." Failed after " . ."  iterations." newline ;
 
 ~ ~~
 ~ ~~ ELF header
@@ -189,16 +230,22 @@ init-labels
   current-offset L' total-size set-label
   ;
 
-0x1000 allocate dup
+~ 0x1000 allocate dup
 ~ output memory start, current output point
 
-all-contents
+~ all-contents
+~ check-labels-converged . newline
+~ list-labels reset-labels list-labels
 
 ~ The two-pass magick: Reset the output offset to the beginning of the block.
-drop dup
+~ drop dup
 
-all-contents
+~ all-contents
+~ check-labels-converged . newline
+~ list-labels reset-labels list-labels
 
 ~ output memory start, current output point
-over - swap sys-write bye
+~ over - swap sys-write bye
+' all-contents entry-to-execution-token label-loop
+swap sys-write bye