BRB
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++.