yadda yadda Hilbert curve.
First of all, we push the three important characters on the stack:
Then we set a catch mark and start by reading a single character. We
duplicate it and negate it, and if the result of this is truthy (so if the string was empty; so the input ended), we jump to the end:
With the remaining copy of the input character, we check whether it is contained in the rest of the stack (i.e. if its one of !, N, U). If it's not, we raise an error, throwing us back to our catch mark where we read another character:
Otherwise, we load what's on quick storage (essentially a register that's initially an empty string; falsy), negate it and send it back to quick storage, then raise the error too (going back to reading characters):
When the input stopped, we are sent to the end. There, we reverse the direction, push an exclamation mark, and load quick storage and negate it. If that is truthy (i.e. we've had an odd number of negation things), we print the exclamation mark we've pushed:
Finally, we push the string in two parts and print them (for space saving reasons):
Afterwards, the program still runs back to the original beginning, but since none of the commands output anything or have loopy behaviour, that doesn't matter. Actually, the first non-nopping command we reach raises an exception, skipping a majority of the code because we jump to the catch mark, meaning all Aceto sees in that part is:
U is now not preceeded by a single-quote character and is therefore not seen as a character literal, it gets interpreted as a command:
U reverses all the elements on the stack (now it's
U, from the top), and
'! push more characters, meaning we end with the stack
[U, N, !, N, !].
Side note: This is the first Aceto program written (in part) with the help of Aceto's new editor.