BRB

From Esolang
Jump to navigation Jump to search

BRB is an esoteric programming language created by Peter Larsen in 2011. BRB stands for: Be Right BRB.

BRB is built on Brainfuck but instead of 8 commands it has 102 commands. It has more than 1 tape (every tape has the option to have a child "generated" tape, and a byte variable (var) for each tape. The variable var is initially set to 65 ('A'). Every tape have 3 Instruction Pointers (IP, IP1, IP2). You can open additional files to a tape from within BRB, and interpret the file.

Code and memory coexists on the tapes, you can edit the tapes (current interpreted tape, child.tape and the parent.tape if the current tape is not the root top-most tape) and the variables and IP's belonging to the tapes using the commands described below.

Commands

Here comes a summary of the available commands. I will add more information later, this summary is based on a snippet from the sourcecode for the BRB interpreter v1.0:

First of all, the 8 bf-commands

// modify IP's on generated code
'>': Increase child.IP1 on child.tape by 1. If passed length of tape a new char is generated at end of child.tape.			
'<': Decrease child.IP1 on child.tape by 1. If passed length of tape a new char is generated at end of child.tape.				

// input and output
'.': Output char from cell on child.tape under the pointer child.IP1	
',': Input char to cell on child.tape at child.IP1		

// SMC on generated code
'+': Increase byte child.tape at child.IP1 by 1	
'-': Decrease byte child.tape at child.IP1 by 1	
			
// Conditional stuff, loops
'[': Jump past the matching ] if the cell on child.tape under the pointer child.IP1 is 0
']': Jump back to the matching [ if the cell on child.tape under the pointer child.IP1 is nonzero

Countdown

'9': Changes to '8' when executed		
'8': Changes to '7' when executed		
'7': Changes to '6' when executed		
'6': Changes to '5' when executed		
'5': Changes to '4' when executed		
'4': Changes to '3' when executed		
'3': Changes to '2' when executed		
'2': Changes to '1' when executed	
'1': Changes to '0' when executed
'0': Changes to '9' when executed

Modify local IP's

'v': Increase IP by 1, jumping past the next char					
'x': Jump back 2 steps, Changes current code from 'x' to 'v'
'{': Increase IP1 by 1					
'}': Decrease IP1 by 1					
'%': Increase IP2 by 1 					
'&': Decrease IP2 by 1					
'*': Set IP1 to IP				
169: Set IP1 to 0				 // ©
174: Set IP2 to 0				 // ®

Modify variables

'B': Increase var by 1			
'A': Decrease var by 1				

'(': Increase child.var by var		
')': Decrease child.var by var

'=': Set var to child.var
'|': Set child.var to var
'/': Increase var by child.var	
'\': Decrease var by child.var

'#': Set var to the byte value at cell on current tape under the pointer IP1		
'"': Set var to the byte value at cell on current tape under the pointer IP2
'!': Set var to the byte value at cell on child.tape under the pointer child.IP1
247: Set var to the byte value at cell on child.tape under the pointer child.IP2  //  ÷ in Lucida Console (notepad)
248: Set child.var to the byte value at cell on current tape under the pointer IP1//  ø in Lucida Console (notepad)
'?': Set child.var to the byte value at cell on current tape under the pointer IP2		
'^': Set child.var to the byte value at cell on child.tape under the pointer child.IP1
':': Set child.var to the byte value at cell on child.tape under the pointer child.IP2

Forward jump

';': Forward jump to and past the next ';'

SMC

'a': Decrease value at cell on current tape right of IP by 1					
'b': Increase value at cell on current tape right of IP by 1				
'c': Decrease value at cell on current tape left of IP by 1					
'd': Increase value at cell on current tape left of IP by 1					

SMC - set neighbour

'f': Set cell on current tape right of IP to var	// SMC on next byte
'e': Set cell on current tape left of IP to var		// SMC on previous byte

SMC on child.tape

'C': Decrease value at cell on child.tape on pointer child.IP2 by 1				
'D': Increase value at cell on child.tape on pointer child.IP2 by 1

'E': Decrease value at cell on child.tape on pointer child.IP by 1	
'F': Increase value at cell on child.tape on pointer child.IP by 1

'G': Set cell on child.tape on pointer child.IP1 to value at cell on child.tape on pointer child.IP2
'H': Set cell on child.tape on pointer child.IP2 to value at cell on child.tape on pointer child.IP1	

SMC on parent.tape if this is a child.tape, else ignore

'I': Decrease value at cell on parent.tape on pointer parent.IP1 by 1						
'J': Increase value at cell on parent.tape on pointer parent.IP1 by 1						
'K': Decrease value at cell on parent.tape on pointer parent.IP2 by 1						
'L': Increase value at cell on parent.tape on pointer parent.IP2 by 1						

'M': Set cell on parent.tape on pointer parent.IP1 to var						
'N': Set cell on parent.tape on pointer parent.IP2 to var
'O': Set cell on parent.tape on pointer parent.IP1 to value at cell on parent.tape on pointer parent.IP2	
'P': Set cell on parent.tape on pointer parent.IP2 to value at cell on parent.tape on pointer parent.IP1

Modify IP's on child.tape

'g': Increase child.IP2 by 1					
'h': Decrease child.IP2 by 1	
'i': Increase child.IP by 1	
'j': Decrease child.IP by 1	

If this is child.tape then modify IP's on parent.tape, else ignore

'k': Increase parent.IP1 by 1	
'l': Decrease parent.IP1 by 1	
'm': Increase parent.IP2 by 1	
'n': Decrease parent.IP2 by 1	
'o': Increase parent.IP by 1	
'p': Decrease parent.IP by 1	

Loop

'q': if var is alpha ( >= 65 && <= 90) || ( >= 97 && <= 122) then loop back until you find a digit char (number) 

Generate additional byte to tapes, appending at end of tape

'r': Generate code, add var to end of child.tape
181: SMC, add var to end of current tape                // µ in Lucida Console ( notepad)
						

Set child.tape

'`':	Set cell on child.tape on pointer child.IP to var	
180:	Set cell on child.tape on pointer child.IP1 to var	// ´ in Lucida Console (notepad)
128:	Set cell on child.tape on pointer child.IP2 to var	// € in Lucida Console (notepad)

Output var and cell values

's':	Output var					
163:	Output child.var				// £ in Lucida Console (notepad)
:	Output cell on current tape on pointer IP1					
'@':	Output cell on current tape on pointer IP2
229:	Output cell on child.tape on pointer child.IP2	// å in Lucida Console (notepad)

Input to var

167:	Input a char and store in var	                // § in Lucida Console (notepad)

Interpret child.tape

't':    interpret child.tape, start at first byte
'u':    interpret child.tape, start at byte var

Open file

'R':	Open a file and interpret it. Read filename from the following characters, filename ends with "\".
              You can open more than 1 file, for example:
              Rfile1.brb file2.brb\

              The code above will load file1.brb into: child.tape, and file2.brb into: child.child.tape and then
              start interpret child.tape

              You can also open a file and supply debug mode by typing "-debug " before the filename(s):
              R-debug file1.brb file2.brb file3.brb\

              If the filename is ignored like this "R\", then the child.tape will be reset

Saving file

'S':	Save child.tape as a file, end filename with "\". Not implemented in the interpreter yet. Feel free to add
       a function for this into the interpreter.

Loops

'T':	Loop backwards on current tape until finding char var
'U':	Loop backwards on current tape until finding char child.var


Conditional stuff. If True: child.var = 1 and execution jumps past next command. If not True: child.var = 2;

'V':	if (var == byte at child tape child IP1)	
'W':	if (var == byte at child tape child IP2)	
'X':	if (var == byte at IP)		
'Y':	if (var == child var)			
'Z':	if (var < child var)			
168:	if (IP1 == IP2)			// '¨' in Lucida Console (notepad)

Loop

'~':	Loop back to char: child.var

Edit byteroller. All bytes read from tapes is altered: byte+byteroller

197:	Increase byteroller by 1		// Å in Lucida Console (notepad)
196:	decrease byteroller by 1		// Ä in Lucida Console (notepad)

'_':	Exit tape execution

Example code

Hello, World!

The following BRB code samples all outputs "Hello, World!"

vRvM{#{{ø1{Aq=1ø£{Aq_Hello, World!
;Hello, World!;{'{'{'{'{'{'{'{'{'{'{'{'{'
vH*}'ve*}'vl*}'vl*}'vo*}'v,*}'v *}'vw*}'vo*}'vr*}'vl*}'vd*}'v!*}'
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.

false Quine

;This brb program is a false quine;&1d'{¨q'|©®_

Cat

2 Examples of the Cat program

1§s=q
,[.,]

Open file

This is a demonstration of how you can open a file from within BRB

t
Rquine.brb\
t
R-debug quine.brb\
t
R\
t
_

Save the above file as t2.brb and run the interpreter like this:

c:\>brbint10 t2.brb

The BRB-file will open quine.brb into child.tape and interpret it using -debug mode.

Then you could try 1 of the following for additional insight into how BRB and the interpreter works:

 c:\>brbint10 t2.brb quine.brb
 c:\>brbint10 -debug t2.brb quine.brb

Output digits

Byte to 3-digit decimal converter. The following BRB code takes a char input and output its numeric 3-digit decimal ascii-number representation:

r>§|v0*}#r#r#r>>>=´\BBBBBBBBBB>´>|\<^<v[v[BY;<<+>>|\-]bZ;>^<-]
<^/´<v9*}#^Z;<+>----------v;v9*}#^Z;<+>----------v;<.>.>._

Here comes the same code with informative comments included into the sourcecode:

; This BRB code outputs the current value of input char as digits ;

; Copy 'A' to child.var            ; r>
; Input a char to var              ; §
; Copy var to child.var            ; |
; Copy "000" to child.tape         ; v0*}#r#r#r>>>
; copy var+10 to child.tape        ; =´\BBBBBBBBBB>´>
; set var to 0, c.var to 10        ; |\<^
; loop down until zero             ; <v[v[  BY; <<+>>  |\  -] bZ   ;>^<   -]
; store var to last digit          ; <^/´
; move to second digit		   ; <
; check if numeric, else add first ; v9*}#^   Z; <+>  ----------    v;
; check if numeric, else add first ; v9*}#^   Z; <+>  ----------    v;
; move to first digit		   ; <
; output digits                    ; .>.>._

Braincrash to Brainfuck converter in BRB

This is a BRB program that converts Braincrash sourcecode into Brainfuck sourcecode:

;!+-><.,[];{#%%[^V;@v;>%}#{?Y;®%%v;#]_

Save the above program as bc2bf-conv.brb and run it like this:

C:\>brbint10 bc2bf-conv.brb cat.bc
,[.,]

The datafile cat.bc is the Braincrash sourcecode to be converted. In the above sample cat.bc is:

     !!     !! !

Braincrash interpreter in BRB

This BRB program interprets a Braincrash sourcecode:

;!+-><.,[];{#%%[^V;"€gv;|\´>%}#{?Y;®%%v;#]t_

For example you can save the above code as: braincrashi.brb, use the BRB interpreter to interpret cat.bc like this:

brbint10 braincrashi.brb cat.bc

External resources

esotericism.se/BRB Author website where you can find an interpreter for BRB written in c++.