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.
===Instruction Set===
  	Name 	Description 	CR0 change 	Example 	Example
A r0,r1 	ADD 	Adds register r1 to register r0. 	1 if carry, 0 otherwise 	A 3,1 	Adds r1 to r3
AND r0,r1 	BITWISE AND 	Performs a bitwise AND between register r0 and register r1 and stores the result into register r0. 	  	AND 3,1 	r1 AND r3
BAND r0,r1	BOOLEAN AND 	Performs a boolean AND between register r0 and register r1 and stores the result into register r0. 	  	BAND 3,1	r1 and r3
BNOT r0 	BOOLEAN NOT 	Applies a boolean NOT to register r0. 	  	BNOT 3 	not r3
BOR r0,r1 	BOOLEAN OR 	Performs a boolean OR between register r0 and register r1 and stores the result into register r0. 	  	BAND 3,1	r1 and r3
DEC r0 	DECREMENT 	Subtracts 1 from register r0. 	1 if wrap around, 0 otherwise 	DEC 3 	Subtracts 1 from r3
DO r0 	LOOP STATEMENT 	While r0 is not null, execution will continue. Otherwise, execution jumps to after the matching OD. When the matching OD is encountered, execution jumps back to the matching DO and r0 is tested again.	  	
LI r1,1
DO r3
A r2,r3
S r3,r1
OD r3	
Sets r1 to 1
While r3 = 0
Adds r3 to r2
Decrement r3
DIV r0,r1 	DIVIDE 	Divides register r0 by register r1. 	1 if the remainder is not 0, 0 otherwise	DIV 2,0 	Divides r2 by r0
ELSE r0 	CONDITIONAL STATEMENT	If the value of register r0 is null, execution will continue. Otherwise, execution will jump to after the matching ESLE instruction. 	  	
ELSE r3
A r3,r2
ESLE r3	
If r3 = 0
Adds r2 to r3
GET r0 	INPUT 	Inputs the next byte into register r0. 	  	GET 1 	Inputs the next byte into r1.
IF r0 	CONDITIONAL STATEMENT	If the value of register r0 is not zero, execution will continue. Otherwise, execution will jump to after the matching FI instruction. 	  	
IF r3
A r3,r2
FI r3	
If r3 is not null
Adds r2 to r3
LI r0,i0 	LOAD IMMEDIATE 	Sets the value of register r0 to the immediate value i0. 	  	LI 3,15 	Sets r3 to 15
INC r0 	INCREMENT 	Adds 1 to register r0. 	1 if carry, 0 otherwise 	INC 3 	Adds 1 to r3
L r0,r1 	LOAD 	Loads the byte at the address pointed by register r1 into register r0. 	  	L 1,3 	Loads the byte at the address pointed to by r3 into r0.
LR r0,r1 	LOAD REGISTER 	Copies register r1 to register r0. 	  	LR 2,0 	Copies r0 to r2
MOD r0,r1 	MODULO 	Divides register r0 by register r1 and sets register r0 to the remainder. 	1 if the remainder is not 0, 0 otherwise	MOD 2,0 	Divides r2 by r0 and sets r2 to the remainder
MUL r0,r1 	MULTIPLY 	Multiplies register r0 by register r1. 	1 if overflow, 0 otherwise 	MUL 2,0 	Multiplies r2 by r0
NOT r0 	BITWISE NOT 	Applies a bitwise NOT to the value of register r0. 	  	NOT 0 	Invert r0
OR r0,r1 	BITWISE OR 	Performs a bitwise OR between register r0 and register r1 and stores the result into register r0. 	  	OR 2,1 	r2 OR r1
PUT r0 	OUTPUT 	Outputs the byte in register r0. 	  	PUT 1 	Outputs r1.
S r0,r1 	SUBTRACT 	Subtracts register r1 from register r0. 	1 if wrap around, 0 otherwise 	S 3,1 	Subtracts r1 to r3
SL r0 	SHIFT LEFT 	Shifts register r0 to the left. 	1 if the leftmost bit was on 	SL 3 	Shift left r3
SR r0 	SHIFT RIGHT 	Shifts register r0 to the right. 	1 if the rightmost bit was on 	SR 3 	Shift right r3
ST r0,r1 	STORE 	Stores register r0 at the address pointed to by register r1. 	  	ST 1,3 	Store r1 at the address pointed to by r3
==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.
===New features of the FRAK/ASA assembler===
====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 
Category:Brainfuck
Category:Languages