Ditch
Ditch is an esolang by User:BoundedBeans where syntax is irreversibly changed periodically.
Syntax
Ditch is a bit like Forth. It has a stack and words that operate on it, though you cannot define your own. However, in Ditch, all data is strings. Strings are enclosed in double quotes and only have two escape sequences: ?", for escaping quotes, and ??, for escaping question marks.
Levels
At level 0, the following operations can be performed in postfix:
+ | concatenation of two strings |
> | the first character |
< | everything except the first character |
The following 5 commands definitions are the same as in Forth. | |
---|---|
: | dup |
/ | swap |
$ | drop |
% | rot |
^ | over |
End forth copying. | |
_ | pop x and use its length as a zero-based index from the top of the stack, pick that element and copy it to the top. |
= | pushes "a" if the top two strings are equal, "" otherwise |
| | pushes the length of the string in unary "a" |
begin ... until | as in forth, but the empty string is falsy and everything else is truthy |
if ... else ... then | as in forth, but the empty string is falsy and everything else is truthy |
. | outputs the top string |
, | inputs a line |
After 5 instructions excluding keywords and string literals, the program automatically and irreversibly "ditches" the code to the next level, resetting the counter back to zero. The stack is preserved when ditching.
At any level besides level 0, there is only one operation:
@ | eval the top string as the previous level. It is an error if a ditch occurs inside of this, unless enclosed within a block. Note that the 5 instruction limit applies to every level, but separately. 5 instructions on level 1 can simulate 25 instructions at level 0. Eval uses the same stack as normal. Eval can have the string preloaded ahead of time, and when it's executing the contents, instructions can manipulate the stuff below. |
Inside of a block, the level is separate. It is possible to have a block ditch and then recover once it exits the block (from any amount of levels). This is to allow conditionals and loops that are longer than a tiny amount of commands. Because of this, commands inside of blocks do not count towards the 5 outside the block, but they do inside. This would require a stack of levels to implement. It can just as well do this inside of eval, although it would need to get down to level zero in order to even use blocks.
Let's make a one line cat and see how it transforms.
Level 0:
, .
Level 1:
", ." @
Level 2:
"?", .?" @" @
Level 3:
"?"???", .???" @?" @" @
Level 4:
"?"???"???????", .???????" @???" @?" @" @
Examples
Hello world!
"Hello world!" .
Truth-machine
, : "0" = / / "if . else begin : . ?"?" until then" @