FRAK

FRAK is an assembler for the esoteric language brainfuck. It works by simulating an 8-bit conventional computer on the brainfuck machine. The simulated architecture is a RISC whose instruction set is inspired by Processor/1. The word "Frak" is the offensive word used in Battlestar Galactica instead of fuck. It was selected to represent the fact that an assembler 'fracked' the goal of brainfuck by allowing the writing of brainfuck program in an intuitive and not clever way.

Since FRAK's goal is to produce a proof of concept, it has many limitations: programs cannot address more than 256 bytes of memory (8-bit addresses), some operations are slow (those which are unknown to native brainfuck such as bitwise manipulations, if-then-else, etc.) and the instruction set is limited (no floating point support, etc.). FRAK/ASA introduces new macro instructions to overcome some of these limitations (see below).

FRAK could be improved by widening registers (16-bit would be enough to map the standard 30 000 byte memory, but 64 or 128 would taste more esoteric), extending the instruction set (a CISC would allow more efficient instructions on brainfuck 'hardware').

Architecture
FRAK has General Purpose Registers (GPR) accessible by the programmer, a System Register (SR) hidden from the programmer, Control Registers (CR) accessible to the programmer but altered as a side effect of operations, and Scratch Cells that are used by the system.

Code examples
This program adds 100 to 200 and sets register 2 to 255 if the result overflows (which is always the case ...): LI 0,200  LOADS IMMEDIATE VALUE 200 INTO GPR 0 LI 1,100  LOADS IMMEDIATE VALUE 100 INTO GPR 1 A 0,1     ADDS GPR 1 TO GPR 0 IF c0     IF CR 0 IS NULL JUMP TO THE MATCHING FI LI 2,X'FF' LOADS IMMEDIATE VALUE 0xFF (255) INTO GPR 2 FI c0

FRAK/ASA
In 2009, FRAK was updated to allow the programmer to access more than 256 bytes of RAM. ASA allow a program to access a larger, but still finite, quantity of memory through distinct 'address spaces' of 256 bytes. The new architecture adds the SPACE macro instruction to the FRAK instruction set to support this feature. ASA maintains upward compatibility and is able to assemble unmodified any FRAK programs.

SPACE
Tells the assembler to use the specified address space until another SPACE instruction is encountered.

Examples: LI 0,0     LOADS 0 INTO GPR 0 LI 1,1     LOADS 1 INTO GPR 1 SPACE 1    USE ADDRESS SPACE 1 INSTEAD OF ADDRESS SPACE 0 (DEFAULT ADDRESS SPACE) ST 1,0     STORES THE CONTENT OF GPR 1 INTO THE BYTE AT ADDRESS 0 (GPR 0 CONTAINS 0) OF ADDRESS SPACE 1 SPACE 0    USE ADDRESS SPACE 0 INSTEAD OF ADDRESS SPACE 1 LI 2,2     LOADS 2 INTO GPR 2 ST 2,0     STORES THE CONTENT OF GPR 2 INTO THE BYTE AT ADDRESS 0 (GPR 0 CONTAINS 0) OF ADDRESS SPACE 0 (DEFAULT ADDRESS SPACE)

SPACE 4095 MOVE TO THE LAST ADDRESS SPACE OF A MEGABYTE GET 1      READS A BYTE FROM THE INPUT STREAM INTO REGISTER 1 LI 0,255   STORES THE ADDRESS OF THE LAST BYTE IN REGISTER 0 ST 1,0     STORES THE CONTENT OF REGISTER 1 INTO THE BYTE POINTED BY REGISTER 0

ADDRESS
Tells the assembler to move the pointer at the specified displacement from the beginning of the current address space. Used in conjunction with literals.

Example: ADDRESS 3  MOVE TO THE FOURTH CELL '+'        INCREMENT THIS CELL

Literals
Literals are strings of brainfuck code to be included as-is in the assembled program or sequences of numerical values to be added to the cells pointed py the pointer. Be careful to move the pointer back to its original position at the end of the execution of the code when coding a code literal because the assembler is dependent of its knowledge of the pointer position. Also, you may have to use the macro instruction ADDRESS to move the pointer to a specific address. By default, the pointer is placed at the beginning of the current address space.

Examples: 'you can include anything including comments' ADDRESS 3  MOVE TO THE FOURTH CELL '[->+<]'   MOVE THE CONTENT OF THE CELL (CODE LITERAL)

C'Hello World' WRITE THE STRING TO MEMORY (DATA LITERAL) ADDRESS 0  MOVE THE POINTER TO THE BEGINNING OF THE STRING '[.>]'     PRINT THE STRING (CODE LITERAL)

SPACE 4095 MOVE TO THE LAST ADDRESS SPACE OF A MEGABYTE ADDRESS 255 MOVE TO THE LAST BYTE OF A MEGABYTE '+'        WRITE A 1 AT THE LAST BYTE OF A MEGABYTE (CODE LITERAL)

SET
Tells the assembler to set the specified number of contiguous cells to the specified value, starting at the current pointer position.

Examples: C'BRAINFUCK' WRITE THE STRING TO MEMORY ADDRESS 6   MOVE THE POINTER TO THE CELL THAT HOLDS U SET 2,C'*'   ERASE 2 CELLS (UC) ADDRESS 0   MOVE THE POINTER TO THE BEGINNING OF THE STRING '[.>]'      PRINT THE EXPURGATED STRING

C'BRAINFUCK' WRITE THE STRING TO MEMORY SET -3,C'*'  ERASE THE 3 PREVIOUS CELLS (UCK) ADDRESS 0   MOVE THE POINTER TO THE BEGINNING OF THE STRING '[.>]'      PRINT THE EXPURGATED STRING

External resources

 * FRAK/ASA Assembler (JavaScript implementation, with 8 GPR)


 * FRAK Assembler Original assembler