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.
* <1, 0, 0> -> <0, -1, 0>
* <0, -1, 0> -> <1, 0, 0>
* <-1, 0, 0> -> <0, 1, 0>
* <0, 1, 0> -> <-1, 0, 0>	
 ~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, ...]
* Gets input from user and removes all characters not in <INPUT_CHARACTER>.	
 ~GATE
 /ce~ha
ClearStack 	n 	WS[...] -> WS[]
* Clears the Stack of all data.	
 ~GATE
 /ri44rs"cats"ne~ha
Output
 StackBottom
CoordinateX 	x 	WS[...] -> WS[x, ..]
* Gets conscious current x coordinate.	
CoordinateY 	y 	WS[...] -> WS[y, ..]
* Gets conscious current y coordinate.	
CoordinateFloor 	f 	WS[...] -> WS[floor, ..]
* Gets conscious current floor coordinate.	
Decrement 	- 	WS[item, ...] -> WS[results, ..]
* results = to_integer(item) - 1
* Subtract one to the item on top of the stack.	
 ~GATE
 /ri40-e~ha
Output
 39
Duplicate 	d 	WS[item, ...] -> WS[item, item, ...]
* Copy the top item on the stack and place the copy onto the stack.	
 ~GATE
 /ri10depe~ha
Output
 1010
Echo 	e 	WS[item, ...] -> WS[item, ...]
* Print the item on top of the stack onto the console.	
 ~GATE
 /e~ha
ForwardMirror 	/ 	Changes Vector based off the direction the conscious comes from.
* <1, 0, 0> -> <0, 1, 0>
* <0, 1, 0> -> <1, 0, 0>
* <-1, 0, 0> -> <0, -1, 0>
* <0, -1, 0> -> <-1, 0, 0>	
 ~GATE
 /.....V
 / . /.~ha
 / . .
 / /./.../
 / . .
 / . .
 / >./
HallwayCall 	hc 	WS[hallway, ...] -> WS[...]
* to_hallway(hallway)
* Jumps to a hallway on the same floor.
* Saves registers onto the Function Stack.
* If StackBottom is in a register it will be replaced by None when put on the Function Stack.
* The return location and current vector will also be saved onto the Function Stack.	
 ~GATE
 /ri3ri4rs"ADD"hc~ha
 ~ADD
 /iaephr
Output
 7
HallwayLevelCall 	hl 	WS[hallway, floor, ...] -> WS[...]
* to_hallway(hallway), to_floor(floor)
* Jumps to a hallway on any floor.
* Saves registers onto the Function Stack.
* If StackBottom is in a register it will be replaced by None when put on the Function Stack.
* The return location and current vector will also be saved onto the Function Stack.	
 ~GATE
 /ri3ri4rs"math"rs"ADD"hl~ha
 +math
 ~ADD
 /iaephr
Output
 7
HallwayReturn 	hr 	
* Restores registers.
* Jump back to return location.
* Restore vector.	
HallwayGetName 	hn 	WS[hallway, floor, ...] -> WS[name, ...]
* to_integer(hallway), to_floor(floor)
* If no name exist None will be given back.
* The exact coordinates must be given.	
 ~GATE
 /fyhne~ha
Output
 GATE
HallwayGetLocation 	hg 	WS[hallway, floor, ...] -> WS[y_location, ...]
* to_floor(floor)
* If hallway is not a String then it will to_integer.
* If no name exist None will be given back.
* As long as the y coordinate is with in the hallway the hallway location will be found.
* If coordinates are not in a hallway then None will be given back.	
 ~GATE
 /frirs"Hallway"hge~ha
 ~Hallway
 /
Output
 -1
HallwaySet 	hs 	WS[hallway, floor, name, ...] -> WS[...]
* to_integer(hallway), to_floor(floor)
* If name is not None then it will to_string.
* Name must fit <NAME>.
* Will make a hallway and remove the hallway with the same name on the same floor if it exists.	
HallwayRemove 	hd 	WS[hallway, floor, ...] -> WS[...]
* to_hallway(hallway), to_floor(floor)
* Will remove the specified hallway.	
HallwayPast 	hp 	WS[hallway, floor, ...] -> WS[y_location, ...]
* to_hallway(hallway), to_floor(floor)
* Will get the past hallway.
* If no past hallway exist then None will be given.	
 ~GATE
 /fyhpe~ha
 ~Hallway
 /
Output
 -1
HallwayNext 	he 	WS[hallway, floor, ...] -> WS[y_location, ...]
* to_hallway(hallway), to_floor(floor)
* Will get the next hallway.
* If no next hallway exist then None will be given.	
 ~Hallway
 /
 ~GATE
 /fyhee~ha
Output
 0
Halt 	~ha 	WS[...] -> WS[...]
* Will stop the program.	
 ~GATE
 /~ha
HopOne 	1 	WS[...] -> WS[...]
* Will hop over one room.	
 ~GATE
 /1^~ha
HopTwo 	2 	WS[...] -> WS[...]
* Will hop over two rooms.	
 ~GATE
 /2^^~ha
HopThree 	3 	WS[...] -> WS[...]
* Will hop over three rooms.	
 ~GATE
 /3^w^~ha
HopFour 	4 	WS[...] -> WS[...]
* Will hop over four rooms.	
 ~GATE
 /4^^^^~ha
HopFive 	5 	WS[...] -> WS[...]
* Will hop over five rooms.	
 ~GATE
 /5^OwO^~ha
HopSix 	6 	WS[...] -> WS[...]
* Will hop over six rooms.	
 ~GATE
 /6^^^^^^~ha
HopSeven 	7 	WS[...] -> WS[...]
* Will hop over seven rooms.	
 ~GATE
 /7^^^^^^^~ha
HopEighth 	8 	WS[...] -> WS[...]
* Will hop over eighth rooms.	
 ~GATE
 /8^^^^^^^^~ha
HopNine 	9 	WS[...] -> WS[...]
* Will hop over nine rooms.	
 ~GATE
 /9^^^^^^^^^~ha
Increment 	+ 	WS[item, ...] -> WS[results, ...]
* results = to_integer(item) + 1
* Add one to the item on top of the stack.	
 ~GATE
 /ri40+e~ha
Output
 41
IntegerCast 	ic 	WS[item, ...] -> WS[results, ...]
* Intgerer -> Integer
* String -> Integer | None
* None -> None
* StackFrame -> None
* StackBottom -> None	
 ~GATE
 /rs"+12"ice~ha
Output
 12
IntegerAdd 	ia 	WS[item2, item, ...] -> WS[results, ...]
* results = item + item2	
 ~GATE
 /ri3ri4iae~ha
Output
 7
IntegerSubtract 	is 	WS[item2, item, ...] -> WS[results, ...]
* results = item - item2	
 ~GATE
 /ri3ri4ise~ha
Output
 -1
IntegerMultiply 	im 	WS[item2, item, ...] -> WS[results, ...]
* results = item * item2	
IntegerDivide 	id 	WS[item2, item, ...] -> WS[results, ...]
* results = ⌊item / item2⌋
* results = None if operation causes a divide by zero.	
IntegerModular 	io 	WS[item2, item, ...] -> WS[results, ...]
* results = item % item2
* results = None if operation causes a divide by zero.	
IntegerPower 	ip 	WS[item2, item, ...] -> WS[results, ...]
* results = ⌊item ** item2⌋	
IntegerByte 	ib 	WS[item, ...] -> WS[results, ...]
* if to_integer(item) can be made into an Extended ASCII then that Extended ASCII character will be the results as a String.
* if to_integer(item) can't be made into an Extended ASCII then the results will be a None.	
 ~GATE
 /ri67ibe~ha
Output
 c
IntegerAbsolute 	il 	WS[item, ...] -> WS[results, ...]
* results = |to_integer(item)|	
 ~GATE
 /ri-44ile~ha
Output
 44
LevelGetFloorName 	ln 	WS[floor_location, ...] -> WS[name, ...]
* to_integer(floor_loaction)	
LevelGetFloorLevel 	ll 	WS[floor_name, ...] -> WS[f_location, ...]
* to_string(floor_name)
* If floor can't be found the f_location will be None.	
LevelSetFloorName 	ls 	WS[floor_name, floor_location, ...] -> WS[...]
* to_string(floor_name) must fit <NAME>.
* to_integer(floor_loaction)	
NOP 	. 	WS[...] -> WS[...]
* No operation.
* Any time Backrooms cant find a rule Backrooms falls back to NOP.	
Keep 	k 	WS[item, ...] -> WS[item, ...], R<DIGIT>: item
* Copy's the top item on the stack into the specific register.	
 ~GATE
 /ri4k3ps3e~ha
Output
 4
Pop 	p 	WS[item, ...] -> WS[...]
* Pops the top item on top of the stack.	
PopFrame 	a 	WS[..., ...] -> WS[...]
* Pops items from the stack till a StackFrame or StackBottom is popped.	
 ~GATE
 /ri4rfrs"cats"ri1ri-9ae~ha
Output
 4
Read 	r 	WS[...] -> WS[item, ...]
* "ri" will try to read in an integer. If an invalid integer is found nothing will be placed onto the stack.
* "rs" will try to read in an String. If the String is never close then Backrooms will never stop running the rule.
* "rn" will load None onto the stack.
* "rf" will load StackFrame onto the stack.	
 ~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[...]
* Will set the current consciences vector to <1, 0, 0>
* If the Signature is repeated Immediately. The rule when enter fast mode.
* If the rule is in fast mode it will keep take steps till it hits another shifter.
* If the rule is in fast mode and sees "!" it will skip the next shift.
* If the rule is in fast mode "!" can stack.
* Shifter will only shift if the branch condition is meet.
* Shifters will always set the branch condition to Clear after checking it.	
 ~GATE
 /V
 />......V
 / >......~ha
 ~GATE
 /ri0.N.V.Z.V
 / >~ha
 ~GATE
 /....>>...!.!..V....^...V
 / >~ha
ShifterLeft 	< 	WS[...] -> WS[...]
* Will set the current consciences vector to <-1, 0, 0>
* If the Signature is repeated Immediately. The rule when enter fast mode.
* If the rule is in fast mode it will keep take steps till it hits another shifter.
* If the rule is in fast mode and sees "!" it will skip the next shift.
* If the rule is in fast mode "!" can stack.
* Shifter will only shift if the branch condition is meet.
* Shifters will always set the branch condition to Clear after checking it.	
ShifterUp 	^ 	WS[...] -> WS[...]
* Will set the current consciences vector to <0, 1, 0>
* If the Signature is repeated Immediately. The rule when enter fast mode.
* If the rule is in fast mode it will keep take steps till it hits another shifter.
* If the rule is in fast mode and sees "!" it will skip the next shift.
* If the rule is in fast mode "!" can stack.
* Shifter will only shift if the branch condition is meet.
* Shifters will always set the branch condition to Clear after checking it.	
ShifterDown 	v 	WS[...] -> WS[...]
* Will set the current consciences vector to <0, -1, 0>
* If the Signature is repeated Immediately. The rule when enter fast mode.
* If the rule is in fast mode it will keep take steps till it hits another shifter.
* If the rule is in fast mode and sees "!" it will skip the next shift.
* If the rule is in fast mode "!" can stack.
* Shifter will only shift if the branch condition is meet.
* Shifters will always set the branch condition to Clear after checking it.	
ShifterDownUpper 	V 	WS[...] -> WS[...]
* Will set the current consciences vector to <0, -1, 0>
* If the Signature is repeated Immediately. The rule when enter fast mode.
* If the rule is in fast mode it will keep take steps till it hits another shifter.
* If the rule is in fast mode and sees "!" it will skip the next shift.
* If the rule is in fast mode "!" can stack.
* Shifter will only shift if the branch condition is meet.
* Shifters will always set the branch condition to Clear after checking it.	
ShifterUpper 	{ 	WS[...] -> WS[...]
* Will set the current consciences vector to <0, 0, 1>
* If the Signature is repeated Immediately. The rule when enter fast mode.
* If the rule is in fast mode it will keep take steps till it hits another shifter.
* If the rule is in fast mode and sees "!" it will skip the next shift.
* If the rule is in fast mode "!" can stack.
* Shifter will only shift if the branch condition is meet.
* Shifters will always set the branch condition to Clear after checking it.	
ShifterLower 	} 	WS[...] -> WS[...]
* Will set the current consciences vector to <0, 0, -1>
* If the Signature is repeated Immediately. The rule when enter fast mode.
* If the rule is in fast mode it will keep take steps till it hits another shifter.
* If the rule is in fast mode and sees "!" it will skip the next shift.
* If the rule is in fast mode "!" can stack.
* Shifter will only shift if the branch condition is meet.
* Shifters will always set the branch condition to Clear after checking it.	
Store 	s 	R<DIGIT>: item, WS[...] -> WS[item, ...], R<DIGIT>: item
* Copy's the item in specific register and put it on the Working Stack.	
StringLength 	bl 	WS[item, ...] -> WS[results, ...]
* results = len(to_string(item))	
 ~GATE
 /rs"cats"ble~ha
Output
 4
StringCast 	bc 	WS[item, ...] -> WS[results, ...]
* results = to_string(item)	
 ~GATE
 /rnbce~ha
Output
 None
StringAt 	ba 	WS[at, item, ...] -> WS[results, ...]
* results = to_string(item)[to_integer(at)]
* If at is out of index results will be None.
* at can be negative and read the string backwards.	
 ~GATE
 /rs"cats"ri1bae~ha
Output
 a
StringByte 	bb 	WS[item, ...] -> WS[results, ...]
* to_string(item)
* Gets the Extended ASCII Integer for the first characters from the String.
* If the String is empty then results will be None.	
 ~GATE
 /rs"c"bbe~ha
Output
 67
StringSplit 	bs 	WS[at, item, ...] -> WS[front, back, ...]
* to_integer(at) to_string(item)
* If at is out of index the front or back will just be empty.
* at can be negative and split the string backwards.	
 ~GATE
 /rs"12345"ri2bseprs" "epe~ha
Output
 12 345
StringJoin 	bj 	WS[back, front, ...] -> WS[results, ...]
* results = to_string(front) + to_string(back)	
 ~GATE
 /rs"cats"rs" 0w0"bje~ha
Output
 cats 0w0
StringEqual 	be 	WS[item2, item, ...] -> WS[results, ...]
* to_string(item) == to_string(item2)
* results is 1 if Strings are equal.
* results is 0 if Strings are not equal.	
 ~GATE
 /rs"cats"rs"cats"bee~ha
Output
 1
StringEqual 	bi 	WS[item2, item, ...] -> WS[results, ...]
* to_string(item) in to_string(item2)
* results is 1 if item is in item2.
* results is 0 if item is not in item2.	
 ~GATE
 /rs"cats"rs"%^*&cats$"bie~ha
Output
 1
StringUpper 	bu 	WS[item, ...] -> WS[results, ...]
* to_string(item).upper()
* Will put the String into upper form.	
StringLower 	bo 	WS[item, ...] -> WS[results, ...]
* to_string(item).lower()
* Will put the String into lower form.	
StringReverse 	br 	WS[item, ...] -> WS[results, ...]
* to_string(item).reverse()
* Will reverse the string.	
Switch 	z 	WS[item2, item, ...] -> WS[item, item2, ...]
* Will switch the top two items on the Working Stack.	
ThreadThread 	tt 	WS[...] -> WS[...]
* Will make a new conscious and copy registers, Working Stack, location and vector.
* The new conscious will get a ID that it not in use.	
 ~GATE
 /ttrs"cats"e.~ha
Output
 catscats
ThreadJoin 	tj 	WS[...] -> WS[...]
* Will terminate the conscious but not the program.
* The main conscious thread 0 wont terminate if it encounters this rule.
* If the conscious holds the ThreadLock it will be release.	
 ~GATE
 /ttrs"cats"etje.~ha
Output
 catscatscats
ThreadID 	ti 	WS[...] -> WS[ID, ...]
* Will put the conscious ID on to the Working Stack.	
ThreadLock 	tl 	WS[...] -> WS[...]
* Will claim the ThreadLock if available if not the conscious will wait.
* A conscious can claim the ThreadLock multiple times which will stack.	
 ~GATE
 /tttlrs"cats"eprs"0w0"etutj~ha
Output
 cats0w0cats0w0
ThreadUnLock 	tu 	WS[...] -> WS[...]
* Will unlock a single thread lock if conscious has the lock.	
UncommonReadFlip 	ur 	WS[...] -> WS[item, ...]
* Works just like the rule Read but after the read the rule will go back to the start and inverse the conscious vector.
* "uri" will try to read in an integer. If an invalid integer is found nothing will be placed onto the stack.
* "urs" will try to read in an String. If the String is never close then Backrooms will never stop running the rule.
* "urn" will load None onto the stack.
* "urf" will load StackFrame onto the stack.	
 ~GATE
 /1Vuri44
 / >e~ha
Output
 44
UncommonWriteFlip 	uw 	WS[item, ...] -> WS[...]
* Works just like the rule Write but after the write the rule will go back to the start and inverse the conscious vector.	
 ~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[...]
* to_string(item)
* Will write the data into the room cells after the rule.	
 ~GATE
 /rs"rs+cats+e"uh.............~ha
Memory
 rs"rs+cats+e"uhrs+cats+e....~ha
UncommonSimpleDump 	us 	WS[floor, y, x, item ,...] -> WS[...]
* to_floor(floor) to_integer(x) to_string(item)
* Will to_hallway(y) if y is not an Integer.
* Will write the data starting out the location <x, y, floor> given. The write vector is the current conscious vector.	
UncommonDynamicDump 	ud 	WS[v_floor, v_y, v_x, floor, y, x, item, ...] -> WS[...]
* to_integer(v_floor) to_integer(v_y) to_integer(v_x) to_floor(floor) to_integer(x) to_string(item)
* Will to_hallway(y) if y is not an Integer.
* Will write the data starting out the location <x, y, floor> given using the given vector <x_v, y_v, floor_v>.	
UncommonDoubleDuplicate	uo 	WS[item2, item, ...] -> WS[item2, item, item2, item, ...]
* Will duplicate the first two items on top of the Working Stack.	
Write 	w 	WS[item, ...] -> WS[...]
* Will write the item into rooms and the next rule will be after the last write.
* If item is StackBottom item will become None.	
 ~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> 	
* will write the row characters to memory
* X axis will shift by 1 after every row character is written to memory
* will shift the Y axis by -1 when all writes are done
* X axis will reset to previous value when all writes are done
<COMMENT> ::= "#" { <COMMENT_CHARACTER> } <NEWLINE> 	
* will just throw away the line
<HALLWAY> ::= "~" [ <NAME> | "@" ] <NEWLINE> 	
* will make and set a hallway with the current location
<FLOOR> ::= "+" [ <NAME> | "@" ] <NEWLINE> 	
* will set the name of a floor of the next floor
* will shift Floor axis by -1
<INCLUDE> ::= "%" <NAME> <NEWLINE> 	
* will include another script if not all ready included
<MUST_INCLUDE> ::= "!" <NAME> <NEWLINE> 	
* will include another script if not all ready included
* will raise an error if script is all ready included
<PARALLEL> ::= "=" [<NAME> | "@"] [<NAME> | "@"] [<NUMBER> | "@"] [<NUMBER> | "@"] <NEWLINE> 	
* will copy a floor onto another floor
* arg 1: The name of the floor that will be copied
* arg 2: The name assigned to the floor you copy to
* arg 3: The location of the floor that will be copied
* arg 4: The location which the floor will be copied onto
* If arg 1 and arg 3 are both None then arg1 will default to current Floor
* If arg 4 is None then default to current Floor - 1 and shift Floor by an additional -1 once all of the script has been read
* Can't provide both arg 1 and arg3 at the same time
<X> ::= "X" <NUMBER> <NEWLINE> 	
* will set the current X location
<XS> ::= "XS" <NUMBER> <NEWLINE> 	
* will shift the current X location
<Y> ::= "Y" <NUMBER> <NEWLINE> 	
* will set the current Y location
<YS> ::= "YS" <NUMBER> <NEWLINE> 	
* will shift the current Y location
<F> ::= "F" <NUMBER> <NEWLINE> 	
* will set the current Floor location
<FS> ::= "FS" <NUMBER> <NEWLINE> 	
* will shift the current Floor location
<Translator> ::= {<ROW> | <COMMENT> | <HALLWAY> | <FLOOR> | <INCLUDE> | <MUST_INCLUDE> | <PARALLEL> | <X> | <XS> | <Y> | <YS> | <F> | <FS>}	
* root definition for translator
== 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.	
* SIZE: WS[...] -> WS[size, ...]
* APPEND: WS[item, ...] -> WS[...]
* POP: WS[...] -> WS[item, ...]
* PEAK: WS[...] -> WS[item, ...]
* READ: WS[spot, ...] -> WS[item, ...]
* WRITE: WS[spot, item, ...] -> WS[item, ...]
* REMOVE: WS[spot, ...] -> WS[...]
* INSERT: WS[spot, item, ...] -> WS[...]
* FIND_INSERT: WS[item, ...] -> WS[...]
heap 	Allows a program to allocate blocks of memory to store data. 	
* AT: WS[AT, ID, ...] -> WS[ID, ...]
* NEW: WS[...] -> WS[ID, ...]
* NEW_A: WS[SIZE, ...] -> WS[ID, ...]
* READ: WS[ID, ...] -> WS[item, ...]
* READ_A: WS[AT, ID, ...] -> WS[item, ...]
* WRITE: WS[ID, item, ...] -> WS[...]
* WRITE_A: WS[AT, ID, item, ...] -> WS[...]
* FREE: WS[ID, ...] -> WS[...]
heap_load	Used to include "heap". 	
utils 	Tools used to build other scripts. 	
* WSIZE: WS[item, ...] -> WS[string, ...]
* EMPTY_BLOCK: WS[block_size, ...] -> WS[empty_block_size, ...]
* TYPE_READ: WS[item, ...] -> WS[string, ...]
* KEEP: WS[y, f, item, ...] -> WS[...]
* STORE: WS[y, f, ...] -> WS[item, ...]
* CLEAR: WS[y, f, ...] -> WS[...]
* REMOVE: WS[y, f, ...] -> WS[...]
* NEW: WS[y, f, name, ...] -> WS[...]
vars 	Allows a program to get, set and delete a variable. 	
* GET: WS[name, ...] -> WS[item, ...]
* SET: WS[name item, ...] -> WS[...]
* DEL: WS[name, ...] -> WS[...]
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
"1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9")
<CHARACTER> ::= All extended ASCII characters excluding \x10.
<COMMENT_CHARACTER> ::= All extended ASCII characters.
"-"] <DIGIT> {<DIGIT>}
<LETTER> ::= a-z and A-Z
<DIGIT> | "_") { <LETTERS> | <DIGIT> | "_" }
<DIGIT> | "," | "<" | "." | "> " | "/" | "?" | ";" | ":" | "'" | "\"" | "[" | "{" | "]" | "}" | "\\" | "|" | "`" | "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-" | "_" | "=" | "+" | " ")
<DIGIT> | "," | "<" | "." | "> " | "/" | "?" | ";" | ":" | "'" | "\"" | "[" | "{" | "]" | "}" | "\\" | "|" | "`" | "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-" | "_" | "=" | "+" | " " | "~")
<NEWLINE> ::= "\n"
"\r" | "\v" |"\f" | " "}
Category:Implemented
Category:Languages
Category:Turing complete
Category:Cell-based
Category:Self-modifying
Category:Low-level
Category:2021