diff options
Diffstat (limited to 'transform.e')
| -rw-r--r-- | transform.e | 75 |
1 files changed, 60 insertions, 15 deletions
diff --git a/transform.e b/transform.e index 52fa24f..e23453b 100644 --- a/transform.e +++ b/transform.e @@ -3027,14 +3027,22 @@ allocate-transformation-state s" transformation-state" variable ~ you are at risk of falling into the abyss[1]. ~ ~ Postprocessing re-organizes entries, without changing their meaning, but -~ in a way that will make them easier to format. There are two things it does, -~ and they happen simultaneously: The whole array is bubble-sorted by the -~ address it's attached to; and every suffix comment entry with a length -~ that's not zero is is split apart into a fresh-line entry at the start of -~ the span it attaches to, and a zero-length suffix comment entry at the end -~ of the span. The bubble sort is a stable sort; any entries that are already -~ attached to the same address will stay in whatever order they're in to begin -~ with. +~ in a way that will make them easier to format. There are two things it +~ does, and they happen simultaneously: The whole array is bubble-sorted; +~ and some suffix comment entries are split apart. +~ +~ The bubble sort resolves ordering first by the address each entry is +~ attached to, low-to-high. As a tiebreaker when two entries have the same +~ address, a comment entry is sorted after a stack-manipulation entry. The +~ tiebreaker rule means that stack-manipulation commands can come after the +~ last byte that's within the comment's span; otherwise they would always have +~ to be before it. If neither criterion applies, the entries will stay in +~ whatever order they were in to begin with; that is, it's a stable sort. +~ +~ The comment splitting applies only to suffix comments, and only when their +~ length is not zero. They become a fresh-line entry at the start of the span +~ the comment originally attached to, and a zero-length suffix comment entry +~ at the end of the span. ~ ~ Please notice that adjust-length commands happen when magic comments are ~ executed, which was long, long ago by now. By the time the postprocessing @@ -3147,6 +3155,13 @@ allocate-transformation-state s" transformation-state" variable ~ -entry-type-roll-subitems, which rolls them, or unrolls them with a negative ~ parameter. ~ +~ In using these commands that manipulate the subitem stack, it's important +~ to remember that, when formatting happens, the left-to-right output of +~ subitems in the final output comment is top-to-bottom on the subitem stack, +~ because they're popped in order. This is the opposite of the usual visual +~ representation of stacks, and can easily be confusing. +~ TODO this seems worth a semantic change once the output vetting is done +~ ~ One more thing: The order in which provide-* commands execute will most ~ likely match the order in which the corresponding bytes are output. This may ~ not always match the order in which the comment template wants to @@ -3698,10 +3713,10 @@ allocate-transformation-state s" transformation-state" variable over hex-output-metadata-entry-data-length @ 0 != && { ~ Split it into two entries so as not to rely on data length for ~ formatting. - ~ (did anything, entry pointer) - dup dup-metadata-entry - ~ (..., entry pointer) + ~ (did anything, entry pointer) + ~ Now we have the original entry at the original location, and a copy + ~ of it at the next location. ~ We have a feature which lets a suffix comment be created with a ~ negative length, which means it covers bytes before the current output @@ -3712,9 +3727,8 @@ allocate-transformation-state s" transformation-state" variable 2dup min 3unroll max ~ (..., entry pointer, low end of data, high end of data) - ~ Now we have the original entry at the original location, and a copy - ~ of it at the next location. We modify the original one in-place to - ~ turn it into a fresh-line entry at the low end of the data... + ~ Now we modify the original in-place to turn it into a fresh-line + ~ entry at the low end of the data... 2 pick hex-output-metadata-entry-type hex-output-metadata-entry-type-fresh-line swap ! ~ (..., entry pointer, low end of data, high end of data) @@ -3738,7 +3752,8 @@ allocate-transformation-state s" transformation-state" variable ~ a different type, and it won't fire on the modified suffix-comment ~ entry because its data length is zero. ~ - ~ It's possible the bubble-sort rule will fire on either of them. + ~ It's possible that one or the other of the bubble-sort rules will + ~ fire on either of them. ~ (did anything, entry pointer) swap drop 1 swap @@ -3767,6 +3782,36 @@ allocate-transformation-state s" transformation-state" variable } if ~ (did anything, entry pointer) + ~ Do this entry and the next entry both exist, and they have the same + ~ data start, and this one is a comment entry, and the next one is a + ~ stack-manipulation entry with zero length? + dup is-comment-entry over hex-output-metadata-next-entry @ && + { ~ (did anything, entry pointer) + dup hex-output-metadata-next-entry + over hex-output-metadata-entry-data-start @ + over hex-output-metadata-entry-data-start @ = + swap dup hex-output-metadata-entry-data-length @ 0 = 3roll && swap + is-subitem-stack-manipulation-entry && } + { 0 } if-else + { + ~ Swap the order of the two entries. Since this whole thing is in a + ~ loop, this functions as a bubble sort. + dup swap-metadata-entries + swap drop 1 swap + + ~ This rule can't fire in the same iteration as the previous swap, + ~ because that one doesn't fire when the starts are equal. It also + ~ won't fire again on the same pair of entries, again because now + ~ they're in the correct order. If it fires again in the next + ~ iteration that'll only be in the usual way it does for a bubble + ~ sort. + ~ + ~ As with the other swap rule, this rule also does nothing to alter + ~ whether the suffix-comment rule will fire on either entry it + ~ touches, so it won't loop through that one. + } if + ~ (did anything, entry pointer) + hex-output-metadata-next-entry } while drop } while ; |