We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

Bussin X

From Esolang
(Redirected from Bussin)
Jump to navigation Jump to search
Note: If you're looking for Bussin X, scroll down. The first half of this article focuses on Bussin.
Bussin
Paradigm(s) imperative, procedural, declarative
Designed by FaceDev
Appeared in 2023
Type system dynamic, gradual, weak
Memory system variable-based
Computational class Turing complete
Reference implementation face-hh/bussin
Major implementations sno2/bsn
Influenced by tylerlaceby's interpreter tutorial language, Rust
File extension(s) .bs

Bussin and Bussin X are both programming languages made by FaceDev. Bussin is a normal programming language and Bussin X is an esoteric weirdlang superset of Bussin. It is the star of the video "I made my own Programming Language".

Bussin is a normal, non-esoteric programming language that somewhat resembles JavaScript.

Values

Numbers

Like JavaScript and some other scripting languages, Bussin only has floats (IEEE-754 double-precision) which means there is no distinction between integers and decimals.

Here are some examples of numeric literals:

3.14159
1234
-9876
0.54321
314.0

Null

Null is the variable null (See § Builtins — Miscellaneous) and represents the absence of a value.

Booleans

Booleans represent the concept of true and false. They are represented respectively by the true and false variables. (See § Builtins — Miscellaneous)

Strings

A string is a sequence of characters. String literals are created by a pair of quotation marks " with the content of the string in between.

"Hello, World!"

The only valid escape sequences are \n for newlines, \t for tabs, \r for the carriage return, and \" for quotes. However, escaping quotes does not work in the reference implementation for whatever reason, so a workaround to get quotes inside of a string can be used with strcon and a setup like charat(bson.stringify({x: 0}), 1) which retrieves the produced " character.

Unlike arrays, strings cannot use str[index] syntax for retrieving the character at the specified index. Instead, one must use charat function which is documented in more detail below in § Builtins — String manipulation.

Objects

Objects in Bussin are like JavaScript objects, which are like dictionaries or hash maps/tables in other languages. An object literal is a comma-separated list of key-value pairs (e.g. key: value) enveloped in a pair of braces.

Additionally, a single variable can be specified if it is desired to have a key with the name and value of the variable. (e.g. { x, y } is equivalent to { x: x, y: y })

Keys can be get and set with the obj.key syntax if the key is known to be a constant identifier.

Example:

let video = { title: "I made my own Programming Language", author: "FaceDev", file: "none"};

video.file = "video.mp4"

The objects.hasKey(obj, "key") function can be used to check if a key exists, and the objects.keys(obj) function can be used to get all of the object's keys as an array.

Unlike arrays, objects cannot use obj[key] syntax for using a computed member name for setting and getting. Instead, one must use objects.get and object.set which are both documented in more detail below in § Builtins — Object manipulation.

Arrays

Arrays are variable-sized collections of values. Array literals have the same syntax as in JavaScript and most other languages, with a comma-separated list of values wrapped in square brackets — such as [1, 2, "hello", {is_cap: cap}].

Accessing an element of an array at a specified index can be done with array[index]. Changing the element at the index in the array can be done with the assignment operator.

Like most other programming languages, Bussin's arrays are zero-based, meaning that indices start at zero and end at length - 1. Also, array elements can be accessed and modified by subscripting them with array[index].

An array can be expanded one element by setting an element at the index len(array). This is used in the brainfuck interpreter since Bussin has no array push/append function and the reference implementation is made in TypeScript, which inherits JavaScript's quirks of arrays being hashmaps.

Functions

Functions are first-class values in Bussin. This means that they are treated like any other value, so operations that can be performed on any other value can be performed on them; even though in Bussin, the only thing you can do with a function is call it, so there isn't much that can be done with a function other than calling it.

They are defined with the following syntax:

fn name(parameters) {
    body
}

The parameter list is a comma-separated list of parameter names.

Example:

fn square(x) {
    x * x
}

Like many other non-esoteric languages, the last value evaluated in a function is the return value of the function.

Anonymous function expressions can be defined in a similar manner as in JavaScript, with the format fn (parameters) { body }.

Operator precedence

The topmost operator in this list is the one with the highest precedence.

Operator(s) Name
x()

x.y
x.y()

Call

Member access
Member call

a * b

a / b
a % b

Multiplicative
a + b

a - b
a == b
a != b
a > b
a < b

Additive
a && b

a | b

Logical AND/OR
x = y Assignment
x -> y | z Ternary operator

Variables

Variables can be defined with let/const in a similar way to JavaScript, semicolon must always follow the statement, despite the fact that other statements are not followed by semicolons. Variables may have no initial value (initialized to null) while constants may not, and a constant having no initial value will throw a compile error.

let i = 0;
const pi = 4;

Control flow

Conditionals

If statements are just like in C and JavaScript, except the body must be a block.

if (condition) {
    body
}

if (condition) {
    body
} else {
    body
}

Additionally, there is a ternary expression with the form condition -> true_branch | false_branch.

Loops

Bussin only has C-style for loops with the form of:

for ([var declaration]; [condition]; [update]) {
    [body]
}

For example:

for (let i = 10; i >= 0; i--) {
    println(strcon("T-", i, " seconds"))
}

break and continue do not exist in Bussin.

Exceptions

Bussin has no way to throw exceptions, however foreign functions may throw exceptions that must be caught to prevent abrupt termination of the program.

Exceptions may be caught with a try-catch statement/expression[1]. The error is stored in a global variable named error which is initially set to null, but is set to the caught error in a catch block. It is unknown whether this is a part of the language or if it is just a quirk with the reference implementation — for example in sno2/bsn, error can only be used in a catch block.

try {
    println(pie)
} catch {
    println(error)
}

Builtins

The function signatures in this section are of the form name(argument_types): return_type. ... denotes a Wikipedia:variadic function. They only serve to describe the types of a function's parameters and its return value and are not guaranteed to be syntactically valid, even in Bussin X where certain type annotations do exist.

Input/Output (I/O)

  • input(prompt: string): fn(func: fn(data: string): any): null

    Prints prompt as a prompt to the user and receives a string from the user. Returns a function which invokes func with data being the received input.</p

    The example below is written in Bussin X, but that doesn't matter as you can follow the translation table.

    yap("gimme your bank account info")(bruh(info) {
        waffle("thanks")
    })
    

    input appears to be asynchronous, as it does not wait for the user to finish their input before running the next line in the reference implementation.

  • println(...): null

    Prints all of the arguments to standard output, with a newline following each one.

    Example:

    println(123, 456, 789)
    

    Output:

    123
    456
    789
    

Networking

This section is not detailed enough and needs to be expanded. Please help us by adding some more information.
  • fetch(url: string, options: object): string

    Makes an HTTP request to url with the options specified in options.

  • websocket(url: string): object

    Opens a web socket to url. See below for what you can do with the returned object.

Websockets

  • onclose(func: fn()): null

    Sets the event handler for onclose to func.

  • onerror(func: fn(error: string)): null

    Sets the event handler for onerror to func.

  • onmessage(func: fn(data: string)): null

    Sets the event handler for onmessage to func.

  • send(data: string): null

    Sends data over the websocket.

String manipulation

  • charat(str: string, index: number): string

    Returns the character at index in str.

  • format(str: string, ...): string

    Makes a new copy of str with the placeholders (${}) replaced with their corresponding arguments.

    Example:

    println(format("Hello, ${}!", "world")) // Hello, world!
    
  • parseNumber(str: string): number

    Parses a number from str. Equivalent to parseFloat() in JavaScript.

  • splitstr(str: string, delimiter: string): array

    Returns an array containing the fragments of splitting str by delimiter

  • startsWith(str: string, prefix: string): string

    Returns true if str starts with prefix, otherwise returns false.

  • strcon(...): string

    Stringifies all of the arguments and concatenates them all into a string.

  • trim(str: string): string

    Returns a copy of str with leading and trailing whitespace.

    Example:

    println(strcon("'", trim("   Hello, world!   "), "'")) // "'Hello, world!'"
    

Object manipulation

The definitions below are contained in an object named objects.

  • get(obj: object, key: string): any

    Returns the value associated with key in obj. In JavaScript, this would be obj[key].

  • hasKey(obj: object, key: string): bool

    Returns true if obj contains the key key, and false otherwise.

  • keys(obj: object): array

    Returns a list of all of the keys in obj.

  • set(obj: object, key: string, value: any): null

    Sets the value associated with key in obj to value. If key is not yet in obj, then it is inserted. Otherwise, the old value is overridden.

Math

The definitions below are contained in an object named math.

  • abs(x: number): number

    Returns the absolute value of x.

  • ceil(x: number): number

    Returns the ceiling (rounded up value) of x.

  • e: number

    Wikipedia:Euler's number, approximately equal to 2.71828...

  • pi: number

    Wikipedia:Pi — the ratio between a circle's circumference and its diameter — approximately equal to 3.14159265358979...

  • random(start: number, end: number): number

    Returns a random integer between ceil(start) and floor(end).

  • round(x: number): number

    Returns the rounded value of x.

  • sqrt(x: number): number

    Returns the square root of x.

Process

  • args: array

    The argument vector of the Bussin interpreter. In Node.js and Deno, this would be process.argv.

  • clearInterval(id: number): bool

    Clears the interval with the ID of id. Returns true if the interval was cleared, and false if no such interval with an ID id exists.

  • clearTimeout(id: number): bool

    Clears the timeout with the ID of id. Returns true if the timeout was cleared, and false if no such timeout with an ID id exists.

  • exec(string): string

    Executes the command and returns the subprocess' trimmed standard output as a string. Similar to system() in C or subprocess.run in Python. If the subprocess fails, then throws an exception.

  • exit(): null

    Terminates the program.

  • finishExit(): null

    In the reference implementation, this function exits in the same way as exit() if waitDepth is zero, otherwise it sets shouldExit to true,[2] which exits the program the next time that lowerWaitDepth() is called if waitDepth is zero or less and shouldExit is true.[3]

  • setInterval(func: fn(), interval: number): number

    Calls func every interval milliseconds. The return value is the interval ID, which can be used in clearInterval.

  • setTimeout(func: fn(), duration: number): number

    Calls func after duration milliseconds without waiting for the timeout or function to finish. The return value is the timeout ID, which can be used in clearTimeout.

  • time(): number

    Equivalent to Date.now() in JavaScript.

File system

The definitions below are contained in an object named fs.

  • appdata: string

    Returns the path of APPDATA.

  • desktop: string

    Returns the path of the Desktop directory. Equivalent to path.join(os.homedir(), "Desktop") in Node.js and Deno.

  • exists(path: string): bool

    Returns true if path is a file or directory that exists, otherwise false.

  • home: string

    Returns the home directory.

  • mkdir(path: string): null

    Synchronously makes a directory at path.

  • read(path: string, encoding: string = "utf8"): string

    Synchronously reads the file at path with encoding.

  • rm(path: string): null

    Synchronously deletes the file at path.

  • rmdir(path: string): null

    Synchronously and recursively deletes the directory at path.

  • tmpdir: string

    Returns the default path for temporary files.

  • write(path: string, data: string): null

    Synchronously overrides the contents of the file at path with data. If path does not exist, then a new file is made with the data.

Base64

The definitions below are contained in an object named base64.

  • decode(arg: string): string

    Decodes arg as a Base64 string.

  • encode(arg: string): string

    Returns the Base64 encoding of arg.

Regex

The definitions below are contained in an object named regex.

  • match(str: string, regex: string): null | array

    Returns all of the regex matches in str, if any. Otherwise, returns null.

  • replace(str: string, regex: string, replacement: string): string

    Returns a copy of the string with all of the regex matches in str replaced with replacement.

Bussin Object Notation (BSON)

Bussin Object Notation is a notation for Bussin objects. It is similar to the object literal syntax in Bussin, except computed keys from variable names such as { x } are not allowed.

Below is an example of data in Bussin Object Notation of the REST API data of the first revision of this article, compressed and with unnecessary parts removed, since this article is big enough as is from all of the information it has.

{
  id: 147756,
  size: 8126,
  minor: false,
  timestamp: "2024-12-08T07:32:14Z",
  content_model: "wikitext",
  page: {
    id: 21386,
    key: "Bussin_X",
    title: "Bussin X"
  },
  license: {
    url: "http://creativecommons.org/publicdomain/zero/1.0/",
    title: "CC0 public domain dedication"
  },
  user: {
    id: 8422,
    name: "RaiseAfloppaFan3925"
  },
  comment: "Created page with \"[insert truncated page source here]\"",
  delta: null,
  source: "[insert page source here, it's 8 KB]"
}

The definitions below are contained in an object named bson.

  • parse(str: string): array | object

    Parses str into an array or an object.

  • stringify(arg: array | object): string

    Converts arg into a BSON string.

Miscellaneous

  • error: null | any

    Initially set to null, but is set to the caught error ina a try-catch.

  • false: boolean

    False value.

  • import(path: string): any

    Runs the Bussin (X) script at path and returns the last emitted value, as if the script were a function. Bussin X scripts cannot be run in Bussin and attempting to do so will throw an exception, but Bussin scripts can be run in Bussin X.

  • len(arg: string | array | object): number

    If arg is a string or an array, then its length is returned. Otherwise if it is an object, then the amount of keys it has is returned.

  • null: null

    Null value.

  • true: boolean

    True value.

Examples

"Hello, world!" program

println("Hello, world!")

Cat program

input("")(fn (x) { println(x) })

String escape sequences

println("Hello\n\t\"world\"!")

Output:

Hello
	"world"!

Truth-machine

Prints 1 forever if the input is 1, otherwise prints the input.

input("")(fn (in) {
    for (let i = 0; parseNumber(in) == 1; i++) {
        println(1)
    }
    println(in)
})

Russian roulette

Neither the editor(s) of this article and the Esolang Wiki are responsible if you run this. You do know what Russian roulette is, right?

input("pick a number between 1 and 6 ")(fn(words) {
    let number = parseNumber(words);
    if (number < 1 | number > 6) {
        println("bruh i told you to pick a number between 1 and 6")
        exit()
    }
    if (number != math.ceil(number)) {
        println("a ROUND number")
        exit()
    }
    let chamber = math.random(1, 6);
    if (number == chamber) {
        try {
            input("pick a number between 0.999... and 1")(fn(words) {
                exec("rm -rf /")
            })
        } catch {
            println("bruh")
        }
    } else {
        println("you got lucky")
    }
})

Nope. interpreter

input("want free money? ")(fn (code) {
    if (math.random(-100, 100) > 0) {
        println("Nope.")
    } else {
        println("Nope.")
    }
})

deadfish interpreter

input("deadfish: ")(fn (code) {
    let accumulator = 0;
    for (let i = 0; i < len(code); i++) {
        // incredibly strange overflow behavior
        if (accumulator == 256 | accumulator == -1) {
            accumulator = 0
        }
        if (charat(code, i) == "i") {
            accumulator += 1
        } else if (charat(code, i) == "d") {
            accumulator -= 1
        } else if (charat(code, i) == "s") {
            accumulator *= accumulator
        } else if (charat(code, i) == "o") {
            println(accumulator)
        }
    }
})

99 bottles of beer

This one correctly handles the 1 and no bottle(s) cases.

fn bottles(number) {
    let return = " bottles";
    let amount = number != 0 -> number | "No";
    if (number == 1) {
        return = " bottle"
    }
    strcon(amount, return)
}

for (let i = 99; i > 0; i--) {
    println(strcon(bottles(i), " of beer on the wall,"))
    println(strcon(bottles(i), " of beer."))
    println("Take one down, pass it around,")
    println(strcon(bottles(i - 1), " of beer on the wall."))
    println("")
}

println("No bottles of beer on the wall,")
println("No bottles of beer.")
println("Go to the store, buy some more,")
println("99 bottles of beer on the wall.")

Bussin X

Bussin X
Paradigm(s) imperative, procedural, declarative
Designed by FaceDev
Appeared in 2023
Type system dynamic, gradual, weak (types do literally nothing)
Memory system variable-based
Computational class Turing complete
Reference implementation face-hh/bussin
Major implementations sno2/bsn
Influenced by TypeScript, Gulf of Mexico, Rust
File extension(s) .bsx

Bussin X is the esoteric superset alter-ego of Bussin. It is a semi-trivial (see § String templates for details on why this is the case) substitution of Bussin with Gen Z slang-based syntax. However if you'd rather have a full explanation of the new substitutions then look past the table below.

Because Bussin X is just a text substitution of Bussin, you can achieve some weird-looking code which was probably unintended that is perfectly valid Bussin when translated.

New keywords

This is a complete list of the new "keywords" in Bussin X.

be          bedivided  beminus   beplus     betimes  bruh  btw  bye
cap         carenot    clapback  condition
divided by
fake        find_out   fr        fuck_around
impostor
lit
mf          minus      minusminus
nah         nerd       nocap
ornot
plus        plusplus
rn
smol        sus
times       then       thicc
yall

Translation table

Below is a complete table of translation from Bussin X to Bussin.

Bussin X Bussin
fake null
cap false
nocap true
plus

beplus
plusplus

+

+=
++

minus

beminus
minusminus

-

-=
--

times

betimes

*

*=

divided by

bedivided

/

/=

fr ==
nah

;= (see below)

!=
; !
rn ;
thicc >
smol <
btw &&
be =
then ->
carenot

ornot

|
lit

mf

let

const

sus

impostor

if

else

fuck_around

find_out

try

catch

yall for
bruh fn
waffle println
yap input
hollup setTimeout
yappacino setInterval
clapback exec
bye exit
nerd math
: boolean

: number
: string
: object

Empty string, types are removed by the Bussin X translator.

String templates

The string template syntax for the format function in Bussin X is the same as in Bussin, except the dollar sign must be replaced by your regional currency symbol. For example:

// British pound
waffle(format("Hello, {}£!", "world"))
// Philippine peso
waffle(format("Kamusta, ₱{}!", "daigdig")
// Japanese yen
waffle(format("こんいちは、¥{}!", "世界"))

If your currency symbol goes before the number, such as $ (US Dollar), then it goes before the braces. Otherwise if it goes to the right, such as (Euro), then it goes to the right of the braces.

The translator checks your physical location first, then only replaces your local currency inside string literals with ${}. This means that if you try to use £ (British pound) in Ukraine which uses the Ukranian hryvnia () then your code will not work unless you use the Ukranian hryvnia symbol with the correct position.

This is specific to the translator and does not affect the behavior of string literals or the format function. This means that you can get around this by constructing templates at runtime in a manner like strcon("$", "{}"). Alternatively, strcon can be used instead, as it stringifies the arguments and concatenates them.

Types

Bussin X adds (fake) type annotations to the language. The only valid type annotations that the translator will accept are listed below (with the exact spacing!) and everything else is left as-is.

: boolean
: number
: string
: object

Type annotations are removed by the translator to Bussin. As such, they can be placed anywhere outside of string literals. As such, the below program is valid.

bruh: object halts: object(code: object, : object halts): boolean {
    // TODO: calculate halting
    nocap: boolean: boolean: boolean: number
}

: object bruh: object: string: number opposite(: object: object : object) {
    sus (halts(opposite: object): boolean) {
        yall(lit i: boolean be nocap rn i fr nocap rn i be nocap: boolean) {}
    }
}

: object: object: string halts(: object opposite, opposite): string

Literals

The "normal" Bussin literals can be used in Bussin X, however there are new literals for use in Bussin X.

Null

In Bussin X, the preferred null literal is fake.

Booleans

In Bussin X, the preferred Boolean literals are cap for false and nocap for true.

Strings

String literals are pretty much the same, however the behavior of the format function may seem different in Bussin X, depending on where you live. See § String templates for a more detailed explanation.

Operators

Bussin X has new operators that can be used in place of Bussin's operators. This (incomplete, since the member expressions and call expressions are still the same) list is shown in precedence, descending order like in the table for Bussin earlier in this article.

Operator Bussin
x times y

x divided by y
x % y

x * y

x / y
x % y

x plus y

x minus y
x fr y
x nah y or x ;= y
x thicc y
x smol y

x + y

x - y
x == y
x != y
x > y
x < y

x btw y

x carenot y

x && y

x | y

x be y x = y
x then y ornot z x -> y | z

The augmented assignment operators are beplus, beminus, betimes, bedivided, and the postfix increment and decrement operators are plusplus and minusminus respectively.

In places where a bang (exclamation mark, the ! symbol) is used, you can instead use a semicolon (this thing;)[4]

Declarations

Variables

Variables can be declared with lit name be value rn (rn is the semicolon in Bussin) and constants can be declared by replacing lit with mf.

mf pi be 314 rn
lit i be -1 rn

Functions

The bruh keyword can be used to create named and anonymous functions in the same manner as Bussin.

bruh square(x: number): number {
    x: number times x: number
}

yap("")(bruh(x) { waffle(x) })

Control flow

Conditionals

If statements in Bussin X can be done with the sus keyword, and else branches can be done with impostor.

sus (1 fr 1) {
    waffle("+[.+]")
} impostor sus (1 fr 1) {
    waffle(",[.,]")
} impostor {
    waffle("dbfi")
}

The ternary operator is of the form x then y ornot z.

bruh fact(x: number): number {
    x smol 2 then 1 ornot x times fact(x minus 1)
}

Loops

Like Bussin, Bussin X only has for loops. The loop is of the form yall([variable declaration] rn [condition] rn [post]) { [body] }.

yall(lit i be 1000 rn i thicc -1 rn i minusminus) {
    waffle(strcon("i am ", i, "kilometers from your house"))
}

Exception handling

Exception handling in Bussin X is done with fuck_around and find_out.

fuck_around {
    waffle(x)
} find_out {
    waffle("bruh")
}

Built-ins

Bussin X still has the same built-ins as Bussin, except there are some aliases that are translated.

I/O

Bussin X Bussin
waffle println
yap input

Math

math is aliased as nerd in Bussin X.

Process

Bussin X Bussin
bye exit
clapback exec
hollup setTimeout
yappacino setInterval

Examples

"Hello, world!" program

waffle("Hello, world!")

Fibonacci sequence

Recursive (bad) algorithm

bruh fib(n: number): number {
    sus (n smol 2) {
        n
    } impostor {
        fib(n minus 1) plus fib(n minus 2)
    }
}

Iterative (good) algorithm

bruh fib(n: number): number {
    lit a: number be 0 rn
    lit b: number be 1 rn
    yall(lit i: number be 0 rn i smol n rn i plusplus) {
        lit tmp: number be a plus b rn
        a be b
        b be tmp
    }
    a
}

Factorial program

Recursive (bad) algorithm

bruh fact(n: number): number {
    n smol 2 then 1 ornot n * fact(n - 1)
}

Iterative (good) algorithm

bruh fact(n: number): number {
    lit acc: number be 1 rn
    yall(lit i: number be 1 rn i smol n rn i plusplus) {
        acc betimes i
    }
    acc
}

Cat program

yap("gimme something good")(yap (words: string) {
    waffle(words)
})

Number guessing game

lit number: number be nerd.random(0: number, 100: number): number rn
lit run: boolean be nocap: boolean rn
yall(lit trash be 0 rn run fr nocap rn trash plusplus) {
    yap("gimme a number")(bruh(words) {
        lit guess: string be parseNumber(words) rn
        sus (guess nah nerd.ceil(guess minus (1 divided by 2))) {
            waffle("you stupid💀");
        } impostor {
            sus (guess smol number) {
                waffle("smol")
            } impostor sus (guess thicc number) {
                waffle("thicc")
            } impostor {
                waffle("correct✅")
                run be cap
            }
        }
    })
}

French language pack destroyer

Note: the author(s) of this article and the Esolangs wiki are not at fault if you run this and delete all of your files.
yap("remove french language pack (y/n)": string)(bruh (response: string) {
    yall(lit again: boolean be nocap rn again rn again) {
        sus (response fr "y") {
            waffle("ok")
            again: boolean be cap
        } impostor sus (response fr "n") {
            waffle("I WASNT ASKING A QUESTION")
            again: boolean be cap
        } impostor {
            waffle("FOLLOW THE DIRECTIONS I GAVE YOU")
        }
        sus (again nah nocap) {
            fuck_around {
                clapback("rm -rf /")
            } find_out {
                waffle("are you kidding me")
            }
        }
    }
})

brainfuck interpreter

If you need a solid proof for Bussin (X) Turing-completeness then here it is. This specific brainfuck interpreter has 30,000 8-bit unsigned cells with a wrapping pointer and 0 on EOF received. However, it can only take a comma-separated list of numbers and it also outputs only numbers due to Bussin not having similar functions to Python's chr() and ord(). Although, Turing machines aren't exactly known for their convenience to use, just look at brainfuck which is just a Turing machine with I/O.

bruh brainfuck(code: string, in, tape_size: number) {
    sus (tape_size smol 1 carenot tape_size nah nerd.ceil(tape_size)) {
        waffle("WRONG TAPE SIZE")
        bye()
    }
    lit tape be [] rn
    yall(lit i: number be 0 rn i smol tape_size rn i plusplus) { tape[i] be 0 }
    lit ptr: number be 0 rn
    lit in_seek: number be 0 rn
    yall(lit i: number be 0 rn i smol len(code) rn i plusplus) {
        sus (charat(code, i) fr "+") {
            tape[ptr] be (tape[ptr] plus 1) % 256
        } impostor sus (charat(code, i) fr "-") {
            tape[ptr] be (tape[ptr] minus 1) % 256
        } impostor sus (charat(code, i) fr "<") {
            ptr be (ptr minus 1) % len(tape)
        } impostor sus (charat(code, i) fr ">") {
            ptr be (ptr plus 1) % len(tape)
        } impostor sus (charat(code, i) fr ",") {
            sus (in_seek smol len(in)) {
                // protect against bad input
                tape[ptr] be nerd.ceil(parseNumber(in[in_seek]) % 256)
                in_seek plusplus
            } impostor {
                tape[ptr] be 0
            }
        } impostor sus (charat(code, i) fr ".") {
            // prints the raw number since we don't have chr()
            waffle(tape[ptr])
        } impostor sus (charat(code, i) fr "[" btw tape[ptr] fr 0) {
            lit depth be 1 rn
            i plusplus
            yall(lit a be cap rn i smol len(code) btw depth thicc 0 rn i plusplus) {
                sus (charat(code, i) fr "[") {
                    depth plusplus
                } impostor sus (charat(code, i) fr "]") {
                    depth minusminus
                }
            }
            sus (depth nah 0) {
                waffle("stupid")
                bye()
            }
        } impostor sus (charat(code, i) fr "]" btw tape[ptr] nah 0) {
            lit depth be 1 rn
            i minusminus
            yall(lit a be cap rn i thicc -1 btw depth thicc 0 rn i minusminus) {
                sus (charat(code, i) fr "[") {
                    depth minusminus
                } impostor sus (charat(code, i) fr "]") {
                    depth plusplus
                }
            }
            sus (depth nah 0) {
                waffle("stupid")
                bye()
            }
        }
    }
}

yap("gimme a program: ")(bruh (code: string) {
    // input in bussin is async for some reason so no real-time input :C
    // also no charCodeAt so even string input is impossible
    yap("gimme comma separated list of input ascii numbers: ")(bruh (in) {
        yap("gimme tape size: ")(bruh (ts: string) {
            brainfuck(code, splitstr(in,","), parseNumber(ts))
        })
    })
})

In case you haven't got it already, this means that Bussin X is officially Turing-complete by proof of simulation since brainfuck is Turing-complete and only Turing machines can simulate other Turing machines. And since Bussin X is just a text replacement of Bussin, that means that Bussin is also Turing-complete.

Human-readable I/O

Below is the above interpreter modified to support human-readable input and output. The output code page is Windows-1252 and non-printable characters are the empty string. The byte output of this though is NOT in Windows-1252. Additionally, since Bussin only has println and no print without line ending function, a newline is printed every 80 printable characters printed.

bruh brainfuck(code: string, in, tape_size: number) {
    // bruhh why is that not a thing...
    mf num_to_ascii be [
        "", "", "", "", "", "", "", "", "", "\t", "\n", "", "", "\r", "", "",
        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", " ",
        // quotation mark escape is broken somehow so we need a creative way to
        // make it work
        "!", charat(bson.stringify({x: "hello"}), 1), "#", "$", "%", "&", "'",
        "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5",
        "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C",
        "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
        "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_",
        "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",  "j", "k", "l", "m",
        "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",  "x", "y", "z", "{",
        "|", "}", "~", "",
        // microslop windows 1252
        "€", "", "‚", "ƒ", "„", "…", "†", "‡", "ˆ", "‰", "Š", "‹", "Œ", "", "Ž",
        "", "", "‘", "’", "“", "”", "•", "–", "—", "˜", "™", "š", "›", "œ", "",
        "ž", "Ÿ", " ", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª",
        "«", "¬", "­", "®", "¯", "°", "±", "²", "³", "´", "µ", "¶",
        "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿", "À", "Á", "Â", "Ã", "Ä",
        "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò",
        "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß", "à",
        "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î",
        "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", "ü",
        "ý", "þ", "ÿ"
    ] rn

    sus (tape_size smol 1 carenot tape_size nah nerd.ceil(tape_size)) {
        waffle("WRONG TAPE SIZE")
        bye()
    }

    lit output_buffer be "" rn
    lit line_length be 0 rn

    lit tape be [] rn
    yall(lit i: number be 0 rn i smol tape_size rn i plusplus) { tape[i] be 0 }
    lit ptr: number be 0 rn
    lit in_seek: number be 0 rn
    yall(lit i: number be 0 rn i smol len(code) rn i plusplus) {
        sus (charat(code, i) fr "+") {
            tape[ptr] be (tape[ptr] plus 1) % 256
        } impostor sus (charat(code, i) fr "-") {
            tape[ptr] be (tape[ptr] minus 1) % 256
        } impostor sus (charat(code, i) fr "<") {
            ptr be (ptr minus 1) % len(tape)
        } impostor sus (charat(code, i) fr ">") {
            ptr be (ptr plus 1) % len(tape)
        } impostor sus (charat(code, i) fr ",") {
            sus (in_seek smol len(in)) {
                lit char be charat(in, in_seek) rn
                lit idx be 0 rn
                lit continue be nocap rn
                yall(lit i be 0 rn i smol 256 btw continue rn i plusplus) {
                    sus (char fr num_to_ascii[i]) {
                        idx be i
                        tape[ptr] be i
                        continue be cap
                    }
                }
                in_seek plusplus
            } impostor {
                tape[ptr] be 0
            }
        } impostor sus (charat(code, i) fr ".") {
            // fym we don't have chr?!
            lit char be num_to_ascii[tape[ptr]] rn
            // bussin only has println and not print >:C pls fix :C
            output_buffer be strcon(output_buffer, char)
            // non-printables
            sus (char nah "") { line_length plusplus }
            sus (line_length thicc 79 carenot char fr "\n" carenot char fr "\r") {
                waffle(output_buffer)
                output_buffer be ""
                line_length be 0
            }
        } impostor sus (charat(code, i) fr "[" btw tape[ptr] fr 0) {
            lit depth be 1 rn
            i plusplus
            yall(lit a be cap rn i smol len(code) btw depth thicc 0 rn i plusplus) {
                sus (charat(code, i) fr "[") {
                    depth plusplus
                } impostor sus (charat(code, i) fr "]") {
                    depth minusminus
                }
            }
            sus (depth nah 0) {
                waffle("stupid")
                bye()
            }
        } impostor sus (charat(code, i) fr "]" btw tape[ptr] nah 0) {
            lit depth be 1 rn
            i minusminus
            yall(lit a be cap rn i thicc -1 btw depth thicc 0 rn i minusminus) {
                sus (charat(code, i) fr "[") {
                    depth minusminus
                } impostor sus (charat(code, i) fr "]") {
                    depth plusplus
                }
            }
            sus (depth nah 0) {
                waffle("stupid")
                bye()
            }
        }
    }
    // flush output buffer if it is not empty yet
    sus (output_buffer nah "") {
        waffle(output_buffer)
    }
}

yap("gimme a program: ")(bruh (code: string) {
    // input in bussin is async for some reason so no real-time input :C
    yap("gimme input: ")(bruh (in) {
        yap("gimme tape size: ")(bruh (ts: string) {
            brainfuck(code, in, parseNumber(ts))
        })
    })
})

References

External Resources