Opcode

From Esolang
Jump to navigation Jump to search

Opcode is a brainfuck derived esoteric language that uses opcodes to execute commands. It was created by pptx704 on 23rd March 2022. The language has only 2 commands: ! and +. It is turing complete as it has exact same commands as brainfuck itself.

Language Description

The language works same as brainfuck works in sense of semantics although the definition of the opcodes are very different from brainfuck itself. Apart from the memory tape of BF, there is an opcode counter capped from 0 to 7 and a 2D array of commands. Theoretically the memory tape is infinitely long on both sides and the 2D array is infinitely expandable towards right and bottom only.

Initially, all cells of the memory tape is valued 0; the same goes to the opcode counter. And the command counter is on row 0 and the commands from the code itself is stored in that row.

Commands
Instruction Description
! Execute opcode
+ Increase opcode counter by 1 and mod it by 8
Opcodes
Opcode Description Brainfuck Equivalent Command
0 Take single character input from the console .
1 Take the value of current memory cell and print ascii version of it on the console ,
2 Increase memory pointer value by 1 +
3 Decrease memory pointer value by 1 -
4 Move memory pointer to one cell right >
5 Move memory pointer to one cell left <
6 Move to one row below.
If the current memory cell is 0, ignore all opcode executions untill an equivalent opcode 7 is met. Else, keep adding the operation for each opcode execution to the current row until an equivalent opcode 7 is met.
[
7 Keep executing the operations of current row sequentially until the current value of memory pointer is 0.
When the value of current memory pointer is 0 and make current row empty and move to the row above.
]

All characters apart from ! and + are ignored.

Interpreter

Although Opcode has its own language definition, as it is derived from brainfuck itself, the most simple opcode interpreter can first convert the opcode into a brainfuck equivalent code, then execute the brainfuck code as is. The pseudocode of such interpreter would be the following-

string m = ""
int opcode = 0
char[] eq = {'.', ',', '+', '-', '>', '<', '[', ']'}
for i in code:
    if i = '+'
        opcode = (opcode + 1) mod 8
    else if i = '!'
        m = m + eq[opcode]
execute_as_brainfuck(m)

See pptx704's implementation of the Opcode interpreter in Java.

Differences with brainfuck

Although the language is derived from brainfuck, it does not follow all brainfuck specifications explicitly. For example, the memory tape is infinitely long on both sides and that makes +++++!!!! a valid command. So the memory tape is implemented with a Doubly Linked List instead of array[3000]. Also the upper limit is 127 instead of 255 for the memory cells.

It is worth noting that, only sane implementation of the 2D command array is a Doubly Linked List of Linked Lists as the Opcode code can be exponentially large and can have a lot of nested loops.

Implementation

Cat Program

Brainfuck code

+[>,.<]

Opcode Code

Each BF command in one line
++!
++++!
++++++!
+++++!
+++++++!
+++++!
++!

Minified

++!++++!++++++!+++++!+++++++!+++++!++!

Hello, World!

++++!++++++!!!!!!!!++++!+++++++!+++++!!!!!!!!!++!+++++++!++++!++++++!+++!++++!++++++!!!!++++!+++++++!+++++!!!!!!!
++!+++++++!++++!++++++!+++++!++++++!++!!!!!!!++++++!!++!!!++++++!++++!!++++++!!!!!!++++!+++++++!+++++!!!!!!!
++!+++++++!++++!++++++!+++++!!++++++!+++!!!!!!!!!!!!+++++!++++!++++++!!!!!!++++!+++++++!+++++!!!!!!!!!++!
+++++++!++++!++++++!+++++!++++++!+++++!+++!++!!!++++++!+++!!!!!!+++++!+++!!!!!!!!+++++!++++!!!++++++!!!!
++++!+++++++!+++++!!!!!!!!++!+++++++!++++!++++++!+++++!++++++!

BF to Opcode Converter

Python implementation of a Brainfuck to Opcode converter

changes = {'.': 0, ',': 1, '+': 2, '-': 3, '>':4, '<': 5, '[': 6, ']': 7}
def convert(code):
    current = 0
    x = ""
    for i in code:
        dest = changes.get(i)
        if dest is None:
            continue
        diff = (dest - current) % 8
        x += "+" * diff + "!"
        current = dest
        print(current)
    return x