summary refs log tree commit diff
path: root/make-hello.e
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 /make-hello.e
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
Diffstat (limited to 'make-hello.e')
-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