Created
August 22, 2023 19:30
-
-
Save neverUsedGithub/fec36d8e6a67441141c1804ede415fba to your computer and use it in GitHub Desktop.
Type only brainfuck interpreter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type StringToArray<str extends string> = str extends `${infer First}${infer Rest}` | |
? [ First, ...StringToArray<Rest> ] | |
: [] | |
type NewArray<length extends number, arr extends any[] = []> = arr["length"] extends length | |
? arr | |
: NewArray<length, [ ...arr, any ]>; | |
type New2DArray<length extends number, arr extends any[][] = []> = arr["length"] extends length | |
? arr | |
: New2DArray<length, [ ...arr, [] ]>; | |
type ModifyCell<cells extends any[][], pos extends any[], addOne extends boolean> = addOne extends true | |
? { [K in keyof cells]: K extends `${pos["length"]}` ? cells[K]["length"] extends 255 ? [] : [ ...cells[K], any ] : cells[K] } | |
: { [K in keyof cells]: K extends `${pos["length"]}` ? cells[K] extends [ infer First, ...infer Rest ] ? Rest : NewArray<255> : cells[K] } | |
type PopArrayFirst<array extends any[]> = array extends [ infer First, ...infer Rest ] | |
? Rest | |
: never; | |
type SetArrayItem<array extends any[], index extends number, item extends any> = {[K in keyof array]: K extends `${index}` ? item : array[K]}; | |
type ConvertCellsToDecimal<cells extends any[][]> = {[K in keyof cells]: cells[K]["length"]} | |
type AllChars = {"\x00": 0,"\x01": 1,"\x02": 2,"\x03": 3,"\x04": 4,"\x05": 5,"\x06": 6,"\x07": 7,"\x08": 8,"\x09": 9,"\x0a": 10,"\x0b": 11,"\x0c": 12,"\x0d": 13,"\x0e": 14,"\x0f": 15,"\x10": 16,"\x11": 17,"\x12": 18,"\x13": 19,"\x14": 20,"\x15": 21,"\x16": 22,"\x17": 23,"\x18": 24,"\x19": 25,"\x1a": 26,"\x1b": 27,"\x1c": 28,"\x1d": 29,"\x1e": 30,"\x1f": 31,"\x20": 32,"\x21": 33,"\x22": 34,"\x23": 35,"\x24": 36,"\x25": 37,"\x26": 38,"\x27": 39,"\x28": 40,"\x29": 41,"\x2a": 42,"\x2b": 43,"\x2c": 44,"\x2d": 45,"\x2e": 46,"\x2f": 47,"\x30": 48,"\x31": 49,"\x32": 50,"\x33": 51,"\x34": 52,"\x35": 53,"\x36": 54,"\x37": 55,"\x38": 56,"\x39": 57,"\x3a": 58,"\x3b": 59,"\x3c": 60,"\x3d": 61,"\x3e": 62,"\x3f": 63,"\x40": 64,"\x41": 65,"\x42": 66,"\x43": 67,"\x44": 68,"\x45": 69,"\x46": 70,"\x47": 71,"\x48": 72,"\x49": 73,"\x4a": 74,"\x4b": 75,"\x4c": 76,"\x4d": 77,"\x4e": 78,"\x4f": 79,"\x50": 80,"\x51": 81,"\x52": 82,"\x53": 83,"\x54": 84,"\x55": 85,"\x56": 86,"\x57": 87,"\x58": 88,"\x59": 89,"\x5a": 90,"\x5b": 91,"\x5c": 92,"\x5d": 93,"\x5e": 94,"\x5f": 95,"\x60": 96,"\x61": 97,"\x62": 98,"\x63": 99,"\x64": 100,"\x65": 101,"\x66": 102,"\x67": 103,"\x68": 104,"\x69": 105,"\x6a": 106,"\x6b": 107,"\x6c": 108,"\x6d": 109,"\x6e": 110,"\x6f": 111,"\x70": 112,"\x71": 113,"\x72": 114,"\x73": 115,"\x74": 116,"\x75": 117,"\x76": 118,"\x77": 119,"\x78": 120,"\x79": 121,"\x7a": 122,"\x7b": 123,"\x7c": 124,"\x7d": 125,"\x7e": 126,"\x7f": 127,"\x80": 128,"\x81": 129,"\x82": 130,"\x83": 131,"\x84": 132,"\x85": 133,"\x86": 134,"\x87": 135,"\x88": 136,"\x89": 137,"\x8a": 138,"\x8b": 139,"\x8c": 140,"\x8d": 141,"\x8e": 142,"\x8f": 143,"\x90": 144,"\x91": 145,"\x92": 146,"\x93": 147,"\x94": 148,"\x95": 149,"\x96": 150,"\x97": 151,"\x98": 152,"\x99": 153,"\x9a": 154,"\x9b": 155,"\x9c": 156,"\x9d": 157,"\x9e": 158,"\x9f": 159,"\xa0": 160,"\xa1": 161,"\xa2": 162,"\xa3": 163,"\xa4": 164,"\xa5": 165,"\xa6": 166,"\xa7": 167,"\xa8": 168,"\xa9": 169,"\xaa": 170,"\xab": 171,"\xac": 172,"\xad": 173,"\xae": 174,"\xaf": 175,"\xb0": 176,"\xb1": 177,"\xb2": 178,"\xb3": 179,"\xb4": 180,"\xb5": 181,"\xb6": 182,"\xb7": 183,"\xb8": 184,"\xb9": 185,"\xba": 186,"\xbb": 187,"\xbc": 188,"\xbd": 189,"\xbe": 190,"\xbf": 191,"\xc0": 192,"\xc1": 193,"\xc2": 194,"\xc3": 195,"\xc4": 196,"\xc5": 197,"\xc6": 198,"\xc7": 199,"\xc8": 200,"\xc9": 201,"\xca": 202,"\xcb": 203,"\xcc": 204,"\xcd": 205,"\xce": 206,"\xcf": 207,"\xd0": 208,"\xd1": 209,"\xd2": 210,"\xd3": 211,"\xd4": 212,"\xd5": 213,"\xd6": 214,"\xd7": 215,"\xd8": 216,"\xd9": 217,"\xda": 218,"\xdb": 219,"\xdc": 220,"\xdd": 221,"\xde": 222,"\xdf": 223,"\xe0": 224,"\xe1": 225,"\xe2": 226,"\xe3": 227,"\xe4": 228,"\xe5": 229,"\xe6": 230,"\xe7": 231,"\xe8": 232,"\xe9": 233,"\xea": 234,"\xeb": 235,"\xec": 236,"\xed": 237,"\xee": 238,"\xef": 239,"\xf0": 240,"\xf1": 241,"\xf2": 242,"\xf3": 243,"\xf4": 244,"\xf5": 245,"\xf6": 246,"\xf7": 247,"\xf8": 248,"\xf9": 249,"\xfa": 250,"\xfb": 251,"\xfc": 252,"\xfd": 253,"\xfe": 254,"\xff": 255} | |
type FromCharCode<N extends number> = ["\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0a","\x0b","\x0c","\x0d","\x0e","\x0f","\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18","\x19","\x1a","\x1b","\x1c","\x1d","\x1e","\x1f","\x20","\x21","\x22","\x23","\x24","\x25","\x26","\x27","\x28","\x29","\x2a","\x2b","\x2c","\x2d","\x2e","\x2f","\x30","\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39","\x3a","\x3b","\x3c","\x3d","\x3e","\x3f","\x40","\x41","\x42","\x43","\x44","\x45","\x46","\x47","\x48","\x49","\x4a","\x4b","\x4c","\x4d","\x4e","\x4f","\x50","\x51","\x52","\x53","\x54","\x55","\x56","\x57","\x58","\x59","\x5a","\x5b","\x5c","\x5d","\x5e","\x5f","\x60","\x61","\x62","\x63","\x64","\x65","\x66","\x67","\x68","\x69","\x6a","\x6b","\x6c","\x6d","\x6e","\x6f","\x70","\x71","\x72","\x73","\x74","\x75","\x76","\x77","\x78","\x79","\x7a","\x7b","\x7c","\x7d","\x7e","\x7f","\x80","\x81","\x82","\x83","\x84","\x85","\x86","\x87","\x88","\x89","\x8a","\x8b","\x8c","\x8d","\x8e","\x8f","\x90","\x91","\x92","\x93","\x94","\x95","\x96","\x97","\x98","\x99","\x9a","\x9b","\x9c","\x9d","\x9e","\x9f","\xa0","\xa1","\xa2","\xa3","\xa4","\xa5","\xa6","\xa7","\xa8","\xa9","\xaa","\xab","\xac","\xad","\xae","\xaf","\xb0","\xb1","\xb2","\xb3","\xb4","\xb5","\xb6","\xb7","\xb8","\xb9","\xba","\xbb","\xbc","\xbd","\xbe","\xbf","\xc0","\xc1","\xc2","\xc3","\xc4","\xc5","\xc6","\xc7","\xc8","\xc9","\xca","\xcb","\xcc","\xcd","\xce","\xcf","\xd0","\xd1","\xd2","\xd3","\xd4","\xd5","\xd6","\xd7","\xd8","\xd9","\xda","\xdb","\xdc","\xdd","\xde","\xdf","\xe0","\xe1","\xe2","\xe3","\xe4","\xe5","\xe6","\xe7","\xe8","\xe9","\xea","\xeb","\xec","\xed","\xee","\xef","\xf0","\xf1","\xf2","\xf3","\xf4","\xf5","\xf6","\xf7","\xf8","\xf9","\xfa","\xfb","\xfc","\xfd","\xfe","\xff"][N]; | |
type GetCharCode<N extends string> = N extends keyof AllChars | |
? AllChars[N] extends number | |
? AllChars[N] | |
: never | |
: never; | |
type GetNextSquareClose<source extends string[], pos extends any[] = [], opened extends any[] = []> = pos["length"] extends source["length"] | |
? unknown | |
: source[pos["length"]] extends "]" | |
? opened["length"] extends 0 | |
? pos | |
: GetNextSquareClose<source, [ ...pos, any ], PopArrayFirst<opened>> | |
: source[pos["length"]] extends "[" | |
? GetNextSquareClose<source, [ ...pos, any ], [ ...opened, any ]> | |
: GetNextSquareClose<source, [ ...pos, any ], opened> | |
type GetLastSquareOpen<source extends string[], pos extends any[] = [], closed extends any[] = []> = source[pos["length"]] extends "[" | |
? closed["length"] extends 0 | |
? pos | |
: pos["length"] extends 0 ? unknown : GetLastSquareOpen<source, PopArrayFirst<pos>, PopArrayFirst<closed>> | |
: source[pos["length"]] extends "]" | |
? pos["length"] extends 0 ? unknown : GetLastSquareOpen<source, PopArrayFirst<pos>, [ ...closed, any ]> | |
: pos["length"] extends 0 ? unknown : GetLastSquareOpen<source, PopArrayFirst<pos>, closed> | |
type Ensure<T extends any, U extends any> = T extends U ? T : never; | |
type BrainfInterpreter<source extends string[], tapeLength extends number = 20, pos extends any[] = [], cells extends any[][] = New2DArray<tapeLength>, pointer extends any[] = [], input extends string[] = [], inputPointer extends any[] = [], output extends string = ""> = source[pos["length"]] extends string | |
? source[pos["length"]] extends "+" | |
? BrainfInterpreter<source, tapeLength, [ ...pos, any ], ModifyCell<cells, pointer, true>, pointer, input, inputPointer, output> | |
: source[pos["length"]] extends "-" | |
? BrainfInterpreter<source, tapeLength, [ ...pos, any ], ModifyCell<cells, pointer, false>, pointer, input, inputPointer, output> | |
: source[pos["length"]] extends ">" | |
? [ ...pointer, any ]["length"] extends tapeLength | |
? "BrainFuck error: tried to move pointer off tape. (too big)" | |
: BrainfInterpreter<source, tapeLength, [ ...pos, any ], cells, [ ...pointer, [] ], input,inputPointer, output> | |
: source[pos["length"]] extends "<" | |
? pointer["length"] extends 0 | |
? "BrainFuck error: tried to move pointer off tape. (too low)" | |
: BrainfInterpreter<source, tapeLength, [ ...pos, any ], cells, PopArrayFirst<pointer>, input, inputPointer, output> | |
: source[pos["length"]] extends "." | |
? BrainfInterpreter<source, tapeLength, [ ...pos, any ], cells, pointer, input, inputPointer, `${output}${FromCharCode<cells[pointer["length"]]["length"]>}`> | |
: source[pos["length"]] extends "," | |
? inputPointer["length"] extends input["length"] | |
? { reason: "no more input", pos: pos["length"], pointer: pointer["length"], output: output, cells: ConvertCellsToDecimal<cells> } | |
: BrainfInterpreter<source, tapeLength, [ ...pos, any ], SetArrayItem<cells, pointer["length"], NewArray<GetCharCode<input[inputPointer["length"]]>>>, pointer, input, [ ...inputPointer, any ], output> | |
: source[pos["length"]] extends "[" | |
? cells[pointer["length"]]["length"] extends 0 | |
? GetNextSquareClose<source, [ ...pos, any ]> extends any[] | |
? BrainfInterpreter<source, tapeLength, [ ...Ensure<GetNextSquareClose<source, [ ...pos, any ]>, any[]>, any ], cells, pointer, input, inputPointer, output> | |
: `BrainFuck error: no closing bracket found for index: ${pos["length"]}` | |
: BrainfInterpreter<source, tapeLength, [ ...pos, any ], cells, pointer, input, inputPointer, output> | |
: source[pos["length"]] extends "]" | |
? pos["length"] extends 0 | |
? `BrainFuck error: no opening bracket found for index: ${pos["length"]}` | |
: GetLastSquareOpen<source, PopArrayFirst<pos>> extends any[] | |
? BrainfInterpreter<source, tapeLength, Ensure<GetLastSquareOpen<source, PopArrayFirst<pos>>, any[]>, cells, pointer, input, inputPointer, output > | |
: `BrainFuck error: no opening bracket found for index: ${pos["length"]}, ${PopArrayFirst<pos>["length"]}` | |
: BrainfInterpreter<source, tapeLength, [ ...pos, any ], cells, pointer, input, inputPointer, output> | |
: { reason: "over", pos: pos["length"], pointer: pointer["length"], output: output, cells: ConvertCellsToDecimal<cells> } | |
export type RunBrainfuck<source extends string, tapeLength extends number = 20, input extends string = "", lastCells extends any[][] = New2DArray<tapeLength>> = | |
BrainfInterpreter<StringToArray<source>, tapeLength, [], lastCells, [], StringToArray<input>> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { RunBrainfuck } from "./brainfuck"; | |
// --------- PROGRAM --------- | |
type Program = RunBrainfuck<"+[>,----- -----]<-[+ +++++ +++++.<-]", 20, "abcdefg\x0a">; | |
// ^? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment