summary refs log tree commit diff
diff options
context:
space:
mode:
-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