Agony
Agony is an esoteric programming language devised by Roy van Rijn in March 2013.
It is based on, and most of the time backwards compatible with Brainfuck. The added instructions and changes to the inner workings turn Brainfuck into a complete self-modifying language.
Memory space
The memory/core of Agony consists of 'cells,' which are 4 bits in size, and 'characters,' which are 8 bits in size (2 cells).
- The memory pointer always points to a cell, the corresponding character is the current cell and previous cell in memory.
- The memory core is circular and loops around.
- After loading a program into the core (the code is placed in cells in memory!), the memory pointer points to the second free cell after the last instruction (leaving one free character).
- Unused memory/core is initialized with '0000'-bit cells.
Instructions
Command | Binary | Description |
---|---|---|
$ | 0000 | Halt the program here. |
} | 0001 | Move pointer right. |
{ | 0010 | Move pointer left. |
> | 0011 | Move pointer right 2 cells. |
< | 0100 | Move pointer left 2 cells. |
@ | 0101 | Increment cell. |
~ | 0110 | Decrement cell. |
+ | 0111 | Increment character. |
- | 1000 | Decrement character. |
. | 1001 | Output the character (2 cells) at pointer and pointer-1. |
, | 1010 | Input a character (2 cells) to pointer and pointer-1. |
( | 1011 | Jump past the matching ) if the cell under the pointer is zero, if no matching ) can be found, halt. |
) | 1100 | Jump back to the matching ( if the cell under the pointer is nonzero, if no matching ( can be found, halt. |
[ | 1101 | Jump past the matching ] if the character under the pointer is zero, if no matching ] can be found, halt. |
] | 1110 | Jump back to the matching [ if the character under the pointer is nonzero, if no matching [ can be found, halt. |
* | 1111 | Swap character (2 cells) at pointer with the buffer (2 cells, buffer has 0000 0000 initially) |
As you can see, the Brainfuck roots are clearly visible. With the BF instructions working on 8 bits it is mostly backwards compatible.
Examples
Here are some Brainfuck examples which work fine in Agony:
cat
A cat program writes its input directly to its output. EOF in Agony is translated to 0000-bits, halt.
,[.,]
Hello, World! in BF
This Brainfuck program works fine in Agony, it prints out the words Hello World!:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Hello, World! in Agony
In Agony we can use the fact instructions are also bits and can be reached:
<[.<]$$$,{}~<~)+{~*@+{$~*~)~)~@<-
Quine in Agony
Agony is a self-modifying language, this means we can also do reflection. Using this fact it should be 'easier' to make a Quine in Agony.
Program:
< [ [>+>+<<-] >*>[>]>>[>]*{(>@<~)}(({@}~)}))<[<]<<[<]<< Create a reversed copy of the last part ] >>>[>]>>[>]< Place pointer at last part of the reversed copy [ Print the instructions [(}+{-)}*<({)<<<({)<<<<* Grab the last instruction [<[->>+<<]>[<+>-]<-]<-.+>>>[[-<<+>>]>]>>} Do look up in the instruction print array (})>>(}){ And go back to the next instruction ] Until the reversed copy is printed @@@@{@@}......{~~}~~~~<< Print the separator [ [>+>+<<-] >*>[>]>>[>]*{(>@<~)}(({@}~)}))<[<]<<[<]<< Same copy as above ] >>>[>]>>[>]< Place pointer at last part of the reversed copy [ Print the instructions again with slightly different offset [(}+{-)}*<({)<<({)<<<<<<* [<[->>+<<]>[<+>-]<-]<-.+>>>[[-<<+>>]>]>>>>} (})>>(}){ ] [[ Halt the program invalid loop {(@]@){,{.{[{*{]{)+*<}>[>*+)+]{@ Lookup table for printing instructions $$$$$$ Seperator space <[[>+>+<<-]>*>[>]>>[>]*{(>@< And the entire block again needed for printing ~)}(({@}~)}))<[<]<<[<]<<]>>> [>]>>[>]<[[(}+{-)}*<({)<<<({ )<<<<*[<[->>+<<]>[<+>-]<-]<- .+>>>[[-<<+>>]>]>>}(})>>(}){ ]@@@@{@@}......{~~}~~~~<<[[> +>+<<-]>*>[>]>>[>]*{(>@<~)}( ({@}~)}))<[<]<<[<]<<]>>>[>]> >[>]<[[(}+{-)}*<({)<<({)<<<< <<*[<[->>+<<]>[<+>-]<-]<-.+> >>[[-<<+>>]>]>>>>}(})>>(}){] [[{(@]@){,{.{[{*{]{)+*<}>[>* +)+]{@
AgonyWar
This language is perfectly suited for a Core War-like (see Redcode) battle. Two or more programs can be put in the same memory core. The program that doesn't halt and survives N-cycles wins. In this case, input and output instructions won't do anything.
An experimental working implementation can be found here.
Implementations
Java
- JAgony - https://github.com/royvanrijn/JAgony