summary refs log tree commit diff
path: root/transform.e
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-09-19 01:51:09 -0700
committerIrene Knapp <ireneista@irenes.space>2026-09-19 01:55:40 -0700
commite627892f79a50708ac9f6d6d82f84fdbb7ca34c5 (patch)
treedd92bc11f15ac89e72886159bd4b6619b63f8377 /transform.e
parent35732444adad4bfa972ce574bd5ecb8509b1906e (diff)
add a bunch more data- and entry-manipulation magic-comment commands
now it's possible to make ;asm replace "docol codeword" with "self codeword", and it does

Force-Push: yes
Change-Id: I1a9b4cee8a3eee308cf421968d6a3cd92adba800
Diffstat (limited to 'transform.e')
-rw-r--r--transform.e167
1 files changed, 145 insertions, 22 deletions
diff --git a/transform.e b/transform.e
index e9b7e0c..12ac253 100644
--- a/transform.e
+++ b/transform.e
@@ -921,7 +921,7 @@ allocate-transformation-state s" transformation-state" variable
   latest @ host-address-space-to-target pack64
   ~ : 1     (entry flags)
   0 pack8
-  ~ : double-null-terminated entry name
+  ~ : bidirectional-null-terminated entry name
   0 pack8
   ~ : 1 data-adjust-output-point
   ~ : fresh-line
@@ -955,6 +955,7 @@ allocate-transformation-state s" transformation-state" variable
   L@' origin
   swap-transform-variables
   + ,
+  ~ : blank-line
 
   latest @ dup entry-flags@ 0x80 | swap entry-flags!
   ] ;
@@ -1001,14 +1002,21 @@ allocate-transformation-state s" transformation-state" variable
 ~ likely to be extremely useful to read and understand ";asm" in dynamic.e
 ~ before attempting to understand label-semicolon-assembly-alternate.
 : label-semicolon-assembly-alternate
-  here @ pack-next 8 packalign here !
+  here @ pack-next 8 packalign
+  ~ : provide-data
+  here !
   ~ : deindent
 
   latest @ dup dup entry-flags@ 0x80 invert & swap entry-flags!
   entry-to-execution-token
   ~ The codeword needs to be transformed to the target address space.
+  ~ : provide-data
+  ~ : data-set-output-point
+  ~ : delete-last-comment-at-output-point
+  ~ : 8     (self codeword)
   dup 8 + host-address-space-to-target
   swap !
+  ~ : data-set-output-point
 
   ~   Since [ is an immediate word, we have to go to extra trouble to compile
   ~ it as part of ;asm.
@@ -2846,8 +2854,15 @@ allocate-transformation-state s" transformation-state" variable
 ~   ~ : -10 adjust-start
 ~   ~ : 1 data-adjust-length
 ~   ~ : -1 data-adjust-start
+~
+~   ~ : 0x1000 set-output-point
+~   ~ : 8 adjust-output-point
+~   ~ : data-set-output-point
 ~   ~ : 1 data-adjust-output-point
+~
 ~   ~ : 1 suppress
+~   ~ : delete-first-comment-at-output-point
+~   ~ : delete-last-comment-at-output-point
 ~
 ~   ~ : Do a thing with # and # ?
 ~   ~ : Do a different #swap # thing to # now.
@@ -3029,9 +3044,20 @@ allocate-transformation-state s" transformation-state" variable
 ~ as adjust-length but for the start address the entry is attached to, rather
 ~ than the length of the attachment. Also, while adjust-length only affects
 ~ comment entries, adjust-start affects any entry that produces output, such
-~ as fresh-line. Meanwhile, adjust-output-point directly modifies the latest
-~ output point, which can be useful if a location has been skipped over
-~ without outputting anything.
+~ as fresh-line.
+~
+~   The various -output-point commands are used to directly interact with the
+~ notion of the latest output point, which can be useful if a location has
+~ been skipped over and there are commands which should be run before
+~ outputting anything at the new location. The simplest variant is
+~ set-output-point, which sets it to the parameter value. The data-set-
+~ variant obtains a value in the manner of the other data-* commands, adds it
+~ to the parameter value, and sets the latest output point to the result. The
+~ adjust- and data-adjust- variants, like other adjust commands, add a value
+~ to the existing one.
+~
+~   Notice that the general rule is that data-set-* commands use their
+~ parameter as an addend, while data-adjust-* commands use it as a multiplier.
 ~
 ~   The data-adjust-* variants deserve further commentary, though you may find
 ~ it more productive to read and understand the entire explanation about
@@ -3065,6 +3091,16 @@ allocate-transformation-state s" transformation-state" variable
 ~ which is decremented any time it's greater than zero and an entry would be
 ~ created, and adjusted every time a call to "suppress" is executed.
 ~
+~   Sometimes, an entry has already been created, and you now need to get rid
+~ of it. While there are reasons to be cautious of more-general mechanisms,
+~ the commands delete-*-comment-at-output-point will search for a metadata
+~ entry which is one of the comment types and which has its start position set
+~ to the same address as the current output point. The -first- variant will
+~ search forward from the start of the array, while -last- will search
+~ backward from the end; both will stop as soon as they encounter one. This is
+~ usually desired when overwriting a location that has already been written
+~ to.
+~
 ~   Take a quick look at the remaining examples. These are part of the comment
 ~ template feature. We'll need to describe the other phases of processing
 ~ before we can talk about how they work, but notice that one of them has the
@@ -3527,6 +3563,17 @@ allocate-transformation-state s" transformation-state" variable
     0 pack64 drop
   } { drop drop drop drop } if-else ;
 
+~ (entry pointer --)
+: delete-metadata-entry
+  transformation-state transformation-state-output-metadata @
+  hex-output-metadata-first-entry
+  { dup @ } { hex-output-metadata-next-entry } while
+  ~ (entry pointer, array-end marker pointer)
+  over hex-output-metadata-next-entry - 8 +
+  ~ (entry pointer, length of block to move)
+  swap dup hex-output-metadata-next-entry swap 3roll memmove ;
+
+
 ~ (-- entry pointer or 0)
 : find-latest-metadata-entry
   ~   Loop forward from the beginning of the entry array to find the last
@@ -3585,6 +3632,44 @@ allocate-transformation-state s" transformation-state" variable
   ~ (entry pointer or 0)
   ;
 
+~ (target start location -- entry pointer or 0)
+: find-first-comment-metadata-entry-with-start
+  ~ Find the first entry, but if it doesn't exist, we want 0 instead.
+  transformation-state transformation-state-output-metadata @
+  hex-output-metadata-first-entry
+  ~ (target start location, entry pointer)
+
+  ~   Now loop forwards to find the first that's a comment entry and has the
+  ~ desired start location.
+  { dup @ } {
+    dup is-comment-entry
+    over hex-output-metadata-entry-data-start @ 3 pick =
+    && { swap drop exit } if
+    hex-output-metadata-next-entry
+  } while drop drop 0 ;
+
+
+~ (target start location -- entry pointer or 0)
+: find-latest-comment-metadata-entry-with-start
+  find-latest-metadata-entry
+  ~ (target start location, entry pointer or 0)
+
+  dup {
+    { dup @ } {
+      dup is-comment-entry
+      over hex-output-metadata-entry-data-start @ 3 pick =
+      && { swap drop exit } if
+
+      dup
+      transformation-state transformation-state-output-metadata @
+      hex-output-metadata-first-entry
+      = { drop drop 0 exit } if
+
+      hex-output-metadata-previous-entry
+    } while
+  } if swap drop ;
+
+
 ~ (length adjustment --)
 : adjust-latest-comment-metadata-entry-length
   find-latest-comment-metadata-entry
@@ -3617,22 +3702,39 @@ allocate-transformation-state s" transformation-state" variable
     crash
   } if-else ;
 
+
+~ (target start location --)
+: delete-first-comment-metadata-entry-with-start
+  find-first-comment-metadata-entry-with-start
+  dup { delete-metadata-entry } { drop } if-else ;
+
+~ (target start location --)
+: delete-latest-comment-metadata-entry-with-start
+  find-latest-comment-metadata-entry-with-start
+  dup { delete-metadata-entry } { drop } if-else ;
+
+: delete-first-comment-metadata-entry-at-output-point
+  transformation-state transformation-state-output-metadata @
+  hex-output-metadata-latest-output-point @
+  delete-first-comment-metadata-entry-with-start ;
+
+: delete-latest-comment-metadata-entry-at-output-point
+  transformation-state transformation-state-output-metadata @
+  hex-output-metadata-latest-output-point @
+  delete-latest-comment-metadata-entry-with-start ;
+
+
+~ (value --)
+: set-latest-output-point
+  transformation-state transformation-state-output-metadata @
+  hex-output-metadata-latest-output-point ! ;
+
 ~ (adjustment --)
 : adjust-latest-output-point
   transformation-state transformation-state-output-metadata @
   hex-output-metadata-latest-output-point
   dup 3unroll @ + swap ! ;
 
-~ (entry pointer --)
-: delete-metadata-entry
-  transformation-state transformation-state-output-metadata @
-  hex-output-metadata-first-entry
-  { dup @ } { hex-output-metadata-next-entry } while
-  ~ (entry pointer, array-end marker pointer)
-  over hex-output-metadata-next-entry - 8 +
-  ~ (entry pointer, length of block to move)
-  swap dup hex-output-metadata-next-entry swap 3roll memmove ;
-
 ~ (-- data value)
 : data-consume
   find-latest-saved-data-metadata-entry
@@ -3656,18 +3758,18 @@ allocate-transformation-state s" transformation-state" variable
 
 ~ (adjustment scale factor --)
 : data-adjust-latest-comment-metadata-entry-length
-  data-consume
-  ~ (adjustment scale factor, data value)
-
-  ~   All the entry array manipulation happened in data-consume. We're done
-  ~ doing that, and the array is now in a consistent state, so we can hand
+  ~   All the entry array manipulation happens in data-consume. Once we're
+  ~ done doing that, the array is now in a consistent state, so we can hand
   ~ off to the non-data implementation to do the rest of the work.
-  * adjust-latest-comment-metadata-entry-length ;
-
+  data-consume * adjust-latest-comment-metadata-entry-length ;
+~ (adjustment scale factor --)
 : data-adjust-latest-output-producing-metadata-entry-start
   ~ Same as for adjusting the entry length.
   data-consume * adjust-latest-output-producing-metadata-entry-start ;
 
+~ (value offset --)
+: data-set-latest-output-point
+  data-consume + set-latest-output-point ;
 ~ (adjustment scale factor --)
 : data-adjust-latest-output-point
   data-consume * adjust-latest-output-point ;
@@ -5255,6 +5357,11 @@ allocate-transformation-state s" transformation-state" variable
     drop drop swap drop adjust-latest-output-producing-metadata-entry-start
     exit
   } if
+  dup s" set-output-point" stringcmp 0 = {
+    ~ Override the latest output point.
+    drop drop swap drop set-latest-output-point
+    exit
+  } if
   dup s" adjust-output-point" stringcmp 0 = {
     ~ Modify the latest output point.
     drop drop swap drop adjust-latest-output-point
@@ -5274,6 +5381,12 @@ allocate-transformation-state s" transformation-state" variable
     data-adjust-latest-output-producing-metadata-entry-start
     exit
   } if
+  dup s" data-set-output-point" stringcmp 0 = {
+    ~   Override the latest output point, also using data from the most recent
+    ~ data entry.
+    drop drop swap drop data-set-latest-output-point
+    exit
+  } if
   dup s" data-adjust-output-point" stringcmp 0 = {
     ~   Modify the latest output point, also using data from the most recent
     ~ data entry.
@@ -5288,6 +5401,16 @@ allocate-transformation-state s" transformation-state" variable
     exit
   } if
 
+  dup s" delete-first-comment-at-output-point" stringcmp 0 = {
+    4 ndrop delete-first-comment-metadata-entry-at-output-point
+    exit
+  } if
+
+  dup s" delete-last-comment-at-output-point" stringcmp 0 = {
+    4 ndrop delete-latest-comment-metadata-entry-at-output-point
+    exit
+  } if
+
   dup s" fresh-line" stringcmp 0 = {
     ~ Create a new fresh-line entry.
     drop drop hex-output-metadata-entry-type-fresh-line 0