Agony

From Esolang
Jump to navigation Jump to search

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