backrooms

From Esolang
Jump to navigation Jump to search

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 hr 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
<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" | " "}