backrooms
backrooms uses a 3D memory space that holds a single Extended ASCII character per room “cell”. It has 10 registers and 2 built in stacks per conscious "thread". Rules “instructions” can be more than one character long. It also has 5 data types that can be used with the registers and stacks. Data can be stored across multiple rooms and can be read as instructions during run-time or be re-read into data.
About
About | |
---|---|
Author | Charles McMarrow |
User | User:Ch44d |
Conceived | 5/22/2021 |
Birthday | 8/16/21 |
Official Interpreter |
---|
pip install backrooms |
https://github.com/cmcmarrow/backrooms |
Inspiration |
---|
Backrooms Creepypasta/MEME |
AsciiDots |
CISC Architecture |
Backrooms is designed to be: |
---|
Hackable VIA memory overflow attacks and poor error handling. |
Visually pleasing. |
Enjoyable to write small/medium programs. |
Capable of rewriting all of a program at run-time. |
Programs
Hello World
~GATE /rs"Hello World!"e~ha
bottles
~GATE /ri10ibri99>ers" bottles of beer on the wall, "epers" bottles of beer."epzez-V /V".llaw eht no reeb fo selttob "srepe" ,dnuora ti ssap dna nwod eno ekaT"sr.< /e>e~ha 1 >rs"1 bottle of beer on the wall, 1 bottle of beer."epers"Take one"epV /pp p pVe".llaw eht no reeb fo selttob erom on ,dnuora ti ssap dna nwod "sr< /ze . p>peers"No more bottles of beer on the wall, no more bottles of beer"V />...eezd-N^.^ e / ^".llaw eht no reeb fo selttob 99 ,erom emos yub dna erots eht ot oG"srepe"."srp<
truth-machine
# 1 will echo forever and 0 will echo a single time. # Any other input will default to a 1. ~GATE /cicOvZVpri1V / p >.e>NV~ha / >ri1e^e<
fibonacci
~GATE /V ah~< />ri0>dri18isZ^pdrs"FIB"V / ^+pe" "srpech......< ~FIB />ZVdri3isLVpd-rs"FIB"hcz--rs"FIB"hciahr /rh<rh1irpp<
tic tac toe
~GATE />ri0>...+dri10isNVpprs"x"k0pri10ibrs"Tic Tac Toe!"epepri0V /. . p a >p+....>dri9isNVpprs"E_BOARD"hcrs"Cats!"ep...V /. . d h >..rs"C_BOARD"hcZ^rs"E_BOARD"hceprs" won!"epri10ibeppVpebi01ir< /. ^..hujbz"k"sr< ~ ^................huch"DRAOB_U"sr< . /^...........................p^Zeb"a"srcpe+ >>+srpebi01irpe+!niaga yalp ot "a" retnE+sr< # Echo board ~E_BOARD />ri10ibrs"#"s1epes2epes3epzezeeeeezezs4epes5epes6epzezeeeeezezs7epes8epes9eppephr # Update board ~U_BOARD />rs"rs+"s0bjrs"+k"bjV >pbjrs"prs+"bjs0rs"x"beZVprs"o">bjrs"+k0p">bjhr / Vpe0sch"DRAOB_E"sr<.pebi01irpe"RORRE"srpp^Nib"123456789"sr< >prs"x"^ / >rs": "epcdri10ibeprs"1~2~3~4~5~6~7~8~9"biZVpdrs"s"zbjuh..^ / ^....ebi01irpe"RORRE"srpp< # Check for winner ~C_BOARD /V >ppzphr />s5ds1beNVpd.....V >beN^ppp..V >ppzphr / >pds9beZVphr ^oupp< 3 V..ppp^Neb< / >pds3beNVpd.....V . >ppuo^ / >pds7beZVphr V+....<pppp^Nebou..hujbz"s"srai3ir< / 2 >ppri0>dri3isNVpprs""hr z / >rs"s"zbjuh..uobeN^pppp>d+....drs"s"z1pbjuh..zri3iadrs"s"zbjuh..^ / ^+z..hujbz"s"srd+z..hujbz"s"srd+mi3ird<
8 bit
~GATE /V >p~ha />ri512>Z^rs"READ"hcrs"INC"hcbjV / ^-pebi01irpejbjbjbjbjbjb< ~READ />V ~INC /V>ri0k0pV >p...V >p...V >p...V >p...V >p...V >p...V >p...V rhp< /. >2>1wri0s0Z^pV>2>1wri0s0Z^pV>2>1wri0s0Z^pV>2>1wri0s0Z^pV>2>1wri0s0Z^pV>2>1wri0s0Z^pV>2>1wri0s0Z^pV>2>1wri0s0Z^pV /. ^................ch"PILF"sr<^................ch"PILF"sr<^................ch"PILF"sr<^................ch"PILF"sr< /. rhp<^................ch"PILF"sr<^................ch"PILF"sr<^................ch"PILF"sr<. />rs"READ"hcri1k0rs"FLIP"hc..............................................................................^ ~FLIP />iaZV-ZVri0hr / d r / h i / r 1 / h / r
dynamic
~GATE /rs"Vrs+hello!+epri10ibep"ri47ri0ri0ri0ri-1ri0ud / / / / / / / / / / / / / / / / / / / / / >~ha
Rules
The rules "instructions" do not care if they are read up, down, left, right, etc, as long as the order of characters matches the rules signature. If a character does not match a rule backrooms will run NOP.
Name | Signatrue | Action | Example |
---|---|---|---|
BackMirror
|
\
|
Changes Vector based off the direction the conscious comes from.
|
~GATE /\ >~ha />....\.....< / . . / \.....^ |
BranchLessThanZero
|
L
|
Sets branch condition to LESS_THAN_ZERO. | |
BranchGreaterThanZero
|
G
|
Sets branch condition to GREATER_THAN_ZERO. | |
BranchZero
|
Z
|
Sets branch condition to ZERO. | |
BranchNotZero
|
N
|
Sets branch condition to NOT_ZERO. | |
BranchIsInteger
|
I
|
Sets branch condition to IS_INTEGER. | |
BranchIsString
|
S
|
Sets branch condition to IS_STRING. | |
BranchIsNone
|
O
|
Sets branch condition to IS_NONE. | |
BranchIsStackFrame
|
F
|
Sets branch condition to IS_STACK_FRAME. | |
BranchIsStackBottom
|
B
|
Sets branch condition to IS_STACK_BOTTOM. | |
Cite
|
c
|
WS[...] -> WS[input, ...]
|
~GATE /ce~ha |
ClearStack
|
n
|
WS[...] -> WS[]
|
~GATE /ri44rs"cats"ne~ha Output StackBottom |
CoordinateX
|
x
|
WS[...] -> WS[x, ..]
| |
CoordinateY
|
y
|
WS[...] -> WS[y, ..]
| |
CoordinateFloor
|
f
|
WS[...] -> WS[floor, ..]
| |
Decrement
|
-
|
WS[item, ...] -> WS[results, ..]
|
~GATE /ri40-e~ha Output 39 |
Duplicate
|
d
|
WS[item, ...] -> WS[item, item, ...]
|
~GATE /ri10depe~ha Output 1010 |
Echo
|
e
|
WS[item, ...] -> WS[item, ...]
|
~GATE /e~ha |
ForwardMirror
|
/
|
Changes Vector based off the direction the conscious comes from.
|
~GATE /.....V / . /.~ha / . . / /./.../ / . . / . . / >./ |
HallwayCall
|
hc
|
WS[hallway, ...] -> WS[...]
|
~GATE /ri3ri4rs"ADD"hc~ha ~ADD /iaephr Output 7 |
HallwayLevelCall
|
hl
|
WS[hallway, floor, ...] -> WS[...]
|
~GATE /ri3ri4rs"math"rs"ADD"hl~ha +math ~ADD /iaephr Output 7 |
HallwayReturn
|
hr
|
| |
HallwayGetName
|
hn
|
WS[hallway, floor, ...] -> WS[name, ...]
|
~GATE /fyhne~ha Output GATE |
HallwayGetLocation
|
hg
|
WS[hallway, floor, ...] -> WS[y_location, ...]
|
~GATE /frirs"Hallway"hge~ha ~Hallway / Output -1 |
HallwaySet
|
hs
|
WS[hallway, floor, name, ...] -> WS[...]
| |
HallwayRemove
|
hd
|
WS[hallway, floor, ...] -> WS[...]
| |
HallwayPast
|
hp
|
WS[hallway, floor, ...] -> WS[y_location, ...]
|
~GATE /fyhpe~ha ~Hallway / Output -1 |
HallwayNext
|
he
|
WS[hallway, floor, ...] -> WS[y_location, ...]
|
~Hallway / ~GATE /fyhee~ha Output 0 |
Halt
|
~ha
|
WS[...] -> WS[...]
|
~GATE /~ha |
HopOne
|
1
|
WS[...] -> WS[...]
|
~GATE /1^~ha |
HopTwo
|
2
|
WS[...] -> WS[...]
|
~GATE /2^^~ha |
HopThree
|
3
|
WS[...] -> WS[...]
|
~GATE /3^w^~ha |
HopFour
|
4
|
WS[...] -> WS[...]
|
~GATE /4^^^^~ha |
HopFive
|
5
|
WS[...] -> WS[...]
|
~GATE /5^OwO^~ha |
HopSix
|
6
|
WS[...] -> WS[...]
|
~GATE /6^^^^^^~ha |
HopSeven
|
7
|
WS[...] -> WS[...]
|
~GATE /7^^^^^^^~ha |
HopEighth
|
8
|
WS[...] -> WS[...]
|
~GATE /8^^^^^^^^~ha |
HopNine
|
9
|
WS[...] -> WS[...]
|
~GATE /9^^^^^^^^^~ha |
Increment
|
+
|
WS[item, ...] -> WS[results, ...]
|
~GATE /ri40+e~ha Output 41 |
IntegerCast
|
ic
|
WS[item, ...] -> WS[results, ...]
|
~GATE /rs"+12"ice~ha Output 12 |
IntegerAdd
|
ia
|
WS[item2, item, ...] -> WS[results, ...]
|
~GATE /ri3ri4iae~ha Output 7 |
IntegerSubtract
|
is
|
WS[item2, item, ...] -> WS[results, ...]
|
~GATE /ri3ri4ise~ha Output -1 |
IntegerMultiply
|
im
|
WS[item2, item, ...] -> WS[results, ...]
| |
IntegerDivide
|
id
|
WS[item2, item, ...] -> WS[results, ...]
| |
IntegerModular
|
io
|
WS[item2, item, ...] -> WS[results, ...]
| |
IntegerPower
|
ip
|
WS[item2, item, ...] -> WS[results, ...]
| |
IntegerByte
|
ib
|
WS[item, ...] -> WS[results, ...]
|
~GATE /ri67ibe~ha Output c |
IntegerAbsolute
|
il
|
WS[item, ...] -> WS[results, ...]
|
~GATE /ri-44ile~ha Output 44 |
LevelGetFloorName
|
ln
|
WS[floor_location, ...] -> WS[name, ...]
| |
LevelGetFloorLevel
|
ll
|
WS[floor_name, ...] -> WS[f_location, ...]
| |
LevelSetFloorName
|
ls
|
WS[floor_name, floor_location, ...] -> WS[...]
| |
NOP
|
.
|
WS[...] -> WS[...]
| |
Keep
|
k
|
WS[item, ...] -> WS[item, ...], R<DIGIT>: item
|
~GATE /ri4k3ps3e~ha Output 4 |
Pop
|
p
|
WS[item, ...] -> WS[...]
| |
PopFrame
|
a
|
WS[..., ...] -> WS[...]
|
~GATE /ri4rfrs"cats"ri1ri-9ae~ha Output 4 |
Read
|
r
|
WS[...] -> WS[item, ...]
|
~GATE /ri-44e~ha Output -44 ~GATE /rs@STRING@e~ha Output STRING ~GATE /rne~ha Output None ~GATE /rfe~ha Output StackFrame |
ShifterRight
|
>
|
WS[...] -> WS[...]
|
~GATE /V />......V / >......~ha ~GATE /ri0.N.V.Z.V / >~ha ~GATE /....>>...!.!..V....^...V / >~ha |
ShifterLeft
|
<
|
WS[...] -> WS[...]
| |
ShifterUp
|
^
|
WS[...] -> WS[...]
| |
ShifterDown
|
v
|
WS[...] -> WS[...]
| |
ShifterDownUpper
|
V
|
WS[...] -> WS[...]
| |
ShifterUpper
|
{
|
WS[...] -> WS[...]
| |
ShifterLower
|
}
|
WS[...] -> WS[...]
| |
Store
|
s
|
R<DIGIT>: item, WS[...] -> WS[item, ...], R<DIGIT>: item
| |
StringLength
|
bl
|
WS[item, ...] -> WS[results, ...]
|
~GATE /rs"cats"ble~ha Output 4 |
StringCast
|
bc
|
WS[item, ...] -> WS[results, ...]
|
~GATE /rnbce~ha Output None |
StringAt
|
ba
|
WS[at, item, ...] -> WS[results, ...]
|
~GATE /rs"cats"ri1bae~ha Output a |
StringByte
|
bb
|
WS[item, ...] -> WS[results, ...]
|
~GATE /rs"c"bbe~ha Output 67 |
StringSplit
|
bs
|
WS[at, item, ...] -> WS[front, back, ...]
|
~GATE /rs"12345"ri2bseprs" "epe~ha Output 12 345 |
StringJoin
|
bj
|
WS[back, front, ...] -> WS[results, ...]
|
~GATE /rs"cats"rs" 0w0"bje~ha Output cats 0w0 |
StringEqual
|
be
|
WS[item2, item, ...] -> WS[results, ...]
|
~GATE /rs"cats"rs"cats"bee~ha Output 1 |
StringEqual
|
bi
|
WS[item2, item, ...] -> WS[results, ...]
|
~GATE /rs"cats"rs"%^*&cats$"bie~ha Output 1 |
StringUpper
|
bu
|
WS[item, ...] -> WS[results, ...]
| |
StringLower
|
bo
|
WS[item, ...] -> WS[results, ...]
| |
StringReverse
|
br
|
WS[item, ...] -> WS[results, ...]
| |
Switch
|
z
|
WS[item2, item, ...] -> WS[item, item2, ...]
| |
ThreadThread
|
tt
|
WS[...] -> WS[...]
|
~GATE /ttrs"cats"e.~ha Output catscats |
ThreadJoin
|
tj
|
WS[...] -> WS[...]
|
~GATE /ttrs"cats"etje.~ha Output catscatscats |
ThreadID
|
ti
|
WS[...] -> WS[ID, ...]
| |
ThreadLock
|
tl
|
WS[...] -> WS[...]
|
~GATE /tttlrs"cats"eprs"0w0"etutj~ha Output cats0w0cats0w0 |
ThreadUnLock
|
tu
|
WS[...] -> WS[...]
| |
UncommonReadFlip
|
ur
|
WS[...] -> WS[item, ...]
|
~GATE /1Vuri44 / >e~ha Output 44 |
UncommonWriteFlip
|
uw
|
WS[item, ...] -> WS[...]
|
~GATE /ri44.1Vuw / >e~ha Memory ri44.1Vuw>1vuri44 >e~ha ~GATE /rs"cats".1Vuw$ / >e~ha Memory rs"cats".1Vuw$>1vurs$cats$ >e~ha |
UncommonHotPatch
|
uh
|
WS[item, ...] -> WS[...]
|
~GATE /rs"rs+cats+e"uh.............~ha Memory rs"rs+cats+e"uhrs+cats+e....~ha |
UncommonSimpleDump
|
us
|
WS[floor, y, x, item ,...] -> WS[...]
| |
UncommonDynamicDump
|
ud
|
WS[v_floor, v_y, v_x, floor, y, x, item, ...] -> WS[...]
| |
UncommonDoubleDuplicate
|
uo
|
WS[item2, item, ...] -> WS[item2, item, item2, item, ...]
| |
Write
|
w
|
WS[item, ...] -> WS[...]
|
~GATE /ri44w.....~ha Memory ri44wri44.~ha ~GATE /rs"cats"w+........~ha Memory rs"cats"w+rs+cats+~ha ~GATE /rnw+........~ha Memory rnwrn.......~ha ~GATE /rfw.........~ha Memory rfwrf.......~ha |
Convert Functions
to_integer
From | To |
---|---|
Integer
|
Integer
|
String
|
len(String)
|
None
|
0
|
StackFrame
|
0
|
StackBottom
|
0
|
to_string
From | To |
---|---|
Integer
|
str(Integer)
|
String
|
String
|
None
|
"None"
|
StackFrame
|
"StackFrame"
|
StackBottom
|
"StackBottom"
|
to_hallway
From | To |
---|---|
Integer
|
Integer if hallway exist else 0, 0 if hallway exist else None
|
String
|
Integer if hallway name exist else len(String), len(String) if hallway exist else 0, 0 if hallway exist else None
|
None
|
0 if hallway exist else None
|
StackFrame
|
0 if hallway exist else None
|
StackBottom
|
0 if hallway exist else None
|
to_floor
From | To |
---|---|
Integer
|
Integer
|
String
|
Finds floor level, if name does not exist then len.(String)
|
None
|
0
|
StackFrame
|
0
|
StackBottom
|
0
|
Memory
backrooms memory space is 3D with the axis X, Y, Floor every room "cell" holds <CHARACTER> and the default character is " ". Every axis is an integer. It is infinite in every direction. backrooms also allows some parts of the 3D memory space to be named <NAME>.
Floor: Every Floor can be given its own name <NAME> or have the name of None. During runtime you can change or remove names. No two floors can have the same name. The last floor to be given the same name will keep it. The others will default to None. A Floor cord looks like <Floor>.
Hallways: Every Floor can be given multiple Hallways. A Hallway an be given its own name <NAME> or have the name of None or not exist. A Hallway cord looks like <Y, Floor> X is all ways 0. No two hallways on the same floor can have the same name. The last hallway to be given the same name will keep it. The others will default to None on that floor.
Data Types
Type | Description |
---|---|
Integer
|
-infinity to infinity |
String
|
extended ASCII characters with a size 0 to infinity |
None
|
null |
StackFrame
|
indicates a frame on the stack |
StackBottom
|
indicates that the stack is empty |
Conscious
The conscious "thread" holds its own state. Each conscious gets it own registers, work stack, hallway stack, branch condition, vectors and thread id.
Registers
Each conscious gets 10 registers which can store all 5 data types.
Work Stack
The work stack allows an unlimited amount of data to be pushed onto it. Note: StackBottom cant be pushed onto the stack.
Hallway Stack
Hallway "Function" Stack preserves registers, current location and current vector. When a the program makes a hallway call. The first hallway with "GATE" to be found is the program entry point.
Branch Condition
Conditions | Operation |
---|---|
Clear
|
True
|
LESS_THAN_ZERO
|
to_integer(item) < 0
|
GREATER_THAN_ZERO
|
to_integer(item) > 0
|
ZERO
|
to_integer(item) == 0
|
NOT_ZERO
|
to_integer(item) != 0
|
IS_INTEGER
|
type(item) == Integer
|
IS_STRING
|
type(item) == String
|
IS_NONE
|
type(item) == None
|
IS_STACK_FRAME
|
type(item) == StackFrame
|
IS_STACK_BOTTOM
|
type(item) == StackBottom
|
Translator
The translator "assembler" of backrooms simplifies the way you can load a program into backrooms. It will ingest a script "file" or scripts and raise a syntax error if one is present. The Translator throw's away any unnecessary <WHITESPACE>. The character "@" represents the data type None and the translator will replace "@" when necessary.
Translator Definitions | Description |
---|---|
<ROW> ::= "/" { <ROW_CHARACTER> } <NEWLINE> |
|
<COMMENT> ::= "#" { <COMMENT_CHARACTER> } <NEWLINE> |
|
<HALLWAY> ::= "~" [ <NAME> | "@" ] <NEWLINE> |
|
<FLOOR> ::= "+" [ <NAME> | "@" ] <NEWLINE> |
|
<INCLUDE> ::= "%" <NAME> <NEWLINE> |
|
<MUST_INCLUDE> ::= "!" <NAME> <NEWLINE> |
|
<PARALLEL> ::= "=" [<NAME> | "@"] [<NAME> | "@"] [<NUMBER> | "@"] [<NUMBER> | "@"] <NEWLINE> |
|
<X> ::= "X" <NUMBER> <NEWLINE> |
|
<XS> ::= "XS" <NUMBER> <NEWLINE> |
|
<Y> ::= "Y" <NUMBER> <NEWLINE> |
|
<YS> ::= "YS" <NUMBER> <NEWLINE> |
|
<F> ::= "F" <NUMBER> <NEWLINE> |
|
<FS> ::= "FS" <NUMBER> <NEWLINE> |
|
<Translator> ::= {<ROW> | <COMMENT> | <HALLWAY> | <FLOOR> | <INCLUDE> | <MUST_INCLUDE> | <PARALLEL> | <X> | <XS> | <Y> | <YS> | <F> | <FS>} |
|
Scripts
- Scripts can have the file extension ".brs" or no extension at all.
- Other Scripts in the same main directory can be included.
- The include check order is main directory then built-in directory of a script.
Built-In Scripts
Although its not necessary for a backrooms interpreter to supply built-in scripts. The official one does offer scripts that makes it much easier to allocate and store data. Built-In scripts are just like any other script.
Scripts | Descriptions | Hallways |
---|---|---|
h_vector
|
Servers as a vector use parallel to make a copy of the floor to have a vector. |
|
heap
|
Allows a program to allocate blocks of memory to store data. |
|
heap_load
|
Used to include "heap". | |
utils
|
Tools used to build other scripts. |
|
vars
|
Allows a program to get, set and delete a variable. |
|
vars_load
|
Used to include "vars". |
Meta-Language
Type | Description |
---|---|
::=
|
start to definition |
|
|
alternative definition |
[]
|
optional |
{}
|
zero or more occurrences |
()
|
only one occurrence |
<X>
|
name of definition <X> |
"x"
|
non-special symbol x |
"\""
|
special symbol " |
\x120
|
byte reputation of special symbol or symbol x |
Meta-Language Implementation |
---|
<DIGIT> ::= ("0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9") |
<CHARACTER> ::= All extended ASCII characters excluding \x10. |
<COMMENT_CHARACTER> ::= All extended ASCII characters. |
<NUMBER> ::= ["+" | "-"] <DIGIT> {<DIGIT>} |
<LETTER> ::= a-z and A-Z |
<NAME> ::= (<LETTER> | <DIGIT> | "_") { <LETTERS> | <DIGIT> | "_" } |
<INPUT_CHARACTER> ::= (<LETTER> | <DIGIT> | "," | "<" | "." | "> " | "/" | "?" | ";" | ":" | "'" | "\"" | "[" | "{" | "]" | "}" | "\\" | "|" | "`" | "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-" | "_" | "=" | "+" | " ") |
<ROW_CHARACTER> ::= (<LETTER> | <DIGIT> | "," | "<" | "." | "> " | "/" | "?" | ";" | ":" | "'" | "\"" | "[" | "{" | "]" | "}" | "\\" | "|" | "`" | "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-" | "_" | "=" | "+" | " " | "~") |
<NEWLINE> ::= "\n" |
<WHITESPACE> ::= {"\t" | "\r" | "\v" |"\f" | " "} |