summary refs log tree commit diff
path: root/labels.e
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-05-15 16:19:07 -0700
committerIrene Knapp <ireneista@irenes.space>2026-05-15 16:19:07 -0700
commit1af849abc637c4890285c4d3cc08d99faae2ea41 (patch)
tree0062b680a357a0820cafe8ce8f2c3f3f65ee99a2 /labels.e
parent13ec0a067a70ee1e5c0a287972c2f9f07d4e1486 (diff)
document the assumptions between labels and transforms
also some minor cleanup that ie. fixes alignment padding

Force-Push: yes
Change-Id: Ia8fcb9a44e05e37751cc1b8334aa72add7e62353
Diffstat (limited to 'labels.e')
-rw-r--r--labels.e40
1 files changed, 29 insertions, 11 deletions
diff --git a/labels.e b/labels.e
index b524229..bfc85fb 100644
--- a/labels.e
+++ b/labels.e
@@ -33,6 +33,20 @@
 ~ same value they started with, we say they've converged, and we announce
 ~ success. If a hundred passes go by without convergence, we fail instead.
 ~
+~   Importantly, the label facility does not have an opinion on where or how
+~ the values of labels should be output, nor does it have concepts of
+~ dependency tracking or topological sorting. It only cares about the sequence
+~ of set- and use-operations. Code relying on the facility is free to make
+~ arbitrarily complex decisions about the layout, size, contents etc of its
+~ output, and to use label values as part of those decisions. It is the
+~ responsibility of this relying code to ensure the process converges, by
+~ whatever means it wishes.
+~
+~   Since the label facility is not directly involved in output, it is also
+~ permissible for code relying on it to make retroactive changes to the
+~ output, as long as all such changes are completed before returning control
+~ to label-loop.
+~
 ~   Most of the time, the shorthand words L@' and L!' will be all you need to
 ~ use from your own code.
 
@@ -54,16 +68,9 @@
 ~
 ~   Just as the Evocation dictionary uses the global variable "latest" as a
 ~ handle (a pointer to a pointer) beginning a linked list of entries, so the
-~ label dictionary also uses a handle variable, named "labels".
-
-~ TODO we should just do this in immediate mode, but right now the word
-~ "variable" steps on the same scratch space that s" uses, so we can't.
-: init-labels
-  8 allocate s" labels" variable
-  0 s" labels" find entry-to-execution-token execute !
-  ;
-~ This needs to happen now because otherwise the word "labels" won't exist.
-init-labels
+~ label dictionary also uses a handle variable, named "labels". We initialize
+~ it here.
+8 allocate s" labels" variable 0 labels !
 
 ~   This is analogous to word-heading, but prints label information.
 ~ (entry pointer --)
@@ -144,11 +151,22 @@ init-labels
 ~
 ~ (new label value, label entry pointer --)
 : set-label
+  dup label-status @
+  ~ (new value, entry, initial status)
+
+  ~   Exit, and print a diagnostic, if the label was already set on this pass.
+  ~
+  ~   Without cooperation from user code, there's no great way to communicate
+  ~ up the call stack that execution should stop, so we don't try to.
+  dup 0x02 & { drop swap drop
+               ." Failed by attempting to redefine "
+               entry-to-name emitstring newline exit } if
+
   ~ We always set the defined bit to true. We leave the other status bits
   ~ as-is, except that we check whether it's unused up to now, and whether
   ~ the previous value equals the new value. If either of those holds, we set
   ~ the guessed-equals-actual bit to true.
-  dup label-status @ 0x02 |
+  0x02 |
   ~ (new value, entry, updated status)
   3unroll dup 4 unroll label-value @ swap dup 3unroll =
   ~ (entry, updated status, new value, equality)